-
Notifications
You must be signed in to change notification settings - Fork 28
/
vdc-manage
executable file
·230 lines (197 loc) · 6.16 KB
/
vdc-manage
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
#!/usr/bin/env ruby
# -*- coding: utf-8 -*-
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
require 'dcmgr/rubygems'
require 'dcmgr'
require 'isono'
require 'thor'
require 'thor/group'
require 'erb'
Dcmgr::Configurations.load Dcmgr::Configurations::Dcmgr
Dcmgr.run_initializers('logger', 'sequel')
if Dcmgr::Configurations.dcmgr.features.openvnet
require 'dcell'
#
# We need to use an port except for some that is used in vdc nodes
#
# http://www.commandlinefu.com/commands/view/7299/find-an-unused-unprivileged-tcp-port
port = `port=32768; while netstat -atn | grep -q :$port; do port=$(expr $port + 1); done; echo $port`
raise "Fail to get an unused port" unless $? == 0
DCell.start(:addr => "tcp://#{Dcmgr::Configurations.dcmgr.vdc_manage_host}:#{port}",
:registry => {
:adapter => Dcmgr::Configurations.dcmgr.dcell_adapter,
:host => Dcmgr::Configurations.dcmgr.dcell_host,
:port => Dcmgr::Configurations.dcmgr.dcell_port
}
)
Dcmgr.run_initializers('vnet_hook')
end
class RootCli < Thor
register(Dcmgr::Cli::Instance, Dcmgr::Cli::Instance.namespace, "instance sub-command", "Operations for instances")
register(Dcmgr::Cli::Network, Dcmgr::Cli::Network.namespace, "network sub-command", "Operations for network information")
register(Dcmgr::Cli::Host, Dcmgr::Cli::Host.namespace, "host sub-command", "Operations for host node")
register(Dcmgr::Cli::Storage, Dcmgr::Cli::Storage.namespace, "storage sub-command", "Operations for storage nodes")
register(Dcmgr::Cli::Vlan, Dcmgr::Cli::Vlan.namespace, "vlan sub-command", "Operations for vlan leases")
register(Dcmgr::Cli::Image, Dcmgr::Cli::Image.namespace, "image sub-command", "Operations for machine images")
register(Dcmgr::Cli::KeyPair, Dcmgr::Cli::KeyPair.namespace, "keypair sub-command", "Operations for key pairs")
register(Dcmgr::Cli::SecurityGroup, Dcmgr::Cli::SecurityGroup.namespace, "securitygroup sub-command", "Operations for security groups")
register(Dcmgr::Cli::ResourceGroup, Dcmgr::Cli::ResourceGroup.namespace, "resourcegroup sub-command", "Operations for resource groups")
register(Dcmgr::Cli::BackupStorage, Dcmgr::Cli::BackupStorage.namespace, "backupstorage sub-command", "Operations for backup storage")
register(Dcmgr::Cli::BackupObject, Dcmgr::Cli::BackupObject.namespace, "backupobject sub-command", "Operations for backup objects")
register(Dcmgr::Cli::MacRange, Dcmgr::Cli::MacRange.namespace, "macrange sub-command", "Operations for mac addres range")
#def self.exit_on_failure?
# true
#end
end
module TxMode
module Bulk
def in_loop
Dcmgr::Models::BaseNew.db.transaction do
super
end
end
end
module Each
def loop_eval(str)
Dcmgr::Models::BaseNew.db.transaction do
super
end
end
end
end
module ExitAtError
def loop_eval(str)
begin
# Ensure Thor to raise exception.
ENV['THOR_DEBUG']='1'
super
rescue ::Exception => e
STDERR.puts "ERROR: #{e.message}"
if $options[:errexit]
$exitcode=1
throw(:ripl_exit)
end
end
end
end
module VdcManageShell
def loop_eval(str)
args = Shellwords.shellsplit(str)
if !args.empty?
RootCli.start(args.dup)
end
end
def print_result(result)
# do nothing from ripl.
end
end
module MultiLine
def before_loop
super
@buffer = []
end
def prompt
@buffer.empty? ? super : (config[:middle_prompt] || ' > ')
end
def loop_once
catch(:multiline) do
super
@buffer = []
end
end
def eval_input(input)
@buffer << input.sub(/\\$/,'')
if middle_line?(input)
throw(:multiline)
else
super(@buffer.join(' '))
end
end
private
def middle_line?(str)
str =~ /\\$/
end
end
require 'optparse'
TX_MODES=['each', 'none', 'bulk'].freeze
$options = {:tx_mode=>TX_MODES.first, :errexit=>false}
argv = ARGV.dup
OptionParser.new { |o|
o.banner += " [TASK [options]]"
o.on('--tx TYPE', '--tx-mode=TYPE', "Set transaction mode (default: #{TX_MODES.first}): #{TX_MODES.join(', ')}") { |v|
if TX_MODES.member?(v)
$options[:tx_mode]=v.to_sym
else
abort("Unknown tx-mode value: #{v}")
end
}
o.on('-e', "Exit interactive loop at error (default: #{$options[:errexit]})") {
$options[:errexit]=true
}
o.on_tail('-h', '--help', 'Show this message') do
puts o.help
RootCli.start(["-h"])
exit
end
}.order!(argv)
if !argv.empty?
# Ensure to raise exception from Thor v0.15.x
ENV['THOR_DEBUG']='1'
# CLI mode
begin
Dcmgr::Models::BaseNew.db.transaction do
RootCli.start(argv)
end
rescue => e
orig_e = e
e = Dcmgr::Cli::Error.new(e,101) unless e.is_a?(Dcmgr::Cli::Error)
STDERR.puts "ERROR: #{e.message} (#{orig_e.backtrace.first})"
if e.respond_to?(:exit_code)
exit(e.exit_code)
else
exit(1)
end
end
else
# Interactive shell mode
require 'ripl'
require 'bond'
require 'shellwords'
$exitcode = 0
# Auto completion
Bond.start
# Override Bond auto completions to include vdc-manage tasks instead of Ruby methods/keywords
class Bond::DefaultMission
def self.completions(input=nil)
Bond::Mission.current_eval("[]") | RootCli.tasks.keys
end
end
# Get the classes of subcommands so we can add their arguments to Bond auto completion
subcommand_classes = Dcmgr::Cli.constants.map { |c|
Dcmgr::Cli.const_get(c)
}.delete_if {|c|
(not c.respond_to?(:namespace)) || c == Dcmgr::Cli::Base
}
subcommand_classes.each { |sc|
Bond.complete(:method=>sc.namespace) { sc.tasks.keys }
}
Ripl::Shell.include VdcManageShell
if $options[:tx_mode].to_sym == :each
Ripl::Shell.include TxMode::Each
else
Ripl::Shell.include TxMode::Bulk
end
Ripl::Shell.include ExitAtError
Ripl::Shell.include MultiLine
Ripl::History.module_eval {
# disable write history file. I could't find not to include Ripl::History.
def write_history; end
}
Ripl::Shell.create(:prompt => 'vdc-manage>> ',
:result_prompt => '',
:name => 'vdc-manage',
:irbrc => nil,
:readline=>true,
).loop
::Kernel.exit($exitcode)
end