pauper 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
data/lib/pauper.rb CHANGED
@@ -20,6 +20,7 @@ require 'pauper/version'
20
20
  class Pauper
21
21
  DEFAULT_PAUPERFILE = './Pauperfile'
22
22
  DEFAULT_VM_PATH = File.expand_path('/var/lib/lxc/')
23
+ SUPPORTED_RELEASES = [:lucid, :precise]
23
24
 
24
25
  def initialize(ignore_network = false, pauperfile = DEFAULT_PAUPERFILE)
25
26
  if root?
@@ -39,37 +40,69 @@ class Pauper
39
40
  @pauper_config
40
41
  end
41
42
 
42
- def bootstrap
43
- raise "Base already exists!" if vm_exists?("base")
43
+ def self.version
44
+ puts "Pauper v#{VERSION}"
45
+ end
46
+
47
+ def self.grok_release(release_s)
48
+ release = release_s.intern
49
+ raise "Unsupported release '#{release_s}'" unless SUPPORTED_RELEASES.include?(release)
50
+ release
51
+ end
52
+
53
+ def get_base_name(release)
54
+ case Pauper.grok_release(release)
55
+ when :lucid
56
+ 'base'
57
+ when :precise
58
+ 'base-precise'
59
+ else
60
+ raise "Unsupported release #{release}"
61
+ end
62
+ end
63
+
64
+ def get_base_ip(base_name)
65
+ if base_name == 'base'
66
+ return @pauper_config.config[:subnet] + '.2'
67
+ elsif base_name == 'base-precise'
68
+ return @pauper_config.config[:subnet] + '.3'
69
+ end
70
+ end
71
+
72
+ def bootstrap(release)
73
+ release = Pauper.grok_release(release)
74
+ base_name = get_base_name(release)
75
+
76
+ raise "Base '#{base_name}' already exists!" if vm_exists?(base_name)
44
77
 
45
- ip = "#{@pauper_config.config[:subnet]}.2"
46
- ssh_clean_known_hosts('base', ip)
78
+ ip = get_base_ip(base_name)
79
+ ssh_clean_known_hosts(base_name, ip)
47
80
  @pauper_config.config[:nodes].each { |n| ssh_clean_known_hosts(n.name, "#{@pauper_config.config[:subnet]}.#{n.config[:last_octet]}") }
48
81
 
49
82
  lxc_pauper_template
50
83
  system("sudo touch /var/lib/lxc/lxc.conf")
51
- system("sudo lxc-create -n base -t pauper -f /var/lib/lxc/lxc.conf -- -a amd64 --auth-key #{public_ssh_key} -r lucid")
84
+ system("sudo lxc-create -n #{base_name} -t pauper -f /var/lib/lxc/lxc.conf -- -a amd64 --auth-key #{public_ssh_key} -r #{release}")
52
85
  mac = generate_mac
53
86
 
54
- lxc = LXC.new('base')
87
+ lxc = LXC.new(base_name)
55
88
  lxc.interface = @pauper_config.config[:bridge]
56
89
  lxc.mac = mac
57
90
  lxc.save
58
91
 
59
- prepare_fstab('base')
60
- prepare_vm_network('base',ip)
61
- prepare_base_cache
92
+ prepare_fstab(base_name, release)
93
+ prepare_vm_network(base_name,ip)
94
+ prepare_base_cache(release)
62
95
 
63
96
  puts "Installing chef..."
64
- cmd "sudo chroot /var/lib/lxc/base/rootfs/ bash -c 'wget #{@pauper_config.config[:chef_download_url]}/#{@pauper_config.config[:chef_deb_name]} && dpkg -i #{@pauper_config.config[:chef_deb_name]}; rm #{@pauper_config.config[:chef_deb_name]}'"
97
+ cmd "sudo chroot /var/lib/lxc/#{base_name}/rootfs/ bash -c 'wget #{@pauper_config.config[:chef_download_url][release]}/#{@pauper_config.config[:chef_deb_name][release]} && dpkg -i #{@pauper_config.config[:chef_deb_name][release]}; rm #{@pauper_config.config[:chef_deb_name][release]}'"
65
98
 
66
- start_node('base')
99
+ start_node(base_name)
67
100
  sleep 3
68
101
 
69
- chef_node = "base#{@pauper_config.config[:node_suffix]}"
102
+ chef_node = "#{base_name}#{@pauper_config.config[:node_suffix]}"
70
103
  cmd "knife bootstrap --bootstrap-version chef-full -N #{chef_node} -E #{@pauper_config.config[:chef_environment]} -x root -r \"#{@pauper_config.config[:default_run_list].join(",")}\" #{ip}"
71
104
 
72
- stop_node('base')
105
+ stop_node(base_name)
73
106
  end
74
107
 
75
108
  def username
@@ -89,9 +122,14 @@ class Pauper
89
122
  ssh_key + ".pub"
90
123
  end
91
124
 
92
- def prepare_fstab(node_name)
125
+ def get_share_release(options)
126
+ options[:release] || :lucid
127
+ end
128
+
129
+ def prepare_fstab(node_name, release)
93
130
  File.open('.tmp.fstab','w') do |f|
