vagrant-simple_cloud 0.0.5

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