コード例 #1
0
ファイル: interface.py プロジェクト: zeus911/vpnease-l2tp
 def up_dns(self, dns_servers):
     resolvconf = '# automatically generated, do not edit\n'
     for srv in dns_servers:
         addr = srv.address
         if addr is not None:  # XXX: when?
             resolvconf += 'nameserver %s\n' % addr.toString()
     helpers.write_file('/etc/resolv.conf', resolvconf, perms=0644)
コード例 #2
0
ファイル: interface.py プロジェクト: nakedible/vpnease-l2tp
 def up_dns(self, dns_servers):
     resolvconf = '# automatically generated, do not edit\n'
     for srv in dns_servers:
         addr = srv.address
         if addr is not None:  # XXX: when?
             resolvconf += 'nameserver %s\n' % addr.toString()
     helpers.write_file('/etc/resolv.conf', resolvconf, perms=0644)
コード例 #3
0
ファイル: daemon.py プロジェクト: zeus911/vpnease-l2tp
 def write_config(self):
     for i in self.configs:
         mode = 0644
         try:
             mode = i['mode']
         except:
             pass
         helpers.write_file(i['file'], i['cont'], perms=mode)
コード例 #4
0
 def write_status(self, status):
     try:
         helpers.write_file(constants.INSTALL_STATUS_FILE,
                            status,
                            append=False,
                            perms=0644)
     except:
         self.error('writing installation status failed, ignored.')
コード例 #5
0
ファイル: timesync.py プロジェクト: nakedible/vpnease-l2tp
def _write_update_timestamps():
    try:
        from codebay.common import datatypes
        from codebay.l2tpserver import helpers
        from codebay.l2tpserver import constants

        helpers.write_file(constants.TIMESYNC_TIMESTAMP_FILE, datatypes.encode_datetime_to_iso8601_subset(datetime.datetime.utcnow()))
        helpers.write_file(constants.TIMESYNC_PERSISTENT_TIMESTAMP_FILE, datatypes.encode_datetime_to_iso8601_subset(datetime.datetime.utcnow()))
    except:
        if _log is not None:
            _log.exception('writing system time update timestamp failed.')
コード例 #6
0
ファイル: aptsupport.py プロジェクト: nakedible/vpnease-l2tp
    def get_apt_info(self, apt_sources_list):
        """Get apt information for an apt sources.list.

        Retrieves relevant information (with caching), and returns a tuple
        consisting of: latest version number, changelog.

        FIXME: has some trouble now with downgrade, maybe need to nuke
        /var/lib/apt/lists/vpnease* or something.  Also, could we download
        lists to some temporary file instead?
        """
        try:
            now = datetime.datetime.utcnow()

            # serve from cache?
            if self.cache.has_key(apt_sources_list):
                cinfo = self.cache[apt_sources_list]
                diff = now - cinfo.cachetime
                if (diff >= datetime.timedelta(0, 0, 0)) and (diff <= datetime.timedelta(0, self.interval, 0)):
                    _log.info('serving cached apt info for version %s' % cinfo.version)
                    return cinfo.version, cinfo.changelog
            else:
                pass

            # no, fetch using apt and cache
            _log.info('fetching apt info, apt source:')
            _log.info(apt_sources_list)
            helpers.write_file(self.tmpsource, apt_sources_list, perms=0644)
            run_command(['aptitude'] + self.aptitude_options + ['update'], retval=runcommand.FAIL)
            run_command(['aptitude'] + self.aptitude_options + ['download', 'vpnease'], cwd='/tmp', retval=runcommand.FAIL)
            version = None
            for i in os.listdir('/tmp'):
                if self.package_name_re.match(i):
                    version = versioninfo.get_package_version_info(os.path.join('/tmp', i))
                    changelog = versioninfo.get_package_changelog(os.path.join('/tmp', i))
                    run_command(['/bin/rm', '-f', os.path.join('/tmp', i)], retval=runcommand.FAIL)
            if version is None:
                raise Exception('vpnease package file not found')
            if changelog is None:
                raise Exception('vpnease package changelog not found')
            
            # create a new cache object
            cinfo = AptCacheInfo(now, version, changelog)
            self.cache[apt_sources_list] = cinfo
            
            # return fresh data
            _log.info('serving fresh apt info for version %s' % cinfo.version)
            return cinfo.version, cinfo.changelog
        except:
            _log.exception('failed to get package version info')
            raise

        raise Exception('should not be here')
コード例 #7
0
ファイル: init.py プロジェクト: nakedible/vpnease-l2tp
def _update_etc_issue(_log, is_livecd):
    from codebay.l2tpserver import versioninfo

    [version_string, cached] = versioninfo.get_version_info()

    if is_livecd:
        name = 'VPNease'
    else:
        name = 'VPNease'

    issue = textwrap.dedent("""\
    VPNease (version %s)

    """ % version_string)

    helpers.write_file('/etc/issue', issue, append=False, perms=0644)
    helpers.write_file('/etc/issue.net', issue, append=False, perms=0644)
コード例 #8
0
ファイル: timesync.py プロジェクト: zeus911/vpnease-l2tp
def _write_update_timestamps():
    try:
        from codebay.common import datatypes
        from codebay.l2tpserver import helpers
        from codebay.l2tpserver import constants

        helpers.write_file(
            constants.TIMESYNC_TIMESTAMP_FILE,
            datatypes.encode_datetime_to_iso8601_subset(
                datetime.datetime.utcnow()))
        helpers.write_file(
            constants.TIMESYNC_PERSISTENT_TIMESTAMP_FILE,
            datatypes.encode_datetime_to_iso8601_subset(
                datetime.datetime.utcnow()))
    except:
        if _log is not None:
            _log.exception('writing system time update timestamp failed.')
コード例 #9
0
ファイル: portmap.py プロジェクト: nakedible/vpnease-l2tp
    def _clear_state(self):
        """Clear portmap state.

        Remove openl2tpd and ippoold PROGRAM numbers from portmap state file
        so that their RPC registering will never fail.

        This is only useful if we want to emulate portmap startup
        script behaviour so that the portmap state is stored/restored in
        start/stop.

        Note: use this only if state-file handling is required, currently it is not done
        """

        progs_to_remove = ['300773', '300774', '300775']

        state = ''
        for line in open(constants.PORTMAP_STATEFILE):
            num = line.strip().split()[0]
            if num in progs_to_remove: continue
            state += line 

        helpers.write_file(constants.PORTMAP_STATEFILE, state, perms=0644)
コード例 #10
0
    def enable_forwarding(self):
        """Enable packet forwarding."""

        _log.debug('enable_forwarding')
        helpers.write_file('/proc/sys/net/ipv4/ip_forward', '1', perms=None)
