#!/usr/local/bin/dib-python # Copyright 2014 Hewlett-Packard Development Company, L.P. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. from __future__ import print_function import argparse import json import subprocess import sys # run a command, return output # if follow is set, output will be echoed to stdout def process_output(cmdline, follow=False): proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE, universal_newlines=True) if follow: print("Running command: %s" % cmdline) out = "" with proc.stdout: for line in iter(proc.stdout.readline, ''): out += line print("> %s" % line, end="") proc.wait() print("returncode: %d" % proc.returncode) else: out = proc.communicate()[0] if proc.returncode: e = subprocess.CalledProcessError(proc.returncode, cmdline) e.output = out raise e return out def main(): parser = argparse.ArgumentParser( description="Install or uninstall packages for a specific phase based" " on package-installs files.") parser.add_argument('--phase', required=True, help="Install phase to filter on. Valid options are" " 'install.d' or pre-install.d") parser.add_argument('--uninstall', action="store_true", help="Only show packages to uninstall. By default only" " packages to install are shown") parser.add_argument('-n', '--noop', action="store_true", help="Don't actually install, just print the command") parser.add_argument('infile', help="File to process") args = parser.parse_args() packages = json.load(open(args.infile)) if args.uninstall: install = "uninstall" else: install = "install" pkgs = list() if args.phase in packages and install in packages[args.phase]: install_packages = packages[args.phase][install] else: print("Nothing to %s" % install) sys.exit(0) for (pkg, element) in install_packages: print("%sing %s from %s" % (install, pkg, element)) pkg_map_args = ['pkg-map', '--missing-ok', '--element', element, pkg] try: map_output = process_output(pkg_map_args) pkgs.extend(map_output.strip().split('\n')) except subprocess.CalledProcessError as e: if e.returncode == 1: if args.noop: pkgs.append(pkg) continue else: print("pkg-map failed") sys.exit(1) elif e.returncode == 2: pkgs.append(pkg) continue install_args = ["install-packages"] if args.uninstall: install_args.append("-e") install_args.extend(list(set(pkgs))) if args.noop: print(" ".join(install_args)) else: try: process_output(install_args, follow=True) except subprocess.CalledProcessError as e: print("install failed with error %s" % e.output) sys.exit(1) if __name__ == '__main__': main() # Tell emacs to use python-mode # Local variables: # mode: python # End: