Exemple #1
0
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)
Exemple #2
0
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
Exemple #3
0
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
Exemple #4
0
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)
Exemple #5
0
                                        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 = "*"
Exemple #6
0
 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
Exemple #7
0
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)