vagrant-aliyun 0.0.2

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,90 @@
1
+ require "log4r"
2
+ require 'json'
3
+ require "aliyun"
4
+
5
+ module VagrantPlugins
6
+ module AliyunECS
7
+ module Action
8
+ # This runs the configured instance.
9
+ class StartInstance
10
+
11
+ def initialize(app, env)
12
+ @app = app
13
+ @logger = Log4r::Logger.new("vagrant_aliyun::action::start_instance")
14
+ end
15
+
16
+ def call(env)
17
+ start_instance(env[:machine], env)
18
+
19
+ @app.call(env)
20
+ end
21
+
22
+ def start_instance(machine, env)
23
+ return nil if machine.id.nil?
24
+
25
+ config = machine.provider_config
26
+ options = {
27
+ :access_key_id => config.access_key_id,
28
+ :access_key_secret => config.access_key_secret
29
+ }
30
+ Aliyun.config options
31
+ ecs = Aliyun::ECS.new
32
+
33
+ env[:ui].info(I18n.t("vagrant_aliyun.starting"))
34
+ ecs.start_instance :instance_id=>machine.id
35
+
36
+ # Wait for the instance to be ready first
37
+ env[:ui].info(I18n.t("vagrant_aliyun.waiting_for_ready"))
38
+ begin
39
+ instance = ecs.describe_instance_attribute :instance_id=>machine.id
40
+ Timeout.timeout(config.instance_ready_timeout) do
41
+ until instance["Status"] == "Running"
42
+ sleep 2
43
+ instance = ecs.describe_instance_attribute :instance_id=>machine.id
44
+ end
45
+ end
46
+ rescue Timeout::Error
47
+ env[:result] = false # couldn't reach state in time
48
+ # Delete the instance
49
+ terminate(env)
50
+
51
+ # Notify the user
52
+ raise Errors::InstanceReadyTimeout,
53
+ timeout: config.instance_ready_timeout
54
+ end
55
+
56
+ if !env[:interrupted]
57
+ # Wait for SSH to be ready.
58
+ env[:ui].info(I18n.t("vagrant_aliyun.waiting_for_ssh"))
59
+ network_ready_retries = 0
60
+ network_ready_retries_max = 10
61
+ while true
62
+ # If we're interrupted then just back out
63
+ break if env[:interrupted]
64
+ # When an ECS instance comes up, it's networking may not be ready
65
+ # by the time we connect.
66
+ begin
67
+ break if env[:machine].communicate.ready?
68
+ rescue Exception => e
69
+ if network_ready_retries < network_ready_retries_max then
70
+ network_ready_retries += 1
71
+ @logger.warn(I18n.t("vagrant_aliyun.waiting_for_ssh, retrying"))
72
+ else
73
+ raise e
74
+ end
75
+ end
76
+ sleep 2
77
+ end
78
+
79
+ # Ready and booted!
80
+ env[:ui].info(I18n.t("vagrant_aliyun.ready"))
81
+ end
82
+
83
+ # Terminate the instance if we were interrupted
84
+ terminate(env) if env[:interrupted]
85
+ end
86
+
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,52 @@
1
+ require "log4r"
2
+
3
+ module VagrantPlugins
4
+ module AliyunECS
5
+ module Action
6
+ # This stops the running instance.
7
+ class StopInstance
8
+ def initialize(app, env)
9
+ @app = app
10
+ @logger = Log4r::Logger.new("vagrant_aliyun::action::stop_instance")
11
+ end
12
+
13
+ def call(env)
14
+ stop_instance(env[:machine], env)
15
+
16
+ @app.call(env)
17
+ end
18
+
19
+ def stop_instance(machine, env)
20
+ return nil if machine.id.nil?
21
+
22
+ config = machine.provider_config
23
+ options = {
24
+ :access_key_id => config.access_key_id,
25
+ :access_key_secret => config.access_key_secret
26
+ }
27
+ Aliyun.config options
28
+ ecs = Aliyun::ECS.new
29
+
30
+ if machine.state.id == :stopped
31
+ env[:ui].info(I18n.t("vagrant_aliyun.already_status", :status => machine.state.id))
32
+ else
33
+ env[:ui].info(I18n.t("vagrant_aliyun.stopping"))
34
+ ecs.stop_instance :instance_id=>machine.id
35
+ begin
36
+ instance = ecs.describe_instance_attribute :instance_id=>machine.id
37
+ Timeout.timeout(config.instance_ready_timeout) do
38
+ until instance["Status"] == "Stopped"
39
+ sleep 2
40
+ instance = ecs.describe_instance_attribute :instance_id=>machine.id
41
+ end
42
+ end
43
+ rescue Timeout::Error
44
+ env[:result] = false # couldn't reach state in time
45
+ end
46
+ end
47
+
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,51 @@
1
+ require "log4r"
2
+
3
+ module VagrantPlugins
4
+ module AliyunECS
5
+ module Action
6
+ # This stops the running instance.
7
+ class TerminateInstance
8
+ def initialize(app, env)
9
+ @app = app
10
+ @logger = Log4r::Logger.new("vagrant_aliyun::action::terminate_instance")
11
+ end
12
+
13
+ def call(env)
14
+ terminate_instance(env[:machine], env)
15
+
16
+ @app.call(env)
17
+ end
18
+
19
+ def terminate_instance(machine, env)
20
+ return nil if machine.id.nil?
21
+
22
+ config = machine.provider_config
23
+ options = {
24
+ :access_key_id => config.access_key_id,
25
+ :access_key_secret => config.access_key_secret
26
+ }
27
+ Aliyun.config options
28
+ ecs = Aliyun::ECS.new
29
+
30
+ env[:ui].info(I18n.t("vagrant_aliyun.terminating"))
31
+ ecs.stop_instance :instance_id=>machine.id
32
+
33
+ begin
34
+ instance = ecs.describe_instance_attribute :instance_id=>machine.id
35
+ Timeout.timeout(config.instance_ready_timeout) do
36
+ until instance["Status"] == "Stopped"
37
+ sleep 2
38
+ instance = ecs.describe_instance_attribute :instance_id=>machine.id
39
+ end
40
+ end
41
+ rescue Timeout::Error
42
+ env[:result] = false # couldn't reach state in time
43
+ end
44
+
45
+ ecs.delete_instance :instance_id=>machine.id
46
+ machine.id = nil
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,41 @@
1
+ require "log4r"
2
+ require "timeout"
3
+
4
+ module VagrantPlugins
5
+ module AliyunECS
6
+ module Action
7
+ # This action will wait for a machine to reach a specific state or quit by timeout
8
+ class WaitForState
9
+ # env[:result] will be false in case of timeout.
10
+ # @param [Symbol] state Target machine state.
11
+ # @param [Number] timeout Timeout in seconds.
12
+ def initialize(app, env, state, timeout)
13
+ @app = app
14
+ @logger = Log4r::Logger.new("vagrant_aliyun::action::wait_for_state")
15
+ @state = state
16
+ @timeout = timeout
17
+ end
18
+
19
+ def call(env)
20
+ env[:result] = true
21
+ if env[:machine].state.id == @state
22
+ @logger.info(I18n.t("vagrant_aliyun.already_status", :status => @state))
23
+ else
24
+ @logger.info("Waiting for machine to reach state #{@state}")
25
+ begin
26
+ Timeout.timeout(@timeout) do
27
+ until env[:machine].state.id == @state
28
+ sleep 2
29
+ end
30
+ end
31
+ rescue Timeout::Error
32
+ env[:result] = false # couldn't reach state in time
33
+ end
34
+ end
35
+
36
+ @app.call(env)
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,19 @@
1
+ module VagrantPlugins
2
+ module AliyunECS
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 > 0
11
+ env[:ui].warn(I18n.t("vagrant_aliyun.warn_networks"))
12
+ end
13
+
14
+ @app.call(env)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,182 @@
1
+ require "pathname"
2
+ require "aliyun"
3
+ require "vagrant/action/builder"
4
+
5
+ module VagrantPlugins
6
+ module AliyunECS
7
+ module Action
8
+ # Include the built-in modules so we can use them as top-level things.
9
+ include Vagrant::Action::Builtin
10
+
11
+ # This action is called to halt the remote machine.
12
+ def self.action_halt
13
+ Vagrant::Action::Builder.new.tap do |b|
14
+ b.use ConfigValidate
15
+ b.use Call, IsCreated do |env, b2|
16
+ if !env[:result]
17
+ b2.use MessageNotCreated
18
+ next
19
+ end
20
+
21
+ b2.use StopInstance
22
+ end
23
+ end
24
+ end
25
+
26
+ # This action is called to terminate the remote machine.
27
+ def self.action_destroy
28
+ Vagrant::Action::Builder.new.tap do |b|
29
+ b.use Call, DestroyConfirm do |env, b2|
30
+ if env[:result]
31
+ b2.use ConfigValidate
32
+ b2.use Call, IsCreated do |env2, b3|
33
+ if !env2[:result]
34
+ b3.use MessageNotCreated
35
+ next
36
+ end
37
+ b3.use TerminateInstance
38
+ b3.use ProvisionerCleanup if defined?(ProvisionerCleanup)
39
+ end
40
+ else
41
+ b2.use MessageWillNotDestroy
42
+ end
43
+ end
44
+ end
45
+ end
46
+
47
+ # This action is called when `vagrant provision` is called.
48
+ def self.action_provision
49
+ Vagrant::Action::Builder.new.tap do |b|
50
+ b.use ConfigValidate
51
+ b.use Call, IsCreated do |env, b2|
52
+ if !env[:result]
53
+ b2.use MessageNotCreated
54
+ next
55
+ end
56
+
57
+ b2.use Provision
58
+ end
59
+ end
60
+ end
61
+
62
+ # This action is called to read the SSH info of the machine. The
63
+ # resulting state is expected to be put into the `:machine_ssh_info`
64
+ # key.
65
+ def self.action_read_ssh_info
66
+ Vagrant::Action::Builder.new.tap do |b|
67
+ b.use ConfigValidate
68
+ b.use ReadSSHInfo
69
+ end
70
+ end
71
+
72
+ # This action is called to read the state of the machine. The
73
+ # resulting state is expected to be put into the `:machine_state_id`
74
+ # key.
75
+ def self.action_read_state
76
+ Vagrant::Action::Builder.new.tap do |b|
77
+ b.use ConfigValidate
78
+ b.use ReadState
79
+ end
80
+ end
81
+
82
+ # This action is called to SSH into the machine.
83
+ def self.action_ssh
84
+ Vagrant::Action::Builder.new.tap do |b|
85
+ b.use ConfigValidate
86
+ b.use Call, IsCreated do |env, b2|
87
+ if !env[:result]
88
+ b2.use MessageNotCreated
89
+ next
90
+ end
91
+
92
+ b2.use SSHExec
93
+ end
94
+ end
95
+ end
96
+
97
+ def self.action_ssh_run
98
+ Vagrant::Action::Builder.new.tap do |b|
99
+ b.use ConfigValidate
100
+ b.use Call, IsCreated do |env, b2|
101
+ if !env[:result]
102
+ b2.use MessageNotCreated
103
+ next
104
+ end
105
+
106
+ b2.use SSHRun
107
+ end
108
+ end
109
+ end
110
+
111
+ def self.action_prepare_boot
112
+ Vagrant::Action::Builder.new.tap do |b|
113
+ b.use Provision
114
+ b.use SyncedFolders
115
+ b.use WarnNetworks
116
+ end
117
+ end
118
+
119
+ # This action is called to bring the box up from nothing.
120
+ def self.action_up
121
+ Vagrant::Action::Builder.new.tap do |b|
122
+ b.use HandleBox
123
+ b.use ConfigValidate
124
+ b.use BoxCheckOutdated
125
+ b.use Call, IsCreated do |env1, b1|
126
+ if env1[:result]
127
+ b1.use Call, IsStopped do |env2, b2|
128
+ if env2[:result]
129
+ b2.use action_prepare_boot
130
+ b2.use StartInstance # restart this instance
131
+ else
132
+ b2.use MessageAlreadyCreated # TODO write a better message
133
+ end
134
+ end
135
+ else
136
+ b1.use action_prepare_boot
137
+ b1.use RunInstance # launch a new instance
138
+ end
139
+ end
140
+ end
141
+ end
142
+
143
+ def self.action_reload
144
+ Vagrant::Action::Builder.new.tap do |b|
145
+ b.use ConfigValidate
146
+ b.use Call, IsCreated do |env, b2|
147
+ if !env[:result]
148
+ b2.use MessageNotCreated
149
+ next
150
+ end
151
+
152
+ b2.use action_halt
153
+ b2.use Call, WaitForState, :stopped, 120 do |env2, b3|
154
+ if env2[:result]
155
+ b3.use action_up
156
+ else
157
+ # TODO we couldn't reach :stopped, what now?
158
+ end
159
+ end
160
+ end
161
+ end
162
+ end
163
+
164
+ # The autoload farm
165
+ action_root = Pathname.new(File.expand_path("../action", __FILE__))
166
+ autoload :IsCreated, action_root.join("is_created")
167
+ autoload :IsStopped, action_root.join("is_stopped")
168
+ autoload :MessageAlreadyCreated, action_root.join("message_already_created")
169
+ autoload :MessageNotCreated, action_root.join("message_not_created")
170
+ autoload :MessageWillNotDestroy, action_root.join("message_will_not_destroy")
171
+ autoload :ReadSSHInfo, action_root.join("read_ssh_info")
172
+ autoload :ReadState, action_root.join("read_state")
173
+ autoload :RunInstance, action_root.join("run_instance")
174
+ autoload :StartInstance, action_root.join("start_instance")
175
+ autoload :StopInstance, action_root.join("stop_instance")
176
+ autoload :TerminateInstance, action_root.join("terminate_instance")
177
+ autoload :WaitForState, action_root.join("wait_for_state")
178
+ autoload :WarnNetworks, action_root.join("warn_networks")
179
+
180
+ end
181
+ end
182
+ end
@@ -0,0 +1,55 @@
1
+ require "vagrant"
2
+
3
+ module VagrantPlugins
4
+ module AliyunECS
5
+ class Config < Vagrant.plugin("2", :config)
6
+
7
+ attr_accessor :access_key_id
8
+ attr_accessor :access_key_secret
9
+ attr_accessor :region_id
10
+ attr_accessor :image_id
11
+ attr_accessor :instance_type
12
+ attr_accessor :internet_max_bandwidth_out
13
+ attr_accessor :security_group_id
14
+ attr_accessor :password
15
+ attr_accessor :instance_ready_timeout
16
+
17
+ def initialize()
18
+ @access_key_id = UNSET_VALUE
19
+ @access_key_secret = UNSET_VALUE
20
+ @region_id = UNSET_VALUE
21
+ @image_id = UNSET_VALUE
22
+ @instance_type = UNSET_VALUE
23
+ @internet_max_bandwidth_out = UNSET_VALUE
24
+ @security_group_id = UNSET_VALUE
25
+ @password = UNSET_VALUE
26
+ @instance_ready_timeout = UNSET_VALUE
27
+ end
28
+
29
+ def finalize!
30
+ @access_key_id = nil if @access_key_id == UNSET_VALUE
31
+ @access_key_secret = nil if @access_key_secret == UNSET_VALUE
32
+ @region_id = nil if @region_id == UNSET_VALUE
33
+ @image_id = nil if @image_id == UNSET_VALUE
34
+ @instance_type = nil if @instance_type == UNSET_VALUE
35
+ @internet_max_bandwidth_out = nil if @internet_max_bandwidth_out == UNSET_VALUE
36
+ @security_group_id = nil if @security_group_id == UNSET_VALUE
37
+ @password = nil if @password == UNSET_VALUE
38
+ @instance_ready_timeout = 120 if @instance_ready_timeout == UNSET_VALUE
39
+ end
40
+
41
+ def validate(machine)
42
+ errors = _detected_errors
43
+ errors << I18n.t("vagrant_aliyun.config.access_key_id_required") if @access_key_id.nil?
44
+ errors << I18n.t("vagrant_aliyun.config.access_key_secret_required") if @access_key_secret.nil?
45
+ errors << I18n.t("vagrant_aliyun.config.region_id_required") if @region_id.nil?
46
+ errors << I18n.t("vagrant_aliyun.config.image_id_required") if @image_id.nil?
47
+ errors << I18n.t("vagrant_aliyun.config.instance_type_required") if @instance_type.nil?
48
+ errors << I18n.t("vagrant_aliyun.config.internet_max_bandwidth_out_required") if @internet_max_bandwidth_out.nil?
49
+ errors << I18n.t("vagrant_aliyun.config.security_group_id_required") if @security_group_id.nil?
50
+ errors << I18n.t("vagrant_aliyun.config.password_required") if @password.nil?
51
+ { "Aliyun Provider" => errors }
52
+ end
53
+ end
54
+ end
55
+ end