vagrant-aliyun 0.0.2

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