cloud-init/cloudinit/CloudConfig/cc_apt_update_upgrade.py
Scott Moser 2294274bbd add apt helper routeins to CloudConfig, and use them in apt and puppet
Adding the apt helper routines to CloudConfig.  
Then, make use of the following from cc_puppet and cc_apt_update_upgrade
 update_package_sources():
 install_packages(pkglist):

I'm not really terribly happy with this location for them.  Their presence
here is really only because of apt-update's use of
'run-once-per-instance'.
2011-02-07 14:43:40 -05:00

145 lines
4.7 KiB
Python

# vi: ts=4 expandtab
#
# Copyright (C) 2009-2010 Canonical Ltd.
#
# Author: Scott Moser <scott.moser@canonical.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 3, as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import cloudinit.util as util
import subprocess
import traceback
import os
import glob
import cloudinit.CloudConfig as cc
def handle(name,cfg,cloud,log,args):
update = util.get_cfg_option_bool(cfg, 'apt_update', False)
upgrade = util.get_cfg_option_bool(cfg, 'apt_upgrade', False)
release = get_release()
if cfg.has_key("apt_mirror"):
mirror = cfg["apt_mirror"]
else:
mirror = cloud.get_mirror()
if not util.get_cfg_option_bool(cfg, \
'apt_preserve_sources_list', False):
generate_sources_list(release, mirror)
old_mir = util.get_cfg_option_str(cfg,'apt_old_mirror', \
"archive.ubuntu.com/ubuntu")
rename_apt_lists(old_mir, mirror)
# process 'apt_sources'
if cfg.has_key('apt_sources'):
errors = add_sources(cfg['apt_sources'],
{ 'MIRROR' : mirror, 'RELEASE' : release } )
for e in errors:
log.warn("Source Error: %s\n" % ':'.join(e))
dconf_sel = util.get_cfg_option_str(cfg, 'debconf_selections', False)
if dconf_sel:
log.debug("setting debconf selections per cloud config")
try:
util.subp(('debconf-set-selections', '-'), dconf_sel)
except:
log.error("Failed to run debconf-set-selections")
log.debug(traceback.format_exc())
if update:
cc.update_package_sources()
if upgrade:
cc.apt_get("upgrade")
pkglist = util.get_cfg_option_list_or_str(cfg,'packages',[])
if len(pkglist):
cc.install_packages(pkglist)
return(True)
def mirror2lists_fileprefix(mirror):
file=mirror
# take of http:// or ftp://
if file.endswith("/"): file=file[0:-1]
pos=file.find("://")
if pos >= 0:
file=file[pos+3:]
file=file.replace("/","_")
return file
def rename_apt_lists(omirror,new_mirror,lists_d="/var/lib/apt/lists"):
oprefix="%s/%s" % (lists_d,mirror2lists_fileprefix(omirror))
nprefix="%s/%s" % (lists_d,mirror2lists_fileprefix(new_mirror))
if(oprefix==nprefix): return
olen=len(oprefix)
for file in glob.glob("%s_*" % oprefix):
os.rename(file,"%s%s" % (nprefix, file[olen:]))
def get_release():
stdout, stderr = subprocess.Popen(['lsb_release', '-cs'], stdout=subprocess.PIPE).communicate()
return(stdout.strip())
def generate_sources_list(codename, mirror):
util.render_to_file('sources.list', '/etc/apt/sources.list', \
{ 'mirror' : mirror, 'codename' : codename })
# srclist is a list of dictionaries,
# each entry must have: 'source'
# may have: key, ( keyid and keyserver)
def add_sources(srclist, searchList={ }):
elst = []
for ent in srclist:
if not ent.has_key('source'):
elst.append([ "", "missing source" ])
continue
source=ent['source']
if source.startswith("ppa:"):
try: util.subp(["add-apt-repository",source])
except:
elst.append([source, "add-apt-repository failed"])
continue
source = util.render_string(source, searchList)
if not ent.has_key('filename'):
ent['filename']='cloud_config_sources.list'
if not ent['filename'].startswith("/"):
ent['filename'] = "%s/%s" % \
("/etc/apt/sources.list.d/", ent['filename'])
if ( ent.has_key('keyid') and not ent.has_key('key') ):
ks = "keyserver.ubuntu.com"
if ent.has_key('keyserver'): ks = ent['keyserver']
try:
ent['key'] = util.getkeybyid(ent['keyid'], ks)
except:
elst.append([source,"failed to get key from %s" % ks])
continue
if ent.has_key('key'):
try: util.subp(('apt-key', 'add', '-'), ent['key'])
except:
elst.append([source, "failed add key"])
try: util.write_file(ent['filename'], source + "\n", omode="ab")
except:
elst.append([source, "failed write to file %s" % ent['filename']])
return(elst)