コード例 #11
0
ファイル: firewall.py プロジェクト: nakedible/vpnease-l2tp
    def enable_forwarding(self):
        """Enable packet forwarding."""

        _log.debug('enable_forwarding')
        helpers.write_file ('/proc/sys/net/ipv4/ip_forward', '1', perms=None)
コード例 #12
0
ファイル: init.py プロジェクト: nakedible/vpnease-l2tp
def _check_interfaces(_log):
    from codebay.l2tpserver import interfacehelper

    _re_iftab_line = re.compile(r'^([^ #]+)\s+\w{3}\s+(\w{2}:\w{2}:\w{2}:\w{2}:\w{2}:\w{2})')

    infos = interfacehelper.get_all_interfaces()
    current_ifaces = {}
    for i in infos.get_interface_list():
        _log.info('system interface: %s' % i.toString())
        if not i.is_ethernet_device():
            continue
        current_ifaces[i.get_device_name()] = i.get_mac()

    iftab_ifaces = {}
    try:
        iftab = open('/etc/iftab', 'r')
        for l in iftab.read().split('\n'):
            m = _re_iftab_line.match(l)
            if m is None or len(m.groups()) < 2:
                continue
            dev = m.groups()[0]
            mac = m.groups()[1]
            info = interfacehelper.InterfaceInfo(dev, 0, 0, 0, 0, 0, mac, 'ether')
            if info.is_ethernet_device():
                iftab_ifaces[dev] = mac
                _log.info('iftab line: %s, %s' % (dev, mac))

        iftab.close()
    except:
        # Note: file may be missing, do not panic
        _log.exception('Failed to read /etc/iftab, creating from scratch.')
        pass

    for i in set(current_ifaces.keys()) - set(iftab_ifaces.keys()):
        # Note: GUI detects new interfaces by itself, no action
        pass

    for i in set(iftab_ifaces.keys()) - set(current_ifaces.keys()):
        # Note: missing interfaces are ok.. and cannot tell if the
        # interface vanished *just* now because mac locks are not removed.
        pass

    # Note: this removes old interface bindings if any..
    # Note: we do not care of invalid iftab bindinds, they are udev problems
    new_ifaces = iftab_ifaces
    new_ifaces.update(current_ifaces)

    if_lines = ''
    keys = new_ifaces.keys()
    keys.sort()
    for i in keys:
        # XXX: could also try to resolve the arp type and write if to
        # config, but propably not worth the effort?
        if_lines += '%s mac %s\n' % (i, new_ifaces[i])

    helpers.write_file('/etc/iftab', textwrap.dedent("""\
    # This file assigns persistent names to network interfaces.
    # See iftab(5) for syntax.
    
    # This file is autogenerated on system boot, do not edit.
    %s""") % if_lines)
