Skip to content

Commit 60d775b

Browse files
author
baslr
committed
reformated create vm form, create one vm works but is not persistent
1 parent 6dc65b8 commit 60d775b

File tree

8 files changed

+275
-66
lines changed

8 files changed

+275
-66
lines changed

isos/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*.iso

lib/qemu.coffee

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,7 @@ exports.Image = Image
88

99
exports.createImage = (cnf, callback) ->
1010
img = new Image cnf
11-
img.create callback
11+
img.create callback
12+
13+
exports.createVm = (cnf) ->
14+
return new Vm cnf.name

lib/src/image.coffee

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
fs = require 'fs'
2-
exec = require('child_process').exec
1+
fs = require 'fs'
2+
exec = require('child_process').exec
3+
imageInfo = require './imageInfo'
34

45
class Image
56
constructor: (img, size) ->
@@ -33,27 +34,7 @@ class Image
3334
callback {status:'error', data:['image already existing']}
3435

3536
info: (callback) ->
36-
exec "qemu-img info images/#{@name}.img", (err, stdout, stderr) =>
37-
b = {}
38-
for row in stdout.split('\n')
39-
if row is ''
40-
continue
41-
b[row.split(':')[0].replace(' ', '_')] = row.split(':')[1].replace ' ', ''
42-
43-
if err? or stderr isnt ''
44-
callback {status:'error', data:[err,stderr]}
45-
else
46-
b['name'] = @name
47-
b['virtual_size'] = b['virtual_size'].split('(')[1].split(' ')[0]
48-
49-
size = b['disk_size'].split ''
50-
51-
if size[size.length-1] is 'K'
52-
size.pop()
53-
size = size.join('') * 1000
54-
b['disk_size'] = size
55-
56-
callback status:'success', data:b
37+
imageInfo.info @name, callback
5738

5839
delete: (callback) ->
5940
fs.unlink "images/#{@name}.img", (err) ->

lib/src/imageInfo.coffee

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
exec = require('child_process').exec
2+
exports.info = (name, callback) ->
3+
exec "qemu-img info images/#{name}.img", (err, stdout, stderr) =>
4+
if err? or stderr isnt ''
5+
callback {status:'error', data:[err,stderr]}
6+
else
7+
b = {}
8+
for row in stdout.split('\n')
9+
if row is ''
10+
continue
11+
b[row.split(':')[0].replace(' ', '_')] = row.split(':')[1].replace ' ', ''
12+
13+
b['name'] = name
14+
b['virtual_size'] = b['virtual_size'].split('(')[1].split(' ')[0]
15+
16+
size = b['disk_size'].split ''
17+
letter = size.pop()
18+
size = size.join ''
19+
20+
console.log size
21+
22+
if letter is 'K'
23+
size = size * 1024
24+
else if letter is 'G'
25+
size = size * 1024 * 1024 * 1024
26+
b['disk_size'] = size
27+
b['percentUsed'] = 100/b['virtual_size']*b['disk_size']
28+
29+
callback status:'success', data:b

lib/src/vm.coffee

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
1+
os = require 'os'
22
net = require 'net'
33
proc = require 'child_process'
44

@@ -7,6 +7,7 @@ class Vm
77
@qmpSocket = 0
88
@process = 0
99
@dataCallback = undefined
10+
@bin = if os.type().toLowerCase() is 'darwin' then 'qemu-system-x86_64' else if os.type().toLowerCase() is 'linux' then 'qemu'
1011

1112
# set from extern
1213
@qmpPort = 0
@@ -18,7 +19,7 @@ class Vm
1819
callback()
1920

2021
startVm: ->
21-
@process = proc.spawn 'qemu', @startArgs, stdio: 'inherit', detached: true
22+
@process = proc.spawn @bin, @startArgs, stdio: 'inherit', detached: true
2223

2324
@process.on 'exit', (code, signal) ->
2425
console.log "qemuVM exit with code: #{code} and signal: #{signal}"
@@ -83,18 +84,18 @@ class Vm
8384
@startArgs.push opts
8485

8586
hd: (img) ->
86-
@pushCmd '-drive', "file=#{img},media=disk"
87+
@pushCmd '-drive', "file=images/#{img}.img,media=disk"
8788
return this
8889
cd: (img) ->
89-
@pushCmd '-drive', "file=#{img},media=cdrom"
90+
@pushCmd '-drive', "file=isos/#{img}.iso,media=cdrom"
9091
return this
9192

9293
boot: (type, once = true) ->
9394
args = ''
9495
if once is true
9596
args += 'once='
9697

