vagrant-simple_cloud 0.0.5

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.
Files changed (37) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/Gemfile +10 -0
  4. data/LICENSE +373 -0
  5. data/Rakefile +22 -0
  6. data/lib/vagrant-simple_cloud/actions/check_state.rb +19 -0
  7. data/lib/vagrant-simple_cloud/actions/create.rb +94 -0
  8. data/lib/vagrant-simple_cloud/actions/destroy.rb +30 -0
  9. data/lib/vagrant-simple_cloud/actions/modify_provision_path.rb +38 -0
  10. data/lib/vagrant-simple_cloud/actions/power_off.rb +35 -0
  11. data/lib/vagrant-simple_cloud/actions/power_on.rb +36 -0
  12. data/lib/vagrant-simple_cloud/actions/rebuild.rb +49 -0
  13. data/lib/vagrant-simple_cloud/actions/reload.rb +33 -0
  14. data/lib/vagrant-simple_cloud/actions/setup_key.rb +58 -0
  15. data/lib/vagrant-simple_cloud/actions/setup_sudo.rb +48 -0
  16. data/lib/vagrant-simple_cloud/actions/setup_user.rb +66 -0
  17. data/lib/vagrant-simple_cloud/actions/shut_down.rb +35 -0
  18. data/lib/vagrant-simple_cloud/actions.rb +164 -0
  19. data/lib/vagrant-simple_cloud/commands/list.rb +93 -0
  20. data/lib/vagrant-simple_cloud/commands/rebuild.rb +29 -0
  21. data/lib/vagrant-simple_cloud/config.rb +69 -0
  22. data/lib/vagrant-simple_cloud/errors.rb +37 -0
  23. data/lib/vagrant-simple_cloud/helpers/client.rb +106 -0
  24. data/lib/vagrant-simple_cloud/helpers/client_service.rb +81 -0
  25. data/lib/vagrant-simple_cloud/helpers/result.rb +40 -0
  26. data/lib/vagrant-simple_cloud/plugin.rb +31 -0
  27. data/lib/vagrant-simple_cloud/provider.rb +102 -0
  28. data/lib/vagrant-simple_cloud/version.rb +5 -0
  29. data/lib/vagrant-simple_cloud.rb +20 -0
  30. data/locales/en.yml +92 -0
  31. data/test/Vagrantfile +24 -0
  32. data/test/scripts/provision.sh +3 -0
  33. data/test/test.sh +10 -0
  34. data/test/test_id_rsa +27 -0
  35. data/test/test_id_rsa.pub +1 -0
  36. data/vagrant-simple_cloud.gemspec +21 -0
  37. metadata +127 -0