コード例 #13
0
    def run_install(self,
                    target,
                    hostname,
                    adminuser,
                    adminpassword,
                    recovery_data=None,
                    large_install=False):
        """Perform normal product install."""
        try:
            # Set umask to be the same as normal ubuntu user umask (0022) that ubuquity install assumes
            # instead of default root umask (0066) that we are otherwise using.
            posix.umask(022)

            self.prepare()
            self.hostname = hostname
            self.large_install = large_install

            self.install_stage_set('Preparing target disk')
            self.debconf_progress_start(0, 100, '')
            self.debconf_progress_set(0)

            self.debconf_progress_region(0, 4)
            self.create_filesystems(target)
            self.setup_fat_partition('/target-fat')
            self.debconf_progress_set(4)

            # Copy recovery data for the first time, to ensure that the data is available
            # in case this recovery fails
            self.copy_recovery_data(recovery_data)

            self.install_stage_set('Copying files')

            # Note: resume partition setup is not a problem
            # because we do not use swap in live-cd => ubiquity
            # cannot find a swap partition to use for resume..

            # Set configuration values to the debconf database so that
            # Ubiquity can find them.

            # Grub boot device
            self.set_debconf_variable('grub-installer/bootdev', target)

            # Disable os-prober so that grub installer will not find other
            # devices to boot from. This is not configurable from debconf
            # and requires this hack (or menu.lst cleanup afterwards).
            os_prober = '/usr/bin/os-prober'
            os_prober_orig = '/usr/bin/os-prober.orig'

            # Note: first move command in unionfs system changes the directory permissions,
            # avoiding this by doing a copy/delete instead of move.
            run_command([constants.CMD_CP, '-f', os_prober, os_prober_orig],
                        retval=runcommand.FAIL)
            run_command([constants.CMD_RM, '-f', os_prober],
                        retval=runcommand.FAIL)

            helpers.write_file(os_prober,
                               '#!/bin/sh\nexit 0\n',
                               append=False,
                               perms=0755)

            # Admin user and passwd
            self.set_debconf_variable('passwd/username', adminuser)
            self.set_debconf_variable('passwd/user-fullname', 'Administrator')
            self.set_debconf_variable('passwd/user-uid', '999')

            # Note: here we could use real password received from UI (currently cleartext)
            # eg.: self.set_debconf_variable('passwd/user-password', adminpassword)
            # For now the admin password is disabled.
            self.set_debconf_variable('passwd/user-password-crypted', '*')

            # Set root password disabled.
            self.set_debconf_variable('passwd/root-password-crypted', '*')

            # Disable unwanted parts of Ubiquity
            # 1. language_apply (first two)
            # 2. apt_setup
            # 3. timezone_apply (zone and clock)
            # 4. keyboard_chooser
            for i in [
                    '/usr/lib/ubiquity/localechooser/post-base-installer',
                    '/usr/lib/ubiquity/localechooser/prebaseconfig',
                    '/usr/share/ubiquity/apt-setup',
                    '/usr/lib/ubiquity/tzsetup/prebaseconfig',
                    '/usr/share/ubiquity/clock-setup',
                    '/usr/lib/ubiquity/kbd-chooser/prebaseconfig'
            ]:
                helpers.write_file(
                    i,
                    textwrap.dedent("""\
                #!/bin/sh
                exit 0
                """))

            # Run Ubiquity to do the main part of installation
            self.debconf_progress_region(4, 97)
            if install.Install(self).run_command():
                raise Exception('Ubiquity installer failed')

            # Set back os-prober
            # Note: first move command in unionfs system changes the directory permissions,
            # avoiding this by doing a delete/copy/delete instead of move.
            run_command([constants.CMD_RM, '-f', os_prober],
                        retval=runcommand.FAIL)
            run_command([constants.CMD_CP, '-f', os_prober_orig, os_prober],
                        retval=runcommand.FAIL)
            run_command([constants.CMD_RM, '-f', os_prober_orig],
                        retval=runcommand.FAIL)

            # Clear debconf database
            for i in [
                    'grub-installer/bootdev', 'passwd/user-password',
                    'passwd/user-password-crypted',
                    'passwd/root-password-crypted', 'passwd/username',
                    'passwd/user-fullname', 'passwd/user-uid'
            ]:
                self.set_debconf_variable(i, None)

            # Ensure that the default user has sudo rights because
            # user-setup-apply fails when username is "admin".
            helpers.write_file('/target/etc/sudoers',
                               textwrap.dedent("""\
            # Ensure that the default user has admin rights always.
            %s ALL=(ALL) NOPASSWD: ALL
            """ % adminuser),
                               append=True,
                               perms=None)

            # Add GRUB options to /boot/grub/menu.lst:
            #   * recover from kernel panic (panic=60)
            #   * force a 16-bit VESA mode for Virtual PC 2007 compatibility
            #     (affects only startup)

            f = open('/target/boot/grub/menu.lst')
            grub_menu = f.read()
            f.close()

            def_re = re.compile(r'^# defoptions=')
            alt_re = re.compile(r'^# altoptions=')

            updated_grub_menu = ''
            for l in grub_menu.split('\n'):
                if (def_re.match(l) is not None) or (alt_re.match(l)
                                                     is not None):
                    updated_grub_menu += '%s panic=60 vga=785' % l
                else:
                    updated_grub_menu += l

                updated_grub_menu += '\n'

            f = open('/target/boot/grub/menu.lst', 'wb')
            f.write(updated_grub_menu)
            f.close()

            run_command(['/usr/sbin/chroot', '/target', '/sbin/update-grub'],
                        retval=runcommand.FAIL)

            # Fix permissions of all ubiquity-created files on target system.
            # These permissions are broken because of root umask (0066) is used
            # when running installer instead of ubuntu-user umask (0022))
            #
            # Files affected include at least: /etc/hosts, /etc/iftab, /etc/kernel-img.conf, /boot/grub, /boot/grub/*
            #
            # The following files already have proper permissions (files do exist before write),
            # but setting anyways: /etc/hostname, /etc/network/interfaces
            #
            # Note: this is still in place as a safeguard even when the umask is now set
            # in script start.

            for f, p in [['etc/hosts', 0644], ['etc/iftab', 0644],
                         ['etc/hostname', 0644],
                         ['etc/network/interfaces', 0644],
                         ['etc/kernel-img.conf', 0644]]:
                os.chmod(os.path.join('/target', f), p)

            for r, d, files in os.walk('/target/boot/grub'):
                os.chmod(r, 0755)
                for f in files:
                    os.chmod(os.path.join(r, f), 0644)

            # Note: Use this if the login stuff gets broken again and
            # debugging is required.
            # helpers.write_file('/target/etc/sudoers', textwrap.dedent("""\
            # debug ALL=(ALL) NOPASSWD: ALL
            # """), append=True, perms=None)
            # run_command(['/usr/sbin/chroot', '/target', 'adduser', '--disabled-password', '--gecos', 'Debug', '--uid', '1020', 'debug'])
            # run_command(['/usr/sbin/chroot', '/target', 'chpasswd'], stdin='debug:debug\n')

            self.install_stage_set('Finishing installation')

            if not os.path.exists(constants.LOWMEM_MARKER_FILE):
                # XXX: database stuff: (when testusage is implemented)
                # - stop database
                # - stop cron scripts from accessing database
                # - copy database to installed system
                # - copy marker files to installed system?
                #   - configured marker, other marker files
                #   - whole /var/lib/l2tpgw/ ?
                # - copy uuid file to installed system?
                # - copy logfiles to installed system
                # - remove/nocopy: fastboot marker
                pass

            self.debconf_progress_region(97, 99)

            # Recreate ssh keys
            for f, t in [['/etc/ssh/ssh_host_rsa_key', 'rsa'],
                         ['/etc/ssh/ssh_host_dsa_key', 'dsa']]:
                run_command(
                    ['/usr/sbin/chroot', '/target', '/bin/rm', '-f', f],
                    retval=runcommand.FAIL)
                run_command([
                    '/usr/sbin/chroot', '/target', '/usr/bin/ssh-keygen', '-q',
                    '-N', '', '-f', f, '-t', t, '-C',
                    'root@%s' % self.hostname
                ],
                            retval=runcommand.FAIL)

            # Copy recovery data (again)
            self.copy_recovery_data(recovery_data)

            self.copy_debconf()
            self.cleanup()
            self.debconf_progress_set(100)

            self.write_status('success\nInstall completed')
            self.info('installation success')
        except:
            self.cleanup()
            self.write_status('failure\nInstall failed')
            self.error('installation failed')
            raise
