vagrant-scaleway 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.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.ruby-version +1 -0
- data/Gemfile +12 -0
- data/LICENSE.txt +21 -0
- data/README.md +69 -0
- data/Rakefile +9 -0
- data/dummy.box +0 -0
- data/example_box/metadata.json +3 -0
- data/lib/vagrant-scaleway.rb +17 -0
- data/lib/vagrant-scaleway/action.rb +179 -0
- data/lib/vagrant-scaleway/action/connect_scaleway.rb +34 -0
- data/lib/vagrant-scaleway/action/create_server.rb +75 -0
- data/lib/vagrant-scaleway/action/destroy_server.rb +34 -0
- data/lib/vagrant-scaleway/action/is_created.rb +18 -0
- data/lib/vagrant-scaleway/action/is_stopped.rb +18 -0
- data/lib/vagrant-scaleway/action/message_already_created.rb +16 -0
- data/lib/vagrant-scaleway/action/message_not_created.rb +16 -0
- data/lib/vagrant-scaleway/action/message_will_not_destroy.rb +16 -0
- data/lib/vagrant-scaleway/action/read_ssh_info.rb +50 -0
- data/lib/vagrant-scaleway/action/read_state.rb +36 -0
- data/lib/vagrant-scaleway/action/start_server.rb +90 -0
- data/lib/vagrant-scaleway/action/stop_server.rb +26 -0
- data/lib/vagrant-scaleway/action/warn_networks.rb +19 -0
- data/lib/vagrant-scaleway/config.rb +113 -0
- data/lib/vagrant-scaleway/errors.rb +21 -0
- data/lib/vagrant-scaleway/plugin.rb +73 -0
- data/lib/vagrant-scaleway/provider.rb +47 -0
- data/lib/vagrant-scaleway/util/timer.rb +17 -0
- data/lib/vagrant-scaleway/version.rb +5 -0
- data/locales/en.yml +81 -0
- data/vagrant-scaleway.gemspec +25 -0
- metadata +131 -0
@@ -0,0 +1,34 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module Scaleway
|
3
|
+
module Action
|
4
|
+
# This destroys the running server.
|
5
|
+
class DestroyServer
|
6
|
+
def initialize(app, _env)
|
7
|
+
@app = app
|
8
|
+
@logger = Log4r::Logger.new('vagrant_scaleway::action::destroy_server')
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(env)
|
12
|
+
server = env[:scaleway_compute].servers.get(env[:machine].id)
|
13
|
+
|
14
|
+
# Destroy the server and remove the tracking ID
|
15
|
+
env[:ui].info(I18n.t('vagrant_scaleway.destroying'))
|
16
|
+
|
17
|
+
begin
|
18
|
+
server.destroy
|
19
|
+
rescue Fog::Scaleway::Compute::InvalidRequestError => e
|
20
|
+
if e.message =~ /server should be stopped/
|
21
|
+
server.terminate(false)
|
22
|
+
else
|
23
|
+
raise
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
env[:machine].id = nil
|
28
|
+
|
29
|
+
@app.call(env)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module Scaleway
|
3
|
+
module Action
|
4
|
+
# This can be used with "Call" built-in to check if the machine
|
5
|
+
# is created and branch in the middleware.
|
6
|
+
class IsCreated
|
7
|
+
def initialize(app, _env)
|
8
|
+
@app = app
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(env)
|
12
|
+
env[:result] = env[:machine].state.id != :not_created
|
13
|
+
@app.call(env)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module Scaleway
|
3
|
+
module Action
|
4
|
+
# This can be used with "Call" built-in to check if the machine
|
5
|
+
# is stopped and branch in the middleware.
|
6
|
+
class IsStopped
|
7
|
+
def initialize(app, _env)
|
8
|
+
@app = app
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(env)
|
12
|
+
env[:result] = env[:machine].state.id == :stopped
|
13
|
+
@app.call(env)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module Scaleway
|
3
|
+
module Action
|
4
|
+
class MessageAlreadyCreated
|
5
|
+
def initialize(app, _env)
|
6
|
+
@app = app
|
7
|
+
end
|
8
|
+
|
9
|
+
def call(env)
|
10
|
+
env[:ui].info(I18n.t('vagrant_scaleway.already_status', status: 'created'))
|
11
|
+
@app.call(env)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module Scaleway
|
3
|
+
module Action
|
4
|
+
class MessageNotCreated
|
5
|
+
def initialize(app, _env)
|
6
|
+
@app = app
|
7
|
+
end
|
8
|
+
|
9
|
+
def call(env)
|
10
|
+
env[:ui].info(I18n.t('vagrant_scaleway.not_created'))
|
11
|
+
@app.call(env)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module Scaleway
|
3
|
+
module Action
|
4
|
+
class MessageWillNotDestroy
|
5
|
+
def initialize(app, _env)
|
6
|
+
@app = app
|
7
|
+
end
|
8
|
+
|
9
|
+
def call(env)
|
10
|
+
env[:ui].info(I18n.t('vagrant_scaleway.will_not_destroy', name: env[:machine].name))
|
11
|
+
@app.call(env)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module Scaleway
|
3
|
+
module Action
|
4
|
+
# This action reads the SSH info for the machine and puts it into the
|
5
|
+
# `:machine_ssh_info` key in the environment.
|
6
|
+
class ReadSSHInfo
|
7
|
+
def initialize(app, _env)
|
8
|
+
@app = app
|
9
|
+
@logger = Log4r::Logger.new('vagrant_scaleway::action::read_ssh_info')
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(env)
|
13
|
+
env[:machine_ssh_info] = read_ssh_info(env[:scaleway_compute], env[:machine])
|
14
|
+
|
15
|
+
@app.call(env)
|
16
|
+
end
|
17
|
+
|
18
|
+
def read_ssh_info(scaleway, machine)
|
19
|
+
return nil if machine.id.nil?
|
20
|
+
|
21
|
+
# Find the machine
|
22
|
+
server = scaleway.servers.get(machine.id)
|
23
|
+
if server.nil?
|
24
|
+
# The machine can't be found
|
25
|
+
@logger.info("Machine couldn't be found, assuming it got destroyed.")
|
26
|
+
machine.id = nil
|
27
|
+
return nil
|
28
|
+
end
|
29
|
+
|
30
|
+
# read attribute override
|
31
|
+
ssh_host_attribute = machine.provider_config.ssh_host_attribute
|
32
|
+
# default host attributes to try. NOTE: Order matters!
|
33
|
+
ssh_attrs = %i(public_ip_address public_dns_name private_ip_address private_dns_name)
|
34
|
+
ssh_attrs = (Array(ssh_host_attribute) + ssh_attrs).uniq if ssh_host_attribute
|
35
|
+
# try each attribute, get out on first value
|
36
|
+
host = nil
|
37
|
+
while !host && (attr = ssh_attrs.shift)
|
38
|
+
begin
|
39
|
+
host = server.send(attr)
|
40
|
+
rescue NoMethodError
|
41
|
+
@logger.info("SSH host attribute not found #{attr}")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
{ host: host, port: 22, username: 'root' }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module Scaleway
|
3
|
+
module Action
|
4
|
+
# This action reads the state of the machine and puts it in the
|
5
|
+
# `:machine_state_id` key in the environment.
|
6
|
+
class ReadState
|
7
|
+
def initialize(app, _env)
|
8
|
+
@app = app
|
9
|
+
@logger = Log4r::Logger.new('vagrant_scaleway::action::read_state')
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(env)
|
13
|
+
env[:machine_state_id] = read_state(env[:scaleway_compute], env[:machine])
|
14
|
+
|
15
|
+
@app.call(env)
|
16
|
+
end
|
17
|
+
|
18
|
+
def read_state(scaleway, machine)
|
19
|
+
return :not_created if machine.id.nil?
|
20
|
+
|
21
|
+
# Find the machine
|
22
|
+
server = scaleway.servers.get(machine.id)
|
23
|
+
if server.nil?
|
24
|
+
# The machine can't be found
|
25
|
+
@logger.info('Machine not found, assuming it got destroyed.')
|
26
|
+
machine.id = nil
|
27
|
+
return :not_created
|
28
|
+
end
|
29
|
+
|
30
|
+
# Return the state
|
31
|
+
server.state.to_sym
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'vagrant/util/retryable'
|
2
|
+
require 'vagrant-scaleway/util/timer'
|
3
|
+
|
4
|
+
module VagrantPlugins
|
5
|
+
module Scaleway
|
6
|
+
module Action
|
7
|
+
# This starts a stopped server.
|
8
|
+
class StartServer
|
9
|
+
include Vagrant::Util::Retryable
|
10
|
+
|
11
|
+
def initialize(app, _env)
|
12
|
+
@app = app
|
13
|
+
@logger = Log4r::Logger.new('vagrant_scaleway::action::start_server')
|
14
|
+
end
|
15
|
+
|
16
|
+
def call(env)
|
17
|
+
# Initialize metrics if they haven't been
|
18
|
+
env[:metrics] ||= {}
|
19
|
+
|
20
|
+
config = env[:machine].provider_config
|
21
|
+
|
22
|
+
server = env[:scaleway_compute].servers.get(env[:machine].id)
|
23
|
+
|
24
|
+
env[:ui].info(I18n.t('vagrant_scaleway.starting'))
|
25
|
+
|
26
|
+
begin
|
27
|
+
server.poweron
|
28
|
+
rescue Fog::Scaleway::Compute::Error => e
|
29
|
+
raise Errors::FogError, message: e.message
|
30
|
+
end
|
31
|
+
|
32
|
+
# Wait for the server to be ready first
|
33
|
+
env[:metrics]['server_ready_time'] = Util::Timer.time do
|
34
|
+
tries = config.server_ready_timeout / 2
|
35
|
+
|
36
|
+
env[:ui].info(I18n.t('vagrant_scaleway.waiting_for_ready'))
|
37
|
+
begin
|
38
|
+
retryable(on: Fog::Errors::TimeoutError, tries: tries) do
|
39
|
+
# If we're interrupted don't worry about waiting
|
40
|
+
next if env[:interrupted]
|
41
|
+
|
42
|
+
# Wait for the server to be ready
|
43
|
+
server.wait_for(2, config.server_check_interval) { ready? }
|
44
|
+
end
|
45
|
+
rescue Fog::Errors::TimeoutError
|
46
|
+
# Notify the user
|
47
|
+
raise Errors::ServerReadyTimeout,
|
48
|
+
timeout: config.server_ready_timeout
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
@logger.info("Time to server ready: #{env[:metrics]['server_ready_time']}")
|
53
|
+
|
54
|
+
unless env[:interrupted]
|
55
|
+
env[:metrics]['server_ssh_time'] = Util::Timer.time do
|
56
|
+
# Wait for SSH to be ready.
|
57
|
+
env[:ui].info(I18n.t('vagrant_scaleway.waiting_for_ssh'))
|
58
|
+
network_ready_retries = 0
|
59
|
+
network_ready_retries_max = 10
|
60
|
+
loop do
|
61
|
+
# If we're interrupted then just back out
|
62
|
+
break if env[:interrupted]
|
63
|
+
# When a server comes up, it's networking may not be ready by
|
64
|
+
# the time we connect.
|
65
|
+
begin
|
66
|
+
break if env[:machine].communicate.ready?
|
67
|
+
rescue Exception => e
|
68
|
+
if network_ready_retries < network_ready_retries_max
|
69
|
+
network_ready_retries += 1
|
70
|
+
@logger.warn(I18n.t('vagrant_scaleway.waiting_for_ssh, retrying'))
|
71
|
+
else
|
72
|
+
raise e
|
73
|
+
end
|
74
|
+
end
|
75
|
+
sleep 2
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
@logger.info("Time for SSH ready: #{env[:metrics]['server_ssh_time']}")
|
80
|
+
|
81
|
+
# Ready and booted!
|
82
|
+
env[:ui].info(I18n.t('vagrant_scaleway.ready'))
|
83
|
+
end
|
84
|
+
|
85
|
+
@app.call(env)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module Scaleway
|
3
|
+
module Action
|
4
|
+
# This stops the running server.
|
5
|
+
class StopServer
|
6
|
+
def initialize(app, _env)
|
7
|
+
@app = app
|
8
|
+
@logger = Log4r::Logger.new('vagrant_scaleway::action::stop_server')
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(env)
|
12
|
+
server = env[:scaleway_compute].servers.get(env[:machine].id)
|
13
|
+
|
14
|
+
if env[:machine].state.id == :stopped
|
15
|
+
env[:ui].info(I18n.t('vagrant_scaleway.already_status', status: env[:machine].state.id))
|
16
|
+
else
|
17
|
+
env[:ui].info(I18n.t('vagrant_scaleway.stopping'))
|
18
|
+
server.poweroff(false)
|
19
|
+
end
|
20
|
+
|
21
|
+
@app.call(env)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module Scaleway
|
3
|
+
module Action
|
4
|
+
class WarnNetworks
|
5
|
+
def initialize(app, _env)
|
6
|
+
@app = app
|
7
|
+
end
|
8
|
+
|
9
|
+
def call(env)
|
10
|
+
if env[:machine].config.vm.networks.length > 1
|
11
|
+
env[:ui].warn(I18n.t('vagrant_scaleway.warn_networks'))
|
12
|
+
end
|
13
|
+
|
14
|
+
@app.call(env)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module Scaleway
|
3
|
+
class Config < Vagrant.plugin('2', :config)
|
4
|
+
# The bootscript ID. If nil, the default bootscript for the image will be
|
5
|
+
# used.
|
6
|
+
#
|
7
|
+
# @return [String]
|
8
|
+
attr_accessor :bootscript
|
9
|
+
|
10
|
+
# The type of the server to launch, such as 'C1'. Defaults to 'C2S'.
|
11
|
+
#
|
12
|
+
# @return [String]
|
13
|
+
attr_accessor :commercial_type
|
14
|
+
|
15
|
+
# The image ID.
|
16
|
+
#
|
17
|
+
# @return [String]
|
18
|
+
attr_accessor :image
|
19
|
+
|
20
|
+
# The name of the server.
|
21
|
+
#
|
22
|
+
# @return [String]
|
23
|
+
attr_accessor :name
|
24
|
+
|
25
|
+
# The organization ID. It can also be configured with SCW_ORGANIZATION
|
26
|
+
# environment variable.
|
27
|
+
#
|
28
|
+
# @return [String]
|
29
|
+
attr_accessor :organization
|
30
|
+
|
31
|
+
# The security group to associate with the server. If nil, organization's
|
32
|
+
# default security group will be used.
|
33
|
+
#
|
34
|
+
# @return [String]
|
35
|
+
attr_accessor :security_group
|
36
|
+
|
37
|
+
# The interval to wait for checking a server's state. Defaults to 2
|
38
|
+
# seconds.
|
39
|
+
#
|
40
|
+
# @return [Fixnum]
|
41
|
+
attr_accessor :server_check_interval
|
42
|
+
|
43
|
+
# The timeout to wait for a server to become ready. Defaults to 120
|
44
|
+
# seconds.
|
45
|
+
#
|
46
|
+
# @return [Fixnum]
|
47
|
+
attr_accessor :server_ready_timeout
|
48
|
+
|
49
|
+
# Specifies which address to connect to with ssh.
|
50
|
+
# Must be one of:
|
51
|
+
# - :public_ip_address
|
52
|
+
# - :public_dns_name
|
53
|
+
# - :private_ip_address
|
54
|
+
# - :private_dns_name
|
55
|
+
# This attribute also accepts an array of symbols.
|
56
|
+
#
|
57
|
+
# @return [Symbol]
|
58
|
+
attr_accessor :ssh_host_attribute
|
59
|
+
|
60
|
+
# Tags to apply to the server.
|
61
|
+
#
|
62
|
+
# @return [Array]
|
63
|
+
attr_accessor :tags
|
64
|
+
|
65
|
+
# The API token to access Scaleway. It can also be configured with
|
66
|
+
# SCW_TOKEN environment variable.
|
67
|
+
#
|
68
|
+
# @return [String]
|
69
|
+
attr_accessor :token
|
70
|
+
|
71
|
+
def initialize
|
72
|
+
@bootscript = UNSET_VALUE
|
73
|
+
@commercial_type = UNSET_VALUE
|
74
|
+
@image = UNSET_VALUE
|
75
|
+
@name = UNSET_VALUE
|
76
|
+
@organization = UNSET_VALUE
|
77
|
+
@server_check_interval = UNSET_VALUE
|
78
|
+
@server_ready_timeout = UNSET_VALUE
|
79
|
+
@security_group = UNSET_VALUE
|
80
|
+
@ssh_host_attribute = UNSET_VALUE
|
81
|
+
@tags = []
|
82
|
+
@token = UNSET_VALUE
|
83
|
+
end
|
84
|
+
|
85
|
+
def finalize!
|
86
|
+
@bootscript = nil if @bootscript == UNSET_VALUE
|
87
|
+
@commercial_type = 'C2S' if @commercial_type == UNSET_VALUE
|
88
|
+
@image = '75c28f52-6c64-40fc-bb31-f53ca9d02de9' if @image == UNSET_VALUE
|
89
|
+
|
90
|
+
if @name == UNSET_VALUE
|
91
|
+
require 'securerandom'
|
92
|
+
@name = "scw-#{SecureRandom.hex(3)}"
|
93
|
+
end
|
94
|
+
|
95
|
+
@organization = ENV['SCW_ORGANIZATION'] if @organization == UNSET_VALUE
|
96
|
+
@server_check_interval = 2 if @server_check_interval == UNSET_VALUE
|
97
|
+
@server_ready_timeout = 120 if @server_ready_timeout == UNSET_VALUE
|
98
|
+
@security_group = nil if @security_group == UNSET_VALUE
|
99
|
+
@ssh_host_attribute = nil if @ssh_host_attribute == UNSET_VALUE
|
100
|
+
@token = ENV['SCW_TOKEN'] if @token == UNSET_VALUE
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def validate(machine)
|
105
|
+
errors = _detected_errors
|
106
|
+
|
107
|
+
errors << I18n.t('vagrant_scaleway.config.organization_required') if @organization.nil?
|
108
|
+
errors << I18n.t('vagrant_scaleway.config.token_required') if @token.nil?
|
109
|
+
|
110
|
+
{ 'Scaleway Provider' => errors }
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|