tdl 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/tdl-apply.rb +133 -0
- data/bin/tdl-config.rb +60 -0
- data/bin/tdl-convert.rb +1 -1
- data/bin/tdl-create.rb +28 -5
- data/bin/tdl-launch.rb +30 -17
- data/bin/tdl-verify.rb +19 -6
- data/data/etdl.rng +311 -0
- data/data/sample.etdl +45 -0
- data/data/sample.tdl +31 -0
- data/data/tdl.rng +272 -0
- data/lib/cloud_inst.rb +3 -8
- data/lib/etdl.rb +40 -52
- data/lib/etdl_processor.rb +18 -45
- data/lib/package_system.rb +20 -0
- data/lib/tdl_gem_path.rb +14 -0
- data/tdl-config.yml +47 -0
- metadata +13 -2
data/data/sample.etdl
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
<template>
|
2
|
+
<name>sample</name>
|
3
|
+
<description></description>
|
4
|
+
<cloud>
|
5
|
+
<type></type>
|
6
|
+
<provider></provider>
|
7
|
+
<username></username>
|
8
|
+
<password></password>
|
9
|
+
<image></image>
|
10
|
+
<keyname></keyname>
|
11
|
+
<ssh_cmd></ssh_cmd>
|
12
|
+
<scp_cmd></scp_cmd>
|
13
|
+
</cloud>
|
14
|
+
|
15
|
+
<os>
|
16
|
+
<name></name>
|
17
|
+
<version></version>
|
18
|
+
<arch>x86_64</arch>
|
19
|
+
<install type='url'>
|
20
|
+
<url>http://</url>
|
21
|
+
</install>
|
22
|
+
<rootpw></rootpw>
|
23
|
+
</os>
|
24
|
+
|
25
|
+
<packages>
|
26
|
+
<package name="" />
|
27
|
+
</packages>
|
28
|
+
|
29
|
+
<files>
|
30
|
+
<file name="">
|
31
|
+
</file>
|
32
|
+
|
33
|
+
<file name="">
|
34
|
+
</file>
|
35
|
+
</files>
|
36
|
+
|
37
|
+
<commands>
|
38
|
+
<command name=""></command>
|
39
|
+
</commands>
|
40
|
+
|
41
|
+
<verify>
|
42
|
+
<command name=""></command>
|
43
|
+
</verify>
|
44
|
+
|
45
|
+
</template>
|
data/data/sample.tdl
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
<template>
|
2
|
+
<name>sample</name>
|
3
|
+
<description></description>
|
4
|
+
|
5
|
+
<os>
|
6
|
+
<name></name>
|
7
|
+
<version></version>
|
8
|
+
<arch>x86_64</arch>
|
9
|
+
<install type='url'>
|
10
|
+
<url>http://</url>
|
11
|
+
</install>
|
12
|
+
<rootpw></rootpw>
|
13
|
+
</os>
|
14
|
+
|
15
|
+
<packages>
|
16
|
+
<package name="" />
|
17
|
+
</packages>
|
18
|
+
|
19
|
+
<files>
|
20
|
+
<file name="">
|
21
|
+
</file>
|
22
|
+
|
23
|
+
<file name="">
|
24
|
+
</file>
|
25
|
+
</files>
|
26
|
+
|
27
|
+
<commands>
|
28
|
+
<command name=""></command>
|
29
|
+
</commands>
|
30
|
+
|
31
|
+
</template>
|
data/data/tdl.rng
ADDED
@@ -0,0 +1,272 @@
|
|
1
|
+
<?xml version="1.0"?>
|
2
|
+
<!-- A Relax NG schema for the TDL (template description language) format -->
|
3
|
+
<grammar xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
|
4
|
+
<start>
|
5
|
+
<ref name='template'/>
|
6
|
+
</start>
|
7
|
+
|
8
|
+
<define name='template'>
|
9
|
+
<element name='template'>
|
10
|
+
<optional>
|
11
|
+
<attribute name='version'>
|
12
|
+
<choice>
|
13
|
+
<value>1.0</value>
|
14
|
+
</choice>
|
15
|
+
</attribute>
|
16
|
+
</optional>
|
17
|
+
<interleave>
|
18
|
+
<element name='name'>
|
19
|
+
<text/>
|
20
|
+
</element>
|
21
|
+
<element name='os'>
|
22
|
+
<interleave>
|
23
|
+
<element name='name'>
|
24
|
+
<text/>
|
25
|
+
</element>
|
26
|
+
<element name='version'>
|
27
|
+
<text/>
|
28
|
+
</element>
|
29
|
+
<element name='arch'>
|
30
|
+
<choice>
|
31
|
+
<value>i386</value>
|
32
|
+
<value>x86_64</value>
|
33
|
+
</choice>
|
34
|
+
</element>
|
35
|
+
<element name='install'>
|
36
|
+
<choice>
|
37
|
+
<ref name='url'/>
|
38
|
+
<ref name='iso'/>
|
39
|
+
</choice>
|
40
|
+
</element>
|
41
|
+
<optional>
|
42
|
+
<element name='rootpw'>
|
43
|
+
<text/>
|
44
|
+
</element>
|
45
|
+
</optional>
|
46
|
+
<optional>
|
47
|
+
<element name='key'>
|
48
|
+
<text/>
|
49
|
+
</element>
|
50
|
+
</optional>
|
51
|
+
</interleave>
|
52
|
+
</element>
|
53
|
+
<optional>
|
54
|
+
<element name='description'>
|
55
|
+
<text/>
|
56
|
+
</element>
|
57
|
+
</optional>
|
58
|
+
<optional>
|
59
|
+
<element name='packages'>
|
60
|
+
<zeroOrMore>
|
61
|
+
<element name='package'>
|
62
|
+
<attribute name='name'>
|
63
|
+
<text/>
|
64
|
+
</attribute>
|
65
|
+
<interleave>
|
66
|
+
<optional>
|
67
|
+
<element name='repository'>
|
68
|
+
<text/>
|
69
|
+
</element>
|
70
|
+
</optional>
|
71
|
+
<optional>
|
72
|
+
<element name='file'>
|
73
|
+
<text/>
|
74
|
+
</element>
|
75
|
+
</optional>
|
76
|
+
<optional>
|
77
|
+
<element name='arguments'>
|
78
|
+
<text/>
|
79
|
+
</element>
|
80
|
+
</optional>
|
81
|
+
</interleave>
|
82
|
+
</element>
|
83
|
+
</zeroOrMore>
|
84
|
+
</element>
|
85
|
+
</optional>
|
86
|
+
<optional>
|
87
|
+
<element name='files'>
|
88
|
+
<zeroOrMore>
|
89
|
+
<element name='file'>
|
90
|
+
<attribute name='name'>
|
91
|
+
<text/>
|
92
|
+
</attribute>
|
93
|
+
<choice>
|
94
|
+
<ref name='rawtype'/>
|
95
|
+
<ref name='base64_or_emptytype'/>
|
96
|
+
</choice>
|
97
|
+
</element>
|
98
|
+
</zeroOrMore>
|
99
|
+
</element>
|
100
|
+
</optional>
|
101
|
+
<optional>
|
102
|
+
<element name='commands'>
|
103
|
+
<zeroOrMore>
|
104
|
+
<element name='command'>
|
105
|
+
<attribute name='name'>
|
106
|
+
<text/>
|
107
|
+
</attribute>
|
108
|
+
<optional>
|
109
|
+
<attribute name='position'>
|
110
|
+
<ref name='number'/>
|
111
|
+
</attribute>
|
112
|
+
</optional>
|
113
|
+
<choice>
|
114
|
+
<ref name='rawtype'/>
|
115
|
+
<ref name='base64type'/>
|
116
|
+
</choice>
|
117
|
+
</element>
|
118
|
+
</zeroOrMore>
|
119
|
+
</element>
|
120
|
+
</optional>
|
121
|
+
<optional>
|
122
|
+
<element name='repositories'>
|
123
|
+
<zeroOrMore>
|
124
|
+
<element name='repository'>
|
125
|
+
<attribute name='name'>
|
126
|
+
<text/>
|
127
|
+
</attribute>
|
128
|
+
<interleave>
|
129
|
+
<element name='url'>
|
130
|
+
<text/>
|
131
|
+
</element>
|
132
|
+
<optional>
|
133
|
+
<element name='signed'>
|
134
|
+
<ref name='bool'/>
|
135
|
+
</element>
|
136
|
+
</optional>
|
137
|
+
<optional>
|
138
|
+
<element name='persisted'>
|
139
|
+
<ref name='bool'/>
|
140
|
+
</element>
|
141
|
+
</optional>
|
142
|
+
<optional>
|
143
|
+
<interleave>
|
144
|
+
<element name='clientcert'>
|
145
|
+
<text/>
|
146
|
+
</element>
|
147
|
+
<optional>
|
148
|
+
<element name='clientkey'>
|
149
|
+
<text/>
|
150
|
+
</element>
|
151
|
+
</optional>
|
152
|
+
</interleave>
|
153
|
+
</optional>
|
154
|
+
<optional>
|
155
|
+
<interleave>
|
156
|
+
<element name='sslverify'>
|
157
|
+
<ref name='bool'/>
|
158
|
+
</element>
|
159
|
+
<element name='cacert'>
|
160
|
+
<text/>
|
161
|
+
</element>
|
162
|
+
</interleave>
|
163
|
+
</optional>
|
164
|
+
</interleave>
|
165
|
+
</element>
|
166
|
+
</zeroOrMore>
|
167
|
+
</element>
|
168
|
+
</optional>
|
169
|
+
<optional>
|
170
|
+
<element name='disk'>
|
171
|
+
<element name='size'>
|
172
|
+
<ref name='number'/>
|
173
|
+
</element>
|
174
|
+
</element>
|
175
|
+
</optional>
|
176
|
+
</interleave>
|
177
|
+
</element>
|
178
|
+
</define>
|
179
|
+
|
180
|
+
<define name='url'>
|
181
|
+
<attribute name='type'>
|
182
|
+
<value>url</value>
|
183
|
+
</attribute>
|
184
|
+
<element name='url'>
|
185
|
+
<text/>
|
186
|
+
</element>
|
187
|
+
</define>
|
188
|
+
|
189
|
+
<define name='iso'>
|
190
|
+
<attribute name='type'>
|
191
|
+
<value>iso</value>
|
192
|
+
</attribute>
|
193
|
+
<interleave>
|
194
|
+
<element name='iso'>
|
195
|
+
<text/>
|
196
|
+
</element>
|
197
|
+
<optional>
|
198
|
+
<choice>
|
199
|
+
<element name='md5sum'>
|
200
|
+
<text/>
|
201
|
+
</element>
|
202
|
+
<element name='sha1sum'>
|
203
|
+
<text/>
|
204
|
+
</element>
|
205
|
+
<element name='sha256sum'>
|
206
|
+
<text/>
|
207
|
+
</element>
|
208
|
+
</choice>
|
209
|
+
</optional>
|
210
|
+
</interleave>
|
211
|
+
</define>
|
212
|
+
|
213
|
+
<define name='bool'>
|
214
|
+
<choice>
|
215
|
+
<data type="string">
|
216
|
+
<param name="pattern">[Tt][Rr][Uu][Ee]</param>
|
217
|
+
</data>
|
218
|
+
<data type="string">
|
219
|
+
<param name="pattern">[Ff][Aa][Ll][Ss][Ee]</param>
|
220
|
+
</data>
|
221
|
+
<data type="string">
|
222
|
+
<param name="pattern">[Yy][Ee][Ss]</param>
|
223
|
+
</data>
|
224
|
+
<data type="string">
|
225
|
+
<param name="pattern">[Nn][Oo]</param>
|
226
|
+
</data>
|
227
|
+
</choice>
|
228
|
+
</define>
|
229
|
+
|
230
|
+
<define name='rawtype'>
|
231
|
+
<optional>
|
232
|
+
<attribute name='type'>
|
233
|
+
<value>raw</value>
|
234
|
+
</attribute>
|
235
|
+
</optional>
|
236
|
+
<text/>
|
237
|
+
</define>
|
238
|
+
|
239
|
+
<define name='base64'>
|
240
|
+
<data type="string">
|
241
|
+
<param name="pattern">[a-zA-Z0-9+/]+={0,2}</param>
|
242
|
+
</data>
|
243
|
+
</define>
|
244
|
+
|
245
|
+
<define name='base64_or_empty'>
|
246
|
+
<choice>
|
247
|
+
<ref name='base64'/>
|
248
|
+
<empty/>
|
249
|
+
</choice>
|
250
|
+
</define>
|
251
|
+
|
252
|
+
<define name='base64_or_emptytype'>
|
253
|
+
<attribute name='type'>
|
254
|
+
<value>base64</value>
|
255
|
+
</attribute>
|
256
|
+
<ref name='base64_or_empty'/>
|
257
|
+
</define>
|
258
|
+
|
259
|
+
<define name='base64type'>
|
260
|
+
<attribute name='type'>
|
261
|
+
<value>base64</value>
|
262
|
+
</attribute>
|
263
|
+
<ref name='base64'/>
|
264
|
+
</define>
|
265
|
+
|
266
|
+
<define name='number'>
|
267
|
+
<data type="string">
|
268
|
+
<param name="pattern">[0-9]*</param>
|
269
|
+
</data>
|
270
|
+
</define>
|
271
|
+
|
272
|
+
</grammar>
|
data/lib/cloud_inst.rb
CHANGED
@@ -56,8 +56,8 @@ class CloudInst
|
|
56
56
|
address = dc_inst.private_addresses.first if address.nil?
|
57
57
|
@address = address[:address]
|
58
58
|
|
59
|
-
@ssh = @ssh.gsub(/\[address\]/, address)
|
60
|
-
@scp = @scp.gsub(/\[address\]/, address)
|
59
|
+
@ssh = @ssh.gsub(/\[address\]/, @address)
|
60
|
+
@scp = @scp.gsub(/\[address\]/, @address)
|
61
61
|
|
62
62
|
self
|
63
63
|
end
|
@@ -68,14 +68,9 @@ class CloudInst
|
|
68
68
|
|
69
69
|
def cp(from, to, append=false)
|
70
70
|
scpf = @scp.gsub(/\[source\]/, from).
|
71
|
-
|
71
|
+
gsub(/\[dst\]/, from)
|
72
72
|
`#{scpf}`
|
73
|
-
if append
|
74
|
-
`#{ssh} sudo 'cat #{to} #{from} > #{from}.new'`
|
75
|
-
`#{ssh} sudo mv #{from}.new #{to}`
|
76
|
-
else
|
77
73
|
`#{ssh} sudo mv #{from} #{to}`
|
78
|
-
end
|
79
74
|
end
|
80
75
|
end
|
81
76
|
end
|
data/lib/etdl.rb
CHANGED
@@ -14,104 +14,92 @@ class ETDL
|
|
14
14
|
attr_reader :cloud_attributes
|
15
15
|
|
16
16
|
# instance attributes
|
17
|
-
#attr_reader :name, :description, :
|
17
|
+
#attr_reader :name, :description, :os, :repositories, :disk, :packages, :files, :commands
|
18
18
|
attr_reader :instance_attributes
|
19
19
|
|
20
|
+
# additional commands to verify instance
|
21
|
+
attr_reader :verify_cmds
|
22
|
+
|
20
23
|
def initialize(args = {})
|
21
24
|
@cloud_attributes = args[:cloud_attributes] || {}
|
22
25
|
@instance_attributes = args[:instance_attributes] || {}
|
26
|
+
@verify_cmds = args[:verify_cmds] || []
|
23
27
|
end
|
24
28
|
|
25
29
|
# Parse / return new eTDL instance from xml document
|
26
30
|
def self.parse(doc)
|
27
31
|
cloud_attributes = {}
|
28
|
-
instance_attributes = {
|
32
|
+
instance_attributes = { :repositories => [], :packages => [],
|
33
|
+
:files => [], :commands => [] }
|
34
|
+
verify_cmds = []
|
29
35
|
|
30
36
|
doc.children.last.children.each { |c|
|
31
37
|
if c.name == 'name'
|
32
|
-
instance_attributes[:name] = c.text
|
38
|
+
instance_attributes[:name] = c.text.strip
|
33
39
|
|
34
40
|
elsif c.name == 'description'
|
35
|
-
instance_attributes[:description] = c.text
|
36
|
-
|
37
|
-
elsif c.name == 'hostname'
|
38
|
-
instance_attributes[:hostname] = c.text
|
41
|
+
instance_attributes[:description] = c.text.strip
|
39
42
|
|
40
43
|
elsif c.name == 'cloud'
|
41
44
|
c.children.each { |ca|
|
42
|
-
cloud_attributes[ca.name.intern] = ca.text
|
45
|
+
cloud_attributes[ca.name.intern] = ca.text.strip
|
46
|
+
}
|
47
|
+
|
48
|
+
elsif c.name == 'os'
|
49
|
+
instance_attributes[:os] = {}
|
50
|
+
c.children.each { |cc|
|
51
|
+
instance_attributes[:os][cc.name] = cc.text.strip
|
43
52
|
}
|
44
53
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
54
|
+
# TODO c.name == 'disk'
|
55
|
+
|
56
|
+
elsif c.name == 'repositories'
|
57
|
+
c.children.each { |repo|
|
58
|
+
unless repo['name'].nil?
|
59
|
+
instance_attributes[:repositories] << { :name => repo['name'],
|
60
|
+
:url => repo['url'] }
|
50
61
|
end
|
51
62
|
}
|
52
63
|
|
53
64
|
elsif c.name == 'packages'
|
54
65
|
c.children.each { |pkg|
|
55
66
|
unless pkg['name'].nil?
|
56
|
-
instance_attributes[:packages] ||= []
|
57
67
|
instance_attributes[:packages] << pkg['name']
|
58
68
|
end
|
59
69
|
}
|
60
70
|
|
61
|
-
elsif c.name == 'services'
|
62
|
-
c.children.each { |srv|
|
63
|
-
unless srv['name'].nil?
|
64
|
-
pre_cmds = []
|
65
|
-
post_cmds = []
|
66
|
-
srv.children.each { |s|
|
67
|
-
if s.name == "before"
|
68
|
-
pre_cmds << s.text
|
69
|
-
elsif s.name == "after"
|
70
|
-
post_cmds << s.text
|
71
|
-
end
|
72
|
-
}
|
73
|
-
instance_attributes[:services] ||= []
|
74
|
-
instance_attributes[:services] << {:name => srv['name'], :pre => pre_cmds, :post => post_cmds}
|
75
|
-
end
|
76
|
-
}
|
77
|
-
|
78
|
-
elsif c.name == 'dirs'
|
79
|
-
c.children.each { |dir|
|
80
|
-
owner = dir['owner'] || 'root'
|
81
|
-
group = dir['group'] || 'root'
|
82
|
-
remove = dir['remove'] || false
|
83
|
-
instance_attributes[:dirs] ||= []
|
84
|
-
instance_attributes[:dirs] << {:name => dir.text, :owner => owner, :group => group, :remove => remove} if dir.text.strip != ""
|
85
|
-
}
|
86
|
-
|
87
71
|
elsif c.name == 'files'
|
88
72
|
c.children.each { |file|
|
89
73
|
unless file['name'].nil?
|
90
|
-
|
91
|
-
|
92
|
-
group = file['group'] || 'root'
|
93
|
-
instance_attributes[:files] ||= []
|
94
|
-
instance_attributes[:files] << {:name => file['name'], :mode => mode, :append => file['append'],
|
95
|
-
:owner => owner, :group => group,
|
96
|
-
:contents => file.text}
|
74
|
+
instance_attributes[:files] << {:name => file['name'],
|
75
|
+
:contents => file.text.strip}
|
97
76
|
end
|
98
77
|
}
|
99
78
|
|
100
79
|
elsif c.name == 'commands'
|
101
80
|
c.children.each { |cmd|
|
102
81
|
unless cmd.name != "command"
|
103
|
-
|
104
|
-
|
105
|
-
|
82
|
+
instance_attributes[:commands] << {:cmd => cmd.text.strip}
|
83
|
+
end
|
84
|
+
}
|
85
|
+
|
86
|
+
elsif c.name == 'verify'
|
87
|
+
c.children.each { |cmd|
|
88
|
+
unless cmd.name != "command"
|
89
|
+
ccmd = cmd.text.strip
|
90
|
+
verify_cmds << ccmd unless ccmd.nil? || ccmd == ""
|
106
91
|
end
|
107
92
|
}
|
93
|
+
|
108
94
|
end
|
109
95
|
}
|
110
|
-
pp instance_attributes
|
96
|
+
#pp instance_attributes
|
111
97
|
#pp cloud_attributes
|
98
|
+
#pp verify_cmds
|
112
99
|
|
113
100
|
etdl = ETDL.new :cloud_attributes => cloud_attributes,
|
114
|
-
:instance_attributes => instance_attributes
|
101
|
+
:instance_attributes => instance_attributes,
|
102
|
+
:verify_cmds => verify_cmds
|
115
103
|
end
|
116
104
|
|
117
105
|
def process(processor)
|