vagabond 0.2.0 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. data/CHANGELOG.md +18 -0
  2. data/README.md +125 -4
  3. data/bin/vagabond +43 -16
  4. data/lib/vagabond/actions/cluster.rb +66 -0
  5. data/lib/vagabond/actions/create.rb +12 -7
  6. data/lib/vagabond/actions/destroy.rb +69 -15
  7. data/lib/vagabond/actions/init.rb +75 -0
  8. data/lib/vagabond/actions/provision.rb +4 -2
  9. data/lib/vagabond/actions/status.rb +33 -22
  10. data/lib/vagabond/actions/up.rb +8 -1
  11. data/lib/vagabond/bootstraps/server-zero.erb +20 -0
  12. data/lib/vagabond/bootstraps/server.erb +3 -2
  13. data/lib/vagabond/constants.rb +0 -15
  14. data/lib/vagabond/cookbooks/lxc/CHANGELOG.md +16 -0
  15. data/lib/vagabond/cookbooks/lxc/Gemfile +3 -2
  16. data/lib/vagabond/cookbooks/lxc/Gemfile.lock +30 -121
  17. data/lib/vagabond/cookbooks/lxc/README.md +43 -14
  18. data/lib/vagabond/cookbooks/lxc/attributes/default.rb +3 -3
  19. data/lib/vagabond/cookbooks/lxc/files/default/lxc-awesome-ephemeral +499 -0
  20. data/lib/vagabond/cookbooks/lxc/libraries/lxc.rb +223 -58
  21. data/lib/vagabond/cookbooks/lxc/libraries/lxc_file_config.rb +3 -0
  22. data/lib/vagabond/cookbooks/lxc/libraries/monkey.rb +51 -0
  23. data/lib/vagabond/cookbooks/lxc/metadata.rb +6 -5
  24. data/lib/vagabond/cookbooks/lxc/providers/config.rb +9 -16
  25. data/lib/vagabond/cookbooks/lxc/providers/container.rb +241 -229
  26. data/lib/vagabond/cookbooks/lxc/providers/default.rb +57 -0
  27. data/lib/vagabond/cookbooks/lxc/providers/ephemeral.rb +40 -0
  28. data/lib/vagabond/cookbooks/lxc/providers/fstab.rb +13 -54
  29. data/lib/vagabond/cookbooks/lxc/providers/interface.rb +13 -67
  30. data/lib/vagabond/cookbooks/lxc/providers/service.rb +14 -14
  31. data/lib/vagabond/cookbooks/lxc/recipes/default.rb +17 -4
  32. data/lib/vagabond/cookbooks/lxc/recipes/install_dependencies.rb +1 -1
  33. data/lib/vagabond/cookbooks/lxc/resources/config.rb +2 -2
  34. data/lib/vagabond/cookbooks/lxc/resources/container.rb +31 -6
  35. data/lib/vagabond/cookbooks/lxc/resources/default.rb +12 -0
  36. data/lib/vagabond/cookbooks/lxc/resources/ephemeral.rb +13 -0
  37. data/lib/vagabond/cookbooks/lxc/resources/fstab.rb +2 -1
  38. data/lib/vagabond/cookbooks/lxc/resources/interface.rb +6 -3
  39. data/lib/vagabond/cookbooks/lxc/resources/service.rb +1 -1
  40. data/lib/vagabond/cookbooks/lxc/templates/default/file_content.erb +2 -0
  41. data/lib/vagabond/cookbooks/lxc/templates/default/interface.erb +9 -3
  42. data/lib/vagabond/cookbooks/vagabond/README.md +10 -0
  43. data/lib/vagabond/cookbooks/vagabond/attributes/default.rb +1 -0
  44. data/lib/vagabond/cookbooks/vagabond/files/default/lxc-centos +13 -6
  45. data/lib/vagabond/cookbooks/vagabond/metadata.rb +1 -0
  46. data/lib/vagabond/cookbooks/vagabond/recipes/default.rb +46 -4
  47. data/lib/vagabond/cookbooks/vagabond/recipes/zero.rb +9 -0
  48. data/lib/vagabond/errors.rb +23 -0
  49. data/lib/vagabond/helpers.rb +41 -14
  50. data/lib/vagabond/internal_configuration.rb +120 -27
  51. data/lib/vagabond/kitchen.rb +143 -63
  52. data/lib/vagabond/knife.rb +8 -5
  53. data/lib/vagabond/layout.rb +16 -0
  54. data/lib/vagabond/monkey/kitchen_config.rb +23 -0
  55. data/lib/vagabond/server.rb +79 -63
  56. data/lib/vagabond/spec.rb +345 -0
  57. data/lib/vagabond/uploader.rb +30 -0
  58. data/lib/vagabond/uploader/berkshelf.rb +53 -0
  59. data/lib/vagabond/uploader/knife.rb +24 -0
  60. data/lib/vagabond/uploader/librarian.rb +31 -0
  61. data/lib/vagabond/vagabond.rb +30 -11
  62. data/lib/vagabond/vagabondfile.rb +40 -5
  63. data/lib/vagabond/version.rb +1 -1
  64. data/vagabond.gemspec +5 -2
  65. metadata +75 -15
  66. data/lib/vagabond/cookbooks/lxc/resources/#container.rb# +0 -28
  67. data/lib/vagabond/cookbooks/lxc/test/kitchen/Kitchenfile +0 -7
  68. data/lib/vagabond/cookbooks/lxc/test/kitchen/cookbooks/lxc_test/metadata.rb +0 -2
  69. data/lib/vagabond/cookbooks/lxc/test/kitchen/cookbooks/lxc_test/recipes/centos_lxc.rb +0 -0
  70. data/lib/vagabond/cookbooks/lxc/test/kitchen/cookbooks/lxc_test/recipes/chef-bootstrap.rb +0 -0
  71. data/lib/vagabond/cookbooks/lxc/test/kitchen/cookbooks/lxc_test/recipes/lxc_files.rb +0 -0
  72. data/lib/vagabond/cookbooks/lxc/test/kitchen/cookbooks/lxc_test/recipes/lxc_templates.rb +0 -0
  73. data/lib/vagabond/cookbooks/lxc/test/kitchen/cookbooks/lxc_test/recipes/ubuntu_lxc.rb +0 -0
