vagrant-scaleway 0.1.0

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