depot.py revision 21
0N/A#!/usr/bin/python
20N/A#
20N/A# CDDL HEADER START
20N/A#
20N/A# The contents of this file are subject to the terms of the
20N/A# Common Development and Distribution License (the "License").
20N/A# You may not use this file except in compliance with the License.
20N/A#
20N/A# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
20N/A# or http://www.opensolaris.org/os/licensing.
20N/A# See the License for the specific language governing permissions
20N/A# and limitations under the License.
20N/A#
20N/A# When distributing Covered Code, include this CDDL HEADER in each
20N/A# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
20N/A# If applicable, add the following below this CDDL HEADER, with the
20N/A# fields enclosed by brackets "[]" replaced with your own identifying
20N/A# information: Portions Copyright [yyyy] [name of copyright owner]
20N/A#
20N/A# CDDL HEADER END
20N/A#
20N/A
20N/A#
20N/A# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
20N/A# Use is subject to license terms.
22N/A#
0N/A
50N/A
50N/Aimport BaseHTTPServer
50N/Aimport os
50N/Aimport re
50N/Aimport sha
50N/Aimport shutil
50N/Aimport time
50N/A
50N/Aimport pkg.version as version
50N/Aimport pkg.fmri as fmri
50N/Aimport pkg.catalog as catalog
50N/Aimport pkg.config as config
50N/A
50N/Adef catalog(scfg, request):
50N/A """The marshalled form of the catalog is
50N/A
0N/A pkg_name (release (branch (sequence ...) ...) ...)
55N/A
54N/A since we know that the server is only to report packages for which it
26N/A can offer a record.
0N/A """
0N/A
0N/A request.send_response(200)
0N/A request.send_header('Content-type:', 'text/plain')
52N/A request.end_headers()
0N/A request.wfile.write('''GET URI %s ; headers %s''' % (request.path, request.headers))
22N/A
0N/Adef trans_open(scfg, request):
34N/A # mkdir repo_root + "/trans/" + trans_id
22N/A trans_root = "%s/trans" % scfg.repo_root
22N/A # XXX refine try/except
22N/A try:
46N/A os.makedirs(trans_root)
34N/A except OSError:
22N/A pass
22N/A opening_time = time.time()
26N/A m = re.match("^/open/(.*)", request.path)
23N/A pkg_name = m.group(1)
23N/A
26N/A # XXX opaquify using hash
26N/A trans_basename = "%d_%s" % (opening_time, pkg_name)
26N/A os.makedirs("%s/%s" % (trans_root, trans_basename))
26N/A
14N/A # record transaction metadata: opening_time, package, user
50N/A # lookup package by name
30N/A # if not found, create package
14N/A # set package state to TRANSACTING
0N/A
25N/A request.send_response(200)
0N/A request.send_header('Content-type:', 'text/plain')
26N/A request.end_headers()
26N/A request.wfile.write('Transaction-ID: %s' % trans_basename)
50N/A
30N/Adef trans_close(scfg, request):
50N/A # Pull transaction ID from headers.
50N/A m = re.match("^/close/(.*)", request.path)
50N/A trans_id = m.group(1)
30N/A
30N/A trans_root = "%s/trans" % scfg.repo_root
30N/A # XXX refine try/except
30N/A #
30N/A # set package state to SUBMITTED
30N/A # attempt to reconcile dependencies
30N/A # if reconciled, set state to PUBLISHED
50N/A # call back to check incomplete list
45N/A # else set state to INCOMPLETE
30N/A try:
50N/A shutil.rmtree("%s/%s" % (trans_root, trans_id))
45N/A request.send_response(200)
30N/A except:
30N/A request.send_response(404)
30N/A
30N/Adef trans_add(scfg, request):
45N/A m = re.match("^/add/([^/]*)/(.*)", request.path)
30N/A trans_id = m.group(1)
50N/A type = m.group(2)
30N/A
30N/A trans_root = "%s/trans" % scfg.repo_root
30N/A # XXX refine try/except
30N/A hdrs = request.headers
30N/A path = hdrs.getheader("Path")
30N/A
54N/A data = request.rfile.read()
54N/A hash = sha.new(data)
54N/A fname = hash.hexdigest()
54N/A
54N/A ofile = file("%s/%s/%s" % (trans_root, trans_id, fname), "wb")
54N/A ofile.write(data)
54N/A
54N/A tfile = file("%s/%s/manifest" % (trans_root, trans_id), "a")
54N/A print >>tfile, "%s %s" % (path, fname)
30N/A
30N/Aif "PKG_REPO" in os.environ:
30N/A scfg = config.SvrConfig(os.environ["PKG_REPO"])
30N/Aelse:
30N/A scfg = config.SvrConfig("/var/pkg/repo")
30N/A
0N/Aclass pkgHandler(BaseHTTPServer.BaseHTTPRequestHandler):
0N/A
22N/A def do_GET(self):
22N/A if re.match("^/catalog$", self.path):
22N/A catalog(scfg, self)
22N/A elif re.match("^/open/(.*)$", self.path):
22N/A trans_open(scfg, self)
22N/A elif re.match("^/close/(.*)$", self.path):
26N/A trans_close(scfg, self)
0N/A elif re.match("^/add/(.*)$", self.path):
22N/A trans_add(scfg, self)
22N/A else:
22N/A self.send_response(404)
22N/A
22N/A
22N/A def do_PUT(self):
22N/A self.send_response(200)
22N/A self.send_header('Content-type:', 'text/plain')
0N/A self.end_headers()
0N/A self.wfile.write('''PUT URI %s ; headers %s''' % (self.path, self.headers))
0N/A
0N/A def do_POST(self):
0N/A if re.match("^/add/(.*)$", self.path):
0N/A trans_add(scfg, self)
0N/A else:
22N/A self.send_response(404)
26N/A
22N/A def do_DELETE(self):
26N/A self.send_response(200)
22N/A self.send_header('Content-type:', 'text/plain')
22N/A self.end_headers()
22N/A self.wfile.write('''URI %s ; headers %s''' % (self.path, self.headers))
22N/A
22N/Aserver = BaseHTTPServer.HTTPServer(('', 10000), pkgHandler)
22N/Aserver.serve_forever()
26N/A