@@ -17,10 +17,10 @@ default[:lxc][:knife] = {}
17
17
  default[:lxc][:knife][:static_range] = ''
18
18
  default[:lxc][:knife][:static_ips] = []
19
19
 
20
- default[:lxc][:user_pass][:debian] = {:username => 'root', :password => 'root'}
21
- default[:lxc][:user_pass][:ubuntu] = {:username => 'ubuntu', :password => 'ubuntu'}
22
- default[:lxc][:user_pass][:fedora] = {:username => 'root', :password => 'root'}
20
+ default[:lxc][:user_locks] = %w(ubuntu)
23
21
 
24
22
  default[:lxc][:packages] = %w(lxc)
25
23
  default[:lxc][:mirror] = 'http://archive.ubuntu.com/ubuntu'
26
24
  default[:lxc][:containers] = {}
25
+
26
+ default[:lxc][:awesome_ephemerals] = true
@@ -0,0 +1,499 @@
1
+ #!/bin/bash
2
+
3
+ # (C) Copyright Canonical 2011,2012
4
+
5
+ # What lxc container to clone
6
+ LXC_BASE=""
7
+ # $2 is a path to bind mount e.g. /tmp/foo.
8
+ LXC_BIND=""
9
+ UNION="overlayfs"
10
+
11
+ usage() {
12
+ echo "usage: lxc-awesome-ephemeral [-I ipaddress] [-G gateway] [-N netmask] [-D size] [-z rdir] [-U uniontype] [-d|--daemon] [-h] [-b bdir] [-u user] [-S key] -o orig -- [COMMAND [ARGS...]]"
13
+ }
14
+
15
+ help() {
16
+ usage
17
+ echo
18
+ echo "Runs an ephemeral (one-off) container"
19
+ echo
20
+ echo "Options:"
21
+ echo "orig : name of the original container"
22
+ echo "bdir : directory to bind mount into container"
23
+ echo "user : the user to connect to the container as"
24
+ echo "key : the path to the SSH key to use to connect"
25
+ echo "size : size of virtual device in M"
26
+ echo "rdir : host directory to store rootfs overlay"
27
+ echo "ipaddress : static ipv4 to use instead of dhcp"
28
+ echo "-d : run in the background"
29
+ echo "-U : type of union (aufs or overlayfs)"
30
+ echo " Default is overlayfs"
31
+ echo "-D : block device for rootfs overlay"
32
+ echo "-z : directory to use for rootfs overlay"
33
+ echo "-I : ip address to use"
34
+ echo "-G : gateway to use"
35
+ echo "-N : netmask to use"
36
+ echo
37
+ echo "if a COMMAND is given, then the container will run only as long"
38
+ echo "as the command runs. If no COMMAND is given, this command will"
39
+ echo "wait until the container is shut down"
40
+ }
41
+
42
+ shortoptions='hb:o:u:D:z:I:G:N:S:dU:'
43
+ longoptions='help,orig:,bdir:,user:,device:,directory:,ipaddress:,gateway:,netmask:,ssh-key:,daemon,union:'
44
+
45
+ LXC_RUNNING=0
46
+ LXC_MOUNTED=0
47
+ DAEMON=0
48
+
49
+ cleanup_dirs()
50
+ {
51
+ if [ $LXC_DIR = '/' ]; then
52
+ echo "ABORT ABORT ABORT -> LXC Directory set to root. Will. Not. Delete!"
53
+ exit 42
54
+ fi
55
+ # echo "umounting ephemeral_bind_dir $EPHEMERAL_BIND_DIR" >&2
56
+ sudo umount $EPHEMERAL_BIND_DIR > /dev/null 2>&1
57
+ # echo "umounting lxc_dir $LXC_DIR" >&2
58
+ sudo umount $LXC_DIR/rootfs > /dev/null 2>&1
59
+ # echo "umounting overlay" >&2
60
+ if [ ! $HOST_OVERLAY_DIRECTORY ]; then
61
+ sudo umount $OVERLAY_DIR > /dev/null 2>&1
62
+ fi
63
+ # remove all contents of the content dir
64
+ sudo rm -rf $LXC_DIR
65
+
66
+ # echo "rming overlay dir $OVERLAY_DIR" >&2
67
+ if [ $HOST_OVERLAY_DIRECTORY ]; then
68
+ if [ $HOST_OVERLAY_DIRECTORY = '/' ]; then
69
+ echo "ABORT ABORT ABORT -> Overlay Directory set to root. Will. Not. Delete!"
70
+ exit 42
71
+ fi
72
+
73
+ if [ $VIRT_DIR ]; then
74
+ sudo umount $VIRT_MNT > /dev/null 2>&1
75
+ sudo rmdir $VIRT_MNT > /dev/null 2>&1
76
+ sudo rm -f $VIRT_DEV
77
+ fi
78
+ sudo rm -rf $HOST_OVERLAY_DIRECTORY
79
+ else
80
+ if [ $OVERLAY_DIR = '/' ]; then
81
+ echo "ABORT ABORT ABORT -> Overlay Directory set to root. Will. Not. Delete!"
82
+ exit 42
83
+ fi
84
+ sudo rm -rf $OVERLAY_DIR
85
+ fi
86
+ }
87
+
88
+ create_virt_device() {
89
+ echo "Creating ephemeral virtual device for rootfs (${OVERLAY_DEVICE}M)"
90
+ VIRT_DIR="/tmp/lxc-virt-devs"
91
+ VIRT_IMG_DIR="${VIRT_DIR}/imgs"
92
+ VIRT_MNT_DIR="${VIRT_DIR}/mnt"
93
+ VIRT_DEV="${VIRT_IMG_DIR}/${LXC_NAME}"
94
+ VIRT_MNT="${VIRT_MNT_DIR}/${LXC_NAME}"
95
+ sudo mkdir -p $VIRT_DIR
96
+ sudo mkdir -p $VIRT_IMG_DIR
97
+ sudo mkdir -p $VIRT_MNT
98
+ # Create empty disk
99
+ sudo dd if=/dev/zero of=$VIRT_DEV bs=1k seek=${OVERLAY_DEVICE}k count=1 > /dev/null
100
+ # format device
101
+ echo "y" | sudo mkfs -t ext4 $VIRT_DEV > /dev/null
102
+ # mount loopback
103
+ sudo mount -o loop $VIRT_DEV $VIRT_MNT
104
+ if [ $? -ne 0 ]; then
105
+ echo "Failed to create and mount virtual device!"
106
+ exit 100
107
+ fi
108
+ HOST_OVERLAY_DIRECTORY=$VIRT_MNT
109
+ }
110
+
111
+ cleanup() {
112
+ if [ $LXC_RUNNING -eq 1 ]; then
113
+ sudo lxc-stop -n $LXC_NAME
114
+ fi
115
+ if [ $LXC_MOUNTED -eq 1 ]; then
116
+ cleanup_dirs
117
+ fi
118
+ exit 1
119
+ }
120
+
121
+ do_mount() {
122
+ lower=$1
123
+ if [ $OVERLAY_DEVICE ]; then
124
+ create_virt_device
125
+ upper=$HOST_OVERLAY_DIRECTORY
126
+ echo "Using local block device for overlay mounted at: ${HOST_OVERLAY_DIRECTORY}"
127
+ elif [ $HOST_OVERLAY_DIRECTORY ]; then
128
+ mkdir -p $HOST_OVERLAY_DIRECTORY
129
+ HOST_OVERLAY_DIRECTORY=`mktemp -d --tmpdir=$HOST_OVERLAY_DIRECTORY $LXC_BASE-temp-XXXXXXX`
130
+ upper=$HOST_OVERLAY_DIRECTORY
131
+ echo "Using local directory for overlay: ${HOST_OVERLAY_DIRECTORY}"
132
+ else
133
+ upper=$2
134
+ fi
135
+ target=$3
136
+ if [ $UNION = "aufs" ]; then
137
+ sudo mount -t aufs -o br=${upper}=rw:${lower}=ro,noplink none ${target}
138
+ else
139
+ sudo mount -t overlayfs -oupperdir=${upper},lowerdir=${lower} none ${target}
140
+ fi
141
+ }
142
+
143
+ trap cleanup SIGTERM SIGINT SIGQUIT
144
+
145
+ getopt=$(getopt -o $shortoptions --longoptions $longoptions -- "$@")
146
+ if [ $? != 0 ]; then
147
+ usage
148
+ exit 1;
149
+ fi
150
+
151
+ eval set -- "$getopt"
152
+
153
+ while true; do
154
+ case "$1" in
155
+ -h|--help)
156
+ help
157
+ exit 1
158
+ ;;
159
+ -o|--orig)
160
+ shift
161
+ LXC_BASE=$1
162
+ shift
163
+ ;;
164
+ -D|--device)
165
+ shift
166
+ OVERLAY_DEVICE=$1
167
+ shift
168
+ ;;
169
+ -z|--directory)
170
+ shift
171
+ HOST_OVERLAY_DIRECTORY=$1
172
+ shift
173
+ ;;
174
+ -b|--bdir)
175
+ shift
176
+ LXC_BIND=$1
177
+ shift
178
+ ;;
179
+ -u|--user)
180
+ shift
181
+ LXC_USER=$1
182
+ shift
183
+ ;;
184
+ -S|--ssh-key)
185
+ shift
186
+ LXC_KEY="-i $1"
187
+ shift
188
+ ;;
189
+ -d|--detach)
190
+ DAEMON=1
191
+ shift
192
+ ;;
193
+ -I|--ipaddress)
194
+ shift
195
+ CUSTOM_IPADDRESS=$1
196
+ shift
197
+ ;;
198
+ -G|--gateway)
199
+ shift
200
+ CUSTOM_GATEWAY=$1
201
+ shift
202
+ ;;
203
+ -N|--netmask)
204
+ shift
205
+ CUSTOM_NETMASK=$1
206
+ shift
207
+ ;;
208
+ -U|--union)
209
+ shift
210
+ UNION=$1
211
+ shift
212
+ ;;
213
+ --)
214
+ shift
215
+ break;;
216
+ *)
217
+ echo $1
218
+ usage
219
+ exit 1
220
+ ;;
221
+ esac
222
+ done
223
+
224
+ COMMAND=$@
225
+ COMMAND_LENGTH=$#
226
+ LXC_USER=${LXC_USER:-`id -un`}
227
+
228
+ # validation
229
+
230
+ if [ -z $LXC_BASE ]; then
231
+ echo "original container must be specified"
232
+ usage
233
+ exit 1
234
+ fi
235
+ if [ ! -d /var/lib/lxc/$LXC_BASE ] ; then
236
+ echo "no such lxc container $LXC_BASE"
237
+ exit 1
238
+ fi
239
+
240
+ if [ "$UNION" != "overlayfs" -a "$UNION" != "aufs" ]; then
241
+ echo "Invalid option for union: choose overlayfs or aufs."
242
+ exit 1
243
+ fi
244
+
245
+ setup_container()
246
+ {
247
+ echo "Setting up ephemeral container..."
248
+ if [ $HOST_OVERLAY_DIRECTORY ]; then
249
+ echo " -- Using local directory for overlay: ${HOST_OVERLAY_DIRECTORY}"
250
+ elif [ $OVERLAY_DEVICE ]; then
251
+ echo " -- Using overlay virtual block device"
252
+ else
253
+ OVERLAY_DIR=`mktemp -d /tmp/lxc-lp-XXXXXXX`
254
+ sudo mount -t tmpfs none $OVERLAY_DIR
255
+ fi
256
+ LXC_DIR=`sudo mktemp -d --tmpdir=/var/lib/lxc $LXC_BASE-temp-XXXXXXX`
257
+ sudo chmod 755 ${LXC_DIR}
258
+ LXC_NAME=`basename $LXC_DIR`
259
+ sudo mkdir ${LXC_DIR}/rootfs
260
+ do_mount "/var/lib/lxc/$LXC_BASE/rootfs" "${OVERLAY_DIR}" ${LXC_DIR}/rootfs
261
+ EPHEMERAL_BIND_DIR=$LXC_DIR/ephemeralbind
262
+ sudo mkdir $EPHEMERAL_BIND_DIR
263
+ sudo mount -t tmpfs none $EPHEMERAL_BIND_DIR
264
+ LXC_MOUNTED=1
265
+ {
266
+ d1=/var/lib/lxc/${LXC_BASE}
267
+ for f in ${d1}/*; do
268
+ if [ -f $f ]; then
269
+ sudo cp $f $LXC_DIR/
270
+ fi
271
+ done
272
+ }
273
+
274
+ # Update the ephemeral lxc's configuration to reflect the new container name.
275
+ # Check all the places known distros keep hostnames.
276
+ # FIXME: should we sanity check the hostname to make sure it contains no bad chars?
277
+ for file in $LXC_DIR/fstab $LXC_DIR/config \
278
+ $LXC_DIR/rootfs/etc/hostname \
279
+ $LXC_DIR/rootfs/etc/hosts \
280
+ $LXC_DIR/rootfs/etc/sysconfig/network \
281
+ $LXC_DIR/rootfs/etc/sysconfig/network-scripts/ifcfg-eth0
282
+ do
283
+ if test -f "$file"
284
+ then
285
+ sudo sed -i -e "s/$LXC_BASE/$LXC_NAME/" $file
286
+ fi
287
+ done
288
+
289
+ if [ -e $LXC_DIR/rootfs/etc/redhat-release ]; then
290
+ DISTRO="EL"
291
+ else
292
+ DISTRO="DEBIAN"
293
+ fi
294
+
295
+ # special tweaks for the centos family of distributions
296
+ if [ $DISTRO = "EL" ] ; then
297
+ cat <<EOF > $LXC_DIR/rootfs/etc/sysconfig/network
298
+ NETWORKING=yes
299
+ HOSTNAME=$LXC_NAME
300
+ EOF
301
+ echo "hostname $LXC_NAME" >> $LXC_DIR/rootfs/etc/rc.local
302
+ fi
303
+
304
+ # Update the fstab to have all bind mounts be ephemeral.
305
+ sudo cp $LXC_DIR/fstab $LXC_DIR/fstab.old
306
+ while read line; do
307
+ # Pull out the second field of the current line of fstab info
308
+ path=`echo -n $line | awk '{print $2}'`
309
+ # If LXC_BIND is not set, or the mount destination of this line is not
310
+ # LXC_BIND...
311
+ if [ -n "$path" ] && [ -z "$LXC_BIND" -o "`readlink -f $path`" != "`readlink -f $LXC_DIR/rootfs$LXC_BIND`" ];
312
+ then
313
+ # ...then we should write some form of this line.
314
+ # If this line is a bind...
315
+ if [ `echo -n $line | awk '{print $4}'` = "bind" ]; then
316
+ # ...we should rewrite it as an overlay.
317
+ source=`echo -n $line | awk '{print $1}'`
318
+ upperdir=$EPHEMERAL_BIND_DIR$source
319
+ sudo mkdir -p $upperdir
320
+ sudo chown `sudo stat -c '%U.%G' $source` $upperdir
321
+ if [ $UNION = "overlayfs" ]; then
322
+ echo "none $path overlayfs upperdir=$upperdir,lowerdir=$source 0 0";
323
+ else
324
+ echo "none $path aufs br=${upperdir}=rw:${lowerdir}=ro,noplink 0 0";
325
+ fi
326
+ else
327
+ # Otherwise, we can pass it through unchanged.
328
+ echo "$line";
329
+ fi
330
+ fi
331
+ done < $LXC_DIR/fstab.old | sudo tee $LXC_DIR/fstab >/dev/null
332
+
333
+ # If LXC_BIND is defined, add it to fstab.
334
+ if [ -n "$LXC_BIND" ]; then
335
+ sudo mkdir -p $LXC_DIR/rootfs$LXC_BIND
336
+ echo "$LXC_BIND $LXC_DIR/rootfs$LXC_BIND none bind 0 0" | sudo tee -a $LXC_DIR/fstab >/dev/null
337
+ fi
338
+
339
+ # update the ephemeral container's MAC address (lifted from lxc-clone)
340
+ c=$LXC_DIR/config
341
+ # change hwaddrs
342
+ sudo mv ${c} ${c}.old
343
+ (
344
+ while read line; do
345
+ if [ "${line:0:18}" = "lxc.network.hwaddr" ]; then
346
+ echo "lxc.network.hwaddr= 00:16:3e:$(openssl rand -hex 3| sed 's/\(..\)/\1:/g; s/.$//')"
347
+ else
348
+ echo "$line"
349
+ fi
350
+ done
351
+ ) < ${c}.old | sudo tee ${c} >/dev/null
352
+ sudo rm -f ${c}.old
353
+
354
+ if [ $CUSTOM_IPADDRESS ]; then
355
+ if [ -z $CUSTOM_GATEWAY ]; then
356
+ CUSTOM_GATEWAY=`echo $CUSTOM_IPADDRESS | sed 's/[0-9]\+$/1/'`
357
+ fi
358
+ if [ -z $CUSTOM_NETMASK ]; then
359
+ CUSTOM_NETMASK='255.255.255.0'
360
+ fi
361
+ write_custom_networking
362
+ fi
363
+ }
364
+
365
+ get_ip()
366
+ {
367
+ # Get init's PID
368
+ PID=$(sudo lxc-info -n $1 -p | awk '{print $2}')
369
+ [ "$PID" = "-1" ] && return 1
370
+
371
+ # Get some unique path
372
+ DST=$(sudo mktemp -u --tmpdir=/run/netns/)
373
+ NAME=$(basename $DST)
374
+
375
+ # Prepare the /run/netns entry for "ip netns"
376
+ sudo mkdir -p /run/netns
377
+ sudo ln -s /proc/$PID/ns/net $DST
378
+
379
+ # Grab all the public globally routed IPv4 and IPv6 addresses
380
+ (sudo ip netns exec $NAME ip -4 addr show scope global && \
381
+ [ sudo ip netns exec $NAME ip -6 addr show scope global) | grep inet | while read line; do
382
+ ip=$(echo $line | awk '{print $2}' | cut -d '/' -f1)
383
+ echo "$ip"
384
+ done
385
+
386
+ sudo rm $DST
387
+ }
388
+
389
+ start_container()
390
+ {
391
+ echo "Starting up the container..."
392
+ sudo lxc-start -n $LXC_NAME -d
393
+ sudo lxc-wait -s RUNNING -n $LXC_NAME
394
+ LXC_RUNNING=1
395
+
396
+ if [ $COMMAND_LENGTH -gt 0 ]; then
397
+ # When lxc-attach support arrives in the kernel, we can switch to
398
+ # that.
399
+ # Meanwhile, we use get_ip to wait for container's network to be up
400
+ # and to obtain the ip address, then we can ssh to the lxc.
401
+ TRIES=60
402
+ FAILED=1
403
+
404
+ # Repeatedly try to connect over SSH until we either succeed
405
+ # or time out.
406
+ for i in $(seq 1 $TRIES); do
407
+ # We call get_ip inside the loop to ensure the correct ip
408
+ # is retrieved even in the case the DHCP ip assignment
409
+ # changes during the process.
410
+ IP_ADDRESS=$(get_ip $LXC_NAME)
411
+ if [ -z "$IP_ADDRESS" ]; then
412
+ sleep 1
413
+ continue
414
+ fi
415
+
416
+ # Iterate through all the addresses (if multiple)
417
+ for ip in $IP_ADDRESS; do
418
+ ssh -n -o StrictHostKeyChecking=no \
419
+ -o UserKnownHostsFile=/dev/null \
420
+ $LXC_KEY $LXC_USER@$IP_ADDRESS -- "$COMMAND"
421
+ SSH_RET=$?
422
+ if [ ! 255 -eq $SSH_RET ]; then
423
+ # If ssh returns 255 then its connection failed.
424
+ # Anything else is either success (status 0) or a
425
+ # failure from whatever we ran over the SSH connection.
426
+ # In those cases we want to stop looping, so we break
427
+ # here
428
+ return $SSH_RET
429
+ fi
430
+ done
431
+ sleep 1
432
+ done
433
+
434
+ echo "could not get IP address - aborting." >&2
435
+ return 255
436
+ else
437
+ sudo lxc-wait -n $LXC_NAME -s RUNNING
438
+ echo "$LXC_NAME is running"
439
+ echo "You connect with the command:"
440
+ echo " sudo lxc-console -n $LXC_NAME"
441
+ sudo lxc-wait -n $LXC_NAME -s STOPPED
442
+ fi
443
+ }
444
+
445
+ write_custom_networking()
446
+ {
447
+ if [ $DISTRO = "EL" ] ; then
448
+ cat <<EOF > $LXC_DIR/rootfs/etc/sysconfig/network-scripts/ifcfg-eth0
449
+ DEVICE=eth0
450
+ BOOTPROTO=static
451
+ NETMASK=$CUSTOM_NETMASK
452
+ IPADDR=$CUSTOM_IPADDRESS
453
+ ONBOOT=yes
454
+ TYPE=Ethernet
455
+ USERCTL=yes
456
+ PEERDNS=yes
457
+ IPV6INIT=no
458
+ GATEWAY=$CUSTOM_GATEWAY
459
+ EOF
460
+ else
461
+ cat <<EOF > $LXC_DIR/rootfs/etc/network/interfaces
462
+ auto lo
463
+ iface lo inet loopback
464
+ auto eth0
465
+ iface eth0 inet static
466
+ address $CUSTOM_IPADDRESS
467
+ netmask $CUSTOM_NETMASK
468
+ gateway $CUSTOM_GATEWAY
469
+ EOF
470
+ fi
471
+ }
472
+
473
+ stop_container()
474
+ {
475
+ echo "Stopping lxc" >&2
476
+ sudo lxc-stop -n $LXC_NAME
477
+ sleep 2
478
+ LXC_RUNNING=0
479
+ cleanup_dirs
480
+ }
481
+
482
+ handle_container()
483
+ {
484
+ setup_container
485
+ start_container
486
+ RET=$?
487
+ stop_container
488
+ if [ $DAEMON -eq 1 ]; then
489
+ cleanup
490
+ fi
491
+ exit $RET
492
+ }
493
+
494
+ if [ $DAEMON -eq 1 ]; then
495
+ handle_container &
496
+ exit 0
497
+ fi
498
+
499
+ handle_container