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-2015 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 CliHostController
|
20
|
+
def initialize(config_dir, output)
|
21
|
+
@config_dir = config_dir
|
22
|
+
@out = output
|
23
|
+
end
|
24
|
+
|
25
|
+
def setup(url)
|
26
|
+
if !url
|
27
|
+
raise GLI::BadCommandLine.new("Please provide a URL argument")
|
28
|
+
end
|
29
|
+
|
30
|
+
@out.puts "Setup from '#{url}'"
|
31
|
+
begin
|
32
|
+
HostConfig.for_directory(@config_dir).setup(url)
|
33
|
+
rescue HostFileError => e
|
34
|
+
@out.puts "Error: #{e}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def list
|
39
|
+
host_config.hosts.each do |host_name|
|
40
|
+
host = host_config.host(host_name)
|
41
|
+
out = "#{host_name}"
|
42
|
+
attributes = []
|
43
|
+
if host['address']
|
44
|
+
attributes.push("address: #{host['address']}")
|
45
|
+
end
|
46
|
+
if host['base_snapshot_id']
|
47
|
+
attributes.push("base snapshot id: #{host['base_snapshot_id']}")
|
48
|
+
end
|
49
|
+
if !attributes.empty?
|
50
|
+
out += " (" + attributes.join(", ") + ")"
|
51
|
+
end
|
52
|
+
@out.puts(out)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def lock(host_name)
|
57
|
+
check_host(host_name)
|
58
|
+
|
59
|
+
locker = LockService.new(host_config.lock_server_address)
|
60
|
+
if locker.request_lock(host_name)
|
61
|
+
@out.puts "Lock acquired for host '#{host_name}'"
|
62
|
+
|
63
|
+
locker.keep_lock
|
64
|
+
else
|
65
|
+
@out.puts "Failed to acquire lock for host '#{host_name}': " +
|
66
|
+
"#{locker.info(host_name)}"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def info(host_name)
|
71
|
+
check_host(host_name)
|
72
|
+
|
73
|
+
locker = LockService.new(host_config.lock_server_address)
|
74
|
+
@out.puts(locker.info(host_name))
|
75
|
+
end
|
76
|
+
|
77
|
+
def reset(host_name)
|
78
|
+
check_host(host_name)
|
79
|
+
|
80
|
+
runner = HostRunner.new(host_name, host_config)
|
81
|
+
runner.start
|
82
|
+
runner.cleanup
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
def check_host(host_name)
|
88
|
+
if !host_name
|
89
|
+
raise GLI::BadCommandLine.new("Please provide a host name argument")
|
90
|
+
end
|
91
|
+
|
92
|
+
if !host_config.host(host_name)
|
93
|
+
raise LockError.new("Host name #{host_name} doesn't exist in " +
|
94
|
+
"configuration file '#{host_config.config_file}'")
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def host_config
|
99
|
+
return @host_config if @host_config
|
100
|
+
|
101
|
+
@host_config = HostConfig.for_directory(@config_dir)
|
102
|
+
@host_config.read
|
103
|
+
|
104
|
+
@host_config
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,96 @@
|
|
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 BaseCommand < Command
|
20
|
+
|
21
|
+
attr_reader :kiwi_dir
|
22
|
+
|
23
|
+
def initialize(kiwi_dir, remote_url = nil)
|
24
|
+
super()
|
25
|
+
@kiwi_dir = kiwi_dir
|
26
|
+
@remote_url = remote_url
|
27
|
+
end
|
28
|
+
|
29
|
+
def remote_base_images(subdir = "")
|
30
|
+
return [] if !@remote_url || @remote_url.empty?
|
31
|
+
|
32
|
+
uri = URI.parse(URLs.join(@remote_url, subdir, "import_state.yaml"))
|
33
|
+
response = Net::HTTP.get_response(uri)
|
34
|
+
if response.is_a?(Net::HTTPSuccess)
|
35
|
+
index = YAML.load(response.body)
|
36
|
+
index.keys
|
37
|
+
else
|
38
|
+
STDERR.puts "Could not download remote state file at #{uri.to_s}: " + response.message
|
39
|
+
exit 1
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def local_base_images
|
44
|
+
Dir.glob(File.join(@kiwi_dir, "definitions", "*")).
|
45
|
+
select { |f| File.directory?(f) }.
|
46
|
+
map { |d| File.basename(d) }
|
47
|
+
end
|
48
|
+
|
49
|
+
def process_base_image_parameter(all_images, base_image = nil)
|
50
|
+
if !base_image
|
51
|
+
return all_images
|
52
|
+
end
|
53
|
+
if all_images.include?(base_image)
|
54
|
+
return [base_image]
|
55
|
+
else
|
56
|
+
raise "Unknown base image '#{base_image}'. Known images are: #{all_images.join(", ")}."
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def read_box_sources_state(box_name)
|
61
|
+
sources = Hash.new
|
62
|
+
source_dir = File.join(@kiwi_dir, "definitions", box_name)
|
63
|
+
Find.find(source_dir) do |file|
|
64
|
+
next if File.directory?(file)
|
65
|
+
relative_path = file.gsub(/^#{File.join(source_dir, "/")}/, "")
|
66
|
+
sources[relative_path] = Digest::MD5.file(file).hexdigest
|
67
|
+
end
|
68
|
+
sources
|
69
|
+
end
|
70
|
+
|
71
|
+
def read_box_target_state(box_name)
|
72
|
+
box_file = File.join(@kiwi_dir, box_name) + ".box"
|
73
|
+
if File.exist?(box_file)
|
74
|
+
target_state = Digest::MD5.file(box_file).hexdigest
|
75
|
+
end
|
76
|
+
target_state
|
77
|
+
end
|
78
|
+
|
79
|
+
def write_box_state_file(box_state)
|
80
|
+
File.open(File.join(@kiwi_dir, "box_state.yaml"), "w") do |f|
|
81
|
+
f.write(box_state.to_yaml)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def read_local_box_state_file
|
86
|
+
box_state_file = File.join(@kiwi_dir, "box_state.yaml")
|
87
|
+
if File.exist? box_state_file
|
88
|
+
box_state = YAML.load_file(box_state_file)
|
89
|
+
else
|
90
|
+
box_state = {}
|
91
|
+
end
|
92
|
+
box_state
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,29 @@
|
|
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 BootCommand < Command
|
20
|
+
def execute(image)
|
21
|
+
runner = ImageRunner.new(image)
|
22
|
+
log "Starting image #{runner.name}"
|
23
|
+
|
24
|
+
ip = VM.new(runner).start
|
25
|
+
|
26
|
+
log "System was started with IP #{ip}."
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,103 @@
|
|
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 BuildBaseCommand < BaseCommand
|
20
|
+
|
21
|
+
def initialize(kiwi_dir)
|
22
|
+
super
|
23
|
+
end
|
24
|
+
|
25
|
+
def execute(tmp_dir, image_name = nil)
|
26
|
+
Pennyworth::Libvirt.ensure_libvirt_env_started
|
27
|
+
|
28
|
+
box_state = read_local_box_state_file
|
29
|
+
images = process_base_image_parameter(local_base_images, image_name)
|
30
|
+
log "Creating base images..."
|
31
|
+
images.each do |image|
|
32
|
+
Dir.chdir kiwi_dir do
|
33
|
+
log
|
34
|
+
log "--- #{image} ---"
|
35
|
+
source_state = read_box_sources_state(image)
|
36
|
+
if box_state[image] && box_state[image]["sources"] &&
|
37
|
+
source_state && box_state[image]["sources"] == source_state
|
38
|
+
log " Sources not changed, skipping build"
|
39
|
+
else
|
40
|
+
log " Building base image..."
|
41
|
+
base_image_create(File.join(kiwi_dir, "definitions", image), tmp_dir)
|
42
|
+
log " Exporting image as box for vagrant..."
|
43
|
+
base_image_export(File.join(kiwi_dir, image), tmp_dir)
|
44
|
+
base_image_cleanup_build(tmp_dir)
|
45
|
+
|
46
|
+
box_state[image] = {
|
47
|
+
"sources" => source_state,
|
48
|
+
"target" => read_box_target_state(image)
|
49
|
+
}
|
50
|
+
write_box_state_file(box_state)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
# Creates a KVM image from the according Kiwi description.
|
59
|
+
# See pennyworth/kiwi/definitions for the definitions we use.
|
60
|
+
def base_image_create(description_dir, tmp_dir)
|
61
|
+
FileUtils.mkdir_p(tmp_dir)
|
62
|
+
logfile = "#{tmp_dir}/kiwi-terminal-output.log"
|
63
|
+
log " The build log is available under #{logfile}"
|
64
|
+
begin
|
65
|
+
Cheetah.run "sudo", "/usr/sbin/kiwi", "--build", description_dir,
|
66
|
+
"--destdir", tmp_dir, "--logfile", "#{logfile}",
|
67
|
+
:stdout => :capture
|
68
|
+
rescue Cheetah::ExecutionFailed => e
|
69
|
+
raise ExecutionFailed.new(e)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def base_image_export(kiwi_dir, tmp_dir)
|
74
|
+
Dir.chdir(tmp_dir) do
|
75
|
+
image = Dir.glob("*.box").first
|
76
|
+
if image
|
77
|
+
from_file = File.join(tmp_dir, image)
|
78
|
+
to_file = kiwi_dir.gsub(/\/$/, "") + ".box"
|
79
|
+
begin
|
80
|
+
Cheetah.run "sudo", "mv", from_file, to_file, :stdout => :capture
|
81
|
+
rescue Cheetah::ExecutionFailed => e
|
82
|
+
raise ExecutionFailed.new(e)
|
83
|
+
end
|
84
|
+
else
|
85
|
+
raise BuildFailed, "The built image couldn't be found."
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def base_image_cleanup_build(tmp_dir)
|
91
|
+
if tmp_dir.start_with?("/tmp/")
|
92
|
+
begin
|
93
|
+
Cheetah.run "sudo", "rm", "-r", tmp_dir, :stdout => :capture
|
94
|
+
rescue Cheetah::ExecutionFailed => e
|
95
|
+
raise ExecutionFailed.new(e)
|
96
|
+
end
|
97
|
+
else
|
98
|
+
log " Warning: The KIWI tmp dir #{tmp_dir} was outside of '/tmp' so it" \
|
99
|
+
" wasn't removed!"
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,43 @@
|
|
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 Command
|
20
|
+
|
21
|
+
def initialize
|
22
|
+
Cheetah.default_options = { :logger => logger }
|
23
|
+
end
|
24
|
+
|
25
|
+
def config
|
26
|
+
@config ||= YAML.load_file(File.dirname(__FILE__) + "/../../../config/setup.yml")
|
27
|
+
end
|
28
|
+
|
29
|
+
def logger
|
30
|
+
@logger ||= Logger.new("/tmp/pennyworth.log")
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def print_ssh_config(vagrant, vm_name)
|
36
|
+
config = vagrant.ssh_config(vm_name)
|
37
|
+
|
38
|
+
config.each_pair do |host, host_config|
|
39
|
+
puts "#{host}\t#{host_config["HostName"]}"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,25 @@
|
|
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 DownCommand < Command
|
20
|
+
def execute(vm_name = nil)
|
21
|
+
v = VagrantCommand.new
|
22
|
+
v.down vm_name
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,112 @@
|
|
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 ImportBaseCommand < BaseCommand
|
20
|
+
|
21
|
+
def execute(image_name, options = {})
|
22
|
+
@vagrant = VagrantCommand.new
|
23
|
+
options = {
|
24
|
+
subdir: "",
|
25
|
+
local: false
|
26
|
+
}.merge(options)
|
27
|
+
|
28
|
+
Pennyworth::Libvirt.ensure_libvirt_env_started
|
29
|
+
|
30
|
+
if options[:local]
|
31
|
+
all_images = local_base_images
|
32
|
+
box_state = read_local_box_state_file
|
33
|
+
else
|
34
|
+
all_images = remote_base_images(options[:subdir])
|
35
|
+
box_state = read_remote_box_state_file
|
36
|
+
end
|
37
|
+
import_state = read_import_state_file
|
38
|
+
images = process_base_image_parameter(all_images, image_name)
|
39
|
+
images.each do |image|
|
40
|
+
if box_state[image] && box_state[image]["target"] &&
|
41
|
+
import_state[image] &&
|
42
|
+
box_state[image]["target"] == import_state[image]
|
43
|
+
log "Box '#{image}' hasn't changed since last import. Skipping"
|
44
|
+
else
|
45
|
+
Dir.chdir Cli.settings.vagrant_dir do
|
46
|
+
log "Importing box '#{image}' into vagrant..."
|
47
|
+
base_image_clean(image)
|
48
|
+
base_image_import(image, options)
|
49
|
+
if box_state[image] && box_state[image]["target"]
|
50
|
+
import_state[image] = box_state[image]["target"]
|
51
|
+
else
|
52
|
+
import_state[image] = nil
|
53
|
+
end
|
54
|
+
write_import_state_file(import_state)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def read_import_state_file
|
61
|
+
import_state_file = File.join(kiwi_dir, "import_state.yaml")
|
62
|
+
if File.exist? import_state_file
|
63
|
+
import_state = YAML.load_file(import_state_file)
|
64
|
+
else
|
65
|
+
import_state = {}
|
66
|
+
end
|
67
|
+
import_state
|
68
|
+
end
|
69
|
+
|
70
|
+
def write_import_state_file(import_state)
|
71
|
+
FileUtils.mkdir_p(kiwi_dir) unless Dir.exists?(kiwi_dir)
|
72
|
+
|
73
|
+
File.open(File.join(kiwi_dir, "import_state.yaml"), "w") do |f|
|
74
|
+
f.write(import_state.to_yaml)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def read_remote_box_state_file
|
79
|
+
box_state_yaml = fetch_remote_box_state_file
|
80
|
+
if box_state_yaml
|
81
|
+
return YAML.load(box_state_yaml)
|
82
|
+
else
|
83
|
+
return {}
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
def fetch_remote_box_state_file
|
90
|
+
url = URLs.join(@remote_url, "box_state.yaml")
|
91
|
+
Net::HTTP.get(URI.parse(url))
|
92
|
+
end
|
93
|
+
|
94
|
+
def base_image_clean(box)
|
95
|
+
Cheetah.run "virsh", "-c", "qemu:///system", "vol-delete", "#{box}_vagrant_box_image.img", "--pool=default"
|
96
|
+
Cheetah.run "virsh", "-c", "qemu:///system", "pool-refresh", "--pool=default"
|
97
|
+
@vagrant.destroy
|
98
|
+
rescue
|
99
|
+
end
|
100
|
+
|
101
|
+
# Imports the box into the Vagrant pool so that it can be used for the test
|
102
|
+
# environments.
|
103
|
+
def base_image_import(box, options)
|
104
|
+
if options[:local]
|
105
|
+
box_path = File.join(kiwi_dir, box + ".box")
|
106
|
+
else
|
107
|
+
box_path = URLs.join(@remote_url, options[:subdir], box + ".box")
|
108
|
+
end
|
109
|
+
@vagrant.add_box(box, box_path)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|