pennyworth-tool 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|