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.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/Gemfile +10 -0
- data/LICENSE +373 -0
- data/Rakefile +22 -0
- data/lib/vagrant-simple_cloud/actions/check_state.rb +19 -0
- data/lib/vagrant-simple_cloud/actions/create.rb +94 -0
- data/lib/vagrant-simple_cloud/actions/destroy.rb +30 -0
- data/lib/vagrant-simple_cloud/actions/modify_provision_path.rb +38 -0
- data/lib/vagrant-simple_cloud/actions/power_off.rb +35 -0
- data/lib/vagrant-simple_cloud/actions/power_on.rb +36 -0
- data/lib/vagrant-simple_cloud/actions/rebuild.rb +49 -0
- data/lib/vagrant-simple_cloud/actions/reload.rb +33 -0
- data/lib/vagrant-simple_cloud/actions/setup_key.rb +58 -0
- data/lib/vagrant-simple_cloud/actions/setup_sudo.rb +48 -0
- data/lib/vagrant-simple_cloud/actions/setup_user.rb +66 -0
- data/lib/vagrant-simple_cloud/actions/shut_down.rb +35 -0
- data/lib/vagrant-simple_cloud/actions.rb +164 -0
- data/lib/vagrant-simple_cloud/commands/list.rb +93 -0
- data/lib/vagrant-simple_cloud/commands/rebuild.rb +29 -0
- data/lib/vagrant-simple_cloud/config.rb +69 -0
- data/lib/vagrant-simple_cloud/errors.rb +37 -0
- data/lib/vagrant-simple_cloud/helpers/client.rb +106 -0
- data/lib/vagrant-simple_cloud/helpers/client_service.rb +81 -0
- data/lib/vagrant-simple_cloud/helpers/result.rb +40 -0
- data/lib/vagrant-simple_cloud/plugin.rb +31 -0
- data/lib/vagrant-simple_cloud/provider.rb +102 -0
- data/lib/vagrant-simple_cloud/version.rb +5 -0
- data/lib/vagrant-simple_cloud.rb +20 -0
- data/locales/en.yml +92 -0
- data/test/Vagrantfile +24 -0
- data/test/scripts/provision.sh +3 -0
- data/test/test.sh +10 -0
- data/test/test_id_rsa +27 -0
- data/test/test_id_rsa.pub +1 -0
- data/vagrant-simple_cloud.gemspec +21 -0
- 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
|