Package VMBuilder :: Package plugins :: Package ubuntu :: Module distro
[frames] | no frames]

Source Code for Module VMBuilder.plugins.ubuntu.distro

  1  # 
  2  #    Uncomplicated VM Builder 
  3  #    Copyright (C) 2007-2009 Canonical Ltd. 
  4  #     
  5  #    See AUTHORS for list of contributors 
  6  # 
  7  #    This program is free software: you can redistribute it and/or modify 
  8  #    it under the terms of the GNU General Public License version 3, as 
  9  #    published by the Free Software Foundation. 
 10  # 
 11  #    This program is distributed in the hope that it will be useful, 
 12  #    but WITHOUT ANY WARRANTY; without even the implied warranty of 
 13  #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 14  #    GNU General Public License for more details. 
 15  # 
 16  #    You should have received a copy of the GNU General Public License 
 17  #    along with this program.  If not, see <http://www.gnu.org/licenses/>. 
 18  # 
 19  import logging 
 20  import os 
 21  import socket 
 22  import types 
 23  import shutil 
 24  import VMBuilder 
 25  from   VMBuilder           import register_distro, Distro 
 26  from   VMBuilder.util      import run_cmd 
 27  from   VMBuilder.exception import VMBuilderUserError, VMBuilderException 
 28   