コード例 #14
0
ファイル: install.py プロジェクト: nakedible/vpnease-l2tp
    def create_filesystems(self, device):
        """Repartition the device, create filesystems and /etc/fstab."""

        self.debconf_progress_start(0, 100, '')
        self.debconf_progress_set(0)

        self.debconf_progress_info('Finding target device: %s' % device)

        m = mediahelper.get_media()
        target = m.get_medium_by_device_name(device)
        if target is None:
            self.error('failed to find installation target device: %s' % device)
            raise Exception('failed to find installation target device: %s' % device)

        # determine various parameters for later partitioning and fs setup
        create_swap = True
        part_fat = None
        part_boot = None
        part_swap = None
        part_root = None
        if create_swap:
            if self.large_install:
                part_fat = target.get_partition_devicename(1)
                part_boot = target.get_partition_devicename(2)
                part_swap = target.get_partition_devicename(3)
                part_root = target.get_partition_devicename(4)
                partitions = [part_fat, part_boot, part_swap, part_root]
            else:
                part_fat = target.get_partition_devicename(1)
                part_swap = target.get_partition_devicename(2)
                part_root = target.get_partition_devicename(3)
                partitions = [part_fat, part_swap, part_root]
        else:
            if self.large_install:
                part_fat = target.get_partition_devicename(1)
                part_boot = target.get_partition_devicename(2)
                part_root = target.get_partition_devicename(3)
                partitions = [part_fat, part_boot, part_root]
            else:
                part_fat = target.get_partition_devicename(1)
                part_root = target.get_partition_devicename(2)
                partitions = [part_fat, part_root]

        disk_min_size = (constants.DISK_SIZE_MINIMUM - constants.DISK_SIZE_SAFETY_MARGIN) / 512 * 512 # disk size with safety margin
        disk_size = (target.get_size() - constants.DISK_SIZE_SAFETY_MARGIN) / 512 * 512

        # partition "end points"
        fat_end = '1MB'
        disk_min_end = '%ss' % (disk_min_size / 512)  # sectors
        disk_end = '%ss' % (disk_size / 512)  # sectors

        try:
            self.debconf_progress_info('Wiping target device: %s' % device)

            self.nuke_and_create_disklabel(device)

            # Just in case
            time.sleep(1)
            self.debconf_progress_set(5)
        
            self.wait_for_partition_devices_to_disappear(partitions)

            self.debconf_progress_set(10)

            # MBR is at sector 0, and the first partition should begin at sector 63.
            # This leaves sectors 1...62 as "no man's land" (31kiB) which is used
            # for Grub stage 1.5
            #
            # See: http://en.wikipedia.org/wiki/GNU_GRUB
            #
            # XXX: currently partitions don't end at cylinder
            # boundaries.  It would probably be best to round the
            # partitions up to cylinder boundaries, as a
            # "conservative" partitioning is typically done so.
            # However, this should not matter as long as we only run
            # Grub and Linux itself.
            #
            # NOTE: Even Windows Vista partitions USB sticks without
            # caring about cylinders. Probably not an issue anymore.

            # Just in case
            time.sleep(1)
            self.debconf_progress_set(15)

            # XXX: endpoint is exclusive in parted

            self.debconf_progress_info('Creating partitions')                
            if create_swap:
                if self.large_install:
                    boot_end = '256MB'
                    swap_end = '768MB'
                    parted_cmds = [ ['mkpart', 'primary', 'fat32', '63s', fat_end],
                                    ['mkpart', 'primary', 'ext2', fat_end, boot_end],
                                    ['mkpart', 'primary', 'linux-swap', boot_end, swap_end],
                                    ['mkpart', 'primary', 'ext2', swap_end, disk_end],
                                    ['set', '2', 'boot', 'on'] ]
                else:
                    swap_end = '512MB'
                    parted_cmds = [ ['mkpart', 'primary', 'fat32', '63s', fat_end],
                                    ['mkpart', 'primary', 'linux-swap', fat_end, swap_end],
                                    ['mkpart', 'primary', 'ext2', swap_end, disk_min_end],
                                    ['set', '3', 'boot', 'on'] ]
            else:
                if self.large_install:
                    boot_end = '256MB'
                    parted_cmds = [ ['mkpart', 'primary', 'fat32', '63s', fat_end],
                                    ['mkpart', 'primary', 'ext2', fat_end, boot_end],
                                    ['mkpart', 'primary', 'ext2', boot_end, disk_end],
                                    ['set', '2', 'boot', 'on'] ]
                else:
                    parted_cmds = [ ['mkpart', 'primary', 'fat32', '63s', fat_end],
                                    ['mkpart', 'primary', 'ext2', fat_end, disk_min_end],
                                    ['set', '2', 'boot', 'on'] ]
                
            for i in parted_cmds:
                run_command(['/sbin/parted', '-s', device] + i, retval=runcommand.FAIL)

            self.debconf_progress_set(20)

            # Just in case
            time.sleep(1)
            self.debconf_progress_set(25)

            self.wait_for_partition_devices_to_appear(partitions)

            self.debconf_progress_set(30)

            # Sleep for a while to ensure that there is no "flicker" of device nodes.
            # For some reason this happens with at least native hardware and USB sticks.
            # See #435.
            time.sleep(5)

            self.debconf_progress_set(55)

            self.debconf_progress_info('Creating partitions and filesystems')
            run_command(['/sbin/mkfs.vfat', '-n', constants.PRODUCT_NAME.upper(), part_fat], retval=runcommand.FAIL)

            self.debconf_progress_set(60)

            if part_swap is not None:
                run_command(['/sbin/mkswap', '-L', 'SWAP', part_swap], retval=runcommand.FAIL)

            if part_boot is not None:
                # XXX: opts here?
                run_command(['/sbin/mkfs.ext3',
                             '-L', 'ROOT',
                             '-b', str(1024),
                             '-i', str(4096),
                             '-m', str(0),
                             '-O', 'sparse_super,filetype,resize_inode,dir_index',
                             '-v',
                             part_boot], retval=runcommand.FAIL)
                [rc, stdout, stderr] = run_command(['/sbin/dumpe2fs', part_boot])
                self._log.info('dumpe2fs dump of boot filesystem:\n%s' % stdout)
            else:
                self._log.info('no boot partition, skipping mkfs')
                
            run_command(['/sbin/mkfs.ext3',
                         '-L', 'ROOT',
                         '-b', str(1024),
                         '-i', str(4096),
                         '-m', str(0),
                         '-O', 'sparse_super,filetype,resize_inode,dir_index',
                         '-v',
                         part_root], retval=runcommand.FAIL)
            [rc, stdout, stderr] = run_command(['/sbin/dumpe2fs', part_root])
            self._log.info('dumpe2fs dump of root filesystem:\n%s' % stdout)

            self.debconf_progress_set(95)

        except:
            self.error('failed to create partitions, exiting.')
            raise

        # Create targets and fstab.
        self.debconf_progress_info('Mounting target and creating fstab')

        # Note: not using -p because the target should not exist at this point (cleanup done)
        run_command([constants.CMD_MKDIR, '/target'], retval=runcommand.FAIL)
        run_command([constants.CMD_MKDIR, '/target-fat'], retval=runcommand.FAIL)
            
        run_command([constants.CMD_MOUNT, part_root, '/target'], retval=runcommand.FAIL)
        run_command([constants.CMD_MOUNT, part_fat, '/target-fat'], retval=runcommand.FAIL)

        if part_boot is not None:
            run_command([constants.CMD_MKDIR, '/target/boot'], retval=runcommand.FAIL)
            run_command([constants.CMD_MOUNT, part_boot, '/target/boot'], retval=runcommand.FAIL)

        # Write fstab now (it will not be overwritten by copy process)
        run_command([constants.CMD_MKDIR, '/target/etc/'], retval=runcommand.FAIL)

        fstab = textwrap.dedent("""\
        # /etc/fstab: static file system information.
        #
        # <file system> <mount point>   <type>  <options>       <dump>  <pass>
        proc            /proc           proc    defaults        0       0
        %(part_root)s       /               ext3    defaults,errors=remount-ro,noatime 0       1
        """)
        if part_swap is not None:
            fstab += textwrap.dedent("""\
            %(part_swap)s       none            swap    sw              0       0
            """)
        if part_boot is not None:
            fstab += textwrap.dedent("""\
            %(part_boot)s       /boot           ext3    defaults        0       2
            """)
    
        fstab = fstab % {'part_swap':part_swap, 'part_root':part_root, 'part_boot':part_boot, 'part_fat':part_fat}
        helpers.write_file('/target/etc/fstab', fstab)
        self.debconf_progress_set(100)

        # XXX: cdrom to fstab? nope for now
        # /dev/hdc        /media/cdrom0   iso9660 ro,user,noauto  0       0

        self.debconf_progress_stop()
