#!/usr/bin/env python # -*- coding: utf-8 -*- import os.path import time import tarfile import utils from metafile import Metafile, MalformedMetafileError # ----------------------------------------------------------------------------- def init(parser): parser.add_argument( "apps", type=str, nargs="*", default=[], help="The apps to package ; defaults to all " \ "apps" ) parser.add_argument( "--pkgtype", "-t", type=str, nargs="?", default="tgz", choices = [ "tgz" ], help="The type of package to use" ) parser.add_argument( "--pkgname", "-p", type=str, nargs="?", default="persoconf." + (time.strftime("%Y%m%d")), help="The name of the package to create" ) parser.add_argument( "--nopersoconf", "-n", action="store_true", help="Do not include persoconf own config " \ "directory in the resulting package" ) # ----------------------------------------------------------------------------- def run(args, persoconf, logger): pkgname = args.pkgname # If no app is given: package all apps if args.apps == []: logger.info("Packaging all apps") args.apps = persoconf.list_apps(logger=logger) # Some apps were specified, so we list them with their files appmetas = [] for app in args.apps : # Load app META file try: appmetas.append( Metafile( json_path = os.path.join( persoconf.path, app, persoconf.metafile ) ) ) except FileNotFoundError: logger.warning( "Metafile %s does not exist for app %s; ignoring" % (persoconf.metafile, app) ) continue except MalformedMetafileError: logger.warning( "Malformed metafile %s in app %s; ignoring" % (persoconf.metafile, app) ) continue # TODO check that the app exists # Adds the app name if there is only one packaged if len(appmetas) == 1: pkgname += ("." + appmetas[0].name) # Switch according to the pkgtype if args.pkgtype == "tgz": pkgname += ".tgz" # Create a tar containing the files in the right place pkg = tarfile.open(pkgname, "w:gz") for appmeta in appmetas: # Add META file to the archive if not args.nopersoconf: filename_meta = os.path.join( persoconf.path, appmeta.name, persoconf.metafile ) filedest_meta = utils.contractuser( filename_meta ) if filedest_meta.startswith("~/"): filedest_meta = filedest_meta[2:] try: pkg.add(filename_meta, arcname=filedest_meta) logger.info( "Adding app %s to package".format(appmeta.name) ) except Exception as e: logger.warning( "Failed to add app {app} to tar package {pkg}: {err}" \ .format( app = appmeta.name, pkg = pkgname, err = str(e) ) ) for f in appmeta.files: filename = os.path.join( persoconf.path, appmeta.name, f ) filedest = appmeta.files[f]["dest"] filedest_pc = utils.contractuser( filename ) # Remove possible 'home'. The final targz should be extracted # at $HOME. if filedest.startswith("~/"): filedest = filedest[2:] if filedest_pc.startswith("~/"): filedest_pc = filedest_pc[2:] # TODO save and restore owners and permissions try: pkg.add(filename, arcname=filedest) if not args.nopersoconf: pkg.add(filename, arcname=filedest_pc) logger.info("Adding %s to package" % f) except Exception as e: logger.warning( "Failed to add %s to tar package %s: %s" % (f, pkgname, str(e)) ) pkg.close()