-
Notifications
You must be signed in to change notification settings - Fork 10
/
onecast
executable file
·170 lines (137 loc) · 3.62 KB
/
onecast
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
#!/usr/bin/env ruby
require 'getoptlong'
require 'tempfile'
require 'open-uri'
HELP_TEXT=<<EOT
Usage:
onecast [<options>] <base_template>
Options:
-d, --data <name>=<value> Sets the value that goes into a template
-c, --create [vm|vnet|image] Calls create command of onvm, onevnet
or oneimage. If the object type is no
specified then onevm is called
-h, --help Prints this help text
Template:
Template variables have the form ${NAME}. The name of the variable is
case sensitive and is translated to the value specified in the command
line or the environment. It can also have a default value if the variable
is not specified in the command line or not found in the environment this
way ${NAME|default value}.
EOT
class OneCast
attr_reader :vars, :error
REG_VAR=/\$\{([^}|]+)(\|([^}]+))?\}/
def initialize(template, data)
@vars=ENV.to_hash
@error=nil
@template=template.clone
data.each do |text|
parsed=parse_data_variable(text)
raise "Bad formatted variable: '#{text}'" if !parsed
@vars[parsed[0]]=parsed[1].gsub("\\n", "\n")
end
end
def rewrite_template
@error=nil
@template.gsub(REG_VAR) do |var|
match=REG_VAR.match(var)
var_name=match[1]
default_value=match[3]
d=@vars[var_name]
d||=default_value
if !d
@error||=''
@error+="Variable '#{var_name}' not set. "
end
d
end
end
private
def parse_data_variable(text)
m=(/^([^=]+)=["']?(.*)["']?/m).match(text)
if m
m[1,2]
else
nil
end
end
end
def print_help
puts HELP_TEXT
end
opts = GetoptLong.new(
[ '--help', '-h', GetoptLong::NO_ARGUMENT ],
[ '--data', '-d', GetoptLong::REQUIRED_ARGUMENT ],
[ '--create', '-c', GetoptLong::OPTIONAL_ARGUMENT],
[ '--temp', '-t', GetoptLong::OPTIONAL_ARGUMENT]
)
text_variables=Array.new
create=false
temp=false
begin
opts.each do |opt, arg|
case opt
when '--data'
text_variables<<arg
when '--create'
case arg
when nil, ''
create='vm'
when 'vm', 'vnet', 'datastore', 'template'
create=arg
else
raise "Invalid object to create '#{arg}'."
end
when '--temp'
temp=true
when '--help'
print_help
exit(0)
else
print_help
exit(0)
end
end
rescue StandardError => e
STDERR.puts e
print_help
exit(-1)
end
template_name=ARGV[0]
if !template_name
STDERR.puts "ERROR: Template file not provided.\n\n"
print_help
exit(-1)
end
begin
file=open(template_name)
template_text=file.read
file.close
rescue
puts "Could not read template file '#{template_name}'."
exit(-1)
end
begin
onecast=OneCast.new(template_text, text_variables)
rescue Exception => e
puts e
exit(-1)
end
final_template=onecast.rewrite_template
errors=onecast.error
STDERR.puts errors if errors
if create
temp=Tempfile.new "#{create}.one"
temp.write final_template
temp.close
system "one#{create} create -v #{temp.path}"
temp.unlink
exit(0)
end
if temp
tempf = `mktemp --tmpdir=/tmp --suffix=.one onecast.XXX`.strip
File.open(tempf,'w'){|file| file.write final_template}
puts tempf
else
puts final_template
end