コード例 #15
0
    def get_apt_info(self, apt_sources_list):
        """Get apt information for an apt sources.list.

        Retrieves relevant information (with caching), and returns a tuple
        consisting of: latest version number, changelog.

        FIXME: has some trouble now with downgrade, maybe need to nuke
        /var/lib/apt/lists/vpnease* or something.  Also, could we download
        lists to some temporary file instead?
        """
        try:
            now = datetime.datetime.utcnow()

            # serve from cache?
            if self.cache.has_key(apt_sources_list):
                cinfo = self.cache[apt_sources_list]
                diff = now - cinfo.cachetime
                if (diff >= datetime.timedelta(0, 0, 0)) and (
                        diff <= datetime.timedelta(0, self.interval, 0)):
                    _log.info('serving cached apt info for version %s' %
                              cinfo.version)
                    return cinfo.version, cinfo.changelog
            else:
                pass

            # no, fetch using apt and cache
            _log.info('fetching apt info, apt source:')
            _log.info(apt_sources_list)
            helpers.write_file(self.tmpsource, apt_sources_list, perms=0644)
            run_command(['aptitude'] + self.aptitude_options + ['update'],
                        retval=runcommand.FAIL)
            run_command(['aptitude'] + self.aptitude_options +
                        ['download', 'vpnease'],
                        cwd='/tmp',
                        retval=runcommand.FAIL)
            version = None
            for i in os.listdir('/tmp'):
                if self.package_name_re.match(i):
                    version = versioninfo.get_package_version_info(
                        os.path.join('/tmp', i))
                    changelog = versioninfo.get_package_changelog(
                        os.path.join('/tmp', i))
                    run_command(['/bin/rm', '-f',
                                 os.path.join('/tmp', i)],
                                retval=runcommand.FAIL)
            if version is None:
                raise Exception('vpnease package file not found')
            if changelog is None:
                raise Exception('vpnease package changelog not found')

            # create a new cache object
            cinfo = AptCacheInfo(now, version, changelog)
            self.cache[apt_sources_list] = cinfo

            # return fresh data
            _log.info('serving fresh apt info for version %s' % cinfo.version)
            return cinfo.version, cinfo.changelog
        except:
            _log.exception('failed to get package version info')
            raise

        raise Exception('should not be here')
コード例 #16
0
    def run_update(self):
        """Run update script.

        Returns a Deferred, which either raises an update-related exception (ending up
        in caller's errback), or returns None if the update completes normally.
        """
        def _script_timeout():
            _log.warning('_script_timeout()')
            self.script_timeout_call = None

            # this is not nice, but what else to do here?
            if self._update_process_protocol is not None:
                self._update_process_protocol.sendTerm()
            self.update_failed = True
            self.update_exit_code = 3  # XXX: fake update exit code to cause UpdateFailedError
            self.stop_twisted()

        def _update_completed(res):
            _log.debug('_update_completed()')
            if self.script_timeout_call is not None:
                self.script_timeout_call.cancel()
                self.script_timeout_call = None

            # XXX: In a script timeout case, we get here with 'res' not being
            # an integer.  This is not nice, but causes no actual problems.

            self.update_exit_code = int(res)  # store exit code
            _log.info('update exit code: %s' % self.update_exit_code)
            return None

        _log.info('update needed, starting update process')

        # export configuration before update from sqlite so that new code after
        # update has the option of re-creating the sqlite database or switch to
        # a new backend format without resorting to ugly sqlite dependencies
        try:
            _log.info('exporting rdf/xml for update')
            self._export_rdfxml_for_update()
            _log.info('export rdf/xml for update successful')
        except:
            _log.exception('_export_rdfxml_for_update() failed, ignoring')
            try:
                if os.path.exists(constants.UPDATE_PROCESS_RDFXML_EXPORT_FILE):
                    os.unlink(constants.UPDATE_PROCESS_RDFXML_EXPORT_FILE)
            except:
                _log.exception('_export_rdfxml_for_update(), cleanup failed')

        # set sources.list
        helpers.write_file('/etc/apt/sources.list', self.sources)

        # set repository keys
        helpers.write_file(constants.UPDATE_REPOSITORY_KEYS_FILE,
                           self.repokeys,
                           perms=0600,
                           append=False)

        # determine parameters for update
        cmd = constants.CMD_PYTHON
        if self.scriptspath is not None:
            pyfile = os.path.join(
                self.scriptspath,
                os.path.basename(constants.CMD_L2TPGW_UPDATE_PRODUCT))
        else:
            pyfile = constants.CMD_L2TPGW_UPDATE_PRODUCT
        _log.info('update command: %s, script: %s, arguments: %s' %
                  (cmd, pyfile, self.importpath))

        # failure timer for running script
        self.script_timeout_call = reactor.callLater(
            constants.UPDATE_SCRIPT_TIMEOUT, _script_timeout)

        # start update process
        u = UpdateProcessProtocol()
        self._update_process_protocol = u
        reactor.spawnProcess(
            u,
            executable=cmd,
            args=[cmd, pyfile, '--import-path', self.importpath],
            env=None,  # Uses os.environ if set to None, default is empty
            usePTY=1)
        d = u.waitCompleted()
        d.addCallback(_update_completed)
        self.run_update_deferred = d
        return d
