ievms-ruby 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/README.md +16 -16
- data/docs/cli.md +6 -0
- data/lib/ievms/ievms_cli.rb +55 -19
- data/lib/ievms/version.rb +1 -1
- data/lib/ievms/windows_guest.rb +175 -25
- data/test/test_helper.rb +11 -16
- data/test/test_ievms_cli.rb +69 -38
- data/test/test_ievms_win7.rb +4 -5
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 85c025ffdb4eb040906b9574aebbc02237da1cf5
|
4
|
+
data.tar.gz: b295c401b775fb07805ce59798cf76958332f1e2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0d64a6d900b41a360351e6817550c7b26a0d3d93e7c8a7c2f87483e720400a13826959ece8174f462be778c68eec1f5b20a90650f3405e53f61934e993a49ceb
|
7
|
+
data.tar.gz: 9686fb30c99d1949019601d24a64a975ad9dbada42b3f7f4b7945646cc9904aa6e9c7c5b3393bfcf3fc0066d5d44840f82bb3a9566be109a4c4474f49648b8c1
|
data/CHANGELOG.md
ADDED
data/README.md
CHANGED
@@ -6,10 +6,7 @@
|
|
6
6
|
[![Dependency Status](https://gemnasium.com/mipmip/ievms-ruby.svg)](https://gemnasium.com/mipmip/ievms-ruby)
|
7
7
|
[![Inline docs](http://inch-ci.org/github/mipmip/ievms-ruby.svg?branch=master)](http://inch-ci.org/github/mipmip/ievms-ruby)
|
8
8
|
|
9
|
-
Ruby interface for
|
10
|
-
IE boxes from https://modern.ie.
|
11
|
-
|
12
|
-
Next to [ievms.sh](https://github.com/xdissent/ievms), `ievms-ruby` also works great in combination with [iectrl](https://github.com/xdissent/iectrl).
|
9
|
+
Ruby interface for managing and provisioning IE/Windows Machines from https://modern.ie.
|
13
10
|
|
14
11
|
## WinBoxes supported
|
15
12
|
|
@@ -23,9 +20,9 @@ Next to [ievms.sh](https://github.com/xdissent/ievms), `ievms-ruby` also works g
|
|
23
20
|
|
24
21
|
* Upload and download files from guest machine
|
25
22
|
* Execute cmd.exe and powershell commands on guest machine
|
26
|
-
* Execute
|
27
|
-
*
|
28
|
-
*
|
23
|
+
* Execute commands on guest machine as admin
|
24
|
+
* CLI with shortcut commands for Windows guests like `cat`, `ps`, `reboot` and `shutdown`
|
25
|
+
* Integrated Chocolatey commands to easily install packages
|
29
26
|
|
30
27
|
## Requirements
|
31
28
|
|
@@ -34,10 +31,6 @@ Next to [ievms.sh](https://github.com/xdissent/ievms), `ievms-ruby` also works g
|
|
34
31
|
* VirtualBox Extension Pack and Guest Additions >= 5.0.6
|
35
32
|
* Windows Machines created by [ievms](https://github.com/xdissent/ievms)
|
36
33
|
|
37
|
-
### Recommended
|
38
|
-
* [iectrl](https://github.com/xdissent/iectrl), cli interface for simple
|
39
|
-
ievms admin commands
|
40
|
-
|
41
34
|
## Usage
|
42
35
|
|
43
36
|
### As library
|
@@ -59,6 +52,8 @@ $ ievmsrb help
|
|
59
52
|
|
60
53
|
Commands:
|
61
54
|
ievmsrb cat [vbox name] [file path] # cat file from path in Win vbox
|
55
|
+
ievmsrb choco_inst [vbox name] [package] # Install package in win box with Chocolatey
|
56
|
+
ievmsrb choco_uninst [vbox name] [package] # Uninstall package in win box with Chocolatey
|
62
57
|
ievmsrb cmd [vbox name] [command to execute] # Run command with cmd.exe in Win vbox
|
63
58
|
ievmsrb cmd_adm [vbox name] [command to execute] # Run command as Administrator with cmd.exe in Win vbox
|
64
59
|
ievmsrb copy_from [vbox name] [path in vbox] [local file] # Copy file from Win vbox to local path
|
@@ -66,8 +61,17 @@ Commands:
|
|
66
61
|
ievmsrb copy_to_as_adm [vbox name] [local file] [path in vbox] # Copy local file to Win vbox as Administrator
|
67
62
|
ievmsrb help [COMMAND] # Describe available commands or one specific command
|
68
63
|
ievmsrb ps [vbox name] # Show running tasks in Win vbox
|
64
|
+
ievmsrb pwrsh_as_adm [vbox name] [command to execute] # Run command as Administrator with PowerShell in Win vbox
|
69
65
|
ievmsrb reboot [vbox name] # Reboot Win box
|
66
|
+
ievmsrb reset_ievms_taskmgr [vbox name] # Reset ievms task manager
|
67
|
+
ievmsrb restore_clean [vbox name] # Restore clean snapshot
|
70
68
|
ievmsrb shutdown [vbox name] # Shutdown Win vbox
|
69
|
+
ievmsrb start [vbox name] # Start Win box
|
70
|
+
ievmsrb version # display version
|
71
|
+
|
72
|
+
Options:
|
73
|
+
-v, [--verbose], [--no-verbose] # Be more verbose
|
74
|
+
[--timeout=N] # Timeout in seconds
|
71
75
|
```
|
72
76
|
|
73
77
|
Read the docs for more info about [ievms-ruby CLI usage](http://mipmip.github.io/ievms-ruby/cli/).
|
@@ -83,12 +87,8 @@ To run the tests you need to fullfil the testing requirements first:
|
|
83
87
|
|
84
88
|
* "IE9 - Win7" installed by ievms.sh and make sure its running
|
85
89
|
|
86
|
-
* [iectrl](https://github.com/xdissent/iectrl), cli interface for simple
|
87
|
-
|
88
90
|
```bash
|
89
|
-
|
90
|
-
$ echo 'PATH="$HOME/node_modules/.bin:$PATH"' >> ~/.profile
|
91
|
-
$ source ~/.Provider
|
91
|
+
curl -s https://raw.githubusercontent.com/xdissent/ievms/master/ievms.sh | env IEVMS_VERSIONS="9" bash
|
92
92
|
```
|
93
93
|
|
94
94
|
* Create an new virtual machine called `standbymachine`. Keep the disk size as
|
data/docs/cli.md
CHANGED
@@ -54,3 +54,9 @@ Turn of the Filewall executing a command as Administator
|
|
54
54
|
$ ievmsrb cmd_adm "IE9 - Win7" 'NetSh Advfirewall set allprofiles state off'
|
55
55
|
```
|
56
56
|
|
57
|
+
|
58
|
+
Show all current account information
|
59
|
+
To display the user rights that have been assigned to the account you used to log on to a Windows system, use the whoami command line tool with the /priv switch:
|
60
|
+
```
|
61
|
+
ievmsrb cmd "IE9 - Win7" "Whoami /ALL"
|
62
|
+
```
|
data/lib/ievms/ievms_cli.rb
CHANGED
@@ -2,70 +2,106 @@ class IevmsRb < Thor
|
|
2
2
|
class_option :verbose, :desc => 'Be more verbose', :type => :boolean, :aliases => '-v'
|
3
3
|
class_option :timeout, :desc => 'Timeout in seconds', :type => :numeric
|
4
4
|
|
5
|
+
def initialize(*args)
|
6
|
+
super
|
7
|
+
|
8
|
+
#p args
|
9
|
+
|
10
|
+
if args[0].count > 0
|
11
|
+
@machine = Ievms::WindowsGuest.new args[0][0]
|
12
|
+
@machine.verbose = true if options[:verbose]
|
13
|
+
@machine.timeout_secs = options[:timeout] if options[:timeout]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
desc "version", "display version"
|
18
|
+
def version
|
19
|
+
print Ievms::VERSION
|
20
|
+
end
|
21
|
+
|
5
22
|
desc "cat [vbox name] [file path]", "cat file from path in Win vbox"
|
6
23
|
def cat(vbox_name,guest_path)
|
7
|
-
init vbox_name
|
8
24
|
print @machine.download_string_from_file_to_guest guest_path, true
|
9
25
|
end
|
10
26
|
|
11
27
|
desc "ps [vbox name]", "Show running tasks in Win vbox"
|
12
28
|
def ps(vbox_name)
|
13
|
-
init vbox_name
|
14
29
|
print @machine.run_command "tasklist"
|
15
30
|
end
|
16
31
|
|
17
32
|
desc "shutdown [vbox name]", "Shutdown Win vbox"
|
18
33
|
def shutdown(vbox_name)
|
19
|
-
|
20
|
-
print @machine.run_command "shutdown.exe /s /f /t 0"
|
34
|
+
@machine.shutdown
|
21
35
|
end
|
22
36
|
|
37
|
+
option :gui, :desc => 'start as gui', :type => :boolean
|
38
|
+
desc "start [vbox name]", "Start Win box"
|
39
|
+
def start(vbox_name)
|
40
|
+
@machine.headless = false if options[:gui]
|
41
|
+
@machine.start
|
42
|
+
end
|
43
|
+
|
44
|
+
desc "restore_clean [vbox name]", "Restore clean snapshot"
|
45
|
+
def restore_clean(vbox_name)
|
46
|
+
@machine.restore_clean_snapshot
|
47
|
+
end
|
23
48
|
desc "reboot [vbox name]", "Reboot Win box"
|
24
49
|
def reboot(vbox_name)
|
25
|
-
|
26
|
-
print @machine.run_command "shutdown.exe /r /f /t 0"
|
50
|
+
@machine.reboot
|
27
51
|
end
|
28
52
|
|
29
53
|
desc "copy_to_as_adm [vbox name] [local file] [path in vbox]", "Copy local file to Win vbox as Administrator"
|
30
54
|
def copy_to_as_adm(vbox_name,local_path, guest_path)
|
31
|
-
init vbox_name
|
32
55
|
@machine.upload_file_to_guest_as_admin(local_path, guest_path, false)
|
33
56
|
end
|
34
57
|
|
35
58
|
desc "copy_to [vbox name] [local file] [path in vbox]", "Copy local file to Win vbox"
|
36
59
|
def copy_to(vbox_name,local_path, guest_path)
|
37
|
-
init vbox_name
|
38
60
|
@machine.upload_file_to_guest(local_path, guest_path, false)
|
39
61
|
end
|
40
62
|
|
41
63
|
desc "copy_from [vbox name] [path in vbox] [local file]", "Copy file from Win vbox to local path"
|
42
64
|
def copy_from(vbox_name, guest_path, local_path)
|
43
|
-
init vbox_name
|
44
65
|
@machine.download_file_from_guest(guest_path, local_path, false)
|
45
66
|
end
|
46
67
|
|
47
68
|
desc "cmd [vbox name] [command to execute]", "Run command with cmd.exe in Win vbox"
|
48
69
|
def cmd(vbox_name,command)
|
49
|
-
init vbox_name
|
50
|
-
|
51
70
|
print @machine.run_command command
|
52
71
|
print "\n"
|
53
72
|
end
|
54
73
|
|
55
74
|
desc "cmd_adm [vbox name] [command to execute]", "Run command as Administrator with cmd.exe in Win vbox"
|
56
75
|
def cmd_as_adm(vbox_name,command)
|
57
|
-
init vbox_name
|
58
|
-
|
59
76
|
print @machine.run_command_as_admin command
|
60
77
|
end
|
61
78
|
|
62
|
-
|
79
|
+
# desc "pwrsh [vbox name] [command to execute]", "Run command with PowerShell in Win vbox"
|
80
|
+
# def pwrsh(vbox_name,command)
|
81
|
+
# print @machine.run_powershell_cmd command
|
82
|
+
# end
|
83
|
+
|
84
|
+
desc "pwrsh_as_adm [vbox name] [command to execute]", "Run command as Administrator with PowerShell in Win vbox"
|
85
|
+
def pwrsh_as_adm(vbox_name,command)
|
86
|
+
print @machine.run_powershell_cmd_as_admin command
|
87
|
+
end
|
88
|
+
|
89
|
+
desc "choco_inst [vbox name] [package]", "Install package in win box with Chocolatey"
|
90
|
+
def choco_inst(vbox_name,pkg)
|
91
|
+
@machine.choco_install pkg
|
92
|
+
end
|
63
93
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
@machine.verbose = true if options[:verbose]
|
68
|
-
@machine.timeout_secs = options[:timeout] if options[:timeout]
|
94
|
+
desc "choco_uninst [vbox name] [package]", "Uninstall package in win box with Chocolatey"
|
95
|
+
def choco_uninst(vbox_name,pkg)
|
96
|
+
@machine.choco_uninstall pkg
|
69
97
|
end
|
98
|
+
|
99
|
+
desc "reset_ievms_taskmgr [vbox name]", "Reset ievms task manager"
|
100
|
+
def reset_ievms_taskmgr(vbox_name)
|
101
|
+
@machine.end_ievms_task
|
102
|
+
end
|
103
|
+
|
104
|
+
private
|
105
|
+
|
70
106
|
end
|
71
107
|
|
data/lib/ievms/version.rb
CHANGED
data/lib/ievms/windows_guest.rb
CHANGED
@@ -16,18 +16,21 @@ IEVMS_HOME = ENV['HOME']+'/.ievms'
|
|
16
16
|
module Ievms
|
17
17
|
class WindowsGuest
|
18
18
|
attr_accessor :verbose
|
19
|
+
attr_accessor :headless
|
19
20
|
attr_accessor :timeout_secs
|
20
21
|
|
21
22
|
def initialize(vbox_name)
|
23
|
+
@vbox_name = vbox_name
|
24
|
+
|
25
|
+
check_virtualbox_version
|
26
|
+
is_vm?
|
22
27
|
|
23
28
|
@verbose = false
|
29
|
+
@headless = true
|
24
30
|
@timeout_secs = 600 #default timeout for a single task 5 minutes
|
25
|
-
|
26
|
-
@vbox_name = vbox_name
|
27
|
-
|
28
|
-
is_vm vbox_name
|
29
31
|
end
|
30
32
|
|
33
|
+
# copy file from guest (win) machine to host machine
|
31
34
|
def download_file_from_guest(guest_path, local_path, quiet=false)
|
32
35
|
|
33
36
|
log_stdout "Copying #{guest_path} to #{local_path}", quiet
|
@@ -55,17 +58,23 @@ module Ievms
|
|
55
58
|
FileUtils.rm File.join(IEVMS_HOME,File.basename(local_path))
|
56
59
|
end
|
57
60
|
|
61
|
+
# return string from remote file
|
58
62
|
def download_string_from_file_to_guest( guest_path, quiet=false)
|
59
63
|
log_stdout "Copying #{guest_path} to tempfile.txt", quiet
|
60
64
|
guestcontrol_exec "cmd.exe", "cmd.exe /c copy \"#{guest_path}\" \"E:\\tmpfile.txt\""
|
61
65
|
|
62
|
-
|
63
|
-
|
66
|
+
tmpfile = File.join(IEVMS_HOME,'tmpfile.txt')
|
67
|
+
if File.exists? tmpfile
|
68
|
+
string = IO.read(tmpfile)
|
69
|
+
FileUtils.rm tmpfile
|
70
|
+
else
|
71
|
+
string = ''
|
72
|
+
end
|
64
73
|
string
|
65
74
|
end
|
66
75
|
|
76
|
+
# make remote file from string
|
67
77
|
def upload_string_as_file_to_guest(string, guest_path, quiet=false)
|
68
|
-
|
69
78
|
tmp = Tempfile.new('txtfile')
|
70
79
|
tmp.write "#{string}\n"
|
71
80
|
path = tmp.path
|
@@ -86,13 +95,20 @@ module Ievms
|
|
86
95
|
run_command 'del C:\Users\IEUser\.tempadminfile', true
|
87
96
|
end
|
88
97
|
|
89
|
-
# execute
|
90
|
-
def run_command_as_admin(command,quiet=false)
|
98
|
+
# execute existing batch file in Windows guest as Administrator
|
99
|
+
def run_command_as_admin(command,quiet=false, dont_wait=false)
|
91
100
|
log_stdout "Executing command as administrator: #{command}", quiet
|
92
101
|
|
93
102
|
run_command 'if exist C:\Users\IEUser\ievms.bat del C:\Users\IEUser\ievms.bat && Exit', true
|
103
|
+
upload_string_as_file_to_guest('C:\Users\IEUser\ievms_cmd.bat > C:\Users\IEUser\ievms.txt', 'C:\Users\IEUser\ievms.bat', true)
|
94
104
|
|
95
|
-
|
105
|
+
run_command 'if exist C:\Users\IEUser\ievms.bat del C:\Users\IEUser\ievms_cmd.bat && Exit', true
|
106
|
+
upload_string_as_file_to_guest(command, 'C:\Users\IEUser\ievms_cmd.bat', true)
|
107
|
+
|
108
|
+
if(dont_wait)
|
109
|
+
guestcontrol_exec "schtasks.exe", "schtasks.exe /run /tn ievms"
|
110
|
+
return
|
111
|
+
end
|
96
112
|
|
97
113
|
_ = Timeout::timeout(@timeout_secs) {
|
98
114
|
|
@@ -108,6 +124,9 @@ module Ievms
|
|
108
124
|
end
|
109
125
|
}
|
110
126
|
|
127
|
+
run_command 'if exist C:\Users\IEUser\ievms.bat del C:\Users\IEUser\ievms_cmd.bat && Exit', true
|
128
|
+
print download_string_from_file_to_guest 'c:\Users\IEUser\ievms.txt' unless quiet
|
129
|
+
download_string_from_file_to_guest 'c:\Users\IEUser\ievms.txt', true
|
111
130
|
end
|
112
131
|
|
113
132
|
# execute existing batch file in Windows guest
|
@@ -117,14 +136,136 @@ module Ievms
|
|
117
136
|
out
|
118
137
|
end
|
119
138
|
|
139
|
+
|
140
|
+
#def run_powershell_cmd(command, quiet=false)
|
141
|
+
# run_command '@powershell -NoProfile -Command "' + command +'"', quiet
|
142
|
+
#end
|
143
|
+
|
144
|
+
def run_powershell_cmd_as_admin(command, quiet=false)
|
145
|
+
run_command_as_admin '@powershell -NoProfile -ExecutionPolicy unrestricted -Command "' + command + '"', quiet
|
146
|
+
end
|
147
|
+
|
148
|
+
# shutdown windows machine
|
149
|
+
def shutdown(quiet=false)
|
150
|
+
log_stdout "Trying to shutdown ...", false if @verbose
|
151
|
+
if powered_off?
|
152
|
+
log_stdout "Already powered off.", false
|
153
|
+
else
|
154
|
+
log_stdout "shutting down ...", quiet
|
155
|
+
# run_command_as_admin "shutdown.exe /s /f /t 0", quiet
|
156
|
+
run_command "shutdown.exe /s /f /t 0", quiet
|
157
|
+
wait_for_shutdown
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
# start windows, finish as soon as boot is complete
|
162
|
+
def start(quiet=false)
|
163
|
+
if powered_off?
|
164
|
+
log_stdout "starting ...", quiet
|
165
|
+
|
166
|
+
if(@headless)
|
167
|
+
type = 'headless'
|
168
|
+
else
|
169
|
+
type = 'gui'
|
170
|
+
end
|
171
|
+
`VBoxManage startvm "#{@vbox_name}" --type #{type}`
|
172
|
+
wait_for_guestcontrol
|
173
|
+
else
|
174
|
+
log_stdout "Already started ...", quiet
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
# reboot windows machine
|
179
|
+
def reboot(quiet=false)
|
180
|
+
log_stdout "rebooting...", quiet
|
181
|
+
shutdown(true)
|
182
|
+
start(true)
|
183
|
+
end
|
184
|
+
|
185
|
+
def restore_clean_snapshot(quiet=false)
|
186
|
+
log_stdout "Restoring Clean Snapshot ...", quiet
|
187
|
+
shutdown
|
188
|
+
cmd = "VBoxManage snapshot \"#{@vbox_name}\" restore clean"
|
189
|
+
log_stdout cmd, false if @verbose
|
190
|
+
stdout,_,_ = Open3.capture3(cmd)
|
191
|
+
print stdout
|
192
|
+
end
|
193
|
+
|
194
|
+
# show status of administrative ievms task.
|
120
195
|
def schtasks_query_ievms
|
121
196
|
out, _, _ = guestcontrol_exec "schtasks.exe", "schtasks.exe /query /tn ievms"
|
122
197
|
out
|
123
198
|
end
|
124
199
|
|
200
|
+
# install choco package(s)
|
201
|
+
def choco_install(pkg, quiet=false)
|
202
|
+
if ! chocolatey?
|
203
|
+
log_stdout "First time.. installing Chocolatey first", quiet
|
204
|
+
install_chocolatey
|
205
|
+
end
|
206
|
+
|
207
|
+
log_stdout "Installing with choco: #{pkg} \n", quiet
|
208
|
+
run_powershell_cmd_as_admin("choco install -y #{pkg}", false)
|
209
|
+
end
|
210
|
+
|
211
|
+
# uninstall package(s)
|
212
|
+
def choco_uninstall(pkg,quiet=false)
|
213
|
+
if chocolatey?
|
214
|
+
log_stdout "Uninstalling with choco: #{pkg} \n", false
|
215
|
+
run_powershell_cmd_as_admin("cuninst -y #{pkg}", false)
|
216
|
+
else
|
217
|
+
log_stdout "Chocolatey is not installed, guess you don't need to uninstall anything.", quiet
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
# is chocolatey installed
|
222
|
+
def chocolatey?
|
223
|
+
out = run_command_as_admin('@powershell -Command "choco"',false)
|
224
|
+
if out.include?("CommandNotFoundException")
|
225
|
+
return false
|
226
|
+
else
|
227
|
+
return true
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
# install the Chocolatey Package Manager for Windows
|
232
|
+
def install_chocolatey(quiet=false)
|
233
|
+
log_stdout "Installing Chocolatey", quiet
|
234
|
+
run_command_as_admin('@powershell -NoProfile -ExecutionPolicy unrestricted -Command "(iex ((new-object net.webclient).DownloadString(\'https://chocolatey.org/install.ps1\'))) >$null 2>&1" && SET PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin')
|
235
|
+
reboot
|
236
|
+
end
|
237
|
+
|
238
|
+
# end the administrative task
|
239
|
+
def end_ievms_task(quiet=true)
|
240
|
+
run_command('schtasks.exe /End /TN ievms', quiet)
|
241
|
+
end
|
242
|
+
|
243
|
+
# true when machine powered off
|
244
|
+
def powered_off?
|
245
|
+
cmd = "VBoxManage showvminfo \"#{@vbox_name}\" | grep \"State:\""
|
246
|
+
print cmd if @verbose
|
247
|
+
out = `#{cmd}`
|
248
|
+
print out if @verbose
|
249
|
+
if out.include?('powered off') || out.include?('aborted')
|
250
|
+
return true
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
# return true when run level is 3 boot complete
|
255
|
+
def boot_complete?
|
256
|
+
out = `VBoxManage showvminfo "#{@vbox_name}" | grep 'Additions run level:'`
|
257
|
+
print out if @verbose
|
258
|
+
if out[-2..-2].to_i == 3
|
259
|
+
return true
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
###############################################################
|
264
|
+
|
125
265
|
private
|
126
266
|
|
127
267
|
def log_stdout(msg, quiet=true)
|
268
|
+
quiet = false if @verbose
|
128
269
|
print "[#{@vbox_name}] #{msg}\n" unless quiet
|
129
270
|
end
|
130
271
|
|
@@ -133,7 +274,7 @@ module Ievms
|
|
133
274
|
def guestcontrol_exec(image, cmd)
|
134
275
|
|
135
276
|
_ = Timeout::timeout(@timeout_secs) {
|
136
|
-
wait_for_guestcontrol
|
277
|
+
wait_for_guestcontrol
|
137
278
|
cmd = "VBoxManage guestcontrol \"#{@vbox_name}\" run --username \"#{USERNAME}\" --password '#{PASSWD}' --exe \"#{image}\" -- #{cmd}"
|
138
279
|
|
139
280
|
log_stdout cmd, false if @verbose
|
@@ -143,29 +284,38 @@ module Ievms
|
|
143
284
|
|
144
285
|
end
|
145
286
|
|
146
|
-
# function taken from ievms
|
147
287
|
# Pause execution until guest control is available for a virtual machine
|
148
|
-
def wait_for_guestcontrol
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
out = `VBoxManage showvminfo "#{vboxname}" | grep 'Additions run level:'`
|
153
|
-
run_level = out[-2..-2].to_i
|
154
|
-
if run_level < 3
|
155
|
-
sleep 3
|
156
|
-
end
|
288
|
+
def wait_for_guestcontrol
|
289
|
+
until boot_complete? do
|
290
|
+
print "Waiting for #{@vbox_name} to be available for guestcontrol...\n" if @verbose
|
291
|
+
sleep 3
|
157
292
|
end
|
158
293
|
end
|
159
294
|
|
160
|
-
#
|
161
|
-
def
|
162
|
-
|
295
|
+
# Pause execution until guest machine has shut down
|
296
|
+
def wait_for_shutdown
|
297
|
+
until powered_off? do
|
298
|
+
print "Waiting for #{@vbox_name} to be finished shutdown...\n" if @verbose
|
299
|
+
sleep 3
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
# raise when version is not compatible
|
304
|
+
def check_virtualbox_version
|
305
|
+
if Gem::Version.new(`VBoxManage -v`.strip.split('r')[0]) < Gem::Version.new('5.0.6')
|
306
|
+
raise "VirtualBox >= 5.0.6 is not installed"
|
307
|
+
end
|
308
|
+
end
|
163
309
|
|
310
|
+
# raise when name is not a virtual machine in VirtualBox
|
311
|
+
def is_vm?
|
312
|
+
cmd = "VBoxManage showvminfo \"#{@vbox_name}\""
|
164
313
|
_, stderr, _ = Open3.capture3(cmd)
|
165
314
|
if stderr.include? 'Could not find a registered machine named'
|
166
|
-
raise "Virtual Machine #{
|
315
|
+
raise "Virtual Machine #{@vbox_name} does not exist"
|
167
316
|
end
|
168
317
|
end
|
169
318
|
|
319
|
+
|
170
320
|
end
|
171
321
|
end
|
data/test/test_helper.rb
CHANGED
@@ -1,10 +1,15 @@
|
|
1
1
|
require 'simplecov'
|
2
|
+
require 'thor'
|
3
|
+
require 'timeout'
|
2
4
|
|
3
5
|
SimpleCov.start do
|
4
6
|
add_filter '/test/'
|
5
7
|
add_filter '/vendor/'
|
6
8
|
end
|
7
9
|
|
10
|
+
require 'ievms/ievms_cli'
|
11
|
+
require 'ievms/windows_guest'
|
12
|
+
|
8
13
|
require 'minitest'
|
9
14
|
require 'minitest/unit'
|
10
15
|
require 'minitest/autorun'
|
@@ -13,6 +18,12 @@ require 'minitest/pride'
|
|
13
18
|
require "codeclimate-test-reporter"
|
14
19
|
CodeClimate::TestReporter.start
|
15
20
|
|
21
|
+
machine = Ievms::WindowsGuest.new 'IE9 - Win7'
|
22
|
+
machine.headless=true
|
23
|
+
machine.verbose=false
|
24
|
+
machine.restore_clean_snapshot
|
25
|
+
machine = nil
|
26
|
+
|
16
27
|
module IevmsRubyTestsShared
|
17
28
|
|
18
29
|
def initialize(name = nil)
|
@@ -21,20 +32,4 @@ module IevmsRubyTestsShared
|
|
21
32
|
super(name) unless name.nil?
|
22
33
|
end
|
23
34
|
|
24
|
-
def ensure_machine_running vbox_name
|
25
|
-
|
26
|
-
iectrl = `iectrl status "#{vbox_name}"`
|
27
|
-
if not iectrl.include?('RUNNING')
|
28
|
-
iectrl = `iectrl start "#{vbox_name}"`
|
29
|
-
sleep 5
|
30
|
-
iectrl = `iectrl status "#{vbox_name}"`
|
31
|
-
if not iectrl.include?('RUNNING')
|
32
|
-
iectrl = `VBoxManage startvm --type headless "#{vbox_name}"`
|
33
|
-
sleep 5
|
34
|
-
end
|
35
|
-
|
36
|
-
IevmsRb.start(['ps', "IE9 - Win7"])
|
37
|
-
end
|
38
|
-
|
39
|
-
end
|
40
35
|
end
|
data/test/test_ievms_cli.rb
CHANGED
@@ -1,101 +1,132 @@
|
|
1
1
|
require 'test_helper'
|
2
|
-
require 'thor'
|
3
|
-
require 'ievms/ievms_cli'
|
4
|
-
require 'ievms/windows_guest'
|
5
|
-
require 'timeout'
|
6
2
|
|
7
3
|
class TestWin7 < Minitest::Test
|
8
4
|
include IevmsRubyTestsShared
|
9
5
|
|
10
|
-
|
11
6
|
def setup
|
12
|
-
|
7
|
+
machine = Ievms::WindowsGuest.new 'IE9 - Win7'
|
8
|
+
machine.headless=true
|
9
|
+
machine.verbose=false
|
10
|
+
machine.start
|
13
11
|
end
|
14
12
|
|
15
13
|
def test_timeout_option
|
16
14
|
assert_raises {
|
17
|
-
|
15
|
+
run_thor_capture(["cmd", "IE9 - Win7", "ping 127.0.0.1 -n 6 > nul", "--verbose", "--timeout", "3" ])
|
18
16
|
}
|
19
17
|
end
|
20
18
|
|
21
19
|
def test_ps
|
22
|
-
assert_equal true,
|
20
|
+
assert_equal true, run_thor_capture(["ps", "IE9 - Win7"]).include?('winlogon.exe')
|
23
21
|
end
|
24
22
|
|
25
23
|
def test_help
|
26
|
-
assert_equal true,
|
27
|
-
assert_equal true,
|
24
|
+
assert_equal true, run_thor_capture([]).include?('[vbox name]')
|
25
|
+
assert_equal true, run_thor_capture(['help']).include?('[file path]')
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_version
|
29
|
+
assert_equal Ievms::VERSION, run_thor_capture(['version'])
|
28
30
|
end
|
29
31
|
|
30
32
|
def test_copy_from
|
31
33
|
FileUtils.rm '/tmp/testdlfile2.txt' if File.exists? '/tmp/testdlfile2.txt'
|
32
|
-
out =
|
34
|
+
out = run_thor_capture ['copy_from',"IE9 - Win7",'C:\ievms.xml', '/tmp/testdlfile2.txt']
|
33
35
|
|
34
36
|
assert_equal out, "[IE9 - Win7] Copying C:\\ievms.xml to /tmp/testdlfile2.txt\n"
|
35
37
|
assert_equal true, File.exists?('/tmp/testdlfile2.txt')
|
36
38
|
end
|
37
39
|
|
38
40
|
def test_copy_to
|
39
|
-
|
41
|
+
run_thor ['cmd', "IE9 - Win7", 'if exist C:\Users\IEUser\ievms_test_upload3.txt del C:\Users\IEUsers\ievms_test_upload3.txt && Exit']
|
40
42
|
FileUtils.rm '/tmp/ievms_test_upload3.txt' if File.exists? '/tmp/ievms_test_upload3.txt'
|
41
43
|
`echo "uploadasadmin_yes" > /tmp/ievms_test_upload3.txt`
|
42
|
-
out =
|
43
|
-
out2 =
|
44
|
+
out = run_thor_capture ['copy_to',"IE9 - Win7", '/tmp/ievms_test_upload3.txt', 'C:\Users\IEUser\ievms_test_upload3.txt']
|
45
|
+
out2 = run_thor_capture ['cat',"IE9 - Win7", 'C:\Users\IEUser\ievms_test_upload3.txt']
|
44
46
|
assert_equal "[IE9 - Win7] Copying /tmp/ievms_test_upload3.txt to C:\\Users\\IEUser\\ievms_test_upload3.txt\n", out
|
45
47
|
assert_match(/uploadasadmin_yes/, out2)
|
46
48
|
end
|
47
49
|
|
48
50
|
def test_copy_to_as_adm
|
49
|
-
|
51
|
+
run_thor ['cmd_as_adm', "IE9 - Win7", 'if exist C:\ievms_test_upload2.txt del C:\ievms_test_upload2.txt && Exit']
|
50
52
|
FileUtils.rm '/tmp/ievms_test_upload2.txt' if File.exists? '/tmp/ievms_test_upload2.txt'
|
51
53
|
`echo "uploadasadmin_yes" > /tmp/ievms_test_upload2.txt`
|
52
54
|
|
53
|
-
out =
|
54
|
-
out2 =
|
55
|
+
out = run_thor_capture ['copy_to_as_adm',"IE9 - Win7", '/tmp/ievms_test_upload2.txt', 'C:\ievms_test_upload2.txt']
|
56
|
+
out2 = run_thor_capture ['cat',"IE9 - Win7", 'C:\ievms_test_upload2.txt']
|
55
57
|
assert_equal "[IE9 - Win7] Copying /tmp/ievms_test_upload2.txt to C:\\ievms_test_upload2.txt as Administrator\n", out
|
56
58
|
assert_match(/uploadasadmin_yes/, out2)
|
57
59
|
end
|
58
60
|
|
59
61
|
def test_reboot
|
60
|
-
sysinfo =
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
62
|
+
# sysinfo = run_thor_capture(['cmd', "IE9 - Win7", 'systeminfo'])
|
63
|
+
# print sysinfo
|
64
|
+
# boottime1 = sysinfo.lines.find { |line| line.include?("Boot") }
|
65
|
+
# print boottime1
|
66
|
+
|
67
|
+
run_thor(['reboot', "IE9 - Win7"])
|
68
|
+
|
69
|
+
# sysinfo2 = run_thor_capture(['cmd', "IE9 - Win7", 'systeminfo'])
|
70
|
+
# boottime2 = sysinfo2.lines.find { |line| line.include?("Boot") }
|
71
|
+
# p sysinfo2
|
72
|
+
# print boottime2
|
73
|
+
#refute_equal boottime1, boottime2
|
74
|
+
#FIXME update?
|
69
75
|
end
|
70
76
|
|
71
77
|
def test_shutdown
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
iectrl2 = `iectrl status "IE9 - Win7"`
|
79
|
-
refute_match(/RUNNING/, iectrl2)
|
78
|
+
machine = Ievms::WindowsGuest.new 'IE9 - Win7'
|
79
|
+
assert_equal(true, machine.boot_complete?)
|
80
|
+
run_thor(['shutdown', "IE9 - Win7"])
|
81
|
+
assert_equal(true, machine.powered_off?)
|
82
|
+
assert_match(/Already\ powered\ off/ , run_thor_capture(['shutdown', "IE9 - Win7"]))
|
80
83
|
end
|
81
84
|
|
82
85
|
def test_cat
|
83
|
-
out =
|
86
|
+
out = run_thor_capture(['cat', "IE9 - Win7", 'C:\Windows\System32\Drivers\Etc\hosts'])
|
84
87
|
assert_match(/rhino\.acme\.com/, out)
|
85
88
|
end
|
86
89
|
|
87
90
|
def test_cmd
|
88
|
-
out =
|
91
|
+
out = run_thor_capture(['cmd', "IE9 - Win7", 'tasklist'])
|
89
92
|
assert_match(/winlogon\.exe/, out)
|
90
93
|
end
|
91
94
|
|
92
95
|
def test_cmd_adm
|
93
|
-
out =
|
96
|
+
out = run_thor_capture(['cmd', "IE9 - Win7", 'tasklist'])
|
94
97
|
assert_match(/winlogon\.exe/, out)
|
95
98
|
end
|
96
99
|
|
100
|
+
#def test_pwrsh_as_adm
|
101
|
+
# p run_thor_capture(['pwrsh_as_adm', "IE9 - Win7", 'curl'])
|
102
|
+
#end
|
103
|
+
|
104
|
+
# takes 5 minutes
|
105
|
+
def test_choco
|
106
|
+
cmd1 = run_thor_capture(['choco_uninst', "IE9 - Win7", 'curl'])
|
107
|
+
assert_match(/Chocolatey\ is\ not\ installed,\ guess\ you/,cmd1)
|
108
|
+
run_thor(['choco_inst', "IE9 - Win7", 'curl'])
|
109
|
+
p run_thor_capture(['cmd_as_adm', "IE9 - Win7", 'curl'])
|
110
|
+
run_thor(['choco_uninst', "IE9 - Win7", 'curl'])
|
111
|
+
p run_thor_capture(['cmd_as_adm', "IE9 - Win7", 'curl'])
|
112
|
+
end
|
113
|
+
|
114
|
+
def test_reset_ievms_taskmgr
|
115
|
+
machine = Ievms::WindowsGuest.new 'IE9 - Win7'
|
116
|
+
machine.run_command_as_admin 'ping 127.0.0.1 -n 30 > nul', true, true
|
117
|
+
run_thor(['reset_ievms_taskmgr', "IE9 - Win7"])
|
118
|
+
assert_match(/Ready/,run_thor_capture(['cmd', "IE9 - Win7", 'schtasks.exe /Query /TN ievms']))
|
119
|
+
end
|
120
|
+
|
97
121
|
private
|
98
|
-
|
122
|
+
|
123
|
+
def run_thor(args)
|
124
|
+
# args << '--verbose'
|
125
|
+
IevmsRb.start(args)
|
126
|
+
end
|
127
|
+
|
128
|
+
def run_thor_capture(args)
|
129
|
+
# args << '--verbose'
|
99
130
|
out, _ = capture_io do
|
100
131
|
IevmsRb.start(args)
|
101
132
|
end
|
data/test/test_ievms_win7.rb
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
require 'test_helper'
|
2
|
-
require 'ievms/windows_guest'
|
3
|
-
require 'timeout'
|
4
2
|
|
5
3
|
class TestWin7 < Minitest::Test
|
6
4
|
|
7
5
|
include IevmsRubyTestsShared
|
8
6
|
|
9
7
|
def setup
|
10
|
-
ensure_machine_running("IE9 - Win7")
|
11
8
|
@machine = Ievms::WindowsGuest.new 'IE9 - Win7'
|
9
|
+
@machine.headless=true
|
10
|
+
@machine.start
|
12
11
|
end
|
13
12
|
|
14
13
|
def test_non_existing_guest
|
@@ -40,14 +39,14 @@ include IevmsRubyTestsShared
|
|
40
39
|
def test_long_cmd_timeout
|
41
40
|
@machine.timeout_secs = 3
|
42
41
|
assert_raises {
|
43
|
-
@machine.run_command 'ping 127.0.0.1 -n
|
42
|
+
@machine.run_command 'ping 127.0.0.1 -n 10 > nul'
|
44
43
|
}
|
45
44
|
end
|
46
45
|
|
47
46
|
def test_long_admin_cmd_timeout
|
48
47
|
@machine.timeout_secs = 3
|
49
48
|
assert_raises {
|
50
|
-
@machine.run_command_as_admin 'ping 127.0.0.1 -n
|
49
|
+
@machine.run_command_as_admin 'ping 127.0.0.1 -n 10 > nul'
|
51
50
|
}
|
52
51
|
end
|
53
52
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ievms-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pim Snel
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-10-
|
11
|
+
date: 2015-10-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -89,6 +89,7 @@ extensions: []
|
|
89
89
|
extra_rdoc_files: []
|
90
90
|
files:
|
91
91
|
- ".gitignore"
|
92
|
+
- CHANGELOG.md
|
92
93
|
- Gemfile
|
93
94
|
- LICENSE.txt
|
94
95
|
- README.md
|