#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
#
import fnmatch
import getopt
import gettext
import locale
import os
import six
import sys
import traceback
import warnings
import errno
else:
# These attributes should always be stripped from input manifests for 'publish';
# they will be re-calculated during publication.
strip_attrs = [
"elfarch",
"elfbits",
"elfhash",
"pkg.content-hash",
"pkg.csize",
"pkg.size",
]
"""Emit an error message prefixed by the command name """
# Assume it's an object that can be stringified.
# If the message starts with whitespace, assume that it should come
# *before* the command-name prefix.
if cmd:
pkg_cmd = "pkgsend "
else:
pkg_cmd = "pkgsend: "
# This has to be a constant value as we can't reliably get our actual
# program name on all platforms.
"""Emit a usage message and optionally prefix it with a more specific
error message. Causes program to exit."""
if usage_error:
print(_("""\
Usage:
pkgsend [options] command [cmd_options] [operands]
Packager subcommands:
pkgsend generate [-T pattern] [-u] [--target file] source ...
pkgsend publish [-b bundle ...] [-d source ...] [-s repo_uri_or_path]
[-T pattern] [--key ssl_key ... --cert ssl_cert ...]
[--no-catalog] [manifest ...]
Options:
--help or -? display usage message
Environment:
PKG_REPO The path or URI of the destination repository."""))
"""Used to gather information about the SVR4 packages we visit"""
# a list of classes for which we do not report warnings
"""visit a pkg.bundle.SolarisPackage*Bundle object"""
return
"WARNING: Several SVR4 packages detected. "
"Multiple pkg.summary and pkg.description "
"attributes may have been generated."))
continue
if svr4_class and \
_("ERROR: class action script "
"used in {pkg}: {path} belongs "
"to \"{classname}\" class").format(
_("ERROR: script present in {pkg}: {script}").format(
"""DEPRECATED"""
repo_props = {}
if opt == "--set-property":
try:
except ValueError:
usage(_("property arguments must be of "
"the form '<section.property>="
try:
except trans.TransactionRepositoryConfigError as e:
emsg(_("Invalid repository configuration values were "
"specified using --set-property or required values are "
"values using the --set-property option."))
except trans.TransactionError as e:
return EXIT_OOPS
return EXIT_OK
"""DEPRECATED"""
parsed = []
if opt == "-e":
if opt == "-n":
if eval_form:
else:
return EXIT_OK
"""DEPRECATED"""
parsed = []
if opt == "-e":
if opt == "-n":
if eval_form:
else:
return EXIT_OK
"""DEPRECATED"""
trans_id = None
# --no-index is now silently ignored as the publication process no
# longer builds search indexes automatically.
if opt == "-A":
elif opt == "-t":
elif opt == "--no-catalog":
if trans_id is None:
try:
except KeyError:
usage(_("No transaction ID specified using -t or in "
if val is not None:
return EXIT_OK
"""DEPRECATED"""
try:
except KeyError:
usage(_("No transaction ID specified in $PKG_TRANS_ID"),
cmd="add")
if not args:
cmd="add")
return EXIT_OOPS
return EXIT_OK
"""Publish packages in a single step using provided manifest data and
sources."""
# --no-index is now silently ignored as the publication process no
# longer builds search indexes automatically.
"no-index", "no-catalog", "key=", "cert="])
basedirs = []
bundles = []
timestamp_files = []
key = None
cert = None
if opt == "-b":
elif opt == "-d":
elif opt == "-s":
elif opt == "-T":
elif opt == "--no-catalog":
elif opt == "--key":
elif opt == "--cert":
if not repo_uri:
usage(_("A destination package repository must be provided "
if not pargs:
else:
try:
except IOError as e:
return EXIT_OOPS
linecnts = [] # tuples of starting line number, ending line number
try:
except IOError as e:
return EXIT_OOPS
f.close()
try:
break
else:
filename = "???"
lineno = "???"
cmd="publish")
return EXIT_OOPS
try:
# Cannot have a FMRI without version
error(_("The pkg.fmri attribute '{0}' in the package "
cmd="publish")
return EXIT_OOPS
if not DebugValues["allow-timestamp"]:
# If not debugging, timestamps are ignored.
except KeyError:
error(_("Manifest does not set pkg.fmri"))
return EXIT_OOPS
t.open()
target_files = []
if bundles:
# Ensure hardlinks marked as files in the manifest are
# treated as files. This necessary when sourcing files
# from some bundle types.
a.attrs["path"]
for a in m.gen_actions()
if a.name == "file"
)
bundles = [
]
for a in m.gen_actions():
# don't publish these actions
if a.name == "signature":
a)))
continue
continue
elif a.has_payload:
# Forcibly discard content-related attributes to prevent
# errors when reusing manifests with different content.
for attr in strip_attrs:
elif a.name in nopub_actions:
return EXIT_OOPS
if a.name == "file":
for pattern in timestamp_files:
# Target is from bundle; can't
# apply timestamp now.
continue
break
try:
t.add(a)
except:
raise
if val is not None:
return EXIT_OK
"""DEPRECATED"""
basedirs = []
timestamp_files = []
if opt == "-d":
elif opt == "-T":
if transaction == None:
try:
except KeyError:
usage(_("No transaction ID specified in $PKG_TRANS_ID"),
cmd="include")
else:
t = transaction
if not pargs:
else:
try:
except IOError as e:
return EXIT_OOPS
lines = [] # giant string of all input files concatenated together
linecnts = [] # tuples of starting line number, ending line number
try:
except IOError as e:
return EXIT_OOPS
try:
break
else:
filename = "???"
lineno = "???"
cmd="include")
return EXIT_OOPS
for a in m.gen_actions():
# don't publish this action
continue
elif a.has_payload:
if a.name == "file":
for pattern in timestamp_files:
break
if a.name in nopub_actions:
else:
t.add(a)
if invalid_action:
return EXIT_PARTIAL
else:
return EXIT_OK
for pattern in timestamp_files:
break
else:
if minimal:
# pkgsend import needs attributes such as size
# retained so that the publication modules know
# how many bytes to read from the .data prop.
# However, pkgsend generate attempts to
# minimize the attributes output for each
# action to only those necessary for use
# so that the resulting manifest remains valid
# even after mogrification or changing content.
"""DEPRECATED"""
try:
except KeyError:
print(_("No transaction ID specified in $PKG_TRANS_ID"),
timestamp_files = []
target_files = []
if opt == "-T":
elif opt == "--target":
if not args:
usage(_("No arguments specified for subcommand."),
cmd="import")
try:
if err:
else:
if not abandon:
except TypeError as e:
return EXIT_OOPS
except EnvironmentError as e:
cmd="import")
return EXIT_OOPS
else:
raise
if abandon:
error("Abandoning transaction due to errors.")
return ret
"""Generate a package manifest based on the provided sources."""
timestamp_files = []
target_files = []
if opt == "-T":
elif opt == "--target":
elif opt == "-u":
if not args:
usage(_("No arguments specified for subcommand."),
cmd="generate")
try:
print(action)
except TypeError as e:
return EXIT_OOPS
except EnvironmentError as e:
cmd="generate")
return EXIT_OOPS
else:
raise
return EXIT_OK
"""DEPRECATED"""
if args:
usage(_("command does not take operands"),
cmd="refresh-index")
try:
except trans.TransactionError as e:
return EXIT_OOPS
return EXIT_OK
ssl_cert=None):
return None, None
def main_func():
try:
if opt == "-s":
if arg == "allow-timestamp":
else:
try:
except (AttributeError, ValueError):
usage(_("{opt} takes argument of form "
"name=value, not {arg}").format(
except getopt.GetoptError as e:
if DebugValues:
subcommand = None
if pargs:
if subcommand == "help":
if show_usage:
elif not subcommand:
usage()
"publish"):
usage(_("A destination package repository must be provided "
visitors = [SolarisBundleVisitor()]
try:
if subcommand == "create-repository":
elif subcommand == "open":
elif subcommand == "append":
elif subcommand == "close":
elif subcommand == "add":
elif subcommand == "import":
elif subcommand == "include":
elif subcommand == "publish":
elif subcommand == "generate":
elif subcommand == "refresh-index":
else:
if not printed_space:
print("")
if not printed_space:
print("")
except getopt.GetoptError as e:
return ret
#
# Establish a specific exit status which means: "python barfed an exception"
# so that we can more easily detect these in testing of the CLI commands.
#
if __name__ == "__main__":
# Make all warnings be errors.
# disable ResourceWarning: unclosed file
try:
except (PipeError, KeyboardInterrupt):
# We don't want to display any messages here to prevent
# possible further broken pipe (EPIPE) errors.
# Only print message if failure wasn't due to
# broken pipe (EPIPE) error.
except MemoryError:
except SystemExit as _e:
raise _e
except: