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.
@@ -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