vagrant-sakura 0.0.1
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 +19 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +7 -0
- data/LICENSE.txt +22 -0
- data/README.md +102 -0
- data/Rakefile +3 -0
- data/dummy.box +0 -0
- data/example_box/Vagrantfile +8 -0
- data/example_box/metadata.json +3 -0
- data/lib/vagrant-sakura.rb +16 -0
- data/lib/vagrant-sakura/action.rb +158 -0
- data/lib/vagrant-sakura/action/connect_sakura.rb +23 -0
- data/lib/vagrant-sakura/action/delete_server.rb +39 -0
- data/lib/vagrant-sakura/action/halt.rb +31 -0
- data/lib/vagrant-sakura/action/is_created.rb +16 -0
- data/lib/vagrant-sakura/action/message_already_created.rb +16 -0
- data/lib/vagrant-sakura/action/message_down.rb +16 -0
- data/lib/vagrant-sakura/action/message_not_created.rb +16 -0
- data/lib/vagrant-sakura/action/message_will_not_destroy.rb +17 -0
- data/lib/vagrant-sakura/action/power_on.rb +23 -0
- data/lib/vagrant-sakura/action/read_ssh_info.rb +37 -0
- data/lib/vagrant-sakura/action/read_state.rb +35 -0
- data/lib/vagrant-sakura/action/reset.rb +24 -0
- data/lib/vagrant-sakura/action/run_instance.rb +143 -0
- data/lib/vagrant-sakura/command.rb +12 -0
- data/lib/vagrant-sakura/config.rb +98 -0
- data/lib/vagrant-sakura/driver/api.rb +77 -0
- data/lib/vagrant-sakura/driver/cert.pem +76 -0
- data/lib/vagrant-sakura/errors.rb +19 -0
- data/lib/vagrant-sakura/plugin.rb +53 -0
- data/lib/vagrant-sakura/provider.rb +31 -0
- data/lib/vagrant-sakura/version.rb +5 -0
- data/locales/en.yml +39 -0
- metadata +105 -0
@@ -0,0 +1,16 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module Sakura
|
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_sakura.already_created"))
|
11
|
+
@app.call(env)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module Sakura
|
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_sakura.not_created"))
|
11
|
+
@app.call(env)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module Sakura
|
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_sakura.will_not_destroy",
|
11
|
+
name: env[:machine].name))
|
12
|
+
@app.call(env)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require "log4r"
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module Sakura
|
5
|
+
module Action
|
6
|
+
class PowerOn
|
7
|
+
def initialize(app, env)
|
8
|
+
@app = app
|
9
|
+
@logger = Log4r::Logger.new("vagrant_sakura::action::power_on")
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(env)
|
13
|
+
api = env[:sakura_api]
|
14
|
+
serverid = env[:machine].id
|
15
|
+
|
16
|
+
env[:ui].info(I18n.t("vagrant_sakura.power_on"))
|
17
|
+
api.put("/server/#{serverid}/power")
|
18
|
+
@app.call(env)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require "log4r"
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module Sakura
|
5
|
+
module Action
|
6
|
+
class ReadSSHInfo
|
7
|
+
def initialize(app, env)
|
8
|
+
@app = app
|
9
|
+
@logger = Log4r::Logger.new("vagrant_sakura::action::read_ssh_info")
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(env)
|
13
|
+
api = env[:sakura_api]
|
14
|
+
serverid = env[:machine].id
|
15
|
+
|
16
|
+
if serverid.nil?
|
17
|
+
env[:machine_ssh_info] = nil
|
18
|
+
else
|
19
|
+
begin
|
20
|
+
response = api.get("/server/#{serverid}")
|
21
|
+
env[:machine_ssh_info] = {
|
22
|
+
:host => response["Server"]["Interfaces"][0]["IPAddress"],
|
23
|
+
:port => 22
|
24
|
+
}
|
25
|
+
rescue Driver::NotFoundError
|
26
|
+
@logger.info("Machine couldn't be found, assuming it has been destroyed.")
|
27
|
+
env[:machine].id = nil
|
28
|
+
env[:machine_ssh_info] = nil
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
@app.call(env)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'log4r'
|
2
|
+
require 'vagrant-sakura/driver/api'
|
3
|
+
|
4
|
+
module VagrantPlugins
|
5
|
+
module Sakura
|
6
|
+
module Action
|
7
|
+
class ReadState
|
8
|
+
def initialize(app, env)
|
9
|
+
@app = app
|
10
|
+
@logger = Log4r::Logger.new("vagrant_sakura::action::read_state")
|
11
|
+
end
|
12
|
+
|
13
|
+
def call(env)
|
14
|
+
env[:machine_state_id] = read_state(env[:sakura_api], env[:machine])
|
15
|
+
@app.call(env)
|
16
|
+
end
|
17
|
+
|
18
|
+
# returns one of [ :cleaning, :down, :not_created, :up, ]
|
19
|
+
def read_state(api, machine)
|
20
|
+
|
21
|
+
return :not_created if machine.id.nil?
|
22
|
+
|
23
|
+
serverid = machine.id
|
24
|
+
begin
|
25
|
+
response = api.get("/server/#{serverid}")
|
26
|
+
rescue Driver::NotFoundError
|
27
|
+
machine.id = nil
|
28
|
+
return :not_created
|
29
|
+
end
|
30
|
+
return response["Server"]["Instance"]["Status"].to_sym
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require "log4r"
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module Sakura
|
5
|
+
module Action
|
6
|
+
class Reset
|
7
|
+
def initialize(app, env)
|
8
|
+
@app = app
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(env)
|
12
|
+
api = env[:sakura_api]
|
13
|
+
serverid = env[:machine].id
|
14
|
+
|
15
|
+
# when "PUT /server/#{serverid}/reset" returns, power is up.
|
16
|
+
api.put("/server/#{serverid}/reset")
|
17
|
+
env[:ui].info I18n.t("vagrant_sakura.reset")
|
18
|
+
|
19
|
+
@app.call(env)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
require 'vagrant/util/retryable'
|
2
|
+
|
3
|
+
require 'vagrant-sakura/driver/api'
|
4
|
+
#require 'vagrant-sakura/util/timer'
|
5
|
+
require 'log4r'
|
6
|
+
|
7
|
+
module VagrantPlugins
|
8
|
+
module Sakura
|
9
|
+
module Action
|
10
|
+
class RunInstance
|
11
|
+
include Vagrant::Util::Retryable
|
12
|
+
|
13
|
+
def initialize(app, env)
|
14
|
+
@app = app
|
15
|
+
@logger = Log4r::Logger.new("vagrant_sakura::action::run_instance")
|
16
|
+
end
|
17
|
+
|
18
|
+
def call(env)
|
19
|
+
server_name = env[:machine].name
|
20
|
+
server_name ||= env[:machine].provider_config.server_name
|
21
|
+
server_plan = env[:machine].provider_config.server_plan
|
22
|
+
disk_plan = env[:machine].provider_config.disk_plan
|
23
|
+
disk_source_archive = env[:machine].provider_config.disk_source_archive
|
24
|
+
sshkey_id = env[:machine].provider_config.sshkey_id
|
25
|
+
|
26
|
+
env[:ui].info(I18n.t("vagrant_sakura.creating_instance"))
|
27
|
+
env[:ui].info(" -- Server Name: #{server_name}")
|
28
|
+
env[:ui].info(" -- Server Plan: #{server_plan}")
|
29
|
+
env[:ui].info(" -- Disk Plan: #{disk_plan}")
|
30
|
+
env[:ui].info(" -- Disk Source Archive: #{disk_source_archive}")
|
31
|
+
|
32
|
+
api = env[:sakura_api]
|
33
|
+
data = {
|
34
|
+
"Disk" => {
|
35
|
+
"Name" => server_name,
|
36
|
+
"Zone" => { "ID" => 31001 }, # Ishikari only
|
37
|
+
"Plan" => { "ID" => disk_plan },
|
38
|
+
"Connection" => "virtio",
|
39
|
+
"SourceArchive" => {
|
40
|
+
"ID" => disk_source_archive
|
41
|
+
}
|
42
|
+
}
|
43
|
+
}
|
44
|
+
response = api.post("/disk", data)
|
45
|
+
unless response["Disk"]["ID"]
|
46
|
+
raise 'no Disk ID returned'
|
47
|
+
end
|
48
|
+
diskid = response["Disk"]["ID"]
|
49
|
+
# Disk Created
|
50
|
+
|
51
|
+
while true
|
52
|
+
response = api.get("/disk/#{diskid}")
|
53
|
+
case response["Disk"]["Availability"]
|
54
|
+
when "available"
|
55
|
+
break
|
56
|
+
when "migrating"
|
57
|
+
migrated = response["Disk"]["MigratedMB"]
|
58
|
+
size = response["Disk"]["SizeMB"]
|
59
|
+
env[:ui].info("Disk #{diskid} is migrating (#{migrated}/#{size})")
|
60
|
+
else
|
61
|
+
status = presponse["Disk"]["Availability"]
|
62
|
+
env[:ui].info("Disk #{diskid} is #{status}")
|
63
|
+
end
|
64
|
+
sleep 3
|
65
|
+
end
|
66
|
+
# Wait for Disk is available
|
67
|
+
|
68
|
+
data = {
|
69
|
+
"Server" => {
|
70
|
+
"Name" => server_name,
|
71
|
+
"Zone" => { "ID" => 31001 }, # Ishikari
|
72
|
+
"ServerPlan" => { "ID" => server_plan },
|
73
|
+
"ConnectedSwitches" => [
|
74
|
+
{ "Scope" => "shared", "BandWidthMbps" => 100 }
|
75
|
+
]
|
76
|
+
}
|
77
|
+
}
|
78
|
+
response = api.post("/server", data)
|
79
|
+
unless response["Server"]["ID"]
|
80
|
+
raise 'no Server ID returned'
|
81
|
+
end
|
82
|
+
env[:machine].id = serverid = response["Server"]["ID"]
|
83
|
+
# Server Created
|
84
|
+
|
85
|
+
response = api.put("/disk/#{diskid}/to/server/#{serverid}")
|
86
|
+
# Disk mounted to Server
|
87
|
+
|
88
|
+
data = {
|
89
|
+
"UserSubnet" => {}
|
90
|
+
}
|
91
|
+
if sshkey_id
|
92
|
+
data["SSHKey"] = { "ID" => sshkey_id }
|
93
|
+
else
|
94
|
+
path = env[:machine].ssh_info[:private_key_path] + '.pub'
|
95
|
+
data["SSHKey"] = { "PublicKey" => File.read(path) }
|
96
|
+
end
|
97
|
+
response = api.put("/disk/#{diskid}/config", data)
|
98
|
+
# Config
|
99
|
+
|
100
|
+
response = api.put("/server/#{serverid}/power")
|
101
|
+
# Power On
|
102
|
+
|
103
|
+
if !env[:interrupted]
|
104
|
+
# Wait for SSH to be ready.
|
105
|
+
env[:ui].info(I18n.t("vagrant_sakura.waiting_for_ssh"))
|
106
|
+
while true
|
107
|
+
break if env[:interrupted]
|
108
|
+
break if env[:machine].communicate.ready?
|
109
|
+
sleep 2
|
110
|
+
end
|
111
|
+
|
112
|
+
#@logger.info("Time for SSH ready: #{env[:metrics]["instance_ssh_time"]}")
|
113
|
+
|
114
|
+
# Ready and booted!
|
115
|
+
env[:ui].info(I18n.t("vagrant_sakura.ready"))
|
116
|
+
end
|
117
|
+
|
118
|
+
# Terminate the instance if we were interrupted
|
119
|
+
terminate(env) if env[:interrupted]
|
120
|
+
|
121
|
+
@app.call(env)
|
122
|
+
end
|
123
|
+
|
124
|
+
def recover(env)
|
125
|
+
return if env["vagrant.error"].is_a?(Vagrant::Errors::VagrantError)
|
126
|
+
|
127
|
+
if env[:machine].provider.state.id != :not_created
|
128
|
+
# Undo the import
|
129
|
+
terminate(env)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def terminate(env)
|
134
|
+
destroy_env = env.dup
|
135
|
+
destroy_env.delete(:interrupted)
|
136
|
+
destroy_env[:config_validate] = false
|
137
|
+
destroy_env[:force_confirm_destroy] = true
|
138
|
+
env[:action_runner].run(Action.action_destroy, destroy_env)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require "vagrant"
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module Sakura
|
5
|
+
class Config < Vagrant.plugin("2", :config)
|
6
|
+
# The ACCESS TOKEN to access Sakura Cloud API.
|
7
|
+
#
|
8
|
+
# @return [String]
|
9
|
+
attr_accessor :access_token
|
10
|
+
|
11
|
+
# The ACCESS TOKEN SECRET to access Sakura Cloud API.
|
12
|
+
#
|
13
|
+
# @return [String]
|
14
|
+
attr_accessor :access_token_secret
|
15
|
+
|
16
|
+
# The plan ID of the disk to be connected to the server.
|
17
|
+
#
|
18
|
+
# @return [Fixnum]
|
19
|
+
attr_accessor :disk_plan
|
20
|
+
|
21
|
+
# The source archive of the disk image to be copied to the instance.
|
22
|
+
#
|
23
|
+
# @return [String]
|
24
|
+
attr_accessor :disk_source_archive
|
25
|
+
|
26
|
+
# The name of the server.
|
27
|
+
#
|
28
|
+
# @return [String]
|
29
|
+
attr_accessor :server_name
|
30
|
+
|
31
|
+
# The Plan ID of the server.
|
32
|
+
#
|
33
|
+
# @return [Fixnum]
|
34
|
+
attr_accessor :server_plan
|
35
|
+
|
36
|
+
# The resource ID of the SSH public key to login the server.
|
37
|
+
#
|
38
|
+
# @return [String]
|
39
|
+
attr_accessor :sshkey_id
|
40
|
+
|
41
|
+
# No Zone ID config - there is only one zone available now :)
|
42
|
+
#attr_accessor :zone_id
|
43
|
+
|
44
|
+
def initialize
|
45
|
+
@access_token = UNSET_VALUE
|
46
|
+
@access_token_secret = UNSET_VALUE
|
47
|
+
@disk_plan = UNSET_VALUE
|
48
|
+
@disk_source_archive = UNSET_VALUE
|
49
|
+
@server_name = UNSET_VALUE
|
50
|
+
@server_plan = UNSET_VALUE
|
51
|
+
@sshkey_id = UNSET_VALUE
|
52
|
+
end
|
53
|
+
|
54
|
+
def finalize!
|
55
|
+
if @access_token == UNSET_VALUE
|
56
|
+
@access_token = ENV['SAKURA_ACCESS_TOKEN']
|
57
|
+
end
|
58
|
+
|
59
|
+
if @access_token_secret == UNSET_VALUE
|
60
|
+
@access_token_secret = ENV['SAKURA_ACCESS_TOKEN_SECRET']
|
61
|
+
end
|
62
|
+
|
63
|
+
if @disk_plan == UNSET_VALUE
|
64
|
+
@disk_plan = 4 # SSD
|
65
|
+
end
|
66
|
+
|
67
|
+
if @disk_source_archive == UNSET_VALUE
|
68
|
+
@disk_source_archive = 112500182464 # Ubuntu 12.04
|
69
|
+
end
|
70
|
+
|
71
|
+
if @server_name == UNSET_VALUE
|
72
|
+
@server_name = nil
|
73
|
+
end
|
74
|
+
|
75
|
+
if @server_plan == UNSET_VALUE
|
76
|
+
@server_plan = 1001 # 1Core-1GB - cheapest
|
77
|
+
end
|
78
|
+
|
79
|
+
if @sshkey_id == UNSET_VALUE
|
80
|
+
@sshkey_id = nil
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def validate(machine)
|
85
|
+
errors = []
|
86
|
+
|
87
|
+
if config.access_token.nil?
|
88
|
+
errors << I18n.t("vagrant_sakura.config.access_token_required")
|
89
|
+
end
|
90
|
+
if config.access_token_secret.nil?
|
91
|
+
errors << I18n.t("vagrant_sakura.config.access_token_secret_required")
|
92
|
+
end
|
93
|
+
|
94
|
+
{ "Sakura Provider" => errors }
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|