コード例 #17
0
ファイル: install.py プロジェクト: nakedible/vpnease-l2tp
    def run_install(self, target, hostname, adminuser, adminpassword, recovery_data=None, large_install=False):
        """Perform normal product install."""
        try:
            # Set umask to be the same as normal ubuntu user umask (0022) that ubuquity install assumes
            # instead of default root umask (0066) that we are otherwise using.
            posix.umask(022)

            self.prepare()
            self.hostname = hostname
            self.large_install = large_install
            
            self.install_stage_set('Preparing target disk')
            self.debconf_progress_start(0, 100, '')
            self.debconf_progress_set(0)

            self.debconf_progress_region(0, 4)
            self.create_filesystems(target)
            self.setup_fat_partition('/target-fat')
            self.debconf_progress_set(4)

            # Copy recovery data for the first time, to ensure that the data is available
            # in case this recovery fails
            self.copy_recovery_data(recovery_data)
            
            self.install_stage_set('Copying files')

            # Note: resume partition setup is not a problem
            # because we do not use swap in live-cd => ubiquity
            # cannot find a swap partition to use for resume..

            # Set configuration values to the debconf database so that
            # Ubiquity can find them.

            # Grub boot device
            self.set_debconf_variable('grub-installer/bootdev', target)

            # Disable os-prober so that grub installer will not find other
            # devices to boot from. This is not configurable from debconf
            # and requires this hack (or menu.lst cleanup afterwards).
            os_prober = '/usr/bin/os-prober'
            os_prober_orig = '/usr/bin/os-prober.orig'

            # Note: first move command in unionfs system changes the directory permissions,
            # avoiding this by doing a copy/delete instead of move.
            run_command([constants.CMD_CP, '-f', os_prober, os_prober_orig], retval=runcommand.FAIL)
            run_command([constants.CMD_RM, '-f', os_prober], retval=runcommand.FAIL)

            helpers.write_file(os_prober, '#!/bin/sh\nexit 0\n', append=False, perms=0755)

            # Admin user and passwd
            self.set_debconf_variable('passwd/username', adminuser)
            self.set_debconf_variable('passwd/user-fullname', 'Administrator')
            self.set_debconf_variable('passwd/user-uid', '999')

            # Note: here we could use real password received from UI (currently cleartext)
            # eg.: self.set_debconf_variable('passwd/user-password', adminpassword)
            # For now the admin password is disabled.
            self.set_debconf_variable('passwd/user-password-crypted', '*')

            # Set root password disabled.
            self.set_debconf_variable('passwd/root-password-crypted', '*')

            # Disable unwanted parts of Ubiquity
            # 1. language_apply (first two)
            # 2. apt_setup
            # 3. timezone_apply (zone and clock)
            # 4. keyboard_chooser
            for i in ['/usr/lib/ubiquity/localechooser/post-base-installer',
                      '/usr/lib/ubiquity/localechooser/prebaseconfig',
                      '/usr/share/ubiquity/apt-setup',
                      '/usr/lib/ubiquity/tzsetup/prebaseconfig',
                      '/usr/share/ubiquity/clock-setup',
                      '/usr/lib/ubiquity/kbd-chooser/prebaseconfig']:
                helpers.write_file(i, textwrap.dedent("""\
                #!/bin/sh
                exit 0
                """))

            # Run Ubiquity to do the main part of installation
            self.debconf_progress_region(4, 97)
            if install.Install(self).run_command():
                raise Exception('Ubiquity installer failed')

            # Set back os-prober
            # Note: first move command in unionfs system changes the directory permissions,
            # avoiding this by doing a delete/copy/delete instead of move.
            run_command([constants.CMD_RM, '-f', os_prober], retval=runcommand.FAIL)
            run_command([constants.CMD_CP, '-f', os_prober_orig, os_prober], retval=runcommand.FAIL)
            run_command([constants.CMD_RM, '-f', os_prober_orig], retval=runcommand.FAIL)

            # Clear debconf database
            for i in ['grub-installer/bootdev',
                      'passwd/user-password',
                      'passwd/user-password-crypted',
                      'passwd/root-password-crypted',
                      'passwd/username',
                      'passwd/user-fullname',
                      'passwd/user-uid']:
                self.set_debconf_variable(i, None)

            # Ensure that the default user has sudo rights because
            # user-setup-apply fails when username is "admin".
            helpers.write_file('/target/etc/sudoers', textwrap.dedent("""\
            # Ensure that the default user has admin rights always.
            %s ALL=(ALL) NOPASSWD: ALL
            """ % adminuser), append=True, perms=None)

            # Add GRUB options to /boot/grub/menu.lst:
            #   * recover from kernel panic (panic=60)
            #   * force a 16-bit VESA mode for Virtual PC 2007 compatibility
            #     (affects only startup)
            
            f = open('/target/boot/grub/menu.lst')
            grub_menu = f.read()
            f.close()

            def_re = re.compile(r'^# defoptions=')
            alt_re = re.compile(r'^# altoptions=')

            updated_grub_menu = ''
            for l in grub_menu.split('\n'):
                if (def_re.match(l) is not None) or (alt_re.match(l) is not None):
                    updated_grub_menu += '%s panic=60 vga=785' % l
                else:
                    updated_grub_menu += l

                updated_grub_menu += '\n'

            f = open('/target/boot/grub/menu.lst', 'wb')
            f.write(updated_grub_menu)
            f.close()

            run_command(['/usr/sbin/chroot', '/target', '/sbin/update-grub'], retval=runcommand.FAIL)

            # Fix permissions of all ubiquity-created files on target system.
            # These permissions are broken because of root umask (0066) is used
            # when running installer instead of ubuntu-user umask (0022))
            #
            # Files affected include at least: /etc/hosts, /etc/iftab, /etc/kernel-img.conf, /boot/grub, /boot/grub/*
            #
            # The following files already have proper permissions (files do exist before write),
            # but setting anyways: /etc/hostname, /etc/network/interfaces
            #
            # Note: this is still in place as a safeguard even when the umask is now set
            # in script start.

            for f, p in [['etc/hosts', 0644],
                         ['etc/iftab', 0644],
                         ['etc/hostname', 0644],
                         ['etc/network/interfaces', 0644],
                         ['etc/kernel-img.conf', 0644]]:
                os.chmod(os.path.join('/target', f), p)

            for r, d, files in os.walk('/target/boot/grub'):
                os.chmod(r, 0755)
                for f in files:
                    os.chmod(os.path.join(r, f), 0644)

            # Note: Use this if the login stuff gets broken again and
            # debugging is required.
            # helpers.write_file('/target/etc/sudoers', textwrap.dedent("""\
            # debug ALL=(ALL) NOPASSWD: ALL
            # """), append=True, perms=None)
            # run_command(['/usr/sbin/chroot', '/target', 'adduser', '--disabled-password', '--gecos', 'Debug', '--uid', '1020', 'debug'])
            # run_command(['/usr/sbin/chroot', '/target', 'chpasswd'], stdin='debug:debug\n')

            self.install_stage_set('Finishing installation')

            if not os.path.exists(constants.LOWMEM_MARKER_FILE):
                # XXX: database stuff: (when testusage is implemented)
                # - stop database
                # - stop cron scripts from accessing database
                # - copy database to installed system
                # - copy marker files to installed system?
                #   - configured marker, other marker files
                #   - whole /var/lib/l2tpgw/ ?
                # - copy uuid file to installed system?
                # - copy logfiles to installed system
                # - remove/nocopy: fastboot marker
                pass

            self.debconf_progress_region(97, 99)

            # Recreate ssh keys
            for f, t in [['/etc/ssh/ssh_host_rsa_key', 'rsa'], ['/etc/ssh/ssh_host_dsa_key', 'dsa']]:
                run_command(['/usr/sbin/chroot', '/target', '/bin/rm', '-f', f], retval=runcommand.FAIL)
                run_command(['/usr/sbin/chroot', '/target', '/usr/bin/ssh-keygen', '-q', '-N', '', '-f',f, '-t', t, '-C', 'root@%s' % self.hostname], retval=runcommand.FAIL)

            # Copy recovery data (again)
            self.copy_recovery_data(recovery_data)

            self.copy_debconf()
            self.cleanup()
            self.debconf_progress_set(100)

            self.write_status('success\nInstall completed')
            self.info('installation success')
        except:
            self.cleanup()
            self.write_status('failure\nInstall failed')
            self.error('installation failed')
            raise
