def __call(args, zone=None): # a way to invoke a separate executable for testing cmds_dir = DebugValues.get_value("smf_cmds_dir") # returned values will be in the user's locale # so we need to ensure that the force_str uses # their locale. encoding = locale.getpreferredencoding(do_setlocale=False) if cmds_dir: args = ( os.path.join(cmds_dir, args[0].lstrip("/")),) + args[1:] if zone: cmd = DebugValues.get_value("bin_zlogin") if cmd is None: cmd = zlogin_path args = (cmd, zone) + args try: proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) buf = [misc.force_str(l, encoding=encoding) for l in proc.stdout.readlines()] ret = proc.wait() except OSError as e: raise RuntimeError("cannot execute {0}: {1}".format(args, e)) if ret != 0: raise NonzeroExitException(args, ret, buf) return buf
def main_func(): gettext.install("pkg", "/usr/share/locale", codeset=locale.getpreferredencoding()) repo_uri = os.getenv("PKG_REPO", None) show_usage = False global_settings.client_name = "pkgsend" try: opts, pargs = getopt.getopt(sys.argv[1:], "s:D:?", ["help"]) for opt, arg in opts: if opt == "-s": repo_uri = arg elif opt == "-D": if arg == "allow-timestamp": key = arg value = True else: try: key, value = arg.split("=", 1) except (AttributeError, ValueError): usage(_("%(opt)s takes argument of form " "name=value, not %(arg)s") % { "opt": opt, "arg": arg }) DebugValues.set_value(key, value) elif opt in ("--help", "-?"): show_usage = True except getopt.GetoptError, e: usage(_("illegal global option -- %s") % e.opt)
def exec_prep(self, image): if not image.is_liveroot(): dir = DebugValues.get_value("actuator_cmds_dir") if not dir: return self.cmd_path = dir self.do_nothing = False
def _zonename(): """Get the zonname of the current system.""" cmd = DebugValues.get_value("zone_name") # pylint: disable=E1120 if not cmd: cmd = ["/bin/zonename"] # if the command doesn't exist then bail. if not li.path_exists(cmd[0]): return fout = tempfile.TemporaryFile() ferrout = tempfile.TemporaryFile() p = pkg.pkgsubprocess.Popen(cmd, stdout=fout, stderr=ferrout) p.wait() if (p.returncode != 0): cmd = " ".join(cmd) ferrout.seek(0) errout = "".join(ferrout.readlines()) raise apx.LinkedImageException( cmd_failed=(p.returncode, cmd, errout)) # parse the command output fout.seek(0) l = fout.readlines()[0].rstrip() return l
def _zonename(): """Get the zonname of the current system.""" cmd = DebugValues.get_value("bin_zonename") # pylint: disable=E1120 if cmd is not None: cmd = [cmd] else: cmd = ["/bin/zonename"] # if the command doesn't exist then bail. if not li.path_exists(cmd[0]): return # open a temporary file in text mode for compatible string handling fout = tempfile.TemporaryFile(mode="w+") ferrout = tempfile.TemporaryFile(mode="w+") p = pkg.pkgsubprocess.Popen(cmd, stdout=fout, stderr=ferrout) p.wait() if p.returncode != 0: cmd = " ".join(cmd) ferrout.seek(0) errout = "".join(ferrout.readlines()) ferrout.close() raise apx.LinkedImageException(cmd_failed=(p.returncode, cmd, errout)) # parse the command output fout.seek(0) l = fout.readlines()[0].rstrip() fout.close() return l
def exec_prep(self, image): if not image.is_liveroot(): cmds_dir = DebugValues.get_value("actuator_cmds_dir") if not cmds_dir: return self.cmd_path = cmds_dir self.do_nothing = False
def exec_prep(self, image): if not image.is_liveroot(): # # XXX don't create the marker file as illumos doesn't support self-assembly # milestone # # # we're doing off-line pkg ops; we need # # to support self-assembly milestone # # so create the necessary marker file # # if image.type != IMG_USER: # path = os.path.join(image.root, # ".SELF-ASSEMBLY-REQUIRED") # # create only if it doesn't exist # # if not os.path.exists(path): # os.close(os.open(path, # os.O_EXCL | # os.O_CREAT | # os.O_WRONLY)) if not DebugValues.get_value("smf_cmds_dir") and \ not self.zone: return self.do_nothing = False
def __usr_sbin_init(): """Initialize paths to device management commands that we will execute when handling package driver actions""" usr_sbin = DebugValues.get("driver-cmd-dir", "/usr/sbin") + "/" DriverAction.usr_sbin = usr_sbin DriverAction.add_drv = usr_sbin + "add_drv" DriverAction.rem_drv = usr_sbin + "rem_drv" DriverAction.update_drv = usr_sbin + "update_drv"
def __call(args): # a way to invoke a separate executable for testing cmds_dir = DebugValues.get_value("smf_cmds_dir") if cmds_dir: args = (os.path.join(cmds_dir, args[0].lstrip("/")),) + args[1:] try: proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) buf = proc.stdout.readlines() ret = proc.wait() except OSError, e: raise RuntimeError, "cannot execute %s: %s" % (args, e)
def __call(args, zone=None): # a way to invoke a separate executable for testing cmds_dir = DebugValues.get_value("smf_cmds_dir") if cmds_dir: args = (os.path.join(cmds_dir, args[0].lstrip("/")), ) + args[1:] if zone: cmd = DebugValues.get_value("bin_zlogin") if cmd is None: cmd = zlogin_path args = (cmd, zone) + args try: proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) buf = [misc.force_str(l) for l in proc.stdout.readlines()] ret = proc.wait() except OSError as e: raise RuntimeError("cannot execute {0}: {1}".format(args, e)) if ret != 0: raise NonzeroExitException(args, ret, buf) return buf
def __zones_supported(self): """Check to see if zones are supported in the current image. i.e. can the current image have zone children.""" # pylint: disable=E1120 if DebugValues.get_value("zones_supported"): return True # pylint: enable=E1120 # first check if the image variant is global variant = "variant.opensolaris.zone" value = self.__img.cfg.variants[variant] if value != "global": return False # # sanity check the path to to /etc/zones. below we check for # the zones packages, and any image that has the zones # packages installed should have a /etc/zones file (since # those packages deliver this file) but it's possible that the # image was corrupted and the user now wants to be able to run # pkg commands to fix it. if the path doesn't exist then we # don't have any zones so just report that zones are # unsupported (since zoneadm may fail to run anyway). # path = self.__img.root if not os.path.isdir(os.path.join(path, "etc")): return False if not os.path.isdir(os.path.join(path, "etc/zones")): return False # get a set of installed packages cati = self.__img.get_catalog(self.__img.IMG_CATALOG_INSTALLED) pkgs_inst = frozenset([ stem # Unused variable 'pub'; pylint: disable=W0612 for pub, stem in cati.pkg_names() # pylint: enable=W0612 ]) # check if the zones packages are installed for pkgs in self.__zone_pkgs: if (pkgs & pkgs_inst) == pkgs: return True return False
def exec_prep(self, image): if not image.is_liveroot(): # we're doing off-line pkg ops; we need # to support self-assembly milestone # so create the necessary marker file if image.type != IMG_USER: path = os.path.join(image.root, ".SELF-ASSEMBLY-REQUIRED") # create only if it doesn't exist if not os.path.exists(path): os.close(os.open(path, os.O_EXCL | os.O_CREAT | os.O_WRONLY)) if not DebugValues.get_value("smf_cmds_dir"): return self.do_nothing = False
def __init__(self, data=None, **attrs): generic.Action.__init__(self, data, **attrs) if not self.__class__.usr_sbin: usr_sbin = DebugValues.get("driver-cmd-dir", "/usr/sbin") + "/" self.__class__.usr_sbin = usr_sbin self.__class__.add_drv = usr_sbin + "add_drv" self.__class__.rem_drv = usr_sbin + "rem_drv" self.__class__.update_drv = usr_sbin + "update_drv" # # Clean up clone_perms. This attribute may been specified either as: # # <minorname> <mode> <owner> <group> # # or # # <mode> <owner> <group> # # In the latter case, the <minorname> is assumed to be # the same as the driver name. Correct any such instances # here so that there is only one form, so that we can cleanly # compare, verify, etc. # if not self.attrlist("clone_perms"): return new_cloneperms = [] for cp in self.attrlist("clone_perms"): # If we're given three fields, assume the minor node # name is the same as the driver name. if len(cp.split()) == 3: new_cloneperms.append( self.attrs["name"] + " " + cp) else: new_cloneperms.append(cp) if len(new_cloneperms) == 1: self.attrs["clone_perms"] = new_cloneperms[0] else: self.attrs["clone_perms"] = new_cloneperms
def __init__(self, data=None, **attrs): generic.Action.__init__(self, data, **attrs) if not self.__class__.usr_sbin: usr_sbin = DebugValues.get("driver-cmd-dir", "/usr/sbin") + "/" self.__class__.usr_sbin = usr_sbin self.__class__.add_drv = usr_sbin + "add_drv" self.__class__.rem_drv = usr_sbin + "rem_drv" self.__class__.update_drv = usr_sbin + "update_drv" # # Clean up clone_perms. This attribute may been specified either as: # # <minorname> <mode> <owner> <group> # # or # # <mode> <owner> <group> # # In the latter case, the <minorname> is assumed to be # the same as the driver name. Correct any such instances # here so that there is only one form, so that we can cleanly # compare, verify, etc. # if not self.attrlist("clone_perms"): return new_cloneperms = [] for cp in self.attrlist("clone_perms"): # If we're given three fields, assume the minor node # name is the same as the driver name. if len(cp.split()) == 3: new_cloneperms.append(self.attrs["name"] + " " + cp) else: new_cloneperms.append(cp) if len(new_cloneperms) == 1: self.attrs["clone_perms"] = new_cloneperms[0] else: self.attrs["clone_perms"] = new_cloneperms
continue # A list of features can be specified using a # "," or any whitespace character as separators. if "," in arg: features = arg.split(",") else: features = arg.split() debug_features.extend(features) # We also allow key=value debug flags, which # get set in pkg.client.debugvalues for feature in features: try: key, val = feature.split("=", 1) DebugValues.set_value(key, val) except (AttributeError, ValueError): pass elif opt == "--disable-ops": if arg is None or arg == "": raise OptionError( "An argument must be specified.") disableops = arg.split(",") for s in disableops: if "/" in s: op, ver = s.rsplit("/", 1) else: op = s ver = "*"
import traceback # pkg classes import pkg.client.api_errors as apx import pkg.client.pkgdefs as pkgdefs import pkg.misc import pkg.nrlock import pkg.pipeutils from pkg.client import global_settings from pkg.client.debugvalues import DebugValues # debugging aids # DebugValues is a singleton; pylint: disable=E1120 pkgremote_debug = ( DebugValues.get_value("pkgremote_debug") is not None or os.environ.get("PKG_PKGREMOTE_DEBUG", None) is not None) class PkgRemote(object): """This class is used to perform packaging operation on an image. It utilizes the "remote" subcommand within the pkg.1 client to manipulate images. Communication between this class and the "pkg remote" process is done via RPC. This class essentially implements an RPC client and the "pkg remote" process is an RPC server.""" # variables to keep track of our RPC client call state. __IDLE = "call-idle" __SETUP = "call-setup" __STARTED = "call-started" def __init__(self):
def _list_zones(root, path_transform): """Get the zones associated with the image located at 'root'. We return a dictionary where the keys are zone names and the values are tuples containing zone root path and current state. The global zone is excluded from the results. Solaris10 branded zones are excluded from the results.""" rv = dict() cmd = DebugValues.get_value("bin_zoneadm") # pylint: disable=E1120 if cmd is not None: cmd = [cmd] else: cmd = ["/usr/sbin/zoneadm"] # if the command doesn't exist then bail. if not li.path_exists(cmd[0]): return rv # make sure "root" has a trailing '/' root = root.rstrip(os.sep) + os.sep # create the zoneadm command line cmd.extend(["-R", str(root), "list", "-cp"]) # execute zoneadm and save its output to a file # open a temporary file in text mode for compatible string handling fout = tempfile.TemporaryFile(mode="w+") ferrout = tempfile.TemporaryFile(mode="w+") p = pkg.pkgsubprocess.Popen(cmd, stdout=fout, stderr=ferrout) p.wait() if p.returncode != 0: cmd = " ".join(cmd) ferrout.seek(0) errout = "".join(ferrout.readlines()) ferrout.close() raise apx.LinkedImageException(cmd_failed=(p.returncode, cmd, errout)) # parse the command output fout.seek(0) output = fout.readlines() fout.close() for l in output: l = l.rstrip() z_name, z_state, z_path, z_brand = \ _zoneadm_list_parse(l, cmd, output) # skip brands that we don't care about # W0511 XXX / FIXME Comments; pylint: disable=W0511 # XXX: don't hard code brand names, use a brand attribute # pylint: enable=W0511 if z_brand not in ["lipkg", "solaris", "sn1", "labeled", "sparse"]: continue # we don't care about the global zone. if z_name == "global": continue # append "/root" to zonepath z_rootpath = os.path.join(z_path, "root") assert z_rootpath.startswith(root), \ "zone path '{0}' doesn't begin with '{1}".format( z_rootpath, root) # If there is a current path transform in effect then revert # the path reported by zoneadm to the original zone path. if li.path_transform_applied(z_rootpath, path_transform): z_rootpath = li.path_transform_revert(z_rootpath, path_transform) # we only care about zones that have been installed if z_state not in zone_installed_states: continue rv[z_name] = (z_rootpath, z_state) return rv
def main_func(): global_settings.client_name = "pkgsign" try: opts, pargs = getopt.getopt(sys.argv[1:], "a:c:i:k:ns:D:", ["help", "no-index", "no-catalog"]) except getopt.GetoptError as e: usage(_("illegal global option -- {0}").format(e.opt)) show_usage = False sig_alg = "rsa-sha256" cert_path = None key_path = None chain_certs = [] add_to_catalog = True set_alg = False dry_run = False repo_uri = os.getenv("PKG_REPO", None) for opt, arg in opts: if opt == "-a": sig_alg = arg set_alg = True elif opt == "-c": cert_path = os.path.abspath(arg) if not os.path.isfile(cert_path): usage(_("{0} was expected to be a certificate " "but isn't a file.").format(cert_path)) elif opt == "-i": p = os.path.abspath(arg) if not os.path.isfile(p): usage(_("{0} was expected to be a certificate " "but isn't a file.").format(p)) chain_certs.append(p) elif opt == "-k": key_path = os.path.abspath(arg) if not os.path.isfile(key_path): usage(_("{0} was expected to be a key file " "but isn't a file.").format(key_path)) elif opt == "-n": dry_run = True elif opt == "-s": repo_uri = misc.parse_uri(arg) elif opt == "--help": show_usage = True elif opt == "--no-catalog": add_to_catalog = False elif opt == "-D": try: key, value = arg.split("=", 1) DebugValues.set_value(key, value) except (AttributeError, ValueError): error(_("{opt} takes argument of form " "name=value, not {arg}").format( opt=opt, arg=arg)) if show_usage: usage(retcode=EXIT_OK) if not repo_uri: usage(_("a repository must be provided")) if key_path and not cert_path: usage(_("If a key is given to sign with, its associated " "certificate must be given.")) if cert_path and not key_path: usage(_("If a certificate is given, its associated key must be " "given.")) if chain_certs and not cert_path: usage(_("Intermediate certificates are only valid if a key " "and certificate are also provided.")) if not pargs: usage(_("At least one fmri or pattern must be provided to " "sign.")) if not set_alg and not key_path: sig_alg = "sha256" s, h = actions.signature.SignatureAction.decompose_sig_alg(sig_alg) if h is None: usage(_("{0} is not a recognized signature algorithm.").format( sig_alg)) if s and not key_path: usage(_("Using {0} as the signature algorithm requires that a " "key and certificate pair be presented using the -k and -c " "options.").format(sig_alg)) if not s and key_path: usage(_("The {0} hash algorithm does not use a key or " "certificate. Do not use the -k or -c options with this " "algorithm.").format(sig_alg)) if DebugValues: reload(digest) errors = [] t = misc.config_temp_root() temp_root = tempfile.mkdtemp(dir=t) del t cache_dir = tempfile.mkdtemp(dir=temp_root) incoming_dir = tempfile.mkdtemp(dir=temp_root) chash_dir = tempfile.mkdtemp(dir=temp_root) cert_dir = tempfile.mkdtemp(dir=temp_root) try: chain_certs = [ __make_tmp_cert(cert_dir, c) for c in chain_certs ] if cert_path is not None: cert_path = __make_tmp_cert(cert_dir, cert_path) xport, xport_cfg = transport.setup_transport() xport_cfg.add_cache(cache_dir, readonly=False) xport_cfg.incoming_root = incoming_dir # Configure publisher(s) transport.setup_publisher(repo_uri, "source", xport, xport_cfg, remote_prefix=True) pats = pargs successful_publish = False concrete_fmris = [] unmatched_pats = set(pats) all_pats = frozenset(pats) get_all_pubs = False pub_prefs = set() # Gather the publishers whose catalogs will be needed. for pat in pats: try: p_obj = fmri.MatchingPkgFmri(pat) except fmri.IllegalMatchingFmri as e: errors.append(e) continue pub_prefix = p_obj.get_publisher() if pub_prefix: pub_prefs.add(pub_prefix) else: get_all_pubs = True # Check each publisher for matches to our patterns. for p in xport_cfg.gen_publishers(): if not get_all_pubs and p.prefix not in pub_prefs: continue cat = fetch_catalog(p, xport, temp_root) ms, tmp1, u = cat.get_matching_fmris(pats) # Find which patterns matched. matched_pats = all_pats - u # Remove those patterns from the unmatched set. unmatched_pats -= matched_pats for v_list in ms.values(): concrete_fmris.extend([(v, p) for v in v_list]) if unmatched_pats: raise api_errors.PackageMatchErrors( unmatched_fmris=unmatched_pats) for pfmri, src_pub in sorted(set(concrete_fmris)): try: # Get the existing manifest for the package to # be signed. m_str = xport.get_manifest(pfmri, content_only=True, pub=src_pub) m = manifest.Manifest() m.set_content(content=m_str) # Construct the base signature action. attrs = { "algorithm": sig_alg } a = actions.signature.SignatureAction(cert_path, **attrs) a.hash = cert_path # Add the action to the manifest to be signed # since the action signs itself. m.add_action(a, misc.EmptyI) # Set the signature value and certificate # information for the signature action. a.set_signature(m.gen_actions(), key_path=key_path, chain_paths=chain_certs, chash_dir=chash_dir) # The hash of 'a' is currently a path, we need # to find the hash of that file to allow # comparison to existing signatures. hsh = None if cert_path: # Action identity still uses the 'hash' # member of the action, so we need to # stay with the sha1 hash. hsh, _dummy = \ misc.get_data_digest(cert_path, hash_func=hashlib.sha1) # Check whether the signature about to be added # is identical, or almost identical, to existing # signatures on the package. Because 'a' has # already been added to the manifest, it is # generated by gen_actions_by_type, so the cnt # must be 2 or higher to be an issue. cnt = 0 almost_identical = False for a2 in m.gen_actions_by_type("signature"): try: if a.identical(a2, hsh): cnt += 1 except api_errors.AlmostIdentical as e: e.pkg = pfmri errors.append(e) almost_identical = True if almost_identical: continue if cnt == 2: continue elif cnt > 2: raise api_errors.DuplicateSignaturesAlreadyExist(pfmri) assert cnt == 1, "Cnt was:{0}".format(cnt) if not dry_run: # Append the finished signature action # to the published manifest. t = trans.Transaction(repo_uri, pkg_name=str(pfmri), xport=xport, pub=src_pub) try: t.append() t.add(a) for c in chain_certs: t.add_file(c) t.close(add_to_catalog= add_to_catalog) except: if t.trans_id: t.close(abandon=True) raise msg(_("Signed {0}").format(pfmri.get_fmri( include_build=False))) successful_publish = True except (api_errors.ApiException, fmri.FmriError, trans.TransactionError) as e: errors.append(e) if errors: error("\n".join([str(e) for e in errors])) if successful_publish: return EXIT_PARTIAL else: return EXIT_OOPS return EXIT_OK except api_errors.ApiException as e: error(e) return EXIT_OOPS finally: shutil.rmtree(temp_root)
def main_func(): # some sensible defaults host = "0.0.0.0" # the port we listen on port = None # a list of (repo_dir, repo_prefix) tuples repo_info = [] # the path where we store indexes and disk caches cache_dir = None # our maximum cache size, in megabytes cache_size = 0 # whether we're writing a full httpd.conf, or just a fragment fragment = False # an optional url-prefix, used to separate pkg5 services from the rest # of the webserver url namespace, only used when running in fragment # mode, otherwise we assume we're the only service running on this # web server instance, and control the entire server URL namespace. sroot = "" # the path where our Mako templates and wsgi scripts are stored template_dir = "/etc/pkg/depot" # a volatile directory used at runtime for storing state runtime_dir = None # where logs are written log_dir = "/var/log/pkg/depot" # whether we should pull configuration from # svc:/application/pkg/server instances use_smf_instances = False # whether we allow admin/0 operations to rebuild the index allow_refresh = False # the current server_type server_type = "apache2" try: opts, pargs = getopt.getopt(sys.argv[1:], "Ac:d:Fh:l:P:p:r:Ss:t:T:?", ["help", "debug="]) for opt, arg in opts: if opt == "--help": usage() elif opt == "-h": host = arg elif opt == "-c": cache_dir = arg elif opt == "-s": cache_size = arg elif opt == "-l": log_dir = arg elif opt == "-p": port = arg elif opt == "-r": runtime_dir = arg elif opt == "-T": template_dir = arg elif opt == "-t": server_type = arg elif opt == "-d": if "=" not in arg: usage(_("-d arguments must be in the " "form <prefix>=<repo path>")) prefix, root = arg.split("=", 1) repo_info.append((root, _affix_slash(prefix))) elif opt == "-P": sroot = _affix_slash(arg) elif opt == "-F": fragment = True elif opt == "-S": use_smf_instances = True elif opt == "-A": allow_refresh = True elif opt == "--debug": try: key, value = arg.split("=", 1) except (AttributeError, ValueError): usage( _("%(opt)s takes argument of form " "name=value, not %(arg)s") % { "opt": opt, "arg": arg }) DebugValues.set_value(key, value) else: usage("unknown option %s" % opt) except getopt.GetoptError, e: usage(_("illegal global option -- %s") % e.opt)
elif opt == "-c": cache_dir = arg elif opt == "-d": target = arg elif opt == "-D": if arg in ["plan", "transport"]: key = arg value = "True" else: try: key, value = arg.split("=", 1) except (AttributeError, ValueError): usage(_("%(opt)s takes argument of form " "name=value, not %(arg)s") % { "opt": opt, "arg": arg }) DebugValues.set_value(key, value) elif opt == "-h": usage(retcode=0) elif opt == "-k": keep_compressed = True elif opt == "-m": if arg == "all-timestamps": all_timestamps = True elif arg == "all-versions": all_versions = True else: usage(_("Illegal option value -- %s") % arg) elif opt == "-n": dry_run = True elif opt == "-r": recursive = True
def main_func(): # some sensible defaults host = "0.0.0.0" # the port we listen on port = None # a list of (repo_dir, repo_prefix) tuples repo_info = [] # the path where we store disk caches cache_dir = None # our maximum cache size, in megabytes cache_size = 0 # whether we're writing a full httpd.conf, or just a fragment fragment = False # Whether we support https service. https = False # The location of server certificate file. ssl_cert_file = "" # The location of server key file. ssl_key_file = "" # The location of the server ca certificate file. ssl_ca_cert_file = "" # The location of the server ca key file. ssl_ca_key_file = "" # Directory for storing generated certificates and keys cert_key_dir = "" # SSL certificate chain file path if the server certificate is not # signed by the top level CA. ssl_cert_chain_file = "" # The pkg/depot smf instance fmri. smf_fmri = "" # an optional url-prefix, used to separate pkg5 services from the rest # of the webserver url namespace, only used when running in fragment # mode, otherwise we assume we're the only service running on this # web server instance, and control the entire server URL namespace. sroot = "" # the path where our Mako templates and wsgi scripts are stored template_dir = "/etc/pkg/depot" # a volatile directory used at runtime for storing state runtime_dir = None # where logs are written log_dir = "/var/log/pkg/depot" # whether we should pull configuration from # svc:/application/pkg/server instances use_smf_instances = False # whether we allow admin/0 operations to rebuild the index allow_refresh = False # the current server_type server_type = "apache2" writable_root_set = False try: opts, pargs = getopt.getopt(sys.argv[1:], "Ac:d:Fh:l:P:p:r:Ss:t:T:?", [ "help", "debug=", "https", "cert=", "key=", "ca-cert=", "ca-key=", "cert-chain=", "cert-key-dir=", "smf-fmri=" ]) for opt, arg in opts: if opt == "--help": usage() elif opt == "-h": host = arg elif opt == "-c": cache_dir = arg elif opt == "-s": cache_size = arg elif opt == "-l": log_dir = arg elif opt == "-p": port = arg elif opt == "-r": runtime_dir = arg elif opt == "-T": template_dir = arg elif opt == "-t": server_type = arg elif opt == "-d": if "=" not in arg: usage( _("-d arguments must be in the " "form <prefix>=<repo path>" "[=writable root]")) components = arg.split("=", 2) if len(components) == 3: prefix, root, writable_root = components writable_root_set = True elif len(components) == 2: prefix, root = components writable_root = None repo_info.append((root, _affix_slash(prefix), writable_root)) elif opt == "-P": sroot = _affix_slash(arg) elif opt == "-F": fragment = True elif opt == "-S": use_smf_instances = True elif opt == "-A": allow_refresh = True elif opt == "--https": https = True elif opt == "--cert": ssl_cert_file = arg elif opt == "--key": ssl_key_file = arg elif opt == "--ca-cert": ssl_ca_cert_file = arg elif opt == "--ca-key": ssl_ca_key_file = arg elif opt == "--cert-chain": ssl_cert_chain_file = arg elif opt == "--cert-key-dir": cert_key_dir = arg elif opt == "--smf-fmri": smf_fmri = arg elif opt == "--debug": try: key, value = arg.split("=", 1) except (AttributeError, ValueError): usage( _("{opt} takes argument of form " "name=value, not {arg}").format(opt=opt, arg=arg)) DebugValues.set_value(key, value) else: usage("unknown option {0}".format(opt)) except getopt.GetoptError as e: usage(_("illegal global option -- {0}").format(e.opt)) if not runtime_dir: usage(_("required runtime dir option -r missing.")) # we need a cache_dir to store the SSLSessionCache if not cache_dir and not fragment: usage(_("cache_dir option -c is required if -F is not used.")) if not fragment and not port: usage(_("required port option -p missing.")) if not use_smf_instances and not repo_info: usage(_("at least one -d option is required if -S is " "not used.")) if repo_info and use_smf_instances: usage(_("cannot use -d and -S together.")) if https: if fragment: usage( _("https configuration is not supported in " "fragment mode.")) if bool(ssl_cert_file) != bool(ssl_key_file): usage( _("certificate and key files must be presented " "at the same time.")) elif not ssl_cert_file and not ssl_key_file: if not cert_key_dir: usage( _("cert-key-dir option is require to " "store the generated certificates and keys")) if ssl_cert_chain_file: usage(_("Cannot use --cert-chain without " "--cert and --key")) if bool(ssl_ca_cert_file) != bool(ssl_ca_key_file): usage( _("server CA certificate and key files " "must be presented at the same time.")) # If fmri is specifed for pkg/depot instance, we need # record the proporty values for updating. if smf_fmri: orig = (ssl_ca_cert_file, ssl_ca_key_file, ssl_cert_file, ssl_key_file) try: ssl_ca_cert_file, ssl_ca_key_file, ssl_cert_file, \ ssl_key_file = \ _generate_server_cert_key(host, port, ca_cert_file=ssl_ca_cert_file, ca_key_file=ssl_ca_key_file, output_dir=cert_key_dir) if ssl_ca_cert_file: msg( _("Server CA certificate is " "located at {0}. Please deploy it " "into /etc/certs/CA directory of " "each client.").format(ssl_ca_cert_file)) except (DepotException, EnvironmentError) as e: error(e) return EXIT_OOPS # Update the pkg/depot instance smf properties if # anything changes. if smf_fmri: dest = (ssl_ca_cert_file, ssl_ca_key_file, ssl_cert_file, ssl_key_file) if orig != dest: prop_list = [ "config/ssl_ca_cert_file", "config/ssl_ca_key_file", "config/ssl_cert_file", "config/ssl_key_file" ] try: _update_smf_props(smf_fmri, prop_list, orig, dest) except (smf.NonzeroExitException, RuntimeError) as e: error(e) return EXIT_OOPS else: if not os.path.exists(ssl_cert_file): error( _("User provided server certificate " "file {0} does not exist.").format(ssl_cert_file)) return EXIT_OOPS if not os.path.exists(ssl_key_file): error( _("User provided server key file {0} " "does not exist.").format(ssl_key_file)) return EXIT_OOPS if ssl_cert_chain_file and not os.path.exists(ssl_cert_chain_file): error( _("User provided certificate chain file " "{0} does not exist.").format(ssl_cert_chain_file)) return EXIT_OOPS else: if ssl_cert_file or ssl_key_file or ssl_ca_cert_file \ or ssl_ca_key_file or ssl_cert_chain_file: usage( _("certificate or key files are given before " "https service is turned on. Use --https to turn " "on the service.")) if smf_fmri: usage(_("cannot use --smf-fmri without --https.")) # We can't support httpd.conf fragments with writable root, because # we don't have the mod_wsgi app that can build the index or serve # search requests everywhere the fragments might be used. (eg. on # non-Solaris systems) if writable_root_set and fragment: usage(_("cannot use -d with writable roots and -F together.")) if fragment and port: usage(_("cannot use -F and -p together.")) if fragment and allow_refresh: usage(_("cannot use -F and -A together.")) if sroot and not fragment: usage(_("cannot use -P without -F.")) if use_smf_instances: try: repo_info = get_smf_repo_info() except DepotException as e: error(e) # In the future we may produce configuration for different # HTTP servers. For now, we only support "apache2" if server_type not in KNOWN_SERVER_TYPES: usage( _("unknown server type {type}. " "Known types are: {known}").format( type=server_type, known=", ".join(KNOWN_SERVER_TYPES))) try: _check_unique_repo_properties(repo_info) except DepotException as e: error(e) ret = refresh_conf(repo_info, log_dir, host, port, runtime_dir, template_dir, cache_dir, cache_size, sroot, fragment=fragment, allow_refresh=allow_refresh, ssl_cert_file=ssl_cert_file, ssl_key_file=ssl_key_file, ssl_cert_chain_file=ssl_cert_chain_file) return ret
def main_func(): repo_uri = os.getenv("PKG_REPO", None) show_usage = False global_settings.client_name = "pkgsend" try: opts, pargs = getopt.getopt(sys.argv[1:], "s:D:?", ["help", "debug="]) for opt, arg in opts: if opt == "-s": repo_uri = arg elif opt == "-D" or opt == "--debug": if arg == "allow-timestamp": key = arg value = True else: try: key, value = arg.split("=", 1) except (AttributeError, ValueError): usage( _("{opt} takes argument of form " "name=value, not {arg}").format(opt=opt, arg=arg)) DebugValues.set_value(key, value) elif opt in ("--help", "-?"): show_usage = True except getopt.GetoptError as e: usage(_("illegal global option -- {0}").format(e.opt)) if repo_uri and not repo_uri.startswith("null:"): repo_uri = misc.parse_uri(repo_uri) if DebugValues: reload(pkg.digest) subcommand = None if pargs: subcommand = pargs.pop(0) if subcommand == "help": show_usage = True if show_usage: usage(retcode=0) elif not subcommand: usage() if not repo_uri and subcommand not in ("create-repository", "generate", "publish"): usage(_("A destination package repository must be provided " "using -s."), cmd=subcommand) visitors = [SolarisBundleVisitor()] ret = EXIT_OK try: if subcommand == "create-repository": ret = trans_create_repository(repo_uri, pargs) elif subcommand == "open": ret = trans_open(repo_uri, pargs) elif subcommand == "append": ret = trans_append(repo_uri, pargs) elif subcommand == "close": ret = trans_close(repo_uri, pargs) elif subcommand == "add": ret = trans_add(repo_uri, pargs) elif subcommand == "import": ret = trans_import(repo_uri, pargs, visitors=visitors) elif subcommand == "include": ret = trans_include(repo_uri, pargs) elif subcommand == "publish": ret = trans_publish(repo_uri, pargs) elif subcommand == "generate": ret = trans_generate(pargs, visitors=visitors) elif subcommand == "refresh-index": ret = trans_refresh_index(repo_uri, pargs) else: usage(_("unknown subcommand '{0}'").format(subcommand)) printed_space = False for visitor in visitors: for warn in visitor.warnings: if not printed_space: print("") printed_space = True error(warn, cmd=subcommand) for err in visitor.errors: if not printed_space: print("") printed_space = True error(err, cmd=subcommand) ret = EXIT_OOPS except pkg.bundle.InvalidBundleException as e: error(e, cmd=subcommand) ret = EXIT_OOPS except getopt.GetoptError as e: usage( _("illegal {cmd} option -- {opt}").format(cmd=subcommand, opt=e.opt)) return ret
import six # pkg classes import pkg.client.api_errors as apx import pkg.client.pkgdefs as pkgdefs import pkg.misc import pkg.nrlock import pkg.pipeutils from pkg.client import global_settings from pkg.client.debugvalues import DebugValues # debugging aids # DebugValues is a singleton; pylint: disable=E1120 pkgremote_debug = (DebugValues.get_value("pkgremote_debug") is not None or os.environ.get("PKG_PKGREMOTE_DEBUG", None) is not None) class PkgRemote(object): """This class is used to perform packaging operation on an image. It utilizes the "remote" subcommand within the pkg.1 client to manipulate images. Communication between this class and the "pkg remote" process is done via RPC. This class essentially implements an RPC client and the "pkg remote" process is an RPC server.""" # variables to keep track of our RPC client call state. __IDLE = "call-idle" __SETUP = "call-setup" __STARTED = "call-started"