pennyworth-tool 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (112) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +8 -0
  3. data/.hound.yml +3 -0
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +18 -0
  6. data/CONTRIBUTING.md +67 -0
  7. data/COPYING +674 -0
  8. data/Gemfile +28 -0
  9. data/README.md +339 -0
  10. data/Rakefile +33 -0
  11. data/bin/pennyworth +26 -0
  12. data/config/setup.yml +17 -0
  13. data/examples/README.md +23 -0
  14. data/examples/kiwi/definitions/base_opensuse13.1_kvm/config.sh +87 -0
  15. data/examples/kiwi/definitions/base_opensuse13.1_kvm/config.xml +64 -0
  16. data/examples/kiwi/definitions/base_opensuse13.1_kvm/root/etc/sysconfig/network/ifcfg-eth0 +2 -0
  17. data/examples/kiwi/definitions/base_opensuse13.1_kvm/root/home/vagrant/.ssh/authorized_keys +1 -0
  18. data/examples/vagrant/Vagrantfile +14 -0
  19. data/files/99-libvirt.rules +2 -0
  20. data/files/image_test-template.xml +43 -0
  21. data/files/pool-default.xml +6 -0
  22. data/lib/image_runner.rb +89 -0
  23. data/lib/pennyworth.rb +65 -0
  24. data/lib/pennyworth/cli.rb +339 -0
  25. data/lib/pennyworth/cli_host_controller.rb +107 -0
  26. data/lib/pennyworth/commands/base_command.rb +96 -0
  27. data/lib/pennyworth/commands/boot_command.rb +29 -0
  28. data/lib/pennyworth/commands/build_base_command.rb +103 -0
  29. data/lib/pennyworth/commands/command.rb +43 -0
  30. data/lib/pennyworth/commands/down_command.rb +25 -0
  31. data/lib/pennyworth/commands/import_base_command.rb +112 -0
  32. data/lib/pennyworth/commands/import_ssh_keys_command.rb +27 -0
  33. data/lib/pennyworth/commands/list_command.rb +41 -0
  34. data/lib/pennyworth/commands/setup_command.rb +209 -0
  35. data/lib/pennyworth/commands/shutdown_command.rb +28 -0
  36. data/lib/pennyworth/commands/status_command.rb +26 -0
  37. data/lib/pennyworth/commands/up_command.rb +27 -0
  38. data/lib/pennyworth/exceptions.rb +39 -0
  39. data/lib/pennyworth/helper.rb +39 -0
  40. data/lib/pennyworth/host_config.rb +86 -0
  41. data/lib/pennyworth/host_runner.rb +133 -0
  42. data/lib/pennyworth/image_runner.rb +89 -0
  43. data/lib/pennyworth/libvirt.rb +93 -0
  44. data/lib/pennyworth/local_command_runner.rb +77 -0
  45. data/lib/pennyworth/local_runner.rb +34 -0
  46. data/lib/pennyworth/lock_service.rb +87 -0
  47. data/lib/pennyworth/remote_command_runner.rb +144 -0
  48. data/lib/pennyworth/runner.rb +27 -0
  49. data/lib/pennyworth/settings.rb +42 -0
  50. data/lib/pennyworth/spec.rb +96 -0
  51. data/lib/pennyworth/spec_profiler.rb +85 -0
  52. data/lib/pennyworth/ssh_keys_importer.rb +107 -0
  53. data/lib/pennyworth/urls.rb +28 -0
  54. data/lib/pennyworth/vagrant.rb +81 -0
  55. data/lib/pennyworth/vagrant_command.rb +120 -0
  56. data/lib/pennyworth/vagrant_runner.rb +44 -0
  57. data/lib/pennyworth/version.rb +22 -0
  58. data/lib/pennyworth/vm.rb +62 -0
  59. data/man/.gitignore +2 -0
  60. data/man/pennyworth.1.md +28 -0
  61. data/pennyworth.gemspec +57 -0
  62. data/prophet/Gemfile +3 -0
  63. data/prophet/prophet.rb +82 -0
  64. data/spec/base_command_spec.rb +30 -0
  65. data/spec/build_base_command_spec.rb +147 -0
  66. data/spec/cli_host_controller_spec.rb +113 -0
  67. data/spec/data/hosts.yaml +10 -0
  68. data/spec/data/kiwi/base_opensuse12.3_kvm.box +1 -0
  69. data/spec/data/kiwi/base_opensuse13.1_kvm.box +1 -0
  70. data/spec/data/kiwi/definitions/base_opensuse12.3_kvm/config.sh +1 -0
  71. data/spec/data/kiwi/definitions/base_opensuse12.3_kvm/config.xml +1 -0
  72. data/spec/data/kiwi/definitions/base_opensuse12.3_kvm/root/home/vagrant/.ssh/authorized_keys +1 -0
  73. data/spec/data/kiwi/definitions/base_opensuse13.1_kvm/config.sh +1 -0
  74. data/spec/data/kiwi/definitions/base_opensuse13.1_kvm/config.xml +1 -0
  75. data/spec/data/kiwi/definitions/base_opensuse13.1_kvm/root/home/vagrant/.ssh/authorized_keys +1 -0
  76. data/spec/data/kiwi2/box_state.yaml +14 -0
  77. data/spec/data/kiwi2/definitions/base_opensuse12.3_kvm/config.sh +1 -0
  78. data/spec/data/kiwi2/definitions/base_opensuse12.3_kvm/config.xml +1 -0
  79. data/spec/data/kiwi2/definitions/base_opensuse12.3_kvm/root/home/vagrant/.ssh/authorized_keys +1 -0
  80. data/spec/data/kiwi2/definitions/base_opensuse13.1_kvm/config.sh +1 -0
  81. data/spec/data/kiwi2/definitions/base_opensuse13.1_kvm/config.xml +1 -0
  82. data/spec/data/kiwi2/definitions/base_opensuse13.1_kvm/root/home/vagrant/.ssh/authorized_keys +1 -0
  83. data/spec/data/kiwi3/box_state.yaml +13 -0
  84. data/spec/data/kiwi3/definitions/base_opensuse12.3_kvm/.gitkeep +0 -0
  85. data/spec/data/kiwi3/definitions/base_opensuse13.1_kvm/.gitkeep +0 -0
  86. data/spec/data/kiwi3/import_state.yaml +3 -0
  87. data/spec/data/kiwi4/definitions/base_opensuse12.3_kvm/.gitkeep +0 -0
  88. data/spec/data/kiwi4/definitions/base_opensuse13.1_kvm/.gitkeep +0 -0
  89. data/spec/data/kiwi4/import_state.yaml +3 -0
  90. data/spec/data/kiwi5/import_state.yaml +3 -0
  91. data/spec/data/vagrant/.gitkeep +0 -0
  92. data/spec/host_config_spec.rb +197 -0
  93. data/spec/host_runner_spec.rb +112 -0
  94. data/spec/image_runner_spec.rb +62 -0
  95. data/spec/import_base_command_spec.rb +189 -0
  96. data/spec/local_command_runner_spec.rb +117 -0
  97. data/spec/local_runner_spec.rb +42 -0
  98. data/spec/lock_service_spec.rb +95 -0
  99. data/spec/remote_command_runner_spec.rb +115 -0
  100. data/spec/settings_spec.rb +26 -0
  101. data/spec/setup_command_spec.rb +49 -0
  102. data/spec/spec_helper.rb +50 -0
  103. data/spec/spec_profiler_spec.rb +63 -0
  104. data/spec/spec_spec.rb +99 -0
  105. data/spec/support/command_runner_examples.rb +29 -0
  106. data/spec/support/runner_examples.rb +34 -0
  107. data/spec/urls_spec.rb +46 -0
  108. data/spec/vagrant_command_spec.rb +51 -0
  109. data/spec/vagrant_runner_spec.rb +40 -0
  110. data/spec/vagrant_spec.rb +288 -0
  111. data/spec/vm_spec.rb +56 -0
  112. 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