@@ -0,0 +1,94 @@
1
+ require 'vagrant-simple_cloud/helpers/client'
2
+ require 'vagrant-simple_cloud/helpers/client_service'
3
+
4
+ module VagrantPlugins
5
+ module SimpleCloud
6
+ module Actions
7
+ class Create
8
+ include Helpers::Client
9
+ include Helpers::ClientService
10
+ include Vagrant::Util::Retryable
11
+
12
+ def initialize(app, env)
13
+ @app = app
14
+ @machine = env[:machine]
15
+ @client = client
16
+ @clientservice = clientservice
17
+ @logger = Log4r::Logger.new('vagrant::simple_cloud::create')
18
+ end
19
+
20
+ def call(env)
21
+ ssh_key_id = [env[:ssh_key_id]]
22
+
23
+ # submit new droplet request
24
+ result = @clientservice.post('/v2/vps', {
25
+ :size => @machine.provider_config.size,
26
+ :region => @machine.provider_config.region,
27
+ :image => @machine.provider_config.image,
28
+ :name => @machine.config.vm.hostname || @machine.name,
29
+ :ssh_keys => ssh_key_id,
30
+ :private_networking => @machine.provider_config.private_networking,
31
+ :backups => @machine.provider_config.backups_enabled,
32
+ :ipv6 => @machine.provider_config.ipv6,
33
+ :user_data => @machine.provider_config.user_data
34
+ }.delete_if { |k, v| v.nil? })
35
+
36
+ # assign the machine id for reference in other commands
37
+ @machine.id = result['vps']['id'].to_s
38
+
39
+ #raise 'VPS not ready, no actions_ids' unless result['vps'].has_key?('action_ids')
40
+ result = @client.request("/v2/vps/#{@machine.id}/actions")
41
+
42
+ # wait for request to complete
43
+ env[:ui].info I18n.t('vagrant_simple_cloud.info.creating')
44
+ @client.wait_for_event(env, result['actions'].first['id'])
45
+
46
+ # refresh droplet state with provider and output ip address
47
+ droplet = Provider.droplet(@machine, :refresh => true)
48
+ public_network = droplet['networks']['v4'].find { |network| network['type'] == 'public' }
49
+ private_network = droplet['networks']['v4'].find { |network| network['type'] == 'private' }
50
+ env[:ui].info I18n.t('vagrant_simple_cloud.info.droplet_ip', {
51
+ :ip => public_network['ip_address']
52
+ })
53
+ if private_network
54
+ env[:ui].info I18n.t('vagrant_simple_cloud.info.droplet_private_ip', {
55
+ :ip => private_network['ip_address']
56
+ })
57
+ end
58
+
59
+ # wait for ssh to be ready
60
+ switch_user = @machine.provider_config.setup?
61
+ user = @machine.config.ssh.username
62
+ @machine.config.ssh.username = 'root' if switch_user
63
+
64
+ retryable(:tries => 120, :sleep => 10) do
65
+ next if env[:interrupted]
66
+ raise 'not ready' if !@machine.communicate.ready?
67
+ end
68
+
69
+ @machine.config.ssh.username = user
70
+
71
+ @app.call(env)
72
+ end
73
+
74
+ # Both the recover and terminate are stolen almost verbatim from
75
+ # the Vagrant AWS provider up action
76
+ def recover(env)
77
+ return if env['vagrant.error'].is_a?(Vagrant::Errors::VagrantError)
78
+
79
+ if @machine.state.id != :not_created
80
+ terminate(env)
81
+ end
82
+ end
83
+
84
+ def terminate(env)
85
+ destroy_env = env.dup
86
+ destroy_env.delete(:interrupted)
87
+ destroy_env[:config_validate] = false
88
+ destroy_env[:force_confirm_destroy] = true
89
+ env[:action_runner].run(Actions.destroy, destroy_env)
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,30 @@
1
+ require 'vagrant-simple_cloud/helpers/client'
2
+
3
+ module VagrantPlugins
4
+ module SimpleCloud
5
+ module Actions
6
+ class Destroy
7
+ include Helpers::Client
8
+
9
+ def initialize(app, env)
10
+ @app = app
11
+ @machine = env[:machine]
12
+ @client = client
13
+ @logger = Log4r::Logger.new('vagrant::simple_cloud::destroy')
14
+ end
15
+
16
+ def call(env)
17
+ # submit destroy droplet request
18
+ @client.delete("/v2/vps/#{@machine.id}")
19
+
20
+ env[:ui].info I18n.t('vagrant_simple_cloud.info.destroying')
21
+
22
+ # set the machine id to nil to cleanup local vagrant state
23
+ @machine.id = nil
24
+
25
+ @app.call(env)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,38 @@
1
+ module VagrantPlugins
2
+ module SimpleCloud
3
+ module Actions
4
+ class ModifyProvisionPath
5
+ def initialize(app, env)
6
+ @app = app
7
+ @machine = env[:machine]
8
+ @logger =
9
+ Log4r::Logger.new('vagrant::simple_cloud::modify_provision_path')
10
+ end
11
+
12
+ def call(env)
13
+ # check if provisioning is enabled
14
+ enabled = true
15
+ enabled = env[:provision_enabled] if env.has_key?(:provision_enabled)
16
+ return @app.call(env) if !enabled
17
+
18
+ username = @machine.ssh_info()[:username]
19
+
20
+ # change ownership of the provisioning path recursively to the
21
+ # ssh user
22
+ #
23
+ # TODO submit patch to vagrant to set appropriate permissions
24
+ # based on ssh username
25
+ @machine.config.vm.provisioners.each do |provisioner|
26
+ cfg = provisioner.config
27
+ path = cfg.upload_path if cfg.respond_to? :upload_path
28
+ path = cfg.provisioning_path if cfg.respond_to? :provisioning_path
29
+ @machine.communicate.sudo("chown -R #{username} #{path}",
30
+ :error_check => false)
31
+ end
32
+
33
+ @app.call(env)
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,35 @@
1
+ require 'vagrant-simple_cloud/helpers/client'
2
+ #TODO: --force
3
+ module VagrantPlugins
4
+ module SimpleCloud
5
+ module Actions
6
+ class PowerOff
7
+ include Helpers::Client
8
+
9
+ def initialize(app, env)
10
+ @app = app
11
+ @machine = env[:machine]
12
+ @client = client
13
+ @logger = Log4r::Logger.new('vagrant::simple_cloud::power_off')
14
+ end
15
+
16
+ def call(env)
17
+ # submit power off droplet request
18
+ result = @client.post("/v2/vps/#{@machine.id}/actions", {
19
+ :type => 'power_off'
20
+ })
21
+
22
+ # wait for request to complete
23
+ env[:ui].info I18n.t('vagrant_simple_cloud.info.powering_off')
24
+ @client.wait_for_event(env, result['action']['id'])
25
+
26
+ # refresh droplet state with provider
27
+ Provider.droplet(@machine, :refresh => true)
28
+
29
+ @app.call(env)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+
@@ -0,0 +1,36 @@
1
+ require 'vagrant-simple_cloud/helpers/client'
2
+
3
+ module VagrantPlugins
4
+ module SimpleCloud
5
+ module Actions
6
+ class PowerOn
7
+ include Helpers::Client
8
+
9
+ def initialize(app, env)
10
+ @app = app
11
+ @machine = env[:machine]
12
+ @client = client
13
+ @logger = Log4r::Logger.new('vagrant::simple_cloud::power_on')
14
+ end
15
+
16
+ def call(env)
17
+ # submit power on droplet request
18
+ result = @client.post("/v2/vps/#{@machine.id}/actions", {
19
+ :type => 'power_on'
20
+ })
21
+
22
+ # wait for request to complete
23
+ env[:ui].info I18n.t('vagrant_simple_cloud.info.powering_on')
24
+ @client.wait_for_event(env, result['action']['id'])
25
+
26
+ # refresh droplet state with provider
27
+ Provider.droplet(@machine, :refresh => true)
28
+
29
+ @app.call(env)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+
@@ -0,0 +1,49 @@
1
+ require 'vagrant-simple_cloud/helpers/client'
2
+
3
+ module VagrantPlugins
4
+ module SimpleCloud
5
+ module Actions
6
+ class Rebuild
7
+ include Helpers::Client
8
+ include Vagrant::Util::Retryable
9
+
10
+ def initialize(app, env)
11
+ @app = app
12
+ @machine = env[:machine]
13
+ @client = client
14
+ @logger = Log4r::Logger.new('vagrant::simple_cloud::rebuild')
15
+ end
16
+
17
+ def call(env)
18
+
19
+ # submit rebuild request
20
+ result = @client.post("/v2/vps/#{@machine.id}/actions", {
21
+ :type => 'rebuild',
22
+ :image => @machine.provider_config.image
23
+ })
24
+
25
+ # wait for request to complete
26
+ env[:ui].info I18n.t('vagrant_simple_cloud.info.rebuilding')
27
+ @client.wait_for_event(env, result['action']['id'])
28
+
29
+ # refresh droplet state with provider
30
+ Provider.droplet(@machine, :refresh => true)
31
+
32
+ # wait for ssh to be ready
33
+ switch_user = @machine.provider_config.setup?
34
+ user = @machine.config.ssh.username
35
+ @machine.config.ssh.username = 'root' if switch_user
36
+
37
+ retryable(:tries => 120, :sleep => 10) do
38
+ next if env[:interrupted]
39
+ raise 'not ready' if !@machine.communicate.ready?
40
+ end
41
+
42
+ @machine.config.ssh.username = user
43
+
44
+ @app.call(env)
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,33 @@
1
+ require 'vagrant-simple_cloud/helpers/client'
2
+
3
+ module VagrantPlugins
4
+ module SimpleCloud
5
+ module Actions
6
+ class Reload
7
+ include Helpers::Client
8
+
9
+ def initialize(app, env)
10
+ @app = app
11
+ @machine = env[:machine]
12
+ @client = client
13
+ @logger = Log4r::Logger.new('vagrant::simple_cloud::reload')
14
+ end
15
+
16
+ def call(env)
17
+ # submit reboot droplet request
18
+ result = @client.post("/v2/vps/#{@machine.id}/actions", {
19
+ :type => 'reboot'
20
+ })
21
+
22
+ # wait for request to complete
23
+ env[:ui].info I18n.t('vagrant_simple_cloud.info.reloading')
24
+ @client.wait_for_event(env, result['action']['id'])
25
+
26
+ @app.call(env)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+
@@ -0,0 +1,58 @@
1
+ require 'vagrant-simple_cloud/helpers/client'
2
+
3
+ module VagrantPlugins
4
+ module SimpleCloud
5
+ module Actions
6
+ class SetupKey
7
+ include Helpers::Client
8
+
9
+ def initialize(app, env)
10
+ @app = app
11
+ @machine = env[:machine]
12
+ @client = client
13
+ @logger = Log4r::Logger.new('vagrant::simple_cloud::setup_key')
14
+ end
15
+
16
+ # TODO check the content of the key to see if it has changed
17
+ def call(env)
18
+ ssh_key_name = @machine.provider_config.ssh_key_name
19
+
20
+ begin
21
+ # assigns existing ssh key id to env for use by other commands
22
+ env[:ssh_key_id] = @client
23
+ .request('/v2/account/keys')
24
+ .find_id(:ssh_keys, :name => ssh_key_name)
25
+
26
+ env[:ui].info I18n.t('vagrant_simple_cloud.info.using_key', {
27
+ :name => ssh_key_name
28
+ })
29
+ rescue Errors::ResultMatchError
30
+ env[:ssh_key_id] = create_ssh_key(ssh_key_name, env)
31
+ end
32
+
33
+ @app.call(env)
34
+ end
35
+
36
+ private
37
+
38
+ def create_ssh_key(name, env)
39
+ # assumes public key exists on the same path as private key with .pub ext
40
+ path = @machine.config.ssh.private_key_path
41
+ path = path[0] if path.is_a?(Array)
42
+ path = File.expand_path(path, @machine.env.root_path)
43
+ pub_key = SimpleCloud.public_key(path)
44
+
45
+ env[:ui].info I18n.t('vagrant_simple_cloud.info.creating_key', {
46
+ :name => name
47
+ })
48
+
49
+ result = @client.post('/v2/account/keys', {
50
+ :name => name,
51
+ :public_key => pub_key
52
+ })
53
+ result['ssh_key']['id']
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,48 @@
1
+ module VagrantPlugins
2
+ module SimpleCloud
3
+ module Actions
4
+ class SetupSudo
5
+ def initialize(app, env)
6
+ @app = app
7
+ @machine = env[:machine]
8
+ @logger = Log4r::Logger.new('vagrant::simple_cloud::setup_sudo')
9
+ end
10
+
11
+ def call(env)
12
+ # check if setup is enabled
13
+ return @app.call(env) unless @machine.provider_config.setup?
14
+
15
+ # override ssh username to root
16
+ user = @machine.config.ssh.username
17
+ @machine.config.ssh.username = 'root'
18
+
19
+ # check for guest name available in Vagrant 1.2 first
20
+ guest_name = @machine.guest.name if @machine.guest.respond_to?(:name)
21
+ guest_name ||= @machine.guest.to_s.downcase
22
+
23
+ case guest_name
24
+ when /debian/
25
+ if @machine.provider_config.image =~ /^debian-8/
26
+ env[:ui].info I18n.t('vagrant_simple_cloud.info.late_sudo_install_deb8')
27
+ @machine.communicate.execute(<<-'BASH')
28
+ if [ ! -x /usr/bin/sudo ] ; then apt-get update -y && apt-get install -y sudo ; fi
29
+ BASH
30
+ end
31
+ when /redhat/
32
+ env[:ui].info I18n.t('vagrant_simple_cloud.info.modifying_sudo')
33
+
34
+ # disable tty requirement for sudo
35
+ @machine.communicate.execute(<<-'BASH')
36
+ sed -i'.bk' -e 's/\(Defaults\s\+requiretty\)/# \1/' /etc/sudoers
37
+ BASH
38
+ end
39
+
40
+ # reset ssh username
41
+ @machine.config.ssh.username = user
42
+
43
+ @app.call(env)
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,66 @@
1
+ module VagrantPlugins
2
+ module SimpleCloud
3
+ module Actions
4
+ class SetupUser
5
+ def initialize(app, env)
6
+ @app = app
7
+ @machine = env[:machine]
8
+ @logger = Log4r::Logger.new('vagrant::simple_cloud::setup_user')
9
+ end
10
+
11
+ def call(env)
12
+ # check if setup is enabled
13
+ return @app.call(env) unless @machine.provider_config.setup?
14
+
15
+ # check if a username has been specified
16
+ return @app.call(env) unless @machine.config.ssh.username
17
+
18
+ # override ssh username to root temporarily
19
+ user = @machine.config.ssh.username
20
+ @machine.config.ssh.username = 'root'
21
+
22
+ env[:ui].info I18n.t('vagrant_simple_cloud.info.creating_user', {
23
+ :user => user
24
+ })
25
+
26
+ # create user account
27
+ @machine.communicate.execute(<<-BASH)
28
+ if ! (grep ^#{user}: /etc/passwd); then
29
+ useradd -m -s /bin/bash #{user};
30
+ fi
31
+ BASH
32
+
33
+ # grant user sudo access with no password requirement
34
+ @machine.communicate.execute(<<-BASH)
35
+ if ! (grep #{user} /etc/sudoers); then
36
+ echo "#{user} ALL=(ALL:ALL) NOPASSWD: ALL" >> /etc/sudoers;
37
+ else
38
+ sed -i -e "/#{user}/ s/=.*/=(ALL:ALL) NOPASSWD: ALL/" /etc/sudoers;
39
+ fi
40
+ BASH
41
+
42
+ # create the .ssh directory in the users home
43
+ @machine.communicate.execute("su #{user} -c 'mkdir -p ~/.ssh'")
44
+
45
+ # add the specified key to the authorized keys file
46
+ path = @machine.config.ssh.private_key_path
47
+ path = path[0] if path.is_a?(Array)
48
+ path = File.expand_path(path, @machine.env.root_path)
49
+ pub_key = SimpleCloud.public_key(path)
50
+ @machine.communicate.execute(<<-BASH)
51
+ if ! grep '#{pub_key}' /home/#{user}/.ssh/authorized_keys; then
52
+ echo '#{pub_key}' >> /home/#{user}/.ssh/authorized_keys;
53
+ fi
54
+
55
+ chown -R #{user} /home/#{user}/.ssh;
56
+ BASH
57
+
58
+ # reset username
59
+ @machine.config.ssh.username = user
60
+
61
+ @app.call(env)
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end