2013-08-10 19:01:54 +02:00
|
|
|
from base import Task
|
|
|
|
from common import phases
|
2013-12-29 16:09:47 +01:00
|
|
|
from common.tasks import apt
|
2013-08-10 19:01:54 +02:00
|
|
|
|
|
|
|
|
2013-12-29 16:09:47 +01:00
|
|
|
class InstallRemotePackages(Task):
|
|
|
|
description = 'Installing remote packages'
|
|
|
|
phase = phases.package_installation
|
|
|
|
predecessors = [apt.AptUpgrade]
|
2013-08-10 19:01:54 +02:00
|
|
|
|
|
|
|
def run(self, info):
|
2013-12-29 16:09:47 +01:00
|
|
|
if len(info.packages.remote) == 0:
|
|
|
|
return
|
|
|
|
import os
|
2013-10-27 09:10:37 +01:00
|
|
|
|
2013-12-29 16:09:47 +01:00
|
|
|
packages = []
|
|
|
|
for name, target in info.packages.remote.iteritems():
|
|
|
|
packages.append('{name}/{target}'.format(name=name, target=target))
|
2013-10-27 13:01:01 +01:00
|
|
|
|
2013-12-29 19:24:16 +01:00
|
|
|
import logging
|
|
|
|
msg = ('The following packages will be installed (package/target-release):'
|
|
|
|
'\n{packages}\n').format(packages='\n'.join(packages))
|
|
|
|
logging.getLogger(__name__).debug(msg)
|
|
|
|
|
|
|
|
from common.tools import log_check_call
|
|
|
|
from subprocess import CalledProcessError
|
|
|
|
try:
|
|
|
|
env = os.environ.copy()
|
|
|
|
env['DEBIAN_FRONTEND'] = 'noninteractive'
|
2013-12-29 20:53:38 +01:00
|
|
|
log_check_call(['/usr/sbin/chroot', info.root,
|
|
|
|
'/usr/bin/apt-get', 'install',
|
|
|
|
'--no-install-recommends',
|
|
|
|
'--assume-yes']
|
|
|
|
+ packages,
|
2013-12-29 19:24:16 +01:00
|
|
|
env=env)
|
|
|
|
except CalledProcessError as e:
|
|
|
|
disk_stat = os.statvfs(info.root)
|
|
|
|
root_free_mb = disk_stat.f_bsize * disk_stat.f_bavail / 1024 / 1024
|
|
|
|
disk_stat = os.statvfs(os.path.join(info.root, 'boot'))
|
|
|
|
boot_free_mb = disk_stat.f_bsize * disk_stat.f_bavail / 1024 / 1024
|
|
|
|
free_mb = min(root_free_mb, boot_free_mb)
|
|
|
|
if free_mb < 50:
|
|
|
|
msg = ('apt exited with a non-zero status, '
|
|
|
|
'this may be because\nthe image volume is '
|
|
|
|
'running out of disk space ({free}MB left)').format(free=free_mb)
|
|
|
|
logging.getLogger(__name__).warn(msg)
|
2013-12-29 23:02:36 +01:00
|
|
|
else:
|
|
|
|
if e.returncode == 100:
|
|
|
|
msg = ('apt exited with status code 100. '
|
|
|
|
'This can sometimes occur when package retrieval times out or a package extraction failed. '
|
|
|
|
'apt might succeed if you try bootstrapping again.')
|
|
|
|
logging.getLogger(__name__).warn(msg)
|
2013-12-29 19:24:16 +01:00
|
|
|
raise e
|
2013-10-27 13:01:01 +01:00
|
|
|
|
2013-08-10 19:01:54 +02:00
|
|
|
|
2013-12-29 16:09:47 +01:00
|
|
|
class InstallLocalPackages(Task):
|
|
|
|
description = 'Installing local packages'
|
|
|
|
phase = phases.package_installation
|
|
|
|
predecessors = [apt.AptUpgrade]
|
|
|
|
successors = [InstallRemotePackages]
|
2013-08-10 19:01:54 +02:00
|
|
|
|
|
|
|
def run(self, info):
|
2013-12-29 16:09:47 +01:00
|
|
|
if len(info.packages.local) == 0:
|
|
|
|
return
|
|
|
|
from shutil import copy
|
|
|
|
from common.tools import log_check_call
|
|
|
|
import os
|
|
|
|
|
|
|
|
for package_src in info.packages.local:
|
|
|
|
pkg_name = os.path.basename(package_src)
|
|
|
|
package_dst = os.path.join('/tmp', pkg_name)
|
|
|
|
copy(package_src, os.path.join(info.root, package_dst))
|
|
|
|
|
|
|
|
env = os.environ.copy()
|
|
|
|
env['DEBIAN_FRONTEND'] = 'noninteractive'
|
|
|
|
log_check_call(['/usr/sbin/chroot', info.root,
|
|
|
|
'/usr/bin/dpkg', '--install', package_dst],
|
|
|
|
env=env)
|
|
|
|
os.remove(package_dst)
|