cucumber-chef 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/.document +5 -0
  2. data/.gitignore +45 -0
  3. data/Gemfile +21 -0
  4. data/LICENSE +201 -0
  5. data/README.md +83 -0
  6. data/Rakefile +53 -0
  7. data/VERSION +1 -0
  8. data/bin/cucumber-chef +162 -0
  9. data/cookbooks/cucumber-chef/README.rdoc +8 -0
  10. data/cookbooks/cucumber-chef/files/default/add-git-identity +2 -0
  11. data/cookbooks/cucumber-chef/files/default/controller-first-boot +1 -0
  12. data/cookbooks/cucumber-chef/files/default/cucumber-net +5 -0
  13. data/cookbooks/cucumber-chef/files/default/cucumber-private-key +27 -0
  14. data/cookbooks/cucumber-chef/files/default/cucumber-run_list +1 -0
  15. data/cookbooks/cucumber-chef/files/default/git-private-key +27 -0
  16. data/cookbooks/cucumber-chef/files/default/install-chef +1 -0
  17. data/cookbooks/cucumber-chef/files/default/lxc-controller-network-config +5 -0
  18. data/cookbooks/cucumber-chef/files/default/lxc-lucid-chef +377 -0
  19. data/cookbooks/cucumber-chef/files/default/permissive-ssh-config +3 -0
  20. data/cookbooks/cucumber-chef/metadata.rb +6 -0
  21. data/cookbooks/cucumber-chef/recipes/controller.rb +50 -0
  22. data/cookbooks/cucumber-chef/recipes/lxc.rb +35 -0
  23. data/cookbooks/cucumber-chef/recipes/test_lab.rb +23 -0
  24. data/cookbooks/cucumber-chef/recipes/testrunner.rb +46 -0
  25. data/cookbooks/cucumber-chef/roles/controller.rb +7 -0
  26. data/cookbooks/cucumber-chef/roles/test_lab_test.rb +9 -0
  27. data/cookbooks/cucumber-chef/templates/default/controller-client.erb +5 -0
  28. data/cookbooks/cucumber-chef/templates/default/lxc-lucid-chef +385 -0
  29. data/cucumber-chef.gemspec +118 -0
  30. data/features/installing.feature +10 -0
  31. data/features/steps/installing_steps.rb +34 -0
  32. data/features/steps/setup_steps.rb +32 -0
  33. data/features/steps/upload_steps.rb +11 -0
  34. data/features/steps/usage_steps.rb +62 -0
  35. data/features/support/env.rb +25 -0
  36. data/features/support/filetools.rb +9 -0
  37. data/features/support/silent_system.rb +4 -0
  38. data/features/usage.feature +26 -0
  39. data/lib/cucumber-chef.rb +1 -0
  40. data/lib/cucumber/chef.rb +195 -0
  41. data/lib/cucumber/chef/handy.rb +87 -0
  42. data/lib/cucumber/chef/templates/controller.erb +35 -0
  43. data/lib/cucumber/chef/templates/env.rb +16 -0
  44. data/lib/cucumber/chef/templates/example_feature.erb +11 -0
  45. data/lib/cucumber/chef/templates/example_step.erb +19 -0
  46. data/lib/cucumber/chef/templates/readme.erb +28 -0
  47. data/lib/cucumber/chef/templates/ubuntu10.04-gems.erb +43 -0
  48. data/lib/cucumber/chef/version.rb +5 -0
  49. data/lib/cucumber/ec2_server_create.rb +99 -0
  50. data/spec/unit/cucumber_chef_spec.rb +270 -0
  51. metadata +213 -0