29 -class Ubuntu(Distro):
30 name = 'Ubuntu' 31 arg = 'ubuntu' 32 suites = ['dapper', 'gutsy', 'hardy', 'intrepid', 'jaunty', 'karmic'] 33 34 # Maps host arch to valid guest archs 35 valid_archs = { 'amd64' : ['amd64', 'i386', 'lpia' ], 36 'i386' : [ 'i386', 'lpia' ], 37 'lpia' : [ 'i386', 'lpia' ] } 38 39 xen_kernel = '' 40
41 - def register_options(self):
42 group = self.vm.setting_group('Package options') 43 group.add_option('--addpkg', action='append', metavar='PKG', help='Install PKG into the guest (can be specfied multiple times).') 44 group.add_option('--removepkg', action='append', metavar='PKG', help='Remove PKG from the guest (can be specfied multiple times)') 45 self.vm.register_setting_group(group) 46 47 group = self.vm.setting_group('General OS options') 48 self.host_arch = run_cmd('dpkg', '--print-architecture').rstrip() 49 group.add_option('-a', '--arch', default=self.host_arch, help='Specify the target architecture. Valid options: amd64 i386 lpia (defaults to host arch)') 50 group.add_option('--hostname', default='ubuntu', help='Set NAME as the hostname of the guest. Default: ubuntu. Also uses this name as the VM name.') 51 self.vm.register_setting_group(group) 52 53 group = self.vm.setting_group('Installation options') 54 group.add_option('--suite', default='jaunty', help='Suite to install. Valid options: %s [default: %%default]' % ' '.join(self.suites)) 55 group.add_option('--flavour', '--kernel-flavour', help='Kernel flavour to use. Default and valid options depend on architecture and suite') 56 group.add_option('--variant', metavar='VARIANT', help='Passed to debootstrap --variant flag; use minbase, buildd, or fakechroot.') 57 group.add_option('--iso', metavar='PATH', help='Use an iso image as the source for installation of file. Full path to the iso must be provided. If --mirror is also provided, it will be used in the final sources.list of the vm. This requires suite and kernel parameter to match what is available on the iso, obviously.') 58 group.add_option('--mirror', metavar='URL', help='Use Ubuntu mirror at URL instead of the default, which is http://archive.ubuntu.com/ubuntu for official arches and http://ports.ubuntu.com/ubuntu-ports otherwise') 59 group.add_option('--proxy', metavar='URL', help='Use proxy at URL for cached packages') 60 group.add_option('--install-mirror', metavar='URL', help='Use Ubuntu mirror at URL for the installation only. Apt\'s sources.list will still use default or URL set by --mirror') 61 group.add_option('--security-mirror', metavar='URL', help='Use Ubuntu security mirror at URL instead of the default, which is http://security.ubuntu.com/ubuntu for official arches and http://ports.ubuntu.com/ubuntu-ports otherwise.') 62 group.add_option('--install-security-mirror', metavar='URL', help='Use the security mirror at URL for installation only. Apt\'s sources.list will still use default or URL set by --security-mirror') 63 group.add_option('--components', metavar='COMPS', help='A comma seperated list of distro components to include (e.g. main,universe).') 64 group.add_option('--ppa', metavar='PPA', action='append', help='Add ppa belonging to PPA to the vm\'s sources.list.') 65 group.add_option('--lang', metavar='LANG', default=self.get_locale(), help='Set the locale to LANG [default: %default]') 66 group.add_option('--timezone', metavar='TZ', default='UTC', help='Set the timezone to TZ in the vm. [default: %default]') 67 self.vm.register_setting_group(group) 68 69 group = self.vm.setting_group('Settings for the initial user') 70 group.add_option('--user', default='ubuntu', help='Username of initial user [default: %default]') 71 group.add_option('--name', default='Ubuntu', help='Full name of initial user [default: %default]') 72 group.add_option('--pass', default='ubuntu', help='Password of initial user [default: %default]') 73 group.add_option('--rootpass', help='Initial root password (WARNING: this has strong security implications).') 74 group.add_option('--uid', help='Initial UID value.') 75 group.add_option('--gid', help='Initial GID value.') 76 group.add_option('--lock-user', action='store_true', help='Lock the initial user [default %default]') 77 self.vm.register_setting_group(group) 78 79 group = self.vm.setting_group('Other options') 80 group.add_option('--ssh-key', metavar='PATH', help='Add PATH to root\'s ~/.ssh/authorized_keys (WARNING: this has strong security implications).') 81 group.add_option('--ssh-user-key', help='Add PATH to the user\'s ~/.ssh/authorized_keys.') 82 group.add_option('--manifest', metavar='PATH', help='If passed, a manifest will be written to PATH') 83 self.vm.register_setting_group(group)
84
85 - def set_defaults(self):
86 if not self.vm.mirror: 87 if self.vm.arch == 'lpia': 88 self.vm.mirror = 'http://ports.ubuntu.com/ubuntu-ports' 89 else: 90 self.vm.mirror = 'http://archive.ubuntu.com/ubuntu' 91 92 if not self.vm.security_mirror: 93 if self.vm.arch == 'lpia': 94 self.vm.security_mirror = 'http://ports.ubuntu.com/ubuntu-ports' 95 else: 96 self.vm.security_mirror = 'http://security.ubuntu.com/ubuntu' 97 98 if not self.vm.components: 99 self.vm.components = ['main', 'restricted', 'universe'] 100 else: 101 self.vm.components = self.vm.components.split(',')
102
103 - def get_locale(self):
104 return os.getenv('LANG')
105
106 - def preflight_check(self):
107 """While not all of these are strictly checks, their failure would inevitably 108 lead to failure, and since we can check them before we start setting up disk 109 and whatnot, we might as well go ahead an do this now.""" 110 111 if not self.vm.suite in self.suites: 112 raise VMBuilderUserError('Invalid suite. Valid suites are: %s' % ' '.join(self.suites)) 113 114 modname = 'VMBuilder.plugins.ubuntu.%s' % (self.vm.suite, ) 115 mod = __import__(modname, fromlist=[self.vm.suite]) 116 self.suite = getattr(mod, self.vm.suite.capitalize())(self.vm) 117 118 if self.vm.arch not in self.valid_archs[self.host_arch] or \ 119 not self.suite.check_arch_validity(self.vm.arch): 120 raise VMBuilderUserError('%s is not a valid architecture. Valid architectures are: %s' % (self.vm.arch, 121 ' '.join(self.valid_archs[self.host_arch]))) 122 123 if not self.vm.components: 124 self.vm.components = ['main', 'restricted', 'universe'] 125 else: 126 if type(self.vm.components) is str: 127 self.vm.components = self.vm.components.split(',') 128 129 if self.vm.hypervisor.name == 'Xen': 130 logging.info('Xen kernel default: linux-image-%s %s', self.suite.xen_kernel_flavour, self.xen_kernel_version()) 131 132 self.vm.virtio_net = self.use_virtio_net() 133 134 if self.vm.lang: 135 try: 136 run_cmd('locale-gen', '%s' % self.vm.lang) 137 except VMBuilderException, e: 138 msg = "locale-gen does not recognize your locale '%s'" % self.vm.lang 139 raise VMBuilderUserError(msg) 140 141 if getattr(self.vm, 'ec2', False): 142 self.get_ec2_kernel() 143 self.get_ec2_ramdisk() 144 self.apply_ec2_settings()
145
146 - def install(self, destdir):
147 self.destdir = destdir 148 self.suite.install(destdir)
149
150 - def install_vmbuilder_log(self, logfile, rootdir):
151 self.suite.install_vmbuilder_log(logfile, rootdir)
152
153 - def post_mount(self, fs):
154 self.suite.post_mount(fs)
155
156 - def use_virtio_net(self):
157 return self.suite.virtio_net
158
160 self.vm.cancel_cleanup(self.install_bootloader_cleanup) 161 tmpdir = '%s/tmp/vmbuilder-grub' % self.destdir 162 for disk in os.listdir(tmpdir): 163 if disk != 'device.map': 164 run_cmd('umount', os.path.join(tmpdir, disk)) 165 shutil.rmtree(tmpdir)
166
167 - def install_bootloader(self):
168 tmpdir = '/tmp/vmbuilder-grub' 169 os.makedirs('%s%s' % (self.destdir, tmpdir)) 170 self.vm.add_clean_cb(self.install_bootloader_cleanup) 171 devmapfile = os.path.join(tmpdir, 'device.map') 172 devmap = open('%s%s' % (self.destdir, devmapfile), 'w') 173 for (disk, id) in zip(self.vm.disks, range(len(self.vm.disks))): 174 new_filename = os.path.join(tmpdir, os.path.basename(disk.filename)) 175 open('%s%s' % (self.destdir, new_filename), 'w').close() 176 run_cmd('mount', '--bind', disk.filename, '%s%s' % (self.destdir, new_filename)) 177 devmap.write("(hd%d) %s\n" % (id, new_filename)) 178 devmap.close() 179 self.run_in_target('grub', '--device-map=%s' % devmapfile, '--batch', stdin='''root (hd0,0) 180 setup (hd0) 181 EOT''') 182 self.install_bootloader_cleanup()
183
184 - def xen_kernel_version(self):
185 if self.suite.xen_kernel_flavour: 186 if not self.xen_kernel: 187 rmad = run_cmd('rmadison', 'linux-image-%s' % self.suite.xen_kernel_flavour) 188 version = ['0', '0','0', '0'] 189 190 for line in rmad.splitlines(): 191 sline = line.split('|') 192 193 if sline[2].strip().startswith(self.vm.suite): 194 vt = sline[1].strip().split('.') 195 for i in range(4): 196 if int(vt[i]) > int(version[i]): 197 version = vt 198 break 199 200 if version[0] == '0': 201 raise VMBuilderException('Something is wrong, no valid xen kernel for the suite %s found by rmadison' % self.vm.suite) 202 203 self.xen_kernel = '%s.%s.%s-%s' % (version[0],version[1],version[2],version[3]) 204 return self.xen_kernel 205 else: 206 raise VMBuilderUserError('There is no valid xen kernel for the suite selected.')
207
208 - def xen_kernel_initrd_path(self, which):
209 path = '/boot/%s-%s-%s' % (which, self.xen_kernel_version(), self.suite.xen_kernel_flavour) 210 return path
211
212 - def xen_kernel_path(self):
213 return self.xen_kernel_initrd_path('kernel')
214
215 - def xen_ramdisk_path(self):
216 return self.xen_kernel_initrd_path('ramdisk')
217
218 - def get_ec2_kernel(self):
219 if self.suite.ec2_kernel_info: 220 return self.suite.ec2_kernel_info[self.vm.arch] 221 else: 222 raise VMBuilderUserError('EC2 is not supported for the suite selected')
223
224 - def get_ec2_ramdisk(self):
225 if self.suite.ec2_ramdisk_info: 226 return self.suite.ec2_ramdisk_info[self.vm.arch] 227 else: 228 raise VMBuilderUserError('EC2 is not supported for the suite selected')
229
230 - def disable_hwclock_access(self):
231 return self.suite.disable_hwclock_access()
232
233 - def apply_ec2_settings(self):
234 return self.suite.apply_ec2_settings()
235 236 register_distro(Ubuntu) 237