97-
if type is 'hd'
98+
if type is 'hd'
9899
args = "#{args}c"
99100
else if type is 'cd'
100101
args = "#{args}d"
@@ -140,7 +141,7 @@ class Vm
140141

141142
qmp: (qmpPort) ->
142143
@qmpPort = qmpPort
143-
@pushCmd '-qmp', "tcp:localhost:#{qmpPort},server"
144+
@pushCmd '-qmp', "tcp:127.0.0.1:#{qmpPort},server"
144145
return this
145146

146147
keyboard: (keyboard) ->

public/index.html

Lines changed: 111 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@
2626
<div class="tab-content">
2727

2828
<div class="tab-pane active" id="listVmsTab">
29+
30+
<div data-bind="foreach: vms" id="vmsList">
31+
<!-- <span data-bind="text: " -->
32+
</div>
2933

3034
</div>
3135

@@ -45,35 +49,115 @@ <h3>list of images</h3>
4549
</div>
4650

4751
<div class="tab-pane" id="createTab">
52+
<div class="row-fluid">
53+
<div class="span10" style="margin-left:20px;">
4854

49-
<h3>create image</h3>
50-
51-
<form id="createImageForm">
52-
<input id="imageName" type="text" placeholder="image name" />
53-
<input id="imageSize" type="number" placeholder="size in gb" />
54-
<a id="createImage" style="margin-bottom:10px;" class="btn btn-primary">create</a>
55-
</form>
56-
57-
<h3>create vm</h3>
58-
59-
<table>
60-
<tr>
61-
<td>vm name</td>
62-
<td>ram in mib</td>
63-
<td>cpu number</td>
64-
<td>hd-image</td>
65-
<td>cd-image</td>
66-
</tr>
67-
<tr>
68-
<td> <input type="text" /></td>
69-
<td> <input type="number" class="input-mini" /></td>
70-
<td> <input type="number" class="input-mini" /></td>
71-
<td> <select class="input-medium"></select></td>
72-
<td> <select class="input-medium"></select></td>
73-
<td> <button style="margin-bottom:10px;" class="btn btn-primary">create</button></td>
74-
</tr>
75-
</table>
55+
<h3>create image</h3>
56+
57+
<form id="createImageForm">
58+
<input id="imageName" type="text" placeholder="image name" />
59+
<input id="imageSize" type="number" placeholder="size in gb" />
60+
<a id="createImage" style="margin-bottom:10px;" class="btn btn-primary">create</a>
61+
</form>
62+
63+
64+
<form id="createVmForm" class="form-horizontal">
65+
<h3>create vm</h3>
66+
<div class="control-group">
67+
<label class="control-label" for="vmName">vm name</label>
68+
<div class="controls">
69+
<input data-bind="value: vmName" type="text" id="vmName" />
70+
</div>
71+
</div>
72+
73+
<div class="control-group">
74+
<div class="controls">
75+
<label class="checkbox">
76+
<input type="checkbox" data-bind="checked: vmImageChecked">also create an hd-image
77+
</label>
78+
</div>
79+
</div>
80+
81+
<div class="control-group" data-bind="visible: vmImageChecked()">
82+
<label class="control-label" for="imageSize">hd image size in GiByte</label>
83+
<div class="controls">
84+
<input data-bind="value: imageSize" type="text" id="imageSize" />
85+
</div>
86+
</div>
87+
88+
<div class="control-group">
89+
<label class="control-label" for="vmRam">specify vm ram</label>
90+
<div class="controls">
91+
<select data-bind="options: memory, optionsText:'mem', value: selectedMemory" class="input-medium" id="vmRam"></select>
92+
</div>
93+
</div>
94+
95+
<div class="control-group">
96+
<label class="control-label" for="vmCpus">specify number of cpus</label>
97+
<div class="controls">
98+
<select data-bind="options: cpus, optionsText:'cpu', value: selectedCpu" class="input-medium" id="vmCpus"></select>
99+
</div>
100+
</div>
101+
102+
<div class="control-group" data-bind="visible: !vmImageChecked() && images().length > 0">
103+
<label class="control-label" for="vmImageName">select image name </label>
104+
<div class="controls">
105+
<select data-bind="options: images, value: selectedImage" class="input-medium" id="vmImageName"></select>
106+
</div>
107+
</div>
108+
109+
<div class="control-group">
110+
<div class="controls">
111+
<label class="checkbox">
112+
<input type="checkbox" data-bind="checked: bootOnceIso">boot once from iso image
113+
</label>
114+
</div>
115+
</div>
116+
117+
<div class="control-group" data-bind="visible: bootOnceIso()">
118+
<label class="control-label" for="vmIso">select iso image</label>
119+
<div class="controls">
120+
<select data-bind="options: isos, value: selectedIso" class="input-large" id="vmIso"></select>
121+
</div>
122+
</div>
123+
124+
<div class="control-group">
125+
<div class="controls">
126+
<label class="checkbox">
127+
<input type="checkbox" data-bind="checked: startVm">boot after creation
128+
</label>
129+
</div>
130+
</div>
131+
132+
<div class="control-group">
133+
<div class="controls">
134+
<button data-bind="click: create, enable: checkCreate" class="btn btn-primary">create</button>
135+
</div>
136+
</div>
137+
</form>
138+
139+
</div>
140+
</div>
76141
</div>
142+
143+
<!--
144+
<div class="control-group">
145+
<label class="control-label" for="inputPassword">Password</label>
146+
<div class="controls">
147+
<input type="password" id="inputPassword" placeholder="Password">
148+
</div>
149+
</div>
150+
<div class="control-group">
151+
<div class="controls">
152+
<label class="checkbox">
153+
<input type="checkbox"> Remember me
154+
</label>
155+
<button type="submit" class="btn">Sign in</button>
156+
</div>
157+
</div>
158+
</form>
159+
-->
160+
77161