94
131
  @pauper_config.config[:shares].each do |share_name, guest_path, host_path, options|
132
+ next if get_share_release(options) != release
95
133
  f.puts "#{host_path} #{DEFAULT_VM_PATH}/#{node_name}/rootfs/#{guest_path} none defaults,bind 0 0"
96
134
  end
97
135
  end
@@ -117,12 +155,15 @@ class Pauper
117
155
  system "sudo mv .tmp.resolv.conf #{DEFAULT_VM_PATH}/#{node_name}/rootfs/etc/resolv.conf"
118
156
  end
119
157
 
120
- def prepare_base_cache
121
- @pauper_config.config[:shares].each do |share_name, guest_path, host_path, options|
158
+ def prepare_base_cache(release)
159
+ base_name = get_base_name(release)
160
+ shares = @pauper_config.config[:shares]
161
+ shares.each do |share_name, guest_path, host_path, options|
162
+ next if get_share_release(options) != release
122
163
  cmd "sudo mkdir -p #{host_path}"
123
- cmd "sudo mkdir -p /var/lib/lxc/base/rootfs#{guest_path}"
164
+ cmd "sudo mkdir -p /var/lib/lxc/#{base_name}/rootfs#{guest_path}"
124
165
  end
125
- cmd "sudo mkdir -p /var/cache/lxc/lucid/cache/apt/partial"
166
+ cmd "sudo mkdir -p /var/cache/lxc/#{release}/cache/apt/partial"
126
167
  end
127
168
 
128
169
  def reconfigure_ssh(node_name)
@@ -134,8 +175,16 @@ class Pauper
134
175
 
135
176
  raise "VM already exists!" if vm_exists?(node_name)
136
177
 
137
- puts "Cloning base..."
138
- clone_base(node_name)
178
+ release = node_config.config[:release]
179
+ base_name = get_base_name(release)
180
+
181
+ unless vm_exists?(base_name)
182
+ puts "Bootstrapping base '#{base_name}' for release '#{release}'"
183
+ bootstrap(release)
184
+ end
185
+
186
+ puts "Cloning #{base_name}..."
187
+ clone_base(base_name, node_name)
139
188
  mac = generate_mac
140
189
  ip = "#{@pauper_config.config[:subnet]}.#{node_config.config[:last_octet]}"
141
190
 
@@ -144,24 +193,26 @@ class Pauper
144
193
  lxc.mac = mac
145
194
  lxc.save
146
195
 
147
- prepare_fstab(node_name)
196
+ prepare_fstab(node_name, release)
148
197
  prepare_vm_network(node_name,ip)
149
198
  reconfigure_ssh(node_name)
150
199
  puts "Starting..."
151
200
  start_node(node_name)
152
201
  sleep 3
202
+ write_hosts
153
203
  setup(node_name)
154
204
  end
155
205
 
156
206
  def setup(node_name)
157
207
  node_config = get_node_config(node_name)
208
+ release = node_config.config[:release]
158
209
  config = @pauper_config.config
159
210
  puts "Setting up #{node_name}..."
160
211
  client_erb = ERB.new <<EOF
161
212
  node_name "<%= chef_node %>"
162
213
  chef_server_url "<%= config[:chef_server_url] %>"
163
- chef_download_url "<%= config[:chef_download_url] %>"
164
- chef_deb_name "<%= config[:chef_deb_name] %>"
214
+ chef_download_url "<%= config[:chef_download_url][release] %>"
215
+ chef_deb_name "<%= config[:chef_deb_name][release] %>"
165
216
  validation_client_name "<%= config[:validation_client_name] %>"
166
217
  environment "<%= config[:chef_environment] %>"
167
218
  verbose_logging false
@@ -207,9 +258,8 @@ EOF
207
258
  end
208
259
 
209
260
  def destroy(node_name)
210
- if node_name == 'base'
211
- ip = @pauper_config.config[:subnet] + '.2'
212
- else
261
+ ip = get_base_ip(node_name)
262
+ if ip.nil?
213
263
  node_config = get_node_config(node_name)
214
264
  ip = node_ip(node_config)
215
265
  end
@@ -225,6 +275,7 @@ EOF
225
275
  puts "Destroying #{node_name}..."
226
276
  cmd "sudo lxc-destroy -n '#{node_name}' >> pauper.log 2>&1"
227
277
  ssh_clean_known_hosts(node_name, ip)
278
+ write_hosts
228
279
  else
229
280
  puts "#{node_name} hasn't even been created yet, thusly you can't destroy it!"
230
281
  end
@@ -273,7 +324,9 @@ EOF
273
324
  def write_hosts
274
325
  puts "Writing /etc/hosts file..."
275
326
  hosts = Hosts.new
327
+ hosts.config.clear
276
328
  @pauper_config.config[:nodes].each do |node|
329
+ next unless vm_exists?(node.name)
277
330
  hosts.config[node_ip(node)] = node.name
278
331
  end
279
332
  hosts.save(@pauper_config.config[:dev_domain])
