libvirtinator 0.0.2 → 0.1.0

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.
@@ -1,7 +1,26 @@
1
+ module Capistrano
2
+ module TaskEnhancements
3
+ alias_method :original_default_tasks, :default_tasks
4
+ def default_tasks
5
+ original_default_tasks + [
6
+ "libvirtinator:install",
7
+ "libvirtinator:install_vm",
8
+ "image:list_bases",
9
+ "image:build_base",
10
+ "users:setup_domain"
11
+ ]
12
+ end
13
+ end
14
+ end
15
+
1
16
  namespace :libvirtinator do
2
- # TODO: fix needing to define a stage before being able to install
17
+ task :load_settings do
18
+ load "./config/deploy.rb"
19
+ SSHKit.config.output_verbosity = fetch(:log_level)
20
+ end
21
+
3
22
  desc 'Write example config files'
4
- task :install do
23
+ task :install => 'libvirtinator:load_settings' do
5
24
  run_locally do
6
25
  execute "mkdir", "-p", "config/deploy", "templates/libvirtinator"
7
26
  {
@@ -9,7 +28,6 @@ namespace :libvirtinator do
9
28
  'examples/config/deploy.rb' => 'config/deploy_example.rb',
10
29
  'examples/config/sysadmins_keys.rb' => 'config/sysadmins_keys_example.rb',
11
30
  'examples/config/deploy/vm_name.rb' => 'config/deploy/vm_name_example.rb',
12
- 'examples/config/deploy/manual.rb' => 'config/deploy/manual_example.rb',
13
31
  'examples/first_boot.sh.erb' => 'templates/libvirtinator/first_boot_example.sh.erb',
14
32
  'examples/fstab.erb' => 'templates/libvirtinator/fstab_example.erb',
15
33
  'examples/hostname.erb' => 'templates/libvirtinator/hostname_example.erb',
@@ -29,7 +47,7 @@ namespace :libvirtinator do
29
47
  end
30
48
 
31
49
  desc 'Write an example VM config file'
32
- task :install_vm do
50
+ task :install_vm => 'libvirtinator:load_settings' do
33
51
  run_locally do
34
52
  execute "mkdir", "-p", "config/deploy"
35
53
  {
@@ -22,7 +22,7 @@ set :ip, "123.123.123.123"
22
22
  set :cidr, "123_123_123_123-27"
23
23
 
24
24
  set :node_fqdn, -> { "#{fetch(:node_name)}.example.com" }
25
- set :app_fqdn, "my-app.example.com"
26
- set :hostname, "my-app"
25
+ set :app_fqdn, -> { "#{fetch(:node_name)}.example.com" }
26
+ set :hostname, -> { fetch(:node_name) }
27
27
 
28
28
  set :usergroups, ["sysadmins"]
@@ -31,19 +31,23 @@ set "231_231_231_231-27_netmask", "255.255.255.224"
31
31
  set :dns_search, "example.com example2.com"
32
32
 
33
33
  # Setup vmbuilder for building a base image
34
- set :release_name, "ubuntu-14.04-v0.0.1-docker1.3.1"
34
+ set :release_name, "ubuntu-14.04_docker-1.9.1_v0.0.0"
35
+ set :build_user, -> { ENV['USER'] }
36
+ set :build_host, "myhost.example.com"
35
37
  set :vmbuilder_run_command, -> {
36
- [ "kvm", "ubuntu",
38
+ # [ "vmbuilder", "kvm", "ubuntu", # Ubuntu 12.04 and older hosts
39
+ [ "ubuntu-vm-builder", "kvm", "ubuntu", # Ubuntu 14.04 and newer hosts
37
40
  "-o",
38
41
  "--debug",
39
42
  "--verbose",
40
43
  "--dest=/tmp/#{fetch(:release_name)}",
41
- "--config=templates/#{fetch(:release_name)}.cfg",
42
- "--execscript=templates/#{fetch(:release_name)}-init.sh",
44
+ "--config=/tmp/vmbuilder.cfg",
45
+ "--execscript=/tmp/vmbuilder-init.sh",
43
46
  "--firstboot=/tmp/first_boot.sh",
47
+ # rootsize & swapsize settings do not get picked up in cfg file, so set here
44
48
  "--rootsize=15360",
45
49
  "--swapsize=2048"
46
- ].join(' ')
50
+ ]
47
51
  }
48
52
 
49
53
 
@@ -1,30 +1,34 @@
1
1
  namespace :image do
2
2
  desc "Build a base qcow2 image."
3
- task :build_base do
4
- on roles(:app) do
3
+ task :build_base => 'libvirtinator:load_settings' do
4
+ on "#{fetch(:build_user)}@#{fetch(:build_host)}" do
5
5
  as :root do
6
6
  ["first_boot.sh", "vmbuilder-init.sh", "vmbuilder.cfg"].each do |file|
7
- template = File.new(File.expand_path("templates/#{file}.erb")).read
7
+ template = File.new(File.expand_path("templates/libvirtinator/#{file}.erb")).read
8
8
  generated_config_file = ERB.new(template).result(binding)
9
9
  upload! StringIO.new(generated_config_file), "/tmp/#{file}"
10
- execute("chown", "-R", "root:root", "/tmp/#{file}")
11
10
  execute("chmod", "770", "/tmp/#{file}")
12
11
  end
13
- # rootsize & swapsize settings do not get picked up in cfg file, so set here
14
- if test "vmbuilder", fetch(:vmbuilder_run_command)
15
- execute "mv /tmp/#{fetch(:release_name)}/*.qcow2 /tmp/#{fetch(:release_name)}/#{fetch(:release_name)}.qcow2"
12
+ command_options = fetch(:vmbuilder_run_command)
13
+ entrypoint = command_options.shift
14
+ SSHKit.config.output_verbosity = :debug # watch long running output
15
+ if test entrypoint, command_options
16
+ final_path = "/tmp/#{fetch(:release_name)}/#{fetch(:release_name)}.qcow2"
17
+ execute "mv /tmp/#{fetch(:release_name)}/*.qcow2 #{final_path}"
16
18
  info("Build finished successfully!")
17
- info("You probably want to run 'cp /tmp/#{fetch(:release_name)}/#{fetch(:release_name)}.qcow2 <root partitions path>'.")
18
- info("If you ran this on a Ubuntu 14.04 or later host, you'll probabaly want to make the image compatible " +
19
- "with older versions of qemu using a command like this: 'sudo qemu-img amend -f qcow2 -o compat=0.10 #{fetch(:release_name)}.qcow2'.")
19
+ info("You probably want to copy '#{final_path}' to your root partitions path.")
20
+ info("If you ran this on a Ubuntu 14.04 or later host, you may want to make the image compatible " +
21
+ "with older versions of qemu using a command like this: 'sudo qemu-img amend -f qcow2 -o compat=0.10 #{final_path}'.")
22
+ else
23
+ fatal "Build failed!"
20
24
  end
21
- execute "rm", "/tmp/first_boot.sh", "-f"
25
+ SSHKit.config.output_verbosity = fetch(:log_level)
22
26
  end
23
27
  end
24
28
  end
25
29
 
26
30
  #desc "Mount qcow2 image by creating a run file holding the nbd needed."
27
- task :mount do
31
+ task :mount => 'libvirtinator:load_settings' do
28
32
  on roles(:app) do
29
33
  as :root do
30
34
  if test "[", "-f", fetch(:nbd_run_file), "]"
@@ -56,7 +60,7 @@ namespace :image do
56
60
  end
57
61
 
58
62
  #desc "Un-mount qcow2 image"
59
- task :umount do
63
+ task :umount => 'libvirtinator:load_settings' do
60
64
  on roles(:app) do
61
65
  as :root do
62
66
  if test "[", "-f", fetch(:nbd_run_file), "]"
@@ -81,7 +85,7 @@ namespace :image do
81
85
  end
82
86
 
83
87
  desc "Find the base image for each root qcow2 image on the host machine"
84
- task :list_bases do
88
+ task :list_bases => 'libvirtinator:load_settings' do
85
89
  on roles(:app) do
86
90
  as :root do
87
91
  set :files, -> { capture("ls", "#{fetch(:root_partitions_path)}/*.qcow2" ).split }
@@ -106,7 +110,7 @@ namespace :image do
106
110
  end
107
111
  end
108
112
 
109
- task :connect_to_unused_nbd do
113
+ task :connect_to_unused_nbd => 'libvirtinator:load_settings' do
110
114
  on roles(:app) do
111
115
  as :root do
112
116
  set :prelock, -> { "#{fetch(:nbd_lock_file)}.prelock" }
@@ -158,7 +162,7 @@ namespace :image do
158
162
  end
159
163
  end
160
164
 
161
- task :disconnect_from_nbd do
165
+ task :disconnect_from_nbd => 'libvirtinator:load_settings' do
162
166
  on roles(:app) do
163
167
  as :root do
164
168
  execute "qemu-nbd", "-d", fetch(:dev_nbd)
@@ -1,6 +1,6 @@
1
1
  namespace :lv do
2
2
  #desc "Remove a logical volume and recreate it."
3
- task :recreate do
3
+ task :recreate => 'libvirtinator:load_settings' do
4
4
  on roles(:app) do
5
5
  as :root do
6
6
  if test "[", "-b", fetch(:data_disk_lv_path), "]"
@@ -18,7 +18,7 @@ namespace :lv do
18
18
  end
19
19
 
20
20
  #desc "Create a logical volume."
21
- task :create do
21
+ task :create => 'libvirtinator:load_settings' do
22
22
  on roles(:app) do
23
23
  as :root do
24
24
  if test "lvcreate", fetch(:data_disk_vg_path), "-L", "#{fetch(:data_disk_gb)}G", "-n", fetch(:data_disk_lv_name)
@@ -32,7 +32,7 @@ namespace :lv do
32
32
  end
33
33
 
34
34
  #desc "Create an ext4 filesystem."
35
- task :mkfs do
35
+ task :mkfs => 'libvirtinator:load_settings' do
36
36
  on roles(:app) do
37
37
  as :root do
38
38
  unless test "[", "-b", fetch(:data_disk_lv_path), "]"
@@ -1,6 +1,6 @@
1
1
  namespace :users do
2
2
 
3
- task :load_settings do
3
+ task :load_settings => 'libvirtinator:load_settings' do
4
4
  if ENV['key_path'].nil?
5
5
  set :path, ""
6
6
  until File.exists?(fetch(:path)) and (! File.directory?(fetch(:path)))
@@ -19,15 +19,19 @@ namespace :users do
19
19
  end
20
20
  end
21
21
 
22
- desc "Idempotently setup admin UNIX users using only a domain name (or IP) and a usergroup file"
23
- task :setup_domain, [:domain, :usergroup] do |t, args|
24
- set :ip, -> { args.domain }
25
- set :usergroups, -> { Array(args.usergroup) }
22
+ desc "Idempotently setup admin UNIX users using only a domain name (or IP) and usergroups files"
23
+ task :setup_domain => 'libvirtinator:load_settings' do
24
+ if ENV['domain'].nil? or ENV['usergroups'].nil?
25
+ fatal "Please set domain and usergroups like 'cap users:setup_domain domain=example.com usergroups=sysadmins,others'"
26
+ exit
27
+ end
28
+ set :ip, -> { ENV['domain'] }
29
+ set :usergroups, -> { Array(ENV['usergroups'].split',') }
26
30
  Rake::Task['users:setup'].invoke
27
31
  end
28
32
 
29
33
  desc "Idempotently setup admin UNIX users."
30
- task :setup => :load_settings do
34
+ task :setup => ['libvirtinator:load_settings', 'users:load_settings'] do
31
35
  on "#{fetch(:user)}@#{fetch(:ip)}" do
32
36
  as :root do
33
37
  fetch(:usergroups).each do |usergroup|
@@ -3,7 +3,7 @@ require 'timeout'
3
3
  require 'erb'
4
4
 
5
5
  desc "Check the current status of a VM"
6
- task :status do
6
+ task :status => 'libvirtinator:load_settings' do
7
7
  on roles(:app) do
8
8
  as :root do
9
9
  if test("virsh", "list", "--all", "|", "grep", "-q", "#{fetch(:node_name)}")
@@ -32,7 +32,7 @@ task :status do
32
32
  end
33
33
 
34
34
  desc "Start a copy-on-write VM from a base image."
35
- task :start do
35
+ task :start => 'libvirtinator:load_settings' do
36
36
  on roles(:app) do
37
37
  info "Preparing to start #{fetch(:node_name)}"
38
38
  Rake::Task['ensure_nbd_module'].invoke
@@ -56,12 +56,14 @@ task :start do
56
56
  Rake::Task['setup_agent_forwarding'].invoke
57
57
  Rake::Task['wait_for_ping'].invoke
58
58
  Rake::Task['wait_for_ssh_alive'].invoke
59
+ # TODO make users:setup offer a yes/no try-again when a specified key doesn't work to connect.
60
+ # TODO make users:setup failure invoke notice "don't worry, you can resume setting up users with 'cap <stage> users:setup'"
59
61
  Rake::Task['users:setup'].invoke
60
62
  info "Say, you don't say? Are we finished?"
61
63
  end
62
64
  end
63
65
 
64
- task :ensure_root_partitions_path do
66
+ task :ensure_root_partitions_path => 'libvirtinator:load_settings' do
65
67
  on roles(:app) do
66
68
  as :root do
67
69
  dir = fetch(:root_partitions_path)
@@ -73,7 +75,7 @@ task :ensure_root_partitions_path do
73
75
  end
74
76
  end
75
77
 
76
- task :ensure_nbd_module do
78
+ task :ensure_nbd_module => 'libvirtinator:load_settings' do
77
79
  on roles(:app) do
78
80
  as :root do
79
81
  unless test("lsmod | grep -q nbd")
@@ -89,7 +91,7 @@ task :ensure_nbd_module do
89
91
  end
90
92
  end
91
93
 
92
- task :ensure_vm_not_running do
94
+ task :ensure_vm_not_running => 'libvirtinator:load_settings' do
93
95
  on roles(:app) do
94
96
  as :root do
95
97
  if test("virsh", "list", "|", "grep", "-q", "#{fetch(:node_name)}")
@@ -100,7 +102,7 @@ task :ensure_vm_not_running do
100
102
  end
101
103
  end
102
104
 
103
- task :ensure_ip_no_ping do
105
+ task :ensure_ip_no_ping => 'libvirtinator:load_settings' do
104
106
  run_locally do
105
107
  info "Attempting to ping #{fetch(:ip)}"
106
108
  if system "bash -c \"ping -c 3 -w 5 #{fetch(:ip)} &> /dev/null\""
@@ -112,7 +114,7 @@ task :ensure_ip_no_ping do
112
114
  end
113
115
  end
114
116
 
115
- task :ensure_vm_not_defined do
117
+ task :ensure_vm_not_defined => 'libvirtinator:load_settings' do
116
118
  on roles(:app) do
117
119
  as :root do
118
120
  if test("virsh", "list", "--all", "|", "grep", "-q", "#{fetch(:node_name)}")
@@ -130,7 +132,7 @@ task :ensure_vm_not_defined do
130
132
  end
131
133
  end
132
134
 
133
- task :verify_base do
135
+ task :verify_base => 'libvirtinator:load_settings' do
134
136
  on roles(:app) do
135
137
  as :root do
136
138
  unless test "[", "-f", fetch(:base_image_path), "]"
@@ -142,7 +144,7 @@ task :verify_base do
142
144
  end
143
145
  end
144
146
 
145
- task :remove_root_image do
147
+ task :remove_root_image => 'libvirtinator:load_settings' do
146
148
  on roles(:app) do
147
149
  as :root do
148
150
  # use 'cap <server> create recreate_root=true' to recreate the root image
@@ -162,7 +164,7 @@ task :remove_root_image do
162
164
  end
163
165
  end
164
166
 
165
- task :create_root_image do
167
+ task :create_root_image => 'libvirtinator:load_settings' do
166
168
  on roles(:app) do
167
169
  as :root do
168
170
  unless test "[", "-f", fetch(:root_image_path), "]"
@@ -183,7 +185,7 @@ task :create_root_image do
183
185
  end
184
186
  end
185
187
 
186
- task :update_root_image do
188
+ task :update_root_image => 'libvirtinator:load_settings' do
187
189
  on roles(:app) do
188
190
  as :root do
189
191
  mount_point = fetch(:mount_point)
@@ -216,6 +218,7 @@ task :update_root_image do
216
218
  upload! StringIO.new(generated_config_file), "/tmp/#{file}.file"
217
219
  execute("mv", "/tmp/#{file}.file", path)
218
220
  execute("chown", "root:root", path)
221
+ execute("chmod", "644", path)
219
222
  end
220
223
  execute "sed", "-i\"\"", "\"/PermitRootLogin/c\\PermitRootLogin no\"",
221
224
  "#{mount_point}/etc/ssh/sshd_config"
@@ -254,7 +257,7 @@ task :update_root_image do
254
257
  end
255
258
  end
256
259
 
257
- task :create_data do
260
+ task :create_data => 'libvirtinator:load_settings' do
258
261
  on roles(:app) do
259
262
  as 'root' do
260
263
  unless fetch(:data_disk_enabled)
@@ -293,7 +296,7 @@ _EOF_"
293
296
  end
294
297
  end
295
298
 
296
- task :define_domain do
299
+ task :define_domain => 'libvirtinator:load_settings' do
297
300
  on roles(:app) do
298
301
  as 'root' do
299
302
  # instance variables needed for ERB
@@ -315,7 +318,7 @@ task :define_domain do
315
318
  end
316
319
  end
317
320
 
318
- task :start_domain do
321
+ task :start_domain => 'libvirtinator:load_settings' do
319
322
  on roles(:app) do
320
323
  as 'root' do
321
324
  execute "virsh", "start", "#{fetch(:node_name)}"
@@ -324,7 +327,7 @@ task :start_domain do
324
327
  end
325
328
 
326
329
  # Keep this to aid with users setup
327
- task :reset_known_hosts_on_host do
330
+ task :reset_known_hosts_on_host => 'libvirtinator:load_settings' do
328
331
  run_locally do
329
332
  user = if ENV['SUDO_USER']; ENV['SUDO_USER']; else; ENV['USER']; end
330
333
  execute "sudo", "-u", user, "ssh-keygen", "-R", "#{fetch(:node_name)}"
@@ -335,7 +338,7 @@ task :reset_known_hosts_on_host do
335
338
  end
336
339
  end
337
340
 
338
- task :wait_for_ping do
341
+ task :wait_for_ping => 'libvirtinator:load_settings' do
339
342
  run_locally do
340
343
  info "Waiting for VM to respond to ping.."
341
344
  begin
@@ -362,7 +365,11 @@ task :wait_for_ping do
362
365
  end
363
366
  end
364
367
 
365
- task :setup_agent_forwarding do
368
+ # TODO confirm and remove auto-setup of agent forwarding,
369
+ # not only is this not idempotent (it continually adds to `.ssh/config`),
370
+ # but it should not be needed, since capistrano forwards the agent automatically.
371
+ # Manual SSH configuration for agent fowarding should be needed. - Confirm VM creation still work this way.
372
+ task :setup_agent_forwarding => 'libvirtinator:load_settings' do
366
373
  run_locally do
367
374
  lines = <<-eos
368
375
  \nHost #{fetch(:node_fqdn)}
@@ -388,7 +395,7 @@ Host #{fetch(:node_name)}
388
395
  end
389
396
  end
390
397
 
391
- task :wait_for_ssh_alive do
398
+ task :wait_for_ssh_alive => 'libvirtinator:load_settings' do
392
399
  run_locally do
393
400
  info "Waiting for VM SSH alive.."
394
401
  begin
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: libvirtinator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,14 +9,14 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-12-11 00:00:00.000000000 Z
12
+ date: 2016-01-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: capistrano
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
- - - '='
19
+ - - ~>
20
20
  - !ruby/object:Gem::Version
21
21
  version: 3.2.1
22
22
  type: :runtime
@@ -24,7 +24,7 @@ dependencies:
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  none: false
26
26
  requirements:
27
- - - '='
27
+ - - ~>
28
28
  - !ruby/object:Gem::Version
29
29
  version: 3.2.1
30
30
  description: An Opinionated libvirt VM Deployment gem
@@ -42,7 +42,6 @@ files:
42
42
  - lib/libvirtinator/examples/Capfile
43
43
  - lib/libvirtinator/examples/config/deploy.rb
44
44
  - lib/libvirtinator/examples/config/deploy/vm_name.rb
45
- - lib/libvirtinator/examples/config/deploy/manual.rb
46
45
  - lib/libvirtinator/examples/config/sysadmins_keys.rb
47
46
  - lib/libvirtinator/examples/first_boot.sh.erb
48
47
  - lib/libvirtinator/examples/fstab.erb
@@ -72,11 +71,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
72
71
  - - ! '>='
73
72
  - !ruby/object:Gem::Version
74
73
  version: '0'
75
- requirements:
76
- - Docker ~1.3.1
74
+ requirements: []
77
75
  rubyforge_project:
78
76
  rubygems_version: 1.8.23.2
79
77
  signing_key:
80
78
  specification_version: 3
81
79
  summary: Deploy libvirt VMs
82
80
  test_files: []
81
+ has_rdoc:
@@ -1,25 +0,0 @@
1
- set :host_machine_name, "none"
2
- set :user, -> { ENV['USER'] }
3
-
4
- role :app, "none"
5
-
6
- set :base_image, "none"
7
- set :node_name, "none"
8
-
9
- set :data_disk_enabled, false
10
- set :data_disk_gb, "0"
11
- set :data_disk_type, "lv"
12
- set :data_disk_mount_point, "/"
13
- set :data_disk_partition, "0"
14
-
15
- set :memory_gb, "0"
16
- set :cpus, "0"
17
-
18
- set :ip, "none"
19
- set :cidr, "none"
20
-
21
- set :node_fqdn, "none"
22
- set :app_fqdn, "none"
23
- set :hostname, "none"
24
-
25
- set :usergroups, ["none"]