susi-qemu 0.0.2 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/susi +9 -4
- data/lib/disk.rb +7 -5
- data/lib/novnc/core/base64.js +104 -0
- data/lib/novnc/core/crypto/aes.js +178 -0
- data/lib/novnc/core/crypto/bigint.js +34 -0
- data/lib/novnc/core/crypto/crypto.js +90 -0
- data/lib/novnc/core/crypto/des.js +330 -0
- data/lib/novnc/core/crypto/dh.js +55 -0
- data/lib/novnc/core/crypto/md5.js +82 -0
- data/lib/novnc/core/crypto/rsa.js +132 -0
- data/lib/novnc/core/decoders/copyrect.js +27 -0
- data/lib/novnc/core/decoders/h264.js +321 -0
- data/lib/novnc/core/decoders/hextile.js +181 -0
- data/lib/novnc/core/decoders/jpeg.js +146 -0
- data/lib/novnc/core/decoders/raw.js +59 -0
- data/lib/novnc/core/decoders/rre.js +44 -0
- data/lib/novnc/core/decoders/tight.js +393 -0
- data/lib/novnc/core/decoders/tightpng.js +27 -0
- data/lib/novnc/core/decoders/zlib.js +51 -0
- data/lib/novnc/core/decoders/zrle.js +185 -0
- data/lib/novnc/core/deflator.js +84 -0
- data/lib/novnc/core/display.js +575 -0
- data/lib/novnc/core/encodings.js +53 -0
- data/lib/novnc/core/inflator.js +65 -0
- data/lib/novnc/core/input/domkeytable.js +311 -0
- data/lib/novnc/core/input/fixedkeys.js +129 -0
- data/lib/novnc/core/input/gesturehandler.js +567 -0
- data/lib/novnc/core/input/keyboard.js +294 -0
- data/lib/novnc/core/input/keysym.js +616 -0
- data/lib/novnc/core/input/keysymdef.js +688 -0
- data/lib/novnc/core/input/util.js +191 -0
- data/lib/novnc/core/input/vkeys.js +116 -0
- data/lib/novnc/core/input/xtscancodes.js +173 -0
- data/lib/novnc/core/ra2.js +312 -0
- data/lib/novnc/core/rfb.js +3257 -0
- data/lib/novnc/core/util/browser.js +172 -0
- data/lib/novnc/core/util/cursor.js +249 -0
- data/lib/novnc/core/util/element.js +32 -0
- data/lib/novnc/core/util/events.js +138 -0
- data/lib/novnc/core/util/eventtarget.js +35 -0
- data/lib/novnc/core/util/int.js +15 -0
- data/lib/novnc/core/util/logging.js +56 -0
- data/lib/novnc/core/util/strings.js +28 -0
- data/lib/novnc/core/websock.js +365 -0
- data/lib/novnc/screen.html +21 -0
- data/lib/novnc/vendor/pako/lib/utils/common.js +45 -0
- data/lib/novnc/vendor/pako/lib/zlib/adler32.js +27 -0
- data/lib/novnc/vendor/pako/lib/zlib/constants.js +47 -0
- data/lib/novnc/vendor/pako/lib/zlib/crc32.js +36 -0
- data/lib/novnc/vendor/pako/lib/zlib/deflate.js +1846 -0
- data/lib/novnc/vendor/pako/lib/zlib/gzheader.js +35 -0
- data/lib/novnc/vendor/pako/lib/zlib/inffast.js +324 -0
- data/lib/novnc/vendor/pako/lib/zlib/inflate.js +1527 -0
- data/lib/novnc/vendor/pako/lib/zlib/inftrees.js +322 -0
- data/lib/novnc/vendor/pako/lib/zlib/messages.js +11 -0
- data/lib/novnc/vendor/pako/lib/zlib/trees.js +1195 -0
- data/lib/novnc/vendor/pako/lib/zlib/zstream.js +24 -0
- data/lib/output.rb +11 -0
- data/lib/qmp.rb +6 -0
- data/lib/ssh.rb +3 -1
- data/lib/susi.rb +7 -6
- data/lib/version.rb +1 -1
- data/lib/vm.rb +44 -26
- data/lib/vnc.rb +34 -31
- metadata +57 -1
@@ -0,0 +1,24 @@
|
|
1
|
+
export default function ZStream() {
|
2
|
+
/* next input byte */
|
3
|
+
this.input = null; // JS specific, because we have no pointers
|
4
|
+
this.next_in = 0;
|
5
|
+
/* number of bytes available at input */
|
6
|
+
this.avail_in = 0;
|
7
|
+
/* total number of input bytes read so far */
|
8
|
+
this.total_in = 0;
|
9
|
+
/* next output byte should be put there */
|
10
|
+
this.output = null; // JS specific, because we have no pointers
|
11
|
+
this.next_out = 0;
|
12
|
+
/* remaining free space at output */
|
13
|
+
this.avail_out = 0;
|
14
|
+
/* total number of bytes output so far */
|
15
|
+
this.total_out = 0;
|
16
|
+
/* last error message, NULL if no error */
|
17
|
+
this.msg = ''/*Z_NULL*/;
|
18
|
+
/* not visible by applications */
|
19
|
+
this.state = null;
|
20
|
+
/* best guess about the data type: binary or text */
|
21
|
+
this.data_type = 2/*Z_UNKNOWN*/;
|
22
|
+
/* adler32 value of the uncompressed data */
|
23
|
+
this.adler = 0;
|
24
|
+
}
|
data/lib/output.rb
ADDED
data/lib/qmp.rb
CHANGED
@@ -1,9 +1,13 @@
|
|
1
1
|
require 'socket'
|
2
2
|
require 'json'
|
3
3
|
|
4
|
+
require_relative 'output'
|
5
|
+
|
4
6
|
module Susi
|
5
7
|
class QMP
|
6
8
|
def initialize(port)
|
9
|
+
Susi::debug "Connecting to QMP on port #{port}"
|
10
|
+
|
7
11
|
@port = port
|
8
12
|
@server = TCPSocket.new('localhost', @port)
|
9
13
|
|
@@ -47,9 +51,11 @@ module Susi
|
|
47
51
|
|
48
52
|
def quit
|
49
53
|
@server.puts('{"execute":"quit"}')
|
54
|
+
close
|
50
55
|
end
|
51
56
|
|
52
57
|
def close
|
58
|
+
Susi::debug "Closing QMP connection"
|
53
59
|
@server.close
|
54
60
|
end
|
55
61
|
end
|
data/lib/ssh.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'socket'
|
2
2
|
require 'net/ssh'
|
3
3
|
|
4
|
+
require_relative 'output'
|
5
|
+
|
4
6
|
module Susi
|
5
7
|
class SSH
|
6
8
|
def self.open(name)
|
@@ -11,7 +13,7 @@ module Susi
|
|
11
13
|
def self.set_hostname(name)
|
12
14
|
vm = VM.new(name)
|
13
15
|
Net::SSH.start(vm.ip, 'dabo', port: vm.ssh_port, keys: [File.expand_path('~/.ssh/id_ed25519')]) do |ssh|
|
14
|
-
|
16
|
+
Susi::debug "setting up VM..."
|
15
17
|
ssh.exec!("sudo hostnamectl set-hostname #{name}")
|
16
18
|
end
|
17
19
|
end
|
data/lib/susi.rb
CHANGED
@@ -5,6 +5,7 @@ require_relative 'vm'
|
|
5
5
|
require_relative 'ssh'
|
6
6
|
require_relative 'vnc'
|
7
7
|
require_relative 'disk'
|
8
|
+
require_relative 'output'
|
8
9
|
|
9
10
|
require 'yaml'
|
10
11
|
require 'securerandom'
|
@@ -59,15 +60,15 @@ YAML
|
|
59
60
|
# check if disk exist, if not clone it
|
60
61
|
disk_name = "#{DISK_DIR}/#{id}"
|
61
62
|
if !File.exist?("#{disk_name}.qcow2")
|
62
|
-
|
63
|
-
|
63
|
+
Susi::debug "Disk not found, cloning..."
|
64
|
+
Disk.clone(disk_template, disk_name)
|
64
65
|
|
65
|
-
|
66
|
+
VM.start(name, disk_name)
|
66
67
|
|
67
68
|
# SSH into VM and set hostname
|
68
|
-
|
69
|
+
SSH.set_hostname(name)
|
69
70
|
else
|
70
|
-
|
71
|
+
VM.start(name, disk_name)
|
71
72
|
end
|
72
73
|
end
|
73
74
|
|
@@ -83,7 +84,7 @@ YAML
|
|
83
84
|
|
84
85
|
if File.exist?(disk_name)
|
85
86
|
# verbose remove file
|
86
|
-
|
87
|
+
Susi::debug "removing #{disk_name}"
|
87
88
|
File.delete(disk_name)
|
88
89
|
end
|
89
90
|
end
|
data/lib/version.rb
CHANGED
data/lib/vm.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require_relative 'output'
|
2
|
+
|
1
3
|
module Susi
|
2
4
|
class VM
|
3
5
|
def self.running?(name)
|
@@ -13,60 +15,78 @@ module Susi
|
|
13
15
|
|
14
16
|
def initialize(name)
|
15
17
|
@name = name
|
18
|
+
@qmp = nil
|
16
19
|
@qmp_port = nil
|
17
20
|
@vnc_port = nil
|
18
21
|
@ssh_port = nil
|
19
22
|
|
23
|
+
Susi::debug "Searching for VM #{name}"
|
24
|
+
|
20
25
|
ps = `ps aux | grep qemu-system-x86_64`
|
26
|
+
Susi::debug ps
|
21
27
|
ps.split("\n").each do |line|
|
22
28
|
next unless line.match /\-name/
|
23
|
-
m = line.match(/-name (
|
29
|
+
m = line.match(/-name ([a-zA-Z0-9\-_\.]+)\s/)
|
30
|
+
Susi::debug "match: #{m[1]}"
|
24
31
|
n = m[1]
|
25
32
|
next unless n == @name
|
33
|
+
Susi::debug "Found VM #{n}"
|
26
34
|
|
27
35
|
m = line.match(/-qmp tcp:localhost:(\d+)/)
|
28
36
|
@qmp_port = m[1].to_i
|
37
|
+
Susi::debug "Found QMP port #{@qmp_port}"
|
38
|
+
end
|
39
|
+
@qmp = QMP.new(@qmp_port)
|
40
|
+
|
41
|
+
if block_given?
|
42
|
+
yield(self)
|
43
|
+
|
44
|
+
@qmp.close
|
29
45
|
end
|
30
46
|
end
|
31
47
|
|
32
48
|
def quit
|
33
|
-
QMP.new(@qmp_port) { |q| q.quit }
|
49
|
+
#QMP.new(@qmp_port) { |q| q.quit }
|
50
|
+
@qmp.quit
|
34
51
|
end
|
35
52
|
|
36
53
|
def disk
|
37
54
|
d = ''
|
38
|
-
QMP.new(@qmp_port) { |q| d = q.execute("query-block")[0]['inserted']['file'] }
|
55
|
+
#QMP.new(@qmp_port) { |q| d = q.execute("query-block")[0]['inserted']['file'] }
|
56
|
+
d = @qmp.execute("query-block")[0]['inserted']['file']
|
39
57
|
d
|
40
58
|
end
|
41
59
|
|
42
60
|
def vnc_port
|
43
61
|
@vnc_port ||= begin
|
44
62
|
port = -1
|
45
|
-
QMP.new(@qmp_port) { |q| port = q.execute("query-vnc")['service'] }
|
63
|
+
#QMP.new(@qmp_port) { |q| port = q.execute("query-vnc")['service'] }
|
64
|
+
port = @qmp.execute("query-vnc")['service']
|
46
65
|
port.to_i
|
47
66
|
end
|
48
67
|
end
|
49
68
|
|
50
69
|
def vnc_www_port
|
51
|
-
vnc_port -
|
70
|
+
vnc_port - 100
|
52
71
|
end
|
53
72
|
|
54
73
|
def vnc_websocket_port
|
55
|
-
vnc_port -
|
74
|
+
vnc_port - 200
|
56
75
|
end
|
57
76
|
|
58
77
|
def ssh_port
|
59
78
|
@ssh_port ||= begin
|
60
79
|
port = -1
|
61
|
-
QMP.new(@qmp_port) do |q|
|
62
|
-
resp = q.execute_with_args("human-monitor-command", {"command-line" => "info usernet"})
|
80
|
+
#QMP.new(@qmp_port) do |q|
|
81
|
+
#resp = q.execute_with_args("human-monitor-command", {"command-line" => "info usernet"})
|
82
|
+
resp = @qmp.execute_with_args("human-monitor-command", {"command-line" => "info usernet"})
|
63
83
|
resp = resp.split("\r\n")[2].split
|
64
84
|
src_port = resp[3].to_i
|
65
85
|
dst_port = resp[5].to_i
|
66
86
|
if dst_port == 22
|
67
87
|
port = src_port
|
68
88
|
end
|
69
|
-
end
|
89
|
+
#end
|
70
90
|
port.to_i
|
71
91
|
end
|
72
92
|
end
|
@@ -106,14 +126,10 @@ module Susi
|
|
106
126
|
qmp_port = self.get_free_port(4000, 4099)
|
107
127
|
ssh_port = self.get_free_port(2000, 2099)
|
108
128
|
vnc_port = self.get_free_port(5900, 5999)
|
109
|
-
vnc_www_port =
|
110
|
-
vnc_websocket_port =
|
129
|
+
vnc_www_port = vnc_port - 100
|
130
|
+
vnc_websocket_port = vnc_port - 200
|
111
131
|
|
112
|
-
|
113
|
-
puts "SSH Port: #{ssh_port}"
|
114
|
-
puts "VNC Port: #{vnc_port}"
|
115
|
-
puts "VNC WWW Port: #{vnc_www_port}"
|
116
|
-
puts "VNC WebSocket Port: #{vnc_websocket_port}"
|
132
|
+
Susi::debug "Starting VM #{name} with QMP on port #{qmp_port}, VNC on port #{vnc_port}, SSH on port #{ssh_port}"
|
117
133
|
|
118
134
|
cmd = []
|
119
135
|
|
@@ -138,8 +154,9 @@ module Susi
|
|
138
154
|
cmd << "-cdrom #{cdrom}"
|
139
155
|
end
|
140
156
|
|
141
|
-
|
142
|
-
|
157
|
+
cmd = cmd.join(" ")
|
158
|
+
Susi::debug cmd
|
159
|
+
system(cmd)
|
143
160
|
|
144
161
|
QMP.new(qmp_port).close
|
145
162
|
end
|
@@ -152,19 +169,20 @@ module Susi
|
|
152
169
|
# get VM access
|
153
170
|
m = line.match(/-name (\w+)/)
|
154
171
|
n = m[1]
|
155
|
-
|
172
|
+
VM.new(n) do |vm|
|
173
|
+
# get local device name or IP
|
174
|
+
ip = vm.ip
|
156
175
|
|
157
|
-
|
158
|
-
ip = Socket.ip_address_list.find { |ai| ai.ipv4? && !ai.ipv4_loopback? }
|
159
|
-
|
160
|
-
puts <<-EOF
|
176
|
+
puts <<-EOF
|
161
177
|
VM: #{n}
|
162
178
|
- Disk: #{vm.disk}
|
163
179
|
- QMP: #{vm.qmp_port}
|
164
|
-
- VNC: vnc://#{ip
|
165
|
-
- Screen: http://#{ip
|
166
|
-
-
|
180
|
+
- VNC: vnc://#{ip}:#{vm.vnc_port}
|
181
|
+
- Screen: http://#{ip}:#{vm.vnc_www_port}/
|
182
|
+
- Websocket: ws://#{ip}:#{vm.vnc_websocket_port}/
|
183
|
+
- SSH: ssh -p #{vm.ssh_port} dabo@#{ip}
|
167
184
|
EOF
|
185
|
+
end
|
168
186
|
end
|
169
187
|
end
|
170
188
|
end
|
data/lib/vnc.rb
CHANGED
@@ -1,46 +1,49 @@
|
|
1
1
|
require 'socket'
|
2
2
|
require 'webrick'
|
3
3
|
|
4
|
+
require_relative 'output'
|
5
|
+
|
4
6
|
module Susi
|
5
7
|
class VNC
|
6
8
|
def self.open(name)
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
VM.new(name) do |vm|
|
10
|
+
port = vm.vnc_www_port
|
11
|
+
token = (0...8).map { (65 + rand(26)).chr }.join
|
12
|
+
url = "http://#{vm.ip}:#{port}/#{token}.html"
|
13
|
+
Susi::info "VNC: #{url}"
|
12
14
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
15
|
+
# prepare paths and files
|
16
|
+
path = File.expand_path(File.dirname(__FILE__))
|
17
|
+
novnc_path = File.join(path, "novnc")
|
18
|
+
html = File.read(File.join(novnc_path, "screen.html"))
|
19
|
+
html.gsub!("###TOKEN###", token)
|
20
|
+
html.gsub!("###HOST###", vm.ip)
|
21
|
+
html.gsub!("###PORT###", vm.vnc_websocket_port.to_s)
|
20
22
|
|
21
|
-
|
23
|
+
server = WEBrick::HTTPServer.new(:Port => port,
|
22
24
|
:Logger => WEBrick::Log.new("/dev/null"),
|
23
25
|
:AccessLog => [])
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
26
|
+
server.mount_proc "/#{token}.html" do |req, res|
|
27
|
+
# print access by someone on command line
|
28
|
+
Susi.info "[#{Time.now}] Access by: #{req.peeraddr[3]}"
|
29
|
+
res.body = html
|
30
|
+
end
|
31
|
+
server.mount_proc "/#{token}.close.html" do |req, res|
|
32
|
+
Susi.info "[#{Time.now}] Closing by #{req.peeraddr[3]}"
|
33
|
+
res.body = "Closing VNC..."
|
34
|
+
server.shutdown
|
35
|
+
end
|
36
|
+
server.mount("/core",
|
37
|
+
WEBrick::HTTPServlet::FileHandler,
|
38
|
+
File.join(novnc_path, "core"))
|
39
|
+
server.mount("/vendor",
|
40
|
+
WEBrick::HTTPServlet::FileHandler,
|
41
|
+
File.join(novnc_path, "vendor"))
|
40
42
|
|
41
|
-
|
43
|
+
Susi::debug "[#{Time.now}] VNC screen: #{url}"
|
42
44
|
|
43
|
-
|
45
|
+
server.start
|
46
|
+
end
|
44
47
|
end
|
45
48
|
end
|
46
49
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: susi-qemu
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Bovensiepen
|
@@ -33,6 +33,62 @@ extra_rdoc_files: []
|
|
33
33
|
files:
|
34
34
|
- bin/susi
|
35
35
|
- lib/disk.rb
|
36
|
+
- lib/novnc/core/base64.js
|
37
|
+
- lib/novnc/core/crypto/aes.js
|
38
|
+
- lib/novnc/core/crypto/bigint.js
|
39
|
+
- lib/novnc/core/crypto/crypto.js
|
40
|
+
- lib/novnc/core/crypto/des.js
|
41
|
+
- lib/novnc/core/crypto/dh.js
|
42
|
+
- lib/novnc/core/crypto/md5.js
|
43
|
+
- lib/novnc/core/crypto/rsa.js
|
44
|
+
- lib/novnc/core/decoders/copyrect.js
|
45
|
+
- lib/novnc/core/decoders/h264.js
|
46
|
+
- lib/novnc/core/decoders/hextile.js
|
47
|
+
- lib/novnc/core/decoders/jpeg.js
|
48
|
+
- lib/novnc/core/decoders/raw.js
|
49
|
+
- lib/novnc/core/decoders/rre.js
|
50
|
+
- lib/novnc/core/decoders/tight.js
|
51
|
+
- lib/novnc/core/decoders/tightpng.js
|
52
|
+
- lib/novnc/core/decoders/zlib.js
|
53
|
+
- lib/novnc/core/decoders/zrle.js
|
54
|
+
- lib/novnc/core/deflator.js
|
55
|
+
- lib/novnc/core/display.js
|
56
|
+
- lib/novnc/core/encodings.js
|
57
|
+
- lib/novnc/core/inflator.js
|
58
|
+
- lib/novnc/core/input/domkeytable.js
|
59
|
+
- lib/novnc/core/input/fixedkeys.js
|
60
|
+
- lib/novnc/core/input/gesturehandler.js
|
61
|
+
- lib/novnc/core/input/keyboard.js
|
62
|
+
- lib/novnc/core/input/keysym.js
|
63
|
+
- lib/novnc/core/input/keysymdef.js
|
64
|
+
- lib/novnc/core/input/util.js
|
65
|
+
- lib/novnc/core/input/vkeys.js
|
66
|
+
- lib/novnc/core/input/xtscancodes.js
|
67
|
+
- lib/novnc/core/ra2.js
|
68
|
+
- lib/novnc/core/rfb.js
|
69
|
+
- lib/novnc/core/util/browser.js
|
70
|
+
- lib/novnc/core/util/cursor.js
|
71
|
+
- lib/novnc/core/util/element.js
|
72
|
+
- lib/novnc/core/util/events.js
|
73
|
+
- lib/novnc/core/util/eventtarget.js
|
74
|
+
- lib/novnc/core/util/int.js
|
75
|
+
- lib/novnc/core/util/logging.js
|
76
|
+
- lib/novnc/core/util/strings.js
|
77
|
+
- lib/novnc/core/websock.js
|
78
|
+
- lib/novnc/screen.html
|
79
|
+
- lib/novnc/vendor/pako/lib/utils/common.js
|
80
|
+
- lib/novnc/vendor/pako/lib/zlib/adler32.js
|
81
|
+
- lib/novnc/vendor/pako/lib/zlib/constants.js
|
82
|
+
- lib/novnc/vendor/pako/lib/zlib/crc32.js
|
83
|
+
- lib/novnc/vendor/pako/lib/zlib/deflate.js
|
84
|
+
- lib/novnc/vendor/pako/lib/zlib/gzheader.js
|
85
|
+
- lib/novnc/vendor/pako/lib/zlib/inffast.js
|
86
|
+
- lib/novnc/vendor/pako/lib/zlib/inflate.js
|
87
|
+
- lib/novnc/vendor/pako/lib/zlib/inftrees.js
|
88
|
+
- lib/novnc/vendor/pako/lib/zlib/messages.js
|
89
|
+
- lib/novnc/vendor/pako/lib/zlib/trees.js
|
90
|
+
- lib/novnc/vendor/pako/lib/zlib/zstream.js
|
91
|
+
- lib/output.rb
|
36
92
|
- lib/qmp.rb
|
37
93
|
- lib/ssh.rb
|
38
94
|
- lib/susi.rb
|