--- /dev/null
+#!/usr/bin/python
+
+import urllib, sys, optparse, re, subprocess
+
+kernel_pkg_re = re.compile('linux-(generic|firmware|headers|image|backports|ec2|source|virtual|preempt)')
+
+def parse_argv():
+ '''Parse CLI options.
+
+ Return (options, manifest) tuple.
+ '''
+
+ optparser = optparse.OptionParser('''%prog [options] <manifest>
+
+Install/remove packages according to a CD build manifest.
+<manifest> can be a local file or URL.''')
+ optparser.add_option('-k', '--keep-kernel',
+ help='Do not change kernel packages', action='store_true',
+ dest='keep_kernel', default=False)
+ options, args = optparser.parse_args()
+
+ if len(args) != 1:
+ optparser.error('You need to specify exactly one manifest argument, see --help')
+ sys.exit(1)
+
+ return (options, args[0])
+
+#
+# main
+#
+
+(options, manifest) = parse_argv()
+
+selection = ''
+for l in urllib.urlopen(manifest):
+ pkg = l.split()[0]
+ if options.keep_kernel and kernel_pkg_re.match(pkg):
+ continue
+ selection += '%s\tinstall\n' % pkg
+
+# add local kernel packages on --keep-kernel
+if options.keep_kernel:
+ dpkg = subprocess.Popen(['dpkg', '--get-selections'],
+ stdout=subprocess.PIPE)
+ for l in dpkg.stdout:
+ pkg, status = l.split()
+ if status != 'install':
+ continue
+ if kernel_pkg_re.match(pkg):
+ selection += '%s\tinstall\n' % pkg
+
+if subprocess.call(['which', 'dselect'], stdout=subprocess.PIPE) != 0:
+ print >> sys.stderr, 'INFO: installing dselect (needed by this script)'
+ assert subprocess.call(['apt-get', '-y', 'install', 'dselect']) == 0
+
+# now apply the new selections
+assert subprocess.call(['dpkg', '--clear-selections']) == 0
+dpkg = subprocess.Popen(['dpkg', '--set-selections'], stdin=subprocess.PIPE)
+dpkg.communicate(selection)
+assert dpkg.returncode == 0
+
+# commit!
+subprocess.call(['dselect', 'install'])