コード例 #18
0
ファイル: install.py プロジェクト: nakedible/vpnease-l2tp
 def write_status(self, status):
     try:
         helpers.write_file(constants.INSTALL_STATUS_FILE, status, append=False, perms=0644)
     except:
         self.error ('writing installation status failed, ignored.')
コード例 #19
0
    def create_filesystems(self, device):
        """Repartition the device, create filesystems and /etc/fstab."""

        self.debconf_progress_start(0, 100, '')
        self.debconf_progress_set(0)

        self.debconf_progress_info('Finding target device: %s' % device)

        m = mediahelper.get_media()
        target = m.get_medium_by_device_name(device)
        if target is None:
            self.error('failed to find installation target device: %s' %
                       device)
            raise Exception('failed to find installation target device: %s' %
                            device)

        # determine various parameters for later partitioning and fs setup
        create_swap = True
        part_fat = None
        part_boot = None
        part_swap = None
        part_root = None
        if create_swap:
            if self.large_install:
                part_fat = target.get_partition_devicename(1)
                part_boot = target.get_partition_devicename(2)
                part_swap = target.get_partition_devicename(3)
                part_root = target.get_partition_devicename(4)
                partitions = [part_fat, part_boot, part_swap, part_root]
            else:
                part_fat = target.get_partition_devicename(1)
                part_swap = target.get_partition_devicename(2)
                part_root = target.get_partition_devicename(3)
                partitions = [part_fat, part_swap, part_root]
        else:
            if self.large_install:
                part_fat = target.get_partition_devicename(1)
                part_boot = target.get_partition_devicename(2)
                part_root = target.get_partition_devicename(3)
                partitions = [part_fat, part_boot, part_root]
            else:
                part_fat = target.get_partition_devicename(1)
                part_root = target.get_partition_devicename(2)
                partitions = [part_fat, part_root]

        disk_min_size = (constants.DISK_SIZE_MINIMUM -
                         constants.DISK_SIZE_SAFETY_MARGIN
                         ) / 512 * 512  # disk size with safety margin
        disk_size = (target.get_size() -
                     constants.DISK_SIZE_SAFETY_MARGIN) / 512 * 512

        # partition "end points"
        fat_end = '1MB'
        disk_min_end = '%ss' % (disk_min_size / 512)  # sectors
        disk_end = '%ss' % (disk_size / 512)  # sectors

        try:
            self.debconf_progress_info('Wiping target device: %s' % device)

            self.nuke_and_create_disklabel(device)

            # Just in case
            time.sleep(1)
            self.debconf_progress_set(5)

            self.wait_for_partition_devices_to_disappear(partitions)

            self.debconf_progress_set(10)

            # MBR is at sector 0, and the first partition should begin at sector 63.
            # This leaves sectors 1...62 as "no man's land" (31kiB) which is used
            # for Grub stage 1.5
            #
            # See: http://en.wikipedia.org/wiki/GNU_GRUB
            #
            # XXX: currently partitions don't end at cylinder
            # boundaries.  It would probably be best to round the
            # partitions up to cylinder boundaries, as a
            # "conservative" partitioning is typically done so.
            # However, this should not matter as long as we only run
            # Grub and Linux itself.
            #
            # NOTE: Even Windows Vista partitions USB sticks without
            # caring about cylinders. Probably not an issue anymore.

            # Just in case
            time.sleep(1)
            self.debconf_progress_set(15)

            # XXX: endpoint is exclusive in parted

            self.debconf_progress_info('Creating partitions')
            if create_swap:
                if self.large_install:
                    boot_end = '256MB'
                    swap_end = '768MB'
                    parted_cmds = [
                        ['mkpart', 'primary', 'fat32', '63s', fat_end],
                        ['mkpart', 'primary', 'ext2', fat_end, boot_end],
                        [
                            'mkpart', 'primary', 'linux-swap', boot_end,
                            swap_end
                        ], ['mkpart', 'primary', 'ext2', swap_end, disk_end],
                        ['set', '2', 'boot', 'on']
                    ]
                else:
                    swap_end = '512MB'
                    parted_cmds = [
                        ['mkpart', 'primary', 'fat32', '63s', fat_end],
                        ['mkpart', 'primary', 'linux-swap', fat_end, swap_end],
                        ['mkpart', 'primary', 'ext2', swap_end, disk_min_end],
                        ['set', '3', 'boot', 'on']
                    ]
            else:
                if self.large_install:
                    boot_end = '256MB'
                    parted_cmds = [
                        ['mkpart', 'primary', 'fat32', '63s', fat_end],
                        ['mkpart', 'primary', 'ext2', fat_end, boot_end],
                        ['mkpart', 'primary', 'ext2', boot_end, disk_end],
                        ['set', '2', 'boot', 'on']
                    ]
                else:
                    parted_cmds = [[
                        'mkpart', 'primary', 'fat32', '63s', fat_end
                    ], ['mkpart', 'primary', 'ext2', fat_end, disk_min_end],
                                   ['set', '2', 'boot', 'on']]

            for i in parted_cmds:
                run_command(['/sbin/parted', '-s', device] + i,
                            retval=runcommand.FAIL)

            self.debconf_progress_set(20)

            # Just in case
            time.sleep(1)
            self.debconf_progress_set(25)

            self.wait_for_partition_devices_to_appear(partitions)

            self.debconf_progress_set(30)

            # Sleep for a while to ensure that there is no "flicker" of device nodes.
            # For some reason this happens with at least native hardware and USB sticks.
            # See #435.
            time.sleep(5)

            self.debconf_progress_set(55)

            self.debconf_progress_info('Creating partitions and filesystems')
            run_command([
                '/sbin/mkfs.vfat', '-n',
                constants.PRODUCT_NAME.upper(), part_fat
            ],
                        retval=runcommand.FAIL)

            self.debconf_progress_set(60)

            if part_swap is not None:
                run_command(['/sbin/mkswap', '-L', 'SWAP', part_swap],
                            retval=runcommand.FAIL)

            if part_boot is not None:
                # XXX: opts here?
                run_command([
                    '/sbin/mkfs.ext3', '-L', 'ROOT', '-b',
                    str(1024), '-i',
                    str(4096), '-m',
                    str(0), '-O',
                    'sparse_super,filetype,resize_inode,dir_index', '-v',
                    part_boot
                ],
                            retval=runcommand.FAIL)
                [rc, stdout,
                 stderr] = run_command(['/sbin/dumpe2fs', part_boot])
                self._log.info('dumpe2fs dump of boot filesystem:\n%s' %
                               stdout)
            else:
                self._log.info('no boot partition, skipping mkfs')

            run_command([
                '/sbin/mkfs.ext3', '-L', 'ROOT', '-b',
                str(1024), '-i',
                str(4096), '-m',
                str(0), '-O', 'sparse_super,filetype,resize_inode,dir_index',
                '-v', part_root
            ],
                        retval=runcommand.FAIL)
            [rc, stdout, stderr] = run_command(['/sbin/dumpe2fs', part_root])
            self._log.info('dumpe2fs dump of root filesystem:\n%s' % stdout)

            self.debconf_progress_set(95)

        except:
            self.error('failed to create partitions, exiting.')
            raise

        # Create targets and fstab.
        self.debconf_progress_info('Mounting target and creating fstab')

        # Note: not using -p because the target should not exist at this point (cleanup done)
        run_command([constants.CMD_MKDIR, '/target'], retval=runcommand.FAIL)
        run_command([constants.CMD_MKDIR, '/target-fat'],
                    retval=runcommand.FAIL)

        run_command([constants.CMD_MOUNT, part_root, '/target'],
                    retval=runcommand.FAIL)
        run_command([constants.CMD_MOUNT, part_fat, '/target-fat'],
                    retval=runcommand.FAIL)

        if part_boot is not None:
            run_command([constants.CMD_MKDIR, '/target/boot'],
                        retval=runcommand.FAIL)
            run_command([constants.CMD_MOUNT, part_boot, '/target/boot'],
                        retval=runcommand.FAIL)

        # Write fstab now (it will not be overwritten by copy process)
        run_command([constants.CMD_MKDIR, '/target/etc/'],
                    retval=runcommand.FAIL)

        fstab = textwrap.dedent("""\
        # /etc/fstab: static file system information.
        #
        # <file system> <mount point>   <type>  <options>       <dump>  <pass>
        proc            /proc           proc    defaults        0       0
        %(part_root)s       /               ext3    defaults,errors=remount-ro,noatime 0       1
        """)
        if part_swap is not None:
            fstab += textwrap.dedent("""\
            %(part_swap)s       none            swap    sw              0       0
            """)
        if part_boot is not None:
            fstab += textwrap.dedent("""\
            %(part_boot)s       /boot           ext3    defaults        0       2
            """)

        fstab = fstab % {
            'part_swap': part_swap,
            'part_root': part_root,
            'part_boot': part_boot,
            'part_fat': part_fat
        }
        helpers.write_file('/target/etc/fstab', fstab)
        self.debconf_progress_set(100)

        # XXX: cdrom to fstab? nope for now
        # /dev/hdc        /media/cdrom0   iso9660 ro,user,noauto  0       0

        self.debconf_progress_stop()