@@ -0,0 +1,3 @@
1
+ UserKnownHostsFile /dev/null
2
+ StrictHostKeyChecking no
3
+ LogLevel error
@@ -0,0 +1,6 @@
1
+ maintainer "Atalanta Systems"
2
+ maintainer_email "stephen@atalanta-systems.com"
3
+ license "Something friendly"
4
+ description "Installs/Configures cucumber-chef"
5
+ long_description IO.read(File.join(File.dirname(__FILE__), 'README.rdoc'))
6
+ version "0.0.1"
@@ -0,0 +1,50 @@
1
+ directory "/root/.ssh" do
2
+ owner "root"
3
+ mode "0600"
4
+ end
5
+
6
+ cookbook_file "/root/.ssh/git-key.rsa" do
7
+ source "git-private-key"
8
+ end
9
+
10
+ cookbook_file "/root/.ssh/config" do
11
+ source "permissive-ssh-config"
12
+ end
13
+
14
+ cookbook_file "/root/.ssh/id_rsa" do
15
+ source "cucumber-private-key"
16
+ mode "0600"
17
+ owner "root"
18
+ end
19
+
20
+ cookbook_file "/root/.bashrc" do
21
+ source "add-git-identity"
22
+ end
23
+
24
+ cookbook_file "/etc/lxc/controller" do
25
+ source "lxc-controller-network-config"
26
+ end
27
+
28
+ execute "lxc-create -n controller -f /etc/lxc/controller -t lucid-chef" do
29
+ not_if {File.exists?("/var/lib/lxc/controller")}
30
+ end
31
+
32
+ template "/var/lib/lxc/controller/rootfs/etc/chef/client.rb" do
33
+ source "controller-client.erb"
34
+ variables( :orgname => node["cucumber-chef"]["orgname"] )
35
+ end
36
+
37
+ cookbook_file "/var/lib/lxc/controller/rootfs/etc/chef/first-boot.json" do
38
+ source "controller-first-boot"
39
+ end
40
+
41
+ execute 'chroot /var/lib/lxc/controller/rootfs /bin/bash -c "chef-client -j /etc/chef/first-boot.json > /dev/null 2>&1"' do
42
+ action :run
43
+ # TODO: Make idempotent perhaps with a node search
44
+ end
45
+
46
+ execute 'lxc-start -d -n controller' do
47
+ status = %x[lxc-info -n #{name} 2>&1]
48
+ not_if {status.include?("RUNNING")}
49
+ end
50
+
@@ -0,0 +1,35 @@
1
+ %w{lxc bridge-utils debootstrap}.each do |pkg|
2
+ package "#{pkg}"
3
+ end
4
+
5
+ bash "Set up networking" do
6
+ code <<-EOH
7
+ brctl addbr br0
8
+ ifconfig br0 192.168.20.1 up
9
+ iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
10
+ sysctl -w net.ipv4.ip_forward=1
11
+ EOH
12
+ not_if "ip link ls dev br0"
13
+ end
14
+
15
+ directory "/cgroup" do
16
+ action :create
17
+ end
18
+
19
+ mount "/cgroup" do
20
+ device "cgroup"
21
+ fstype "cgroup"
22
+ pass 0
23
+ action [:mount, :enable]
24
+ end
25
+
26
+ template "/usr/lib/lxc/templates/lxc-lucid-chef" do
27
+ source "lxc-lucid-chef"
28
+ mode "0755"
29
+ variables( :orgname => node["cucumber-chef"]["orgname"] )
30
+ action :create
31
+ end
32
+
33
+
34
+
35
+
@@ -0,0 +1,23 @@
1
+ %w[rsync build-essential libxml2-dev libxslt-dev].each do |pkg|
2
+ package pkg
3
+ end
4
+
5
+ %w[cucumber-chef rspec cucumber].each do |gem|
6
+ gem_package gem
7
+ end
8
+
9
+ directory "/root/.ssh" do
10
+ mode "0600"
11
+ owner "root"
12
+ end
13
+
14
+ cookbook_file "/root/.ssh/config" do
15
+ source "permissive-ssh-config"
16
+ end
17
+
18
+ cookbook_file "/root/.ssh/id_rsa" do
19
+ source "cucumber-private-key"
20
+ mode "0600"
21
+ owner "root"
22
+ end
23
+
@@ -0,0 +1,46 @@
1
+ %w{build-essential binutils-doc libxml2-dev libxslt-dev}.each do |pkg|
2
+ package pkg do
3
+ action :install
4
+ end
5
+ end
6
+
7
+ package "autoconf" do
8
+ action :install
9
+ end
10
+
11
+ package "flex" do
12
+ action :install
13
+ end
14
+
15
+ package "bison" do
16
+ action :install
17
+ end
18
+
19
+ %w[cucumber-chef cucumber rspec].each do |gem|
20
+ gem_package gem
21
+ end
22
+
23
+ directory "/root/.ssh" do
24
+ owner "root"
25
+ mode "0600"
26
+ end
27
+
28
+ cookbook_file "/root/.ssh/git-key.rsa" do
29
+ source "git-private-key"
30
+ end
31
+
32
+ cookbook_file "/root/.ssh/config" do
33
+ source "permissive-ssh-config"
34
+ end
35
+
36
+ cookbook_file "/root/.ssh/id_rsa" do
37
+ source "cucumber-private-key"
38
+ mode "0600"
39
+ owner "root"
40
+ end
41
+
42
+ cookbook_file "/root/.bashrc" do
43
+ source "add-git-identity"
44
+ end
45
+
46
+
@@ -0,0 +1,7 @@
1
+ name "controller"
2
+ description "Cucumber-chef controller node for running tests."
3
+ run_list(
4
+ "recipe[cucumber-chef::testrunner]"
5
+ )
6
+
7
+ override_attributes "cucumber-chef" => { "orgname" => "#{ENV['ORGNAME']}" }
@@ -0,0 +1,9 @@
1
+ name "test_lab_test"
2
+ description "Platform for running acceptance and integration tests"
3
+ run_list(
4
+ "recipe[cucumber-chef::lxc]",
5
+ "recipe[cucumber-chef::test_lab]",
6
+ "recipe[cucumber-chef::controller]"
7
+ )
8
+
9
+ override_attributes "cucumber-chef" => { "orgname" => "#{ENV['ORGNAME']}" }
@@ -0,0 +1,5 @@
1
+ log_level :info
2
+ log_location STDOUT
3
+ chef_server_url "https://api.opscode.com/organizations/<%= @orgname %>"
4
+ validation_client_name "<%= @orgname %>-validator"
5
+ node_name "cucumber-chef-controller"
@@ -0,0 +1,385 @@
1
+
2
+ #!/bin/bash
3
+
4
+ configure_ubuntu()
5
+ {
6
+ rootfs=$1
7
+ hostname=$2
8
+
9
+ # disable selinux in ubuntu
10
+ mkdir -p $rootfs/selinux
11
+ echo 0 > $rootfs/selinux/enforce
12
+
13
+ # set the hostname
14
+ cat <<EOF > $rootfs/etc/hostname
15
+ $hostname
16
+ EOF
17
+ # set minimal hosts
18
+ cat <<EOF > $rootfs/etc/hosts
19
+ 127.0.0.1 localhost $hostname
20
+ EOF
21
+
22
+ # provide the lxc service
23
+ cat <<EOF > $rootfs/etc/init/lxc.conf
24
+ # fake some events needed for correct startup other services
25
+
26
+ description "Container Upstart"
27
+
28
+ start on startup
29
+
30
+ script
31
+ rm -rf /var/run/*.pid
32
+ rm -rf /var/run/network/*
33
+ /sbin/initctl emit stopped JOB=udevtrigger --no-wait
34
+ /sbin/initctl emit started JOB=udev --no-wait
35
+ end script
36
+ EOF
37
+
38
+ # fix buggus runlevel with sshd
39
+ cat <<EOF > $rootfs/etc/init/ssh.conf
40
+ # ssh - OpenBSD Secure Shell server
41
+ #
42
+ # The OpenSSH server provides secure shell access to the system.
43
+
44
+ description "OpenSSH server"
45
+
46
+ start on filesystem
47
+ stop on runlevel [!2345]
48
+
49
+ expect fork
50
+ respawn
51
+ respawn limit 10 5
52
+ umask 022
53
+ # replaces SSHD_OOM_ADJUST in /etc/default/ssh
54
+ oom never
55
+
56
+ pre-start script
57
+ test -x /usr/sbin/sshd || { stop; exit 0; }
58
+ test -e /etc/ssh/sshd_not_to_be_run && { stop; exit 0; }
59
+ test -c /dev/null || { stop; exit 0; }
60
+
61
+ mkdir -p -m0755 /var/run/sshd
62
+ end script
63
+
64
+ # if you used to set SSHD_OPTS in /etc/default/ssh, you can change the
65
+ # 'exec' line here instead
66
+ exec /usr/sbin/sshd
67
+ EOF
68
+
69
+ cat <<EOF > $rootfs/etc/init/console.conf
70
+ # console - getty
71
+ #
72
+ # This service maintains a console on tty1 from the point the system is
73
+ # started until it is shut down again.
74
+
75
+ start on stopped rc RUNLEVEL=[2345]
76
+ stop on runlevel [!2345]
77
+
78
+ respawn
79
+ exec /sbin/getty -8 38400 /dev/console
80
+ EOF
81
+
82
+ cat <<EOF > $rootfs/lib/init/fstab
83
+ # /lib/init/fstab: lxc system fstab
84
+ none /spu spufs gid=spu,optional 0 0
85
+ none /tmp none defaults 0 0
86
+ none /var/lock tmpfs nodev,noexec,nosuid,showthrough 0 0
87
+ none /lib/init/rw tmpfs mode=0755,nosuid,optional 0 0
88
+ EOF
89
+
90
+
91
+
92
+ # reconfigure some services
93
+ if [ -z "$LANG" ]; then
94
+ chroot $rootfs locale-gen en_US.UTF-8
95
+ chroot $rootfs update-locale LANG=en_US.UTF-8
96
+ else
97
+ chroot $rootfs locale-gen $LANG
98
+ chroot $rootfs update-locale LANG=$LANG
99
+ fi
100
+
101
+ # remove pointless services in a container
102
+ chroot $rootfs /usr/sbin/update-rc.d -f ondemand remove
103
+
104
+ chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls u*.conf); do mv $f $f.orig; done'
105
+ chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls tty[2-9].conf); do mv $f $f.orig; done'
106
+ chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls plymouth*.conf); do mv $f $f.orig; done'
107
+ chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls hwclock*.conf); do mv $f $f.orig; done'
108
+ chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls module*.conf); do mv $f $f.orig; done'
109
+
110
+ echo "Please change root-password !"
111
+ echo "root:root" | chroot $rootfs chpasswd
112
+
113
+ return 0
114
+ }
115
+
116
+ configure_image()
117
+ {
118
+ image=$cache/rootfs-$arch
119
+ mkdir $image/root/.ssh
120
+ chmod 0600 /root/.ssh
121
+
122
+ cat <<EOF > $image/etc/rc.local
123
+ #!/bin/sh -e
124
+ ip route add default via 192.168.20.1
125
+ exit 0
126
+ EOF
127
+
128
+ cat <<EOF > $image/root/.ssh/authorized_keys
129
+ ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAzj2O8BxvLn1Q7vUTiyFdtle9SeataEF//+651mXTV8WdKuXGRgvIKZPu+ZnTsqnDoR+pwMRFf95hDPHScpdYj2WVY1cN2e6xEKEsz3xcKdhaTuAOBd47J9wu6Nmgr1aZ/2/AWTrLEOMxUVVp/bzeSFzfHR2bctfKCKzMUCLGZLEGn0Yv5Qbk56Vr9A5jUJcKgCodWOpTcPlf+kKzxejgt/wHRZTRrJIOyx5Zhddim10/sZZ8ct9+WgBwhIL2fUHrsAb1wjxKpQCOYoxHuRSFnv4zrFzblI737TmQIHkkb9g08z3qIJLLiLKgGNXP2wclA37ctGfqwfJWj9FA9nI9iQ== root@cucumber
130
+ EOF
131
+
132
+ mkdir $image/etc/chef
133
+
134
+ cat <<EOF > $image/tmp/validation.pem
135
+ <%= IO.read(Chef::Config[:validation_key]) %>
136
+ EOF
137
+ awk NF $image/tmp/validation.pem > $image/etc/chef/validation.pem
138
+ rm $image/tmp/validation.pem
139
+
140
+ cat <<EOF > $image/etc/chef/client.rb
141
+ log_level :info
142
+ log_location STDOUT
143
+ chef_server_url "<%= Chef::Config[:chef_server_url] %>"
144
+ validation_client_name "<%= Chef::Config[:validation_client_name] %>"
145
+ EOF
146
+
147
+
148
+ cat <<EOF > $image/etc/apt/sources.list.d/atalanta.list
149
+ deb http://packages.atalanta-systems.com lucid main
150
+ EOF
151
+
152
+ rm $image/etc/resolv.conf
153
+ cp /etc/resolv.conf $image/etc/resolv.conf
154
+ cp /etc/lxc/install-chef.sh $image/tmp/install-chef.sh
155
+ chroot $image /bin/sh -c "/usr/bin/apt-get update && /usr/bin/apt-get --assume-yes --allow-unauthenticated install strace ruby1.9.1p180"
156
+ mkdir -p $image/$HOME
157
+ chroot $image /bin/sh -c "/usr/local/bin/gem install chef --no-ri --no-rdoc 2>&1" 2>&1 >> /tmp/data
158
+ return $?
159
+ }
160
+
161
+ download_ubuntu()
162
+ {
163
+ packages=dialog,apt,apt-utils,resolvconf,iproute,inetutils-ping,vim,dhcp3-client,ssh,lsb-release,wget,gpgv,gnupg
164
+
165
+ cache=$1
166
+ arch=$2
167
+
168
+ # check the mini ubuntu was not already downloaded
169
+ mkdir -p "$cache/partial-$arch"
170
+ if [ $? -ne 0 ]; then
171
+ echo "Failed to create '$cache/partial-$arch' directory"
172
+ return 1
173
+ fi
174
+
175
+ # download a mini ubuntu into a cache
176
+ echo "Downloading ubuntu minimal ..."
177
+ debootstrap --verbose --variant=minbase --components=main,universe --arch=$arch --include=$packages lucid $cache/partial-$arch
178
+ if [ $? -ne 0 ]; then
179
+ echo "Failed to download the rootfs, aborting."
180
+ return 1
181
+ fi
182
+
183
+ mv "$1/partial-$arch" "$1/rootfs-$arch"
184
+ echo "Download complete."
185
+
186
+ return 0
187
+ }
188
+
189
+ copy_ubuntu()
190
+ {
191
+ cache=$1
192
+ arch=$2
193
+ rootfs=$3
194
+
195
+ # make a local copy of the miniubuntu
196
+ echo -n "Copying rootfs to $rootfs ..."
197
+ cp -a $cache/rootfs-$arch $rootfs || return 1
198
+ return 0
199
+ }
200
+
201
+ install_ubuntu()
202
+ {
203
+ cache="/var/cache/lxc/ubuntu"
204
+ rootfs=$1
205
+ mkdir -p /var/lock/subsys/
206
+ (
207
+ flock -n -x 200
208
+ if [ $? -ne 0 ]; then
209
+ echo "Cache repository is busy."
210
+ return 1
211
+ fi
212
+
213
+ arch=$(arch)
214
+ if [ "$arch" == "x86_64" ]; then
215
+ arch=amd64
216
+ fi
217
+
218
+ if [ "$arch" == "i686" ]; then
219
+ arch=i386
220
+ fi
221
+
222
+ echo "Checking cache download in $cache/rootfs-$arch ... "
223
+ if [ ! -e "$cache/rootfs-$arch" ]; then
224
+ download_ubuntu $cache $arch
225
+ if [ $? -ne 0 ]; then
226
+ echo "Failed to download 'ubuntu base'"
227
+ return 1
228
+ fi
229
+ fi
230
+ configure_image
231
+ echo "Copy $cache/rootfs-$arch to $rootfs ... "
232
+ copy_ubuntu $cache $arch $rootfs
233
+ if [ $? -ne 0 ]; then
234
+ echo "Failed to copy rootfs"
235
+ return 1
236
+ fi
237
+
238
+ return 0
239
+
240
+ ) 200>/var/lock/subsys/lxc
241
+
242
+ return $?
243
+ }
244
+
245
+ copy_configuration()
246
+ {
247
+ path=$1
248
+ rootfs=$2
249
+ name=$3
250
+
251
+ cat <<EOF >> $path/config
252
+ lxc.utsname = $name
253
+
254
+ lxc.tty = 4
255
+ lxc.pts = 1024
256
+ lxc.rootfs = $rootfs
257
+ lxc.mount = $path/fstab
258
+
259
+ lxc.cgroup.devices.deny = a
260
+ # /dev/null and zero
261
+ lxc.cgroup.devices.allow = c 1:3 rwm
262
+ lxc.cgroup.devices.allow = c 1:5 rwm
263
+ # consoles
264
+ lxc.cgroup.devices.allow = c 5:1 rwm
265
+ lxc.cgroup.devices.allow = c 5:0 rwm
266
+ lxc.cgroup.devices.allow = c 4:0 rwm
267
+ lxc.cgroup.devices.allow = c 4:1 rwm
268
+ # /dev/{,u}random
269
+ lxc.cgroup.devices.allow = c 1:9 rwm
270
+ lxc.cgroup.devices.allow = c 1:8 rwm
271
+ lxc.cgroup.devices.allow = c 136:* rwm
272
+ lxc.cgroup.devices.allow = c 5:2 rwm
273
+ # rtc
274
+ lxc.cgroup.devices.allow = c 254:0 rwm
275
+ EOF
276
+
277
+ cat <<EOF > $path/fstab
278
+ proc $rootfs/proc proc nodev,noexec,nosuid 0 0
279
+ devpts $rootfs/dev/pts devpts defaults 0 0
280
+ sysfs $rootfs/sys sysfs defaults 0 0
281
+ EOF
282
+
283
+ if [ $? -ne 0 ]; then
284
+ echo "Failed to add configuration"
285
+ return 1
286
+ fi
287
+
288
+ return 0
289
+ }
290
+
291
+ clean()
292
+ {
293
+ cache="/var/cache/lxc/ubuntu"
294
+
295
+ if [ ! -e $cache ]; then
296
+ exit 0
297
+ fi
298
+
299
+ # lock, so we won't purge while someone is creating a repository
300
+ (
301
+ flock -n -x 200
302
+ if [ $? != 0 ]; then
303
+ echo "Cache repository is busy."
304
+ exit 1
305
+ fi
306
+
307
+ echo -n "Purging the download cache..."
308
+ rm --preserve-root --one-file-system -rf $cache && echo "Done." || exit 1
309
+ exit 0
310
+
311
+ ) 200>/var/lock/subsys/lxc
312
+ }
313
+
314
+ usage()
315
+ {
316
+ cat <<EOF
317
+ $1 -h|--help -p|--path=<path> --clean
318
+ EOF
319
+ return 0
320
+ }
321
+
322
+ options=$(getopt -o hp:n:c -l help,path:,name:,clean -- "$@")
323
+ if [ $? -ne 0 ]; then
324
+ usage $(basename $0)
325
+ exit 1
326
+ fi
327
+ eval set -- "$options"
328
+
329
+ while true
330
+ do
331
+ case "$1" in
332
+ -h|--help) usage $0 && exit 0;;
333
+ -p|--path) path=$2; shift 2;;
334
+ -n|--name) name=$2; shift 2;;
335
+ -c|--clean) clean=$2; shift 2;;
336
+ --) shift 1; break ;;
337
+ *) break ;;
338
+ esac
339
+ done
340
+
341
+ if [ ! -z "$clean" -a -z "$path" ]; then
342
+ clean || exit 1
343
+ exit 0
344
+ fi
345
+
346
+ type debootstrap
347
+ if [ $? -ne 0 ]; then
348
+ echo "'debootstrap' command is missing"
349
+ exit 1
350
+ fi
351
+
352
+ if [ -z "$path" ]; then
353
+ echo "'path' parameter is required"
354
+ exit 1
355
+ fi
356
+
357
+ if [ "$(id -u)" != "0" ]; then
358
+ echo "This script should be run as 'root'"
359
+ exit 1
360
+ fi
361
+
362
+ rootfs=$path/rootfs
363
+
364
+ install_ubuntu $rootfs
365
+ if [ $? -ne 0 ]; then
366
+ echo "failed to install ubuntu"
367
+ exit 1
368
+ fi
369
+
370
+ configure_ubuntu $rootfs $name
371
+ if [ $? -ne 0 ]; then
372
+ echo "failed to configure ubuntu for a container"
373
+ exit 1
374
+ fi
375
+
376
+ copy_configuration $path $rootfs $name
377
+ if [ $? -ne 0 ]; then
378
+ echo "failed write configuration file"
379
+ exit 1
380
+ fi
381
+
382
+ if [ ! -z $clean ]; then
383
+ clean || exit 1
384
+ exit 0
385
+ fi