78162
</div>
79163

public/js/js.coffee

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,63 @@ class ImageViewModel
2222
@images.remove image
2323
sock.emit 'deleteImage', image
2424

25+
class VmViewModel
26+
constructor: ->
27+
@images = ko.observableArray()
28+
@isos = ko.observableArray() # [{name:'deiban'},{name:'ubuntu'}]
29+
@cpus = []
30+
for i in [1..8]
31+
@cpus.push {num:i, cpu:"#{i} cpus"}
32+
33+
@memory = []
34+
for i in [1..32]
35+
@memory.push {num:i*128, mem:"#{i*128} MiByte"}
36+
37+
@selectedCpu = ko.observable @cpus[1]
38+
@selectedMemory = ko.observable @memory[7]
39+
@selectedImage = ko.observable()
40+
@selectedIso = ko.observable()
41+
@vmName = ko.observable('')
42+
@imageSize = ko.observable 100
43+
@vmImageChecked = ko.observable false
44+
@bootOnceIso = ko.observable true
45+
@startVm = ko.observable false
46+
47+
@checkCreate = ko.computed ->
48+
if @vmName().length > 3 and ( @images().length or @vmImageChecked())
49+
return true
50+
return false
51+
, this
52+
53+
add: (image) ->
54+
for n,i in @images()
55+
if n is image.name
56+
return
57+
@images.push image
58+
59+
create: (a) ->
60+
vm = { name : @vmName()
61+
, cpus : @selectedCpu().num
62+
, m : @selectedMemory().num
63+
, boot : @startVm() }
64+
65+
if @bootOnceIso()
66+
vm['bootOnce'] = @selectedIso()
67+
68+
if @vmImageChecked()
69+
vm['newImageSize'] = @imageSize()
70+
else
71+
vm['image'] = @selectedImage()
72+
@images.remove @selectedImage()
73+
sock.emit 'createVm', vm
2574

2675
imagesVM = new ImageViewModel()
76+
vmVM = new VmViewModel()
2777

78+
# setTimeout ->
79+
# vmVM.images.removeAll()
80+
# vmVM.images.push {text:'dd'}
81+
# , 10000
2882

2983
($ document).ready ->
3084
console.log "DOC -> ready"
@@ -33,7 +87,8 @@ imagesVM = new ImageViewModel()
3387
sock.on 'connect', ->
3488
console.log 'SOCK -> connected'
3589

36-
sock.emit 'images'
90+
sock.emit 'images'
91+
sock.emit 'isos'
3792

3893
sock.on 'msg', (msg) ->
3994
$.notification msg:msg.msg, type:msg.type, fixed:true
@@ -43,11 +98,16 @@ imagesVM = new ImageViewModel()
4398

4499
image['percentUsed'] = "#{100/image['virtual_size'] * image['disk_size']}%"
45100
imagesVM.add image
101+
vmVM.add image.name
102+
103+
sock.on 'iso', (name) ->
104+
vmVM.isos.push name
46105

47106
($ 'FORM#createImageForm A#createImage').click ->
48107
img = name:($ 'FORM#createImageForm INPUT#imageName').val()
49108
img.size = ($ 'FORM#createImageForm INPUT#imageSize').val()
50109

51110
sock.emit 'createImage', img
52111

53-
ko.applyBindings imagesVM, ($ 'DIV#imagesList').get 0
112+
ko.applyBindings imagesVM, ($ 'DIV#imagesList').get 0
113+
ko.applyBindings vmVM, ($ 'FORM#createVmForm').get 0

0 commit comments

Comments
 (0)