コード例 #20
0
ファイル: update.py プロジェクト: nakedible/vpnease-l2tp
    def run_update(self):
        """Run update script.

        Returns a Deferred, which either raises an update-related exception (ending up
        in caller's errback), or returns None if the update completes normally.
        """

        def _script_timeout():
            _log.warning('_script_timeout()')
            self.script_timeout_call = None

            # this is not nice, but what else to do here?
            if self._update_process_protocol is not None:
                self._update_process_protocol.sendTerm()
            self.update_failed = True
            self.update_exit_code = 3 # XXX: fake update exit code to cause UpdateFailedError
            self.stop_twisted()
        
        def _update_completed(res):
            _log.debug('_update_completed()')
            if self.script_timeout_call is not None:
                self.script_timeout_call.cancel()
                self.script_timeout_call = None

            # XXX: In a script timeout case, we get here with 'res' not being
            # an integer.  This is not nice, but causes no actual problems.

            self.update_exit_code = int(res)  # store exit code
            _log.info('update exit code: %s' % self.update_exit_code)
            return None
        
        _log.info('update needed, starting update process')

        # export configuration before update from sqlite so that new code after
        # update has the option of re-creating the sqlite database or switch to
        # a new backend format without resorting to ugly sqlite dependencies
        try:
            _log.info('exporting rdf/xml for update')
            self._export_rdfxml_for_update()
            _log.info('export rdf/xml for update successful')
        except:
            _log.exception('_export_rdfxml_for_update() failed, ignoring')
            try:
                if os.path.exists(constants.UPDATE_PROCESS_RDFXML_EXPORT_FILE):
                    os.unlink(constants.UPDATE_PROCESS_RDFXML_EXPORT_FILE)                
            except:
                _log.exception('_export_rdfxml_for_update(), cleanup failed')

        # set sources.list
        helpers.write_file('/etc/apt/sources.list', self.sources)

        # set repository keys
        helpers.write_file(constants.UPDATE_REPOSITORY_KEYS_FILE, self.repokeys, perms=0600, append=False)

        # determine parameters for update
        cmd = constants.CMD_PYTHON
        if self.scriptspath is not None:
            pyfile = os.path.join(self.scriptspath, os.path.basename(constants.CMD_L2TPGW_UPDATE_PRODUCT))
        else:
            pyfile = constants.CMD_L2TPGW_UPDATE_PRODUCT
        _log.info('update command: %s, script: %s, arguments: %s' % (cmd, pyfile, self.importpath))

        # failure timer for running script
        self.script_timeout_call = reactor.callLater(constants.UPDATE_SCRIPT_TIMEOUT, _script_timeout)

        # start update process
        u = UpdateProcessProtocol()
        self._update_process_protocol = u
        reactor.spawnProcess(u,
                             executable=cmd,
                             args=[cmd, pyfile, '--import-path', self.importpath],
                             env=None, # Uses os.environ if set to None, default is empty
                             usePTY=1)
        d = u.waitCompleted()
        d.addCallback(_update_completed)
        self.run_update_deferred = d
        return d