@@ -474,7 +527,10 @@ EOF
474
527
 
475
528
  def cmd(*args)
476
529
  puts ["local>", *args].join(" ")
477
- system *args
530
+ ok = system *args
531
+ if not ok
532
+ raise "shell command '"+args.join(" ")+"' failed"
533
+ end
478
534
  end
479
535
 
480
536
  def ssh_clean_known_hosts(hostname, ip)
@@ -505,11 +561,11 @@ EOF
505
561
  `sudo lxc-info -n '#{node_name}'`.include?("FROZEN")
506
562
  end
507
563
 
508
- def clone_base(node_name)
509
- cmd "sudo cp -ax #{DEFAULT_VM_PATH}/base #{DEFAULT_VM_PATH}/#{node_name}"
510
- cmd "sudo rm #{DEFAULT_VM_PATH}/#{node_name}/rootfs/etc/chef/client.pem"
511
- cmd "sudo rm #{DEFAULT_VM_PATH}/#{node_name}/rootfs/etc/ssh/ssh*key*"
512
- cmd "sudo sed -i \"s/base/#{node_name}/g\" /var/lib/lxc/#{node_name}/rootfs/etc/hostname /var/lib/lxc/#{node_name}/rootfs/etc/chef/client.rb"
564
+ def clone_base(base_name, node_name)
565
+ cmd "sudo cp -ax #{DEFAULT_VM_PATH}/#{base_name} #{DEFAULT_VM_PATH}/#{node_name}"
566
+ cmd "sudo rm -f #{DEFAULT_VM_PATH}/#{node_name}/rootfs/etc/chef/client.pem"
567
+ cmd "sudo rm -f #{DEFAULT_VM_PATH}/#{node_name}/rootfs/etc/ssh/ssh*key*"
568
+ cmd "sudo sed -i \"s/#{base_name}/#{node_name}/g\" /var/lib/lxc/#{node_name}/rootfs/etc/hostname /var/lib/lxc/#{node_name}/rootfs/etc/chef/client.rb"
513
569
  end
514
570
 
515
571
  def vm_config(node_name)
@@ -553,637 +609,15 @@ EOF
553
609
  File.dirname(@pauper_config.config[:vmx])
554
610
  end
555
611
 
