depot.py revision 1542
# See the License for the specific language governing permissions # and limitations under the License. # When distributing Covered Code, include this CDDL HEADER in each # 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] # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # pkg.depotd - package repository daemon # XXX The prototype pkg.depotd combines both the version management server that # answers to pkgsend(1) sessions and the HTTP file server that answers to the # various GET operations that a pkg(1) client makes. This split is expected to # be made more explicit, by constraining the pkg(1) operations such that they # can be served as a typical HTTP/HTTPS session. Thus, pkg.depotd will reduce # to a special purpose HTTP/HTTPS server explicitly for the version management # operations, and must manipulate the various state files--catalogs, in # particular--such that the pkg(1) pull client can operately accurately with # XXX Although we pushed the evaluation of next-version, etc. to the pull # client, we should probably provide a query API to do same on the server, for # dumb clients (like a notification service). # The default repository path. # The default path for static and other web content. # cherrypy has a max_request_body_size parameter that determines whether the # server should abort requests with REQUEST_ENTITY_TOO_LARGE when the request # body is larger than the specified size (in bytes). The maximum size supported # by cherrypy is 2048 * 1024 * 1024 - 1 (just short of 2048MB), but the default # here is purposefully conservative. # The default port(s) to serve data from. # The minimum number of threads allowed. # The default number of threads to start. # The maximum number of threads that can be started. # The default server socket timeout in seconds. We want this to be longer than # the normal default of 10 seconds to accommodate clients with poor quality # Whether modify operations should be allowed. # Whether the repository catalog should be rebuilt on startup. # Whether the indexes should be rebuilt # Not in mirror mode by default print >>
sys.
stderr,
"""cherrypy 3.1.0 or greater (but less than """ \
"""3.2.0) is required to use this program.""" """This is a dummy object that we can use to discard log entries without relying on non-portable interfaces such as /dev/null.""" [-t socket_timeout] [--cfg-file] [--content-root] [--disable-ops op[/1][,...]] [--debug] [--log-access dest] [--log-errors dest] [--mirror] [--nasty] [--set-property <section.property>=<value>] [--proxy-base url] [--readonly] [--rebuild] [--ssl-cert-file] [--ssl-dialog] [--ssl-key-file] [--sort-file-max-size size] --add-content Check the repository on startup and add any new packages found. Cannot be used with --mirror or --cfg-file The pathname of the file from which to read and to write configuration information. --content-root The file system path to the directory containing the the static and other web content used by the depot's browser user interface. The default value is --disable-ops A comma separated list of operations that the depot should not configure. If, for example, you wanted to omit loading search v1, 'search/1' should be provided as an argument, or to disable all search operations, simply 'search'. --debug The name of a debug feature to enable; or a whitespace or comma separated list of features to enable. Possible --exit-ready Go through normal startup processing (including rebuilding catalog or indices, if requested) but exit when ready to start serving packages. --log-access The destination for any access related information logged by the depot process. Possible values are: stderr, stdout, none, or an absolute pathname. The default value is stdout if stdout is a tty; otherwise the default value is none. --log-errors The destination for any errors or other information logged by the depot process. Possible values are: stderr, stdout, none, or an absolute pathname. The --mirror Package mirror mode; publishing and metadata operations disallowed. Cannot be used with --readonly or --nasty Instruct the server to misbehave. At random intervals it will time-out, send bad responses, hang up on clients, and generally be hostile. The option takes a value (1 to 100) for how nasty the server --proxy-base The url to use as the base for generating internal --readonly Read-only operation; modifying operations disallowed. Cannot be used with --mirror or --rebuild. --rebuild Re-build the catalog from pkgs in depot. Cannot be used with --mirror or --readonly. --set-property Used to specify initial repository configuration property values or to update existing ones; can be specified multiple times. If used with --readonly this acts as a temporary override. --ssl-cert-file The absolute pathname to a PEM-encoded Certificate file. This option must be used with --ssl-key-file. Usage of this option will cause the depot to only respond to SSL requests on the provided port. --ssl-dialog Specifies what method should be used to obtain the passphrase needed to decrypt the file specified by --ssl-key-file. Supported values are: builtin, --ssl-key-file The absolute pathname to a PEM-encoded Private Key file. This option must be used with --ssl-cert-file. Usage of this option will cause the depot to only respond to SSL requests on the provided port. The maximum size of the indexer sort file. Used to limit the amount of RAM the depot uses for indexing, or increase it for speed. --writable-root The path to a directory to which the program has write access. Used with --readonly to allow server to create needed files, such as search indices, without needing write access to the package information. # By default, if the destination for a particular log type is not # specified, this is where we will send the output. # If stdout is a tty, then send access output there by default instead long_opts = [
"add-content",
"cfg-file=",
"content-root=",
"debug=",
"disable-ops=",
"exit-ready",
"mirror",
"nasty=",
"set-property=",
"proxy-base=",
"readonly",
"rebuild",
"refresh-index",
"ssl-cert-file=",
"ssl-dialog=",
"ssl-key-file=",
"sort-file-max-size=",
"writable-root="]
elif opt ==
"--add-content":
elif opt ==
"--cfg-file":
elif opt ==
"--content-root":
"A debug feature must be specified." # A list of features can be specified using a # "," or any whitespace character as separators. "Invalid debug feature: " \
elif opt ==
"--disable-ops":
"An argument must be specified." elif opt ==
"--exit-ready":
"You must specify a log " \
"for nasty option.\n Please " \
"choose a value between 1 and 100." elif opt ==
"--set-property":
usage(_(
"property arguments must be of " "the form '<section.property>=" elif opt ==
"--proxy-base":
# Attempt to decompose the url provided into # its base parts. This is done so we can # remove any scheme information since we "determine the hostname from " \
"the provided URL; please use a " \
if scheme not in (
"http",
"https"):
"and https are the only supported " \
# Rebuild the url with the sanitized components. elif opt ==
"--readonly":
elif opt ==
"--refresh-index":
# Note: This argument is for internal use # only. It's used when pkg.depotd is reexecing # itself and needs to know that's the case. # This flag is purposefully omitted in usage. # The supported way to forcefully reindex is to # kill any pkg.depot using that directory, # remove the index directory, and restart the # pkg.depot process. The index will be rebuilt # automatically on startup. elif opt ==
"--ssl-cert-file":
"the Certificate file must be " \
"pathname is not a file." elif opt ==
"--ssl-key-file":
"the Private Key file must be " \
"pathname is not a file." elif opt ==
"--ssl-dialog":
if arg !=
"builtin" and not \
"specified. Expected: builtin, " \
# insecure authentication method "not a supported dialog " \
"type for this operating " \
"file path specified for " \
elif opt ==
"--sort-file-max-size":
"a maximum sort file size." elif opt ==
"--writable-root":
usage(
"pkg.depotd: illegal option value: %s specified " \
"for option: %s" % (
arg,
opt))
usage(
"--add-content cannot be used with --rebuild")
usage(
"--refresh-index cannot be used with --rebuild")
usage(
"--readonly and --mirror cannot be used with --rebuild or --add-content")
usage(
"--mirror cannot be used with --refresh-index")
usage(
"--readonly can only be used with --refresh-index if " "--writable-root is used")
usage(
"The --ssl-cert-file and --ssl-key-file options must " "must both be provided when using either option.")
# If they didn't already specify a particular port, use the # default SSL port instead. # If the program is going to reindex, the port is irrelevant since # the program will not bind to a port. print "pkg.depotd: unable to bind to the specified " \
"port: %d. Reason: %s" % (
port,
msg)
# Not applicable if we're not going to serve content print "pkg.depotd: an error occurred while " \
"executing [%s]; unable to obtain the " \
"passphrase needed to decrypt the SSL" \
# The key file requires decryption, but the user has requested # exec-based authentication, so it will have to be decoded first # to an un-named temporary file. print "pkg.depotd: unable to read the SSL private " \
print "pkg.depotd: authentication or cryptography " \
"failure while attempting to decode\nthe SSL " \
"private key file: %s" %
_e # Redirect the server to the decrypted key file. # Setup our global configuration. "environment":
"production",
"server.shutdown_timeout":
0,
"server.socket_host":
"0.0.0.0",
"server.socket_port":
port,
"tools.log_headers.on":
True,
# Despite its name, this only logs headers when there is an # error; it's redundant with the debug feature enabled. # Causes the headers of every request to be logged to the error # log; even if an exception occurs. "param":
"log.error_file",
"param":
"log.access_file",
if dest in (
"stdout",
"stderr",
"none"):
# Since we've replaced cherrypy's log handler with our # own, we don't want the output directed to a file. # Now that our logging, etc. has been setup, it's safe to perform any # Initialize repository state. emsg(
"pkg.depotd: repository configuration error: %s" %
_e)
emsg(
"Please use the --set-property option to provide a value, " "or update the cfg_cache file for the repository to " emsg(
"pkg.depotd: repository configuration error: %s" %
_e)
# Initializing the repository above updated search indices # as needed; nothing left to do, so exit. # ready to start depot; exit now if requested # Next, initialize depot. # Now build our site configuration. # We have to override cherrypy's default response_class so that # we have access to the write() callable to stream data # directly to the client. "tools.staticfile.on":
True,
# This changes the base URL for our server, and is primarily # intended to allow our depot process to operate behind Apache # or some other webserver process. # Visit the following URL for more information: # Now merge or add our proxy configuration information into the # existing configuration. emsg(
"pkg.depotd: unknown error starting depot server, " \
"illegal option value specified?")