libvirtinator 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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"]