pennyworth-tool 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +8 -0
- data/.hound.yml +3 -0
- data/.rspec +2 -0
- data/.rubocop.yml +18 -0
- data/CONTRIBUTING.md +67 -0
- data/COPYING +674 -0
- data/Gemfile +28 -0
- data/README.md +339 -0
- data/Rakefile +33 -0
- data/bin/pennyworth +26 -0
- data/config/setup.yml +17 -0
- data/examples/README.md +23 -0
- data/examples/kiwi/definitions/base_opensuse13.1_kvm/config.sh +87 -0
- data/examples/kiwi/definitions/base_opensuse13.1_kvm/config.xml +64 -0
- data/examples/kiwi/definitions/base_opensuse13.1_kvm/root/etc/sysconfig/network/ifcfg-eth0 +2 -0
- data/examples/kiwi/definitions/base_opensuse13.1_kvm/root/home/vagrant/.ssh/authorized_keys +1 -0
- data/examples/vagrant/Vagrantfile +14 -0
- data/files/99-libvirt.rules +2 -0
- data/files/image_test-template.xml +43 -0
- data/files/pool-default.xml +6 -0
- data/lib/image_runner.rb +89 -0
- data/lib/pennyworth.rb +65 -0
- data/lib/pennyworth/cli.rb +339 -0
- data/lib/pennyworth/cli_host_controller.rb +107 -0
- data/lib/pennyworth/commands/base_command.rb +96 -0
- data/lib/pennyworth/commands/boot_command.rb +29 -0
- data/lib/pennyworth/commands/build_base_command.rb +103 -0
- data/lib/pennyworth/commands/command.rb +43 -0
- data/lib/pennyworth/commands/down_command.rb +25 -0
- data/lib/pennyworth/commands/import_base_command.rb +112 -0
- data/lib/pennyworth/commands/import_ssh_keys_command.rb +27 -0
- data/lib/pennyworth/commands/list_command.rb +41 -0
- data/lib/pennyworth/commands/setup_command.rb +209 -0
- data/lib/pennyworth/commands/shutdown_command.rb +28 -0
- data/lib/pennyworth/commands/status_command.rb +26 -0
- data/lib/pennyworth/commands/up_command.rb +27 -0
- data/lib/pennyworth/exceptions.rb +39 -0
- data/lib/pennyworth/helper.rb +39 -0
- data/lib/pennyworth/host_config.rb +86 -0
- data/lib/pennyworth/host_runner.rb +133 -0
- data/lib/pennyworth/image_runner.rb +89 -0
- data/lib/pennyworth/libvirt.rb +93 -0
- data/lib/pennyworth/local_command_runner.rb +77 -0
- data/lib/pennyworth/local_runner.rb +34 -0
- data/lib/pennyworth/lock_service.rb +87 -0
- data/lib/pennyworth/remote_command_runner.rb +144 -0
- data/lib/pennyworth/runner.rb +27 -0
- data/lib/pennyworth/settings.rb +42 -0
- data/lib/pennyworth/spec.rb +96 -0
- data/lib/pennyworth/spec_profiler.rb +85 -0
- data/lib/pennyworth/ssh_keys_importer.rb +107 -0
- data/lib/pennyworth/urls.rb +28 -0
- data/lib/pennyworth/vagrant.rb +81 -0
- data/lib/pennyworth/vagrant_command.rb +120 -0
- data/lib/pennyworth/vagrant_runner.rb +44 -0
- data/lib/pennyworth/version.rb +22 -0
- data/lib/pennyworth/vm.rb +62 -0
- data/man/.gitignore +2 -0
- data/man/pennyworth.1.md +28 -0
- data/pennyworth.gemspec +57 -0
- data/prophet/Gemfile +3 -0
- data/prophet/prophet.rb +82 -0
- data/spec/base_command_spec.rb +30 -0
- data/spec/build_base_command_spec.rb +147 -0
- data/spec/cli_host_controller_spec.rb +113 -0
- data/spec/data/hosts.yaml +10 -0
- data/spec/data/kiwi/base_opensuse12.3_kvm.box +1 -0
- data/spec/data/kiwi/base_opensuse13.1_kvm.box +1 -0
- data/spec/data/kiwi/definitions/base_opensuse12.3_kvm/config.sh +1 -0
- data/spec/data/kiwi/definitions/base_opensuse12.3_kvm/config.xml +1 -0
- data/spec/data/kiwi/definitions/base_opensuse12.3_kvm/root/home/vagrant/.ssh/authorized_keys +1 -0
- data/spec/data/kiwi/definitions/base_opensuse13.1_kvm/config.sh +1 -0
- data/spec/data/kiwi/definitions/base_opensuse13.1_kvm/config.xml +1 -0
- data/spec/data/kiwi/definitions/base_opensuse13.1_kvm/root/home/vagrant/.ssh/authorized_keys +1 -0
- data/spec/data/kiwi2/box_state.yaml +14 -0
- data/spec/data/kiwi2/definitions/base_opensuse12.3_kvm/config.sh +1 -0
- data/spec/data/kiwi2/definitions/base_opensuse12.3_kvm/config.xml +1 -0
- data/spec/data/kiwi2/definitions/base_opensuse12.3_kvm/root/home/vagrant/.ssh/authorized_keys +1 -0
- data/spec/data/kiwi2/definitions/base_opensuse13.1_kvm/config.sh +1 -0
- data/spec/data/kiwi2/definitions/base_opensuse13.1_kvm/config.xml +1 -0
- data/spec/data/kiwi2/definitions/base_opensuse13.1_kvm/root/home/vagrant/.ssh/authorized_keys +1 -0
- data/spec/data/kiwi3/box_state.yaml +13 -0
- data/spec/data/kiwi3/definitions/base_opensuse12.3_kvm/.gitkeep +0 -0
- data/spec/data/kiwi3/definitions/base_opensuse13.1_kvm/.gitkeep +0 -0
- data/spec/data/kiwi3/import_state.yaml +3 -0
- data/spec/data/kiwi4/definitions/base_opensuse12.3_kvm/.gitkeep +0 -0
- data/spec/data/kiwi4/definitions/base_opensuse13.1_kvm/.gitkeep +0 -0
- data/spec/data/kiwi4/import_state.yaml +3 -0
- data/spec/data/kiwi5/import_state.yaml +3 -0
- data/spec/data/vagrant/.gitkeep +0 -0
- data/spec/host_config_spec.rb +197 -0
- data/spec/host_runner_spec.rb +112 -0
- data/spec/image_runner_spec.rb +62 -0
- data/spec/import_base_command_spec.rb +189 -0
- data/spec/local_command_runner_spec.rb +117 -0
- data/spec/local_runner_spec.rb +42 -0
- data/spec/lock_service_spec.rb +95 -0
- data/spec/remote_command_runner_spec.rb +115 -0
- data/spec/settings_spec.rb +26 -0
- data/spec/setup_command_spec.rb +49 -0
- data/spec/spec_helper.rb +50 -0
- data/spec/spec_profiler_spec.rb +63 -0
- data/spec/spec_spec.rb +99 -0
- data/spec/support/command_runner_examples.rb +29 -0
- data/spec/support/runner_examples.rb +34 -0
- data/spec/urls_spec.rb +46 -0
- data/spec/vagrant_command_spec.rb +51 -0
- data/spec/vagrant_runner_spec.rb +40 -0
- data/spec/vagrant_spec.rb +288 -0
- data/spec/vm_spec.rb +56 -0
- metadata +257 -0
@@ -0,0 +1,107 @@
|
|
1
|
+
# Copyright (c) 2013-2014 SUSE LLC
|
2
|
+
#
|
3
|
+
# This program is free software; you can redistribute it and/or
|
4
|
+
# modify it under the terms of version 3 of the GNU General Public License as
|
5
|
+
# published by the Free Software Foundation.
|
6
|
+
#
|
7
|
+
# This program is distributed in the hope that it will be useful,
|
8
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
9
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
10
|
+
# GNU General Public License for more details.
|
11
|
+
#
|
12
|
+
# You should have received a copy of the GNU General Public License
|
13
|
+
# along with this program; if not, contact SUSE LLC.
|
14
|
+
#
|
15
|
+
# To contact SUSE about this file by physical or electronic mail,
|
16
|
+
# you may find current contact information at www.suse.com
|
17
|
+
|
18
|
+
require "tempfile"
|
19
|
+
|
20
|
+
module Pennyworth
|
21
|
+
class SshKeysImporter
|
22
|
+
def self.import(ip, username, password, identity_file = nil)
|
23
|
+
tmp_file = Tempfile.new("pennyworth-ssh-key-importer")
|
24
|
+
|
25
|
+
cmd = "ssh-copy-id"
|
26
|
+
if identity_file
|
27
|
+
cmd << " -i \"#{identity_file}\""
|
28
|
+
cmd << " -o \"IdentityFile=#{identity_file}\""
|
29
|
+
end
|
30
|
+
cmd << " -o \"UserKnownHostsFile=/dev/null\""
|
31
|
+
cmd << " -o \"StrictHostKeyChecking=no\""
|
32
|
+
cmd << " #{username}@#{ip}"
|
33
|
+
|
34
|
+
# This temporary bash script copies the SSH keys to the host using
|
35
|
+
# ssh-copy-id.
|
36
|
+
#
|
37
|
+
# In order to drive this interactive command it is executed by expect.
|
38
|
+
tmp_file.write(<<-EOF
|
39
|
+
#!/usr/bin/expect -f
|
40
|
+
|
41
|
+
spawn #{cmd}
|
42
|
+
expect {
|
43
|
+
-re ".*assword.*" {
|
44
|
+
send "#{password}\\r"
|
45
|
+
expect {
|
46
|
+
-re ".*assword.*" {
|
47
|
+
exit 1
|
48
|
+
}
|
49
|
+
-re ".*Number of key.*" {
|
50
|
+
exit 0
|
51
|
+
}
|
52
|
+
}
|
53
|
+
}
|
54
|
+
-re ".*Number of key.*" {
|
55
|
+
exit 0
|
56
|
+
}
|
57
|
+
"skipped" {
|
58
|
+
exit 2
|
59
|
+
}
|
60
|
+
"authenticity" {
|
61
|
+
send "yes\\r"
|
62
|
+
exp_continue
|
63
|
+
}
|
64
|
+
"Connection refused" {
|
65
|
+
exit 3
|
66
|
+
}
|
67
|
+
}
|
68
|
+
exit 4
|
69
|
+
EOF
|
70
|
+
)
|
71
|
+
tmp_file.close
|
72
|
+
|
73
|
+
attempt = 1
|
74
|
+
begin
|
75
|
+
Cheetah.run("expect", tmp_file.path)
|
76
|
+
rescue Cheetah::ExecutionFailed => e
|
77
|
+
case e.status.exitstatus
|
78
|
+
when 1
|
79
|
+
raise WrongPasswordException, "Error: Could not upload SSH keys because" \
|
80
|
+
" the password is wrong."
|
81
|
+
when 2
|
82
|
+
raise SshKeysAlreadyExistsException, "SSH keys were not uploaded because they" \
|
83
|
+
" were already on the host."
|
84
|
+
when 3
|
85
|
+
# We give sshd 30 seconds to start up
|
86
|
+
if attempt > 30
|
87
|
+
raise SshConnectionFailed, "SSH connection failed."
|
88
|
+
else
|
89
|
+
attempt += 1
|
90
|
+
sleep 1
|
91
|
+
retry
|
92
|
+
end
|
93
|
+
when 4
|
94
|
+
raise RuntimeError, "An unknown error occured while trying to upload " \
|
95
|
+
"the SSH keys."
|
96
|
+
when 127
|
97
|
+
raise CommandNotFoundError, "Error: Please install expect before running" \
|
98
|
+
" pennyworth copy-ssh-keys."
|
99
|
+
else
|
100
|
+
raise e
|
101
|
+
end
|
102
|
+
end
|
103
|
+
ensure
|
104
|
+
tmp_file.unlink
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# Copyright (c) 2013-2014 SUSE LLC
|
2
|
+
#
|
3
|
+
# This program is free software; you can redistribute it and/or
|
4
|
+
# modify it under the terms of version 3 of the GNU General Public License as
|
5
|
+
# published by the Free Software Foundation.
|
6
|
+
#
|
7
|
+
# This program is distributed in the hope that it will be useful,
|
8
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
9
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
10
|
+
# GNU General Public License for more details.
|
11
|
+
#
|
12
|
+
# You should have received a copy of the GNU General Public License
|
13
|
+
# along with this program; if not, contact SUSE LLC.
|
14
|
+
#
|
15
|
+
# To contact SUSE about this file by physical or electronic mail,
|
16
|
+
# you may find current contact information at www.suse.com
|
17
|
+
|
18
|
+
module Pennyworth
|
19
|
+
# URL manipulation utilities.
|
20
|
+
module URLs
|
21
|
+
def self.join(*parts)
|
22
|
+
parts = parts.reject(&:empty?)
|
23
|
+
parts = [parts.first] + parts[1..-1].map { |p| p.sub(/^\//, "") }
|
24
|
+
parts = parts[0..-2].map { |p| p.sub(/\/$/, "") } + [parts.last]
|
25
|
+
parts.join("/")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# Copyright (c) 2013-2014 SUSE LLC
|
2
|
+
#
|
3
|
+
# This program is free software; you can redistribute it and/or
|
4
|
+
# modify it under the terms of version 3 of the GNU General Public License as
|
5
|
+
# published by the Free Software Foundation.
|
6
|
+
#
|
7
|
+
# This program is distributed in the hope that it will be useful,
|
8
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
9
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
10
|
+
# GNU General Public License for more details.
|
11
|
+
#
|
12
|
+
# You should have received a copy of the GNU General Public License
|
13
|
+
# along with this program; if not, contact SUSE LLC.
|
14
|
+
#
|
15
|
+
# To contact SUSE about this file by physical or electronic mail,
|
16
|
+
# you may find current contact information at www.suse.com
|
17
|
+
|
18
|
+
module Pennyworth
|
19
|
+
class Vagrant
|
20
|
+
def initialize(vagrant_dir)
|
21
|
+
@vagrant_dir = vagrant_dir
|
22
|
+
end
|
23
|
+
|
24
|
+
def run(*args)
|
25
|
+
# Many vagrant commands don't have a --provider option, but they fail
|
26
|
+
# because they can't find VirtualBox. The following code is a crude
|
27
|
+
# workaround.
|
28
|
+
Dir.chdir(@vagrant_dir) do
|
29
|
+
with_env "VAGRANT_DEFAULT_PROVIDER" => "libvirt" do
|
30
|
+
Cheetah.run "vagrant", *args
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def ssh_config(vm_name)
|
36
|
+
output = Dir.chdir(@vagrant_dir) do
|
37
|
+
if vm_name
|
38
|
+
run "ssh-config", vm_name, :stdout => :capture
|
39
|
+
else
|
40
|
+
config = ""
|
41
|
+
status = run "status", :stdout => :capture
|
42
|
+
status.scan(/\n(.*?)\s*running/).each do |vm_name|
|
43
|
+
config += run "ssh-config", vm_name.first, :stdout => :capture
|
44
|
+
end
|
45
|
+
config
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
parse_ssh_config_output(output)
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def parse_ssh_config_output(output)
|
55
|
+
# See http://linux.die.net/man/5/ssh_config for description of the format.
|
56
|
+
|
57
|
+
config = {}
|
58
|
+
host = nil
|
59
|
+
|
60
|
+
output.each_line do |line|
|
61
|
+
line.chomp!("\n")
|
62
|
+
|
63
|
+
next if line.empty? || line.start_with?("#")
|
64
|
+
|
65
|
+
m = /^\s*(?<key>\w+)(\s*=\s*|\s+)(?<value>.*)$/.match(line)
|
66
|
+
raise "Invalid line in SSH config: #{line.inspect}." unless m
|
67
|
+
|
68
|
+
if m[:key] == "Host"
|
69
|
+
host = m[:value]
|
70
|
+
config[host] = {}
|
71
|
+
else
|
72
|
+
raise "Missing Host keyword before #{m[:key]}." unless host
|
73
|
+
|
74
|
+
config[host][m[:key]] = m[:value]
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
config
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
# Copyright (c) 2013-2014 SUSE LLC
|
2
|
+
#
|
3
|
+
# This program is free software; you can redistribute it and/or
|
4
|
+
# modify it under the terms of version 3 of the GNU General Public License as
|
5
|
+
# published by the Free Software Foundation.
|
6
|
+
#
|
7
|
+
# This program is distributed in the hope that it will be useful,
|
8
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
9
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
10
|
+
# GNU General Public License for more details.
|
11
|
+
#
|
12
|
+
# You should have received a copy of the GNU General Public License
|
13
|
+
# along with this program; if not, contact SUSE LLC.
|
14
|
+
#
|
15
|
+
# To contact SUSE about this file by physical or electronic mail,
|
16
|
+
# you may find current contact information at www.suse.com
|
17
|
+
|
18
|
+
module Pennyworth
|
19
|
+
class VagrantCommand < Command
|
20
|
+
attr_reader :vagrant
|
21
|
+
|
22
|
+
def initialize
|
23
|
+
@vagrant = Pennyworth::Vagrant.new(Pennyworth::Cli.settings.vagrant_dir)
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.parse_status output
|
27
|
+
result = []
|
28
|
+
parsing_vms = false
|
29
|
+
output.each_line do |line|
|
30
|
+
line.strip!
|
31
|
+
if line.empty?
|
32
|
+
break if parsing_vms
|
33
|
+
parsing_vms = true
|
34
|
+
elsif parsing_vms
|
35
|
+
line =~ /^(.*?)\s+(.*)$/
|
36
|
+
vm_name = $1
|
37
|
+
vm_state = $2
|
38
|
+
if vm_state =~ /running/
|
39
|
+
vm_name += " (running)"
|
40
|
+
end
|
41
|
+
result.push vm_name
|
42
|
+
end
|
43
|
+
end
|
44
|
+
result
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.setup_environment(dir)
|
48
|
+
if !File.exists?(File.join(dir, "Vagrantfile"))
|
49
|
+
vagrant = Pennyworth::Vagrant.new(dir)
|
50
|
+
FileUtils.mkdir_p(dir)
|
51
|
+
vagrant.run("init")
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def up(vm_name, destroy)
|
56
|
+
Pennyworth::Libvirt.ensure_libvirt_env_started
|
57
|
+
|
58
|
+
if vm_name
|
59
|
+
log "Starting VM #{vm_name}..."
|
60
|
+
@vagrant.run "destroy", vm_name if destroy
|
61
|
+
@vagrant.run "up", vm_name
|
62
|
+
else
|
63
|
+
log "Starting test environment..."
|
64
|
+
@vagrant.run "destroy" if destroy
|
65
|
+
@vagrant.run "up"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def down(vm_name)
|
70
|
+
if vm_name
|
71
|
+
log "Stopping VM #{vm_name}..."
|
72
|
+
@vagrant.run "halt", vm_name
|
73
|
+
else
|
74
|
+
log "Stopping test environment..."
|
75
|
+
@vagrant.run "halt"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def env_clean?
|
80
|
+
status = @vagrant.run "status", :stdout => :capture
|
81
|
+
|
82
|
+
return status.index("running").nil?
|
83
|
+
end
|
84
|
+
|
85
|
+
def reset(vm_name)
|
86
|
+
if vm_name
|
87
|
+
log "Resetting VM #{vm_name}..."
|
88
|
+
@vagrant.run "destroy", vm_name
|
89
|
+
else
|
90
|
+
log "Resetting test environment..."
|
91
|
+
@vagrant.run "destroy"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def ssh(vm_name, cmd, stdout = nil)
|
96
|
+
if vm_name
|
97
|
+
@vagrant.run "ssh", vm_name, "-c", cmd, :stdout => stdout
|
98
|
+
else
|
99
|
+
@vagrant.run "ssh", "-c", cmd, :stdout => stdout
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def list
|
104
|
+
boxes = @vagrant.run "box", "list", :stdout => :capture
|
105
|
+
boxes.split("\n")
|
106
|
+
end
|
107
|
+
|
108
|
+
def status
|
109
|
+
Pennyworth::VagrantCommand.parse_status( @vagrant.run "status", :stdout => :capture )
|
110
|
+
end
|
111
|
+
|
112
|
+
def destroy
|
113
|
+
@vagrant.run "destroy"
|
114
|
+
end
|
115
|
+
|
116
|
+
def add_box box, box_path
|
117
|
+
@vagrant.run "box", "add", box, box_path, "--force"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# Copyright (c) 2013-2014 SUSE LLC
|
2
|
+
#
|
3
|
+
# This program is free software; you can redistribute it and/or
|
4
|
+
# modify it under the terms of version 3 of the GNU General Public License as
|
5
|
+
# published by the Free Software Foundation.
|
6
|
+
#
|
7
|
+
# This program is distributed in the hope that it will be useful,
|
8
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
9
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
10
|
+
# GNU General Public License for more details.
|
11
|
+
#
|
12
|
+
# You should have received a copy of the GNU General Public License
|
13
|
+
# along with this program; if not, contact SUSE LLC.
|
14
|
+
#
|
15
|
+
# To contact SUSE about this file by physical or electronic mail,
|
16
|
+
# you may find current contact information at www.suse.com
|
17
|
+
|
18
|
+
module Pennyworth
|
19
|
+
class VagrantRunner < Runner
|
20
|
+
def initialize(box, vagrant_dir, username)
|
21
|
+
@box = box
|
22
|
+
@username = username
|
23
|
+
@vagrant = Vagrant.new(vagrant_dir)
|
24
|
+
end
|
25
|
+
|
26
|
+
def start
|
27
|
+
@vagrant.run "destroy", @box
|
28
|
+
@vagrant.run "up", @box
|
29
|
+
|
30
|
+
ip = @vagrant.ssh_config(@box)[@box]["HostName"]
|
31
|
+
@command_runner = RemoteCommandRunner.new(ip, @username)
|
32
|
+
|
33
|
+
ip
|
34
|
+
end
|
35
|
+
|
36
|
+
def stop
|
37
|
+
@vagrant.run "halt", @box
|
38
|
+
end
|
39
|
+
|
40
|
+
def cleanup_directory(_dir)
|
41
|
+
# The machine will be reset anyway after the tests, so this is is a NOP
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# Copyright (c) 2013-2014 SUSE LLC
|
2
|
+
#
|
3
|
+
# This program is free software; you can redistribute it and/or
|
4
|
+
# modify it under the terms of version 3 of the GNU General Public License as
|
5
|
+
# published by the Free Software Foundation.
|
6
|
+
#
|
7
|
+
# This program is distributed in the hope that it will be useful,
|
8
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
9
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
10
|
+
# GNU General Public License for more details.
|
11
|
+
#
|
12
|
+
# You should have received a copy of the GNU General Public License
|
13
|
+
# along with this program; if not, contact SUSE LLC.
|
14
|
+
#
|
15
|
+
# To contact SUSE about this file by physical or electronic mail,
|
16
|
+
# you may find current contact information at www.suse.com
|
17
|
+
|
18
|
+
module Pennyworth
|
19
|
+
|
20
|
+
VERSION = "0.0.1"
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# Copyright (c) 2013-2014 SUSE LLC
|
2
|
+
#
|
3
|
+
# This program is free software; you can redistribute it and/or
|
4
|
+
# modify it under the terms of version 3 of the GNU General Public License as
|
5
|
+
# published by the Free Software Foundation.
|
6
|
+
#
|
7
|
+
# This program is distributed in the hope that it will be useful,
|
8
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
9
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
10
|
+
# GNU General Public License for more details.
|
11
|
+
#
|
12
|
+
# You should have received a copy of the GNU General Public License
|
13
|
+
# along with this program; if not, contact SUSE LLC.
|
14
|
+
#
|
15
|
+
# To contact SUSE about this file by physical or electronic mail,
|
16
|
+
# you may find current contact information at www.suse.com
|
17
|
+
|
18
|
+
module Pennyworth
|
19
|
+
# Represents a virtual machine that can be started, stopped, and interacted
|
20
|
+
# with.
|
21
|
+
class VM
|
22
|
+
attr_accessor :ip, :runner
|
23
|
+
|
24
|
+
def initialize(runner)
|
25
|
+
@runner = runner
|
26
|
+
end
|
27
|
+
|
28
|
+
def start
|
29
|
+
@ip = @runner.start
|
30
|
+
end
|
31
|
+
|
32
|
+
def stop
|
33
|
+
@runner.stop
|
34
|
+
end
|
35
|
+
|
36
|
+
def run_command(*args)
|
37
|
+
command_runner.run(*args)
|
38
|
+
end
|
39
|
+
|
40
|
+
def inject_file(source, destination, opts = {})
|
41
|
+
command_runner.inject_file(source, destination, opts)
|
42
|
+
end
|
43
|
+
|
44
|
+
def extract_file(source, destination)
|
45
|
+
command_runner.extract_file(source, destination)
|
46
|
+
end
|
47
|
+
|
48
|
+
def inject_directory(source, destination, opts = {})
|
49
|
+
command_runner.inject_directory(source, destination, opts)
|
50
|
+
end
|
51
|
+
|
52
|
+
def cleanup_directory(dir)
|
53
|
+
runner.cleanup_directory(dir)
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def command_runner
|
59
|
+
@runner.command_runner
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|