556
- def lxc_pauper_template
557
- @template = <<TEMPLATE
558
- #!/bin/bash
559
-
560
- #
561
- # template script for generating ubuntu container for LXC
562
- #
563
- # This script consolidates and extends the existing lxc ubuntu scripts
564
- #
565
-
566
- # Copyright � 2011 Serge Hallyn <serge.hallyn@canonical.com>
567
- # Copyright � 2010 Wilhelm Meier
568
- # Author: Wilhelm Meier <wilhelm.meier@fh-kl.de>
569
- #
570
- # This program is free software; you can redistribute it and/or modify
571
- # it under the terms of the GNU General Public License version 2, as
572
- # published by the Free Software Foundation.
573
-
574
- # This program is distributed in the hope that it will be useful,
575
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
576
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
577
- # GNU General Public License for more details.
578
-
579
- # You should have received a copy of the GNU General Public License along
580
- # with this program; if not, write to the Free Software Foundation, Inc.,
581
- # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
582
- #
583
-
584
- set -e
585
-
586
- if [ -r /etc/default/lxc ]; then
587
- . /etc/default/lxc
588
- fi
589
-
590
- configure_ubuntu()
591
- {
592
- rootfs=$1
593
- hostname=$2
594
- release=$3
595
-
596
- # configure the network using the dhcp
597
- cat <<EOF > $rootfs/etc/network/interfaces
598
- # This file describes the network interfaces available on your system
599
- # and how to activate them. For more information, see interfaces(5).
600
-
601
- # The loopback network interface
602
- auto lo
603
- iface lo inet loopback
604
-
605
- auto eth0
606
- iface eth0 inet dhcp
607
- EOF
608
-
609
- # set the hostname
610
- cat <<EOF > $rootfs/etc/hostname
611
- $hostname
612
- EOF
613
- # set minimal hosts
614
- cat <<EOF > $rootfs/etc/hosts
615
- 127.0.0.1 localhost
616
- 127.0.1.1 $hostname
617
-
618
- # The following lines are desirable for IPv6 capable hosts
619
- ::1 ip6-localhost ip6-loopback
620
- fe00::0 ip6-localnet
621
- ff00::0 ip6-mcastprefix
622
- ff02::1 ip6-allnodes
623
- ff02::2 ip6-allrouters
624
- EOF
625
-
626
- if [ ! -f $rootfs/etc/init/container-detect.conf ]; then
627
- # suppress log level output for udev
628
- sed -i "s/=\"err\"/=0/" $rootfs/etc/udev/udev.conf
629
-
630
- # remove jobs for consoles 5 and 6 since we only create 4 consoles in
631
- # this template
632
- rm -f $rootfs/etc/init/tty{5,6}.conf
633
- fi
634
-
635
- return 0
636
- }
637
-
638
- # finish setting up the user in the container by injecting ssh key
639
- finalize_user()
640
- {
641
- if [ -n "$auth_key" -a -f "$auth_key" ]; then
642
- u_path="/root/.ssh"
643
- root_u_path="$rootfs/$u_path"
644
-
645
- mkdir -p $root_u_path
646
- cp $auth_key "$root_u_path/authorized_keys"
647
- chroot $rootfs chown -R root: "$u_path"
648
-
649
- echo "Inserted SSH public key from $auth_key into /root/.ssh/authorized_keys"
650
- fi
651
- return 0
652
- }
653
-
654
- write_sourceslist()
655
- {
656
- # $1 => path to the rootfs
657
- # $2 => architecture we want to add
658
- # $3 => whether to use the multi-arch syntax or not
659
-
660
- case $2 in
661
- amd64|i386)
662
- MIRROR=${MIRROR:-http://mirrors.fastly.net/ubuntu}
663
- SECURITY_MIRROR=${SECURITY_MIRROR:-http://mirrors.fastly.net/ubuntu}
664
- ;;
665
- *)
666
- MIRROR=${MIRROR:-http://ports.ubuntu.com/ubuntu-ports}
667
- SECURITY_MIRROR=${SECURITY_MIRROR:-http://ports.ubuntu.com/ubuntu-ports}
668
- ;;
669
- esac
670
- if [ -n "$3" ]; then
671
- cat >> "$1/etc/apt/sources.list" << EOF
672
- deb [arch=$2] $MIRROR ${release} main restricted universe multiverse
673
- deb [arch=$2] $MIRROR ${release}-updates main restricted universe multiverse
674
- deb [arch=$2] $SECURITY_MIRROR ${release}-security main restricted universe multiverse
675
- EOF
676
- else
677
- cat >> "$1/etc/apt/sources.list" << EOF
678
- deb $MIRROR ${release} main restricted universe multiverse
679
- deb $MIRROR ${release}-updates main restricted universe multiverse
680
- deb $SECURITY_MIRROR ${release}-security main restricted universe multiverse
681
- EOF
682
- fi
683
- }
684
-
685
- cleanup()
686
- {
687
- rm -rf $cache/partial-$arch
688
- rm -rf $cache/rootfs-$arch
689
- }
690
-
691
- download_ubuntu()
692
- {
693
- cache=$1
694
- arch=$2
695
- release=$3
696
-
697
- packages=vim,ssh,curl,wget
698
- echo "installing packages: $packages"
699
-
700
- trap cleanup EXIT SIGHUP SIGINT SIGTERM
701
- # check the mini ubuntu was not already downloaded
702
- mkdir -p "$cache/partial-$arch"
703
- if [ $? -ne 0 ]; then
704
- echo "Failed to create '$cache/partial-$arch' directory"
705
- return 1
706
- fi
707
-
708
- # download a mini ubuntu into a cache
709
- echo "Downloading ubuntu $release minimal ..."
710
- if [ -n "$(which qemu-debootstrap)" ]; then
711
- qemu-debootstrap --verbose --components=main,universe --arch=$arch --include=$packages $release $cache/partial-$arch $MIRROR
712
- else
713
- debootstrap --verbose --components=main,universe --arch=$arch --include=$packages $release $cache/partial-$arch $MIRROR
714
- fi
715
-
716
- if [ $? -ne 0 ]; then
717
- echo "Failed to download the rootfs, aborting."
718
- return 1
719
- fi
720
-
721
- # Serge isn't sure whether we should avoid doing this when
722
- # $release == `distro-info -d`
723
- echo "Installing updates"
724
- > $cache/partial-$arch/etc/apt/sources.list
725
- write_sourceslist $cache/partial-$arch/ $arch
726
-
727
- chroot "$1/partial-${arch}" apt-get update
728
- if [ $? -ne 0 ]; then
729
- echo "Failed to update the apt cache"
730
- return 1
731
- fi
732
- cat > "$1/partial-${arch}"/usr/sbin/policy-rc.d << EOF
733
- #!/bin/sh
734
- exit 101
735
- EOF
736
- chmod +x "$1/partial-${arch}"/usr/sbin/policy-rc.d
737
-
738
- lxc-unshare -s MOUNT -- chroot "$1/partial-${arch}" apt-get dist-upgrade -y
739
- ret=$?
740
- rm -f "$1/partial-${arch}"/usr/sbin/policy-rc.d
741
-
742
- if [ $ret -ne 0 ]; then
743
- echo "Failed to upgrade the cache"
744
- return 1
745
- fi
746
-
747
- mv "$1/partial-$arch" "$1/rootfs-$arch"
748
- trap EXIT
749
- trap SIGINT
750
- trap SIGTERM
751
- trap SIGHUP
752
- echo "Download complete"
753
- return 0
754
- }
755
-
756
- copy_ubuntu()
757
- {
758
- cache=$1
759
- arch=$2
760
- rootfs=$3
761
-
762
- # make a local copy of the miniubuntu
763
- echo "Copying rootfs to $rootfs ..."
764
- mkdir -p $rootfs
765
- rsync -a $cache/rootfs-$arch/ $rootfs/ || return 1
766
- return 0
767
- }
768
-
769
- install_ubuntu()
770
- {
771
- rootfs=$1
772
- release=$2
773
- flushcache=$3
774
- cache="/var/cache/lxc/$release"
775
- mkdir -p /var/lock/subsys/
776
-
777
- (
778
- flock -x 200
779
- if [ $? -ne 0 ]; then
780
- echo "Cache repository is busy."
781
- return 1
782
- fi
783
-
784
-
785
- if [ $flushcache -eq 1 ]; then
786
- echo "Flushing cache..."
787
- rm -rf "$cache/partial-$arch"
788
- rm -rf "$cache/rootfs-$arch"
789
- fi
790
-
791
- echo "Checking cache download in $cache/rootfs-$arch ... "
792
- if [ ! -e "$cache/rootfs-$arch" ]; then
793
- download_ubuntu $cache $arch $release
794
- if [ $? -ne 0 ]; then
795
- echo "Failed to download 'ubuntu $release base'"
796
- return 1
797
- fi
798
- fi
799
-
800
- echo "Copy $cache/rootfs-$arch to $rootfs ... "
801
- copy_ubuntu $cache $arch $rootfs
802
- if [ $? -ne 0 ]; then
803
- echo "Failed to copy rootfs"
804
- return 1
805
- fi
806
-
807
- return 0
808
-
809
- ) 200>/var/lock/subsys/lxc
810
-
811
- return $?
812
- }
813
-
814
- copy_configuration()
815
- {
816
- path=$1
817
- rootfs=$2
818
- name=$3
819
- arch=$4
820
- release=$5
821
-
822
- if [ $arch = "i386" ]; then
823
- arch="i686"
824
- fi
825
-
826
- ttydir=""
827
- if [ -f $rootfs/etc/init/container-detect.conf ]; then
828
- ttydir=" lxc"
829
- fi
830
-
831
- # if there is exactly one veth network entry, make sure it has an
832
- # associated hwaddr.
833
- nics=`grep -e '^lxc\.network\.type[ \t]*=[ \t]*veth' $path/config | wc -l`
834
- if [ $nics -eq 1 ]; then
835
- grep -q "^lxc.network.hwaddr" $path/config || cat <<EOF >> $path/config
836
- lxc.network.hwaddr = 00:16:3e:$(openssl rand -hex 3| sed 's/\(..\)/\1:/g; s/.$//')
837
- EOF
838
- fi
839
-
840
- cat <<EOF >> $path/config
841
- lxc.utsname = $name
842
-
843
- lxc.devttydir =$ttydir
844
- lxc.tty = 4
845
- lxc.pts = 1024
846
- lxc.rootfs = $rootfs
847
- lxc.mount = $path/fstab
848
- lxc.arch = $arch
849
- lxc.cap.drop = sys_module mac_admin
850
- lxc.pivotdir = lxc_putold
851
-
852
- # uncomment the next line to run the container unconfined:
853
- #lxc.aa_profile = unconfined
854
-
855
- lxc.cgroup.devices.deny = a
856
- # Allow any mknod (but not using the node)
857
- lxc.cgroup.devices.allow = c *:* m
858
- lxc.cgroup.devices.allow = b *:* m
859
- # /dev/null and zero
860
- lxc.cgroup.devices.allow = c 1:3 rwm
861
- lxc.cgroup.devices.allow = c 1:5 rwm
862
- # consoles
863
- lxc.cgroup.devices.allow = c 5:1 rwm
864
- lxc.cgroup.devices.allow = c 5:0 rwm
865
- #lxc.cgroup.devices.allow = c 4:0 rwm
866
- #lxc.cgroup.devices.allow = c 4:1 rwm
867
- # /dev/{,u}random
868
- lxc.cgroup.devices.allow = c 1:9 rwm
869
- lxc.cgroup.devices.allow = c 1:8 rwm
870
- lxc.cgroup.devices.allow = c 136:* rwm
871
- lxc.cgroup.devices.allow = c 5:2 rwm
872
- # rtc
873
- lxc.cgroup.devices.allow = c 254:0 rwm
874
- #fuse
875
- lxc.cgroup.devices.allow = c 10:229 rwm
876
- #tun
877
- lxc.cgroup.devices.allow = c 10:200 rwm
878
- #full
879
- lxc.cgroup.devices.allow = c 1:7 rwm
880
- #hpet
881
- lxc.cgroup.devices.allow = c 10:228 rwm
882
- #kvm
883
- lxc.cgroup.devices.allow = c 10:232 rwm
884
- EOF
885
-
886
- cat <<EOF > $path/fstab
887
- proc proc proc nodev,noexec,nosuid 0 0
888
- sysfs sys sysfs defaults 0 0
889
- EOF
890
-
891
- if [ $? -ne 0 ]; then
892
- echo "Failed to add configuration"
893
- return 1
894
- fi
895
-
896
- return 0
897
- }
898
-
899
- trim()
900
- {
901
- rootfs=$1
902
- release=$2
903
-
904
- # provide the lxc service
905
- cat <<EOF > $rootfs/etc/init/lxc.conf
906
- # fake some events needed for correct startup other services
907
-
908
- description "Container Upstart"
909
-
910
- start on startup
911
-
912
- script
913
- rm -rf /var/run/*.pid
914
- rm -rf /var/run/network/*
915
- /sbin/initctl emit stopped JOB=udevtrigger --no-wait
916
- /sbin/initctl emit started JOB=udev --no-wait
917
- end script
918
- EOF
919
-
920
- # fix buggus runlevel with sshd
921
- cat <<EOF > $rootfs/etc/init/ssh.conf
922
- # ssh - OpenBSD Secure Shell server
923
- #
924
- # The OpenSSH server provides secure shell access to the system.
925
-
926
- description "OpenSSH server"
927
-
928
- start on filesystem
929
- stop on runlevel [!2345]
930
-
931
- expect fork
932
- respawn
933
- respawn limit 10 5
934
- umask 022
935
- # replaces SSHD_OOM_ADJUST in /etc/default/ssh
936
- oom never
937
-
938
- pre-start script
939
- test -x /usr/sbin/sshd || { stop; exit 0; }
940
- test -e /etc/ssh/sshd_not_to_be_run && { stop; exit 0; }
941
- test -c /dev/null || { stop; exit 0; }
942
-
943
- mkdir -p -m0755 /var/run/sshd
944
- end script
945
-
946
- # if you used to set SSHD_OPTS in /etc/default/ssh, you can change the
947
- # 'exec' line here instead
948
- exec /usr/sbin/sshd
949
- EOF
950
-
951
- cat <<EOF > $rootfs/etc/init/console.conf
952
- # console - getty
953
- #
954
- # This service maintains a console on tty1 from the point the system is
955
- # started until it is shut down again.
956
-
957
- start on stopped rc RUNLEVEL=[2345]
958
- stop on runlevel [!2345]
959
-
960
- respawn
961
- exec /sbin/getty -8 38400 /dev/console
962
- EOF
963
-
964
- cat <<EOF > $rootfs/lib/init/fstab
965
- # /lib/init/fstab: cleared out for bare-bones lxc
966
- EOF
967
-
968
- # reconfigure some services
969
- if [ -z "$LANG" ]; then
970
- chroot $rootfs locale-gen en_US.UTF-8
971
- chroot $rootfs update-locale LANG=en_US.UTF-8
972
- else
973
- chroot $rootfs locale-gen $LANG
974
- chroot $rootfs update-locale LANG=$LANG
975
- fi
976
-
977
- # remove pointless services in a container
978
- chroot $rootfs /usr/sbin/update-rc.d -f ondemand remove
979
-
980
- chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls u*.conf); do mv $f $f.orig; done'
981
- chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls tty[2-9].conf); do mv $f $f.orig; done'
982
- chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls plymouth*.conf); do mv $f $f.orig; done'
983
- chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls hwclock*.conf); do mv $f $f.orig; done'
984
- chroot $rootfs /bin/bash -c 'cd /etc/init; for f in $(ls module*.conf); do mv $f $f.orig; done'
985
-
986
- # if this isn't lucid, then we need to twiddle the network upstart bits :(
987
- if [ $release != "lucid" ]; then
988
- sed -i 's/^.*emission handled.*$/echo Emitting lo/' $rootfs/etc/network/if-up.d/upstart
989
- fi
990
- }
991
-
992
- post_process()
993
- {
994
- rootfs=$1
995
- release=$2
996
- trim_container=$3
997
-
998
- if [ $trim_container -eq 1 ]; then
999
- trim $rootfs $release
1000
- elif [ ! -f $rootfs/etc/init/container-detect.conf ]; then
1001
- # Make sure we have a working resolv.conf
1002
- cresolvonf="${rootfs}/etc/resolv.conf"
1003
- mv $cresolvonf ${cresolvonf}.lxcbak
1004
- cat /etc/resolv.conf > ${cresolvonf}
1005
-
1006
- # for lucid, if not trimming, then add the ubuntu-virt
1007
- # ppa and install lxcguest
1008
- if [ $release = "lucid" ]; then
1009
- chroot $rootfs apt-get install --force-yes -y python-software-properties
1010
- chroot $rootfs add-apt-repository ppa:ubuntu-virt/ppa
1011
- fi
1012
-
1013
- chroot $rootfs apt-get update
1014
- chroot $rootfs apt-get install --force-yes -y lxcguest
1015
-
1016
- # Restore old resolv.conf
1017
- rm -f ${cresolvonf}
1018
- mv ${cresolvonf}.lxcbak ${cresolvonf}
1019
- fi
1020
-
1021
- # If the container isn't running a native architecture, setup multiarch
1022
- if [ -x "$(ls -1 ${rootfs}/usr/bin/qemu-*-static 2>/dev/null)" ]; then
1023
- dpkg_version=$(chroot $rootfs dpkg-query -W -f='${Version}' dpkg)
1024
- if chroot $rootfs dpkg --compare-versions $dpkg_version ge "1.16.2"; then
1025
- chroot $rootfs dpkg --add-architecture ${hostarch}
1026
- else
1027
- mkdir -p ${rootfs}/etc/dpkg/dpkg.cfg.d
1028
- echo "foreign-architecture ${hostarch}" > ${rootfs}/etc/dpkg/dpkg.cfg.d/lxc-multiarch
1029
- fi
1030
-
1031
- # Save existing value of MIRROR and SECURITY_MIRROR
1032
- DEFAULT_MIRROR=$MIRROR
1033
- DEFAULT_SECURITY_MIRROR=$SECURITY_MIRROR
1034
-
1035
- # Write a new sources.list containing both native and multiarch entries
1036
- > ${rootfs}/etc/apt/sources.list
1037
- write_sourceslist $rootfs $arch "native"
1038
-
1039
- MIRROR=$DEFAULT_MIRROR
1040
- SECURITY_MIRROR=$DEFAULT_SECURITY_MIRROR
1041
- write_sourceslist $rootfs $hostarch "multiarch"
1042
-
1043
- # Finally update the lists and install upstart using the host architecture
1044
- chroot $rootfs apt-get update
1045
- chroot $rootfs apt-get install --force-yes -y --no-install-recommends upstart:${hostarch} mountall:${hostarch} iproute:${hostarch} isc-dhcp-client:${hostarch}
1046
- fi
1047
-
1048
- # rmdir /dev/shm for containers that have /run/shm
1049
- # I'm afraid of doing rm -rf $rootfs/dev/shm, in case it did
1050
- # get bind mounted to the host's /run/shm. So try to rmdir
1051
- # it, and in case that fails move it out of the way.
1052
- if [ ! -L $rootfs/dev/shm ] && [ -d $rootfs/run/shm ] && [ -e $rootfs/dev/shm ]; then
1053
- mv $rootfs/dev/shm $rootfs/dev/shm.bak
1054
- ln -s /run/shm $rootfs/dev/shm
1055
- fi
1056
- }
1057
-
1058
- usage()
1059
- {
1060
- cat <<EOF
1061
- $1 -h|--help [-a|--arch] [--trim] [-d|--debug]
1062
- [-F | --flush-cache] [-r|--release <release>] [ -S | --auth-key <keyfile>]
1063
- release: the ubuntu release (e.g. precise): defaults to host release on ubuntu, otherwise uses latest LTS
1064
- trim: make a minimal (faster, but not upgrade-safe) container
1065
- arch: the container architecture (e.g. amd64): defaults to host arch
1066
- auth-key: SSH Public key file to inject into container
1067
- EOF
1068
- return 0
1069
- }
1070
-
1071
- options=$(getopt -o a:b:hp:r:xn:FS:d -l arch:,help,path:,release:,trim,name:,flush-cache,auth-key:,debug -- "$@")
1072
- if [ $? -ne 0 ]; then
1073
- usage $(basename $0)
1074
- exit 1
1075
- fi
1076
- eval set -- "$options"
1077
-
1078
- release=precise # Default to the last Ubuntu LTS release for non-Ubuntu systems
1079
- if [ -f /etc/lsb-release ]; then
1080
- . /etc/lsb-release
1081
- if [ "$DISTRIB_ID" = "Ubuntu" ]; then
1082
- release=$DISTRIB_CODENAME
1083
- fi
1084
- fi
1085
-
1086
- bindhome=
1087
- arch=$(arch)
1088
-
1089
- # Code taken from debootstrap
1090
- if [ -x /usr/bin/dpkg ] && /usr/bin/dpkg --print-architecture >/dev/null 2>&1; then
1091
- arch=`/usr/bin/dpkg --print-architecture`
1092
- elif type udpkg >/dev/null 2>&1 && udpkg --print-architecture >/dev/null 2>&1; then
1093
- arch=`/usr/bin/udpkg --print-architecture`
1094
- else
1095
- arch=$(arch)
1096
- if [ "$arch" = "i686" ]; then
1097
- arch="i386"
1098
- elif [ "$arch" = "x86_64" ]; then
1099
- arch="amd64"
1100
- elif [ "$arch" = "armv7l" ]; then
1101
- arch="armel"
1102
- fi
1103
- fi
1104
-
1105
- debug=0
1106
- trim_container=0
1107
- hostarch=$arch
1108
- flushcache=0
1109
- while true
1110
- do
1111
- case "$1" in
1112
- -h|--help) usage $0 && exit 0;;
1113
- -p|--path) path=$2; shift 2;;
1114
- -n|--name) name=$2; shift 2;;
1115
- -F|--flush-cache) flushcache=1; shift 1;;
1116
- -r|--release) release=$2; shift 2;;
1117
- -a|--arch) arch=$2; shift 2;;
1118
- -x|--trim) trim_container=1; shift 1;;
1119
- -S|--auth-key) auth_key=$2; shift 2;;
1120
- -d|--debug) debug=1; shift 1;;
1121
- --) shift 1; break ;;
1122
- *) break ;;
1123
- esac
1124
- done
1125
-
1126
- if [ $debug -eq 1 ]; then
1127
- set -x
1128
- fi
1129
-
1130
- if [ "$arch" == "i686" ]; then
1131
- arch=i386
1132
- fi
1133
-
1134
- if [ $hostarch = "i386" -a $arch = "amd64" ]; then
1135
- echo "can't create amd64 container on i386"
1136
- exit 1
1137
- fi
1138
-
1139
- type debootstrap
1140
- if [ $? -ne 0 ]; then
1141
- echo "'debootstrap' command is missing"
1142
- exit 1
1143
- fi
1144
-
1145
- if [ -z "$path" ]; then
1146
- echo "'path' parameter is required"
1147
- exit 1
1148
- fi
1149
-
1150
- if [ "$(id -u)" != "0" ]; then
1151
- echo "This script should be run as 'root'"
1152
- exit 1
1153
- fi
1154
-
1155
- rootfs=$path/rootfs
1156
-
1157
- install_ubuntu $rootfs $release $flushcache
1158
- if [ $? -ne 0 ]; then
1159
- echo "failed to install ubuntu $release"
1160
- exit 1
1161
- fi
1162
-
1163
- configure_ubuntu $rootfs $name $release
1164
- if [ $? -ne 0 ]; then
1165
- echo "failed to configure ubuntu $release for a container"
1166
- exit 1
1167
- fi
1168
-
1169
- copy_configuration $path $rootfs $name $arch $release
1170
- if [ $? -ne 0 ]; then
1171
- echo "failed write configuration file"
1172
- exit 1
1173
- fi
1174
-
1175
- post_process $rootfs $release $trim_container
1176
-
1177
- finalize_user
1178
-
1179
- TEMPLATE
1180
- File.open(".tmp.lxc-pauper.conf",'w') do |f|
1181
- f.puts @template
612
+ def lxc_pauper_template
613
+ require 'lxc_template'
614
+ File.open(".tmp.lxc-pauper.conf",'w') do |f|
615
+ f.puts Template.lxc
616
+ end
617
+ tmpl_dir = File.exist?('/usr/lib/lxc/templates') ? '/usr/lib/lxc/templates' : '/usr/share/lxc/templates'
618
+ system "sudo mv .tmp.lxc-pauper.conf #{tmpl_dir}/lxc-pauper"
619
+ system "sudo chmod +x #{tmpl_dir}/lxc-pauper"
1182
620
  end
1183
- tmpl_dir = File.exist?('/usr/lib/lxc/templates') ? '/usr/lib/lxc/templates' : '/usr/share/lxc/templates'
1184
- system "sudo mv .tmp.lxc-pauper.conf #{tmpl_dir}/lxc-pauper"
1185
- system "sudo chmod +x #{tmpl_dir}/lxc-pauper"
1186
- end
1187
621
 
1188
622
  class Config
1189
623
  attr_reader :config
@@ -1197,7 +631,15 @@ end
1197
631
  :shares => [],
1198
632
  :subnet => '172.16.254',
1199
633
  :chef_options => {},
1200
- :dev_domain => nil
634
+ :dev_domain => nil,
635
+ :chef_download_url => {
636
+ :lucid => 'https://opscode-omnibus-packages.s3.amazonaws.com/ubuntu/10.04/x86_64',
637
+ :precise => 'https://opscode-omnibus-packages.s3.amazonaws.com/ubuntu/12.04/x86_64',
638
+ },
639
+ :chef_deb_name => {
640
+ :lucid => 'chef_11.0.0-1.ubuntu.10.04_amd64.deb',
641
+ :precise => 'chef_11.10.4-1.ubuntu.12.04_amd64.deb',
642
+ },
1201
643
  }
1202
644
  if File.exists? pauperfile
1203
645
  pauperpath = File.dirname(pauperfile)
@@ -1251,12 +693,12 @@ end
1251
693
  @config[:chef_server_url] = url
1252
694
  end
1253
695
 
1254
- def chef_download_url(url)
1255
- @config[:chef_download_url] = url
696
+ def chef_download_url(url, release='lucid')
697
+ @config[:chef_download_url][Pauper.grok_release(release)] = url
1256
698
  end
1257
699
 
1258
- def chef_deb_name(name)
1259
- @config[:chef_deb_name] = name
700
+ def chef_deb_name(name, release='lucid')
701
+ @config[:chef_deb_name][Pauper.grok_release(release)] = name
1260
702
  end
1261
703
 
1262
704
  def validation_key_path(path)
@@ -1295,7 +737,8 @@ end
1295
737
  @pretty_name = pretty_name
1296
738
  @config = {
1297
739
  :run_list => [],
1298
- :chef_options => {}
740
+ :chef_options => {},
741
+ :release => :lucid,
1299
742
  }
1300
743
  instance_eval &block
1301
744
  end
@@ -1323,6 +766,10 @@ end
1323
766
  def cpus(count)
1324
767
  @config[:cpus] = count
1325
768
  end
769
+
770
+ def release(release_s)
771
+ @config[:release] = Pauper.grok_release(release_s)
772
+ end
1326
773
  end
1327
774
  end
1328
775
  end