src/modules/misc.py
author Shawn Walker <srw@sun.com>
Thu, 11 Jun 2009 12:04:51 -0500
changeset 1142 64d164b5bf04
parent 1072 66ce6aa346d7
child 1191 a48bee2a4b2e
permissions -rw-r--r--
9164 misc.valid_pub_prefix and misc.valid_pub_url should handle None
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
409
713e20963dc2 2314 shebang lines should use minimum python version
Shawn Walker <swalker@opensolaris.org>
parents: 404
diff changeset
     1
#!/usr/bin/python2.4
46
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
     2
#
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
     3
# CDDL HEADER START
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
     4
#
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
     5
# The contents of this file are subject to the terms of the
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
     6
# Common Development and Distribution License (the "License").
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
     7
# You may not use this file except in compliance with the License.
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
     8
#
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
     9
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    10
# or http://www.opensolaris.org/os/licensing.
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    11
# See the License for the specific language governing permissions
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    12
# and limitations under the License.
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    13
#
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    14
# When distributing Covered Code, include this CDDL HEADER in each
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    15
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    16
# If applicable, add the following below this CDDL HEADER, with the
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    17
# fields enclosed by brackets "[]" replaced with your own identifying
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    18
# information: Portions Copyright [yyyy] [name of copyright owner]
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    19
#
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    20
# CDDL HEADER END
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    21
#
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    22
814
76909c2cad8f 5603 server catalog permissions should be 644, not 600
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 791
diff changeset
    23
# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
46
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    24
# Use is subject to license terms.
119
537d69114be4 Implement bundled file downloads using filelist
johansen <johansen@sun.com>
parents: 108
diff changeset
    25
873
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
    26
import calendar
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
    27
import cStringIO
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
    28
import datetime
384
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
    29
import errno
386
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
    30
import httplib
873
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
    31
import locale
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
    32
import OpenSSL.crypto as osc
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
    33
import operator
119
537d69114be4 Implement bundled file downloads using filelist
johansen <johansen@sun.com>
parents: 108
diff changeset
    34
import os
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
    35
import pkg.client.api_errors as api_errors
873
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
    36
import pkg.portable as portable
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
    37
import pkg.urlhelpers as urlhelpers
386
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
    38
import platform
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
    39
import re
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
    40
import sha
873
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
    41
import shutil
386
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
    42
import socket
1035
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
    43
import struct
873
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
    44
import sys
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
    45
import time
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
    46
import urllib
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
    47
import urllib2
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
    48
import urlparse
342
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
    49
import zlib
462
910600c14093 45 "move" action for files that are renamed, but must be preserved
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 461
diff changeset
    50
319
39b8b5c538bf 1104 want custom user-agent string
Danek Duvall <danek.duvall@sun.com>
parents: 310
diff changeset
    51
from pkg.client.imagetypes import img_type_names, IMG_NONE
696
6bbfd2dece6f 4371 user-agent string needs to be different for different client front-ends
Danek Duvall <danek.duvall@sun.com>
parents: 670
diff changeset
    52
from pkg.client import global_settings
319
39b8b5c538bf 1104 want custom user-agent string
Danek Duvall <danek.duvall@sun.com>
parents: 310
diff changeset
    53
from pkg import VERSION
310
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
    54
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
    55
# Minimum number of days to issue warning before a certificate expires
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
    56
MIN_WARN_DAYS = datetime.timedelta(days=30)
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
    57
1023
73f73773b4c9 6358 Release Notes message after Update All needs to be updated
John Rice <john.rice@sun.com>
parents: 956
diff changeset
    58
def get_release_notes_url():
73f73773b4c9 6358 Release Notes message after Update All needs to be updated
John Rice <john.rice@sun.com>
parents: 956
diff changeset
    59
        """Return a release note URL pointing to the correct release notes
73f73773b4c9 6358 Release Notes message after Update All needs to be updated
John Rice <john.rice@sun.com>
parents: 956
diff changeset
    60
           for this version"""
73f73773b4c9 6358 Release Notes message after Update All needs to be updated
John Rice <john.rice@sun.com>
parents: 956
diff changeset
    61
73f73773b4c9 6358 Release Notes message after Update All needs to be updated
John Rice <john.rice@sun.com>
parents: 956
diff changeset
    62
        # TBD: replace with a call to api.info() that can return a "release"
73f73773b4c9 6358 Release Notes message after Update All needs to be updated
John Rice <john.rice@sun.com>
parents: 956
diff changeset
    63
        # attribute of form YYYYMM against the SUNWsolnm package
73f73773b4c9 6358 Release Notes message after Update All needs to be updated
John Rice <john.rice@sun.com>
parents: 956
diff changeset
    64
        release_str = \
73f73773b4c9 6358 Release Notes message after Update All needs to be updated
John Rice <john.rice@sun.com>
parents: 956
diff changeset
    65
                "http://opensolaris.org/os/project/indiana/resources/relnotes/200906/"
73f73773b4c9 6358 Release Notes message after Update All needs to be updated
John Rice <john.rice@sun.com>
parents: 956
diff changeset
    66
        if platform.processor() == 'sparc':
73f73773b4c9 6358 Release Notes message after Update All needs to be updated
John Rice <john.rice@sun.com>
parents: 956
diff changeset
    67
                release_str += 'sparc/'
73f73773b4c9 6358 Release Notes message after Update All needs to be updated
John Rice <john.rice@sun.com>
parents: 956
diff changeset
    68
        else:
73f73773b4c9 6358 Release Notes message after Update All needs to be updated
John Rice <john.rice@sun.com>
parents: 956
diff changeset
    69
                release_str += 'x86/'
73f73773b4c9 6358 Release Notes message after Update All needs to be updated
John Rice <john.rice@sun.com>
parents: 956
diff changeset
    70
73f73773b4c9 6358 Release Notes message after Update All needs to be updated
John Rice <john.rice@sun.com>
parents: 956
diff changeset
    71
        return release_str
73f73773b4c9 6358 Release Notes message after Update All needs to be updated
John Rice <john.rice@sun.com>
parents: 956
diff changeset
    72
443
5ffa5b7dac9c 2589 pyc files generate lots of verify chaff
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 429
diff changeset
    73
def time_to_timestamp(t):
462
910600c14093 45 "move" action for files that are renamed, but must be preserved
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 461
diff changeset
    74
        """convert seconds since epoch to %Y%m%dT%H%M%SZ format"""
443
5ffa5b7dac9c 2589 pyc files generate lots of verify chaff
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 429
diff changeset
    75
        # XXX optimize?
5ffa5b7dac9c 2589 pyc files generate lots of verify chaff
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 429
diff changeset
    76
        return time.strftime("%Y%m%dT%H%M%SZ", time.gmtime(t))
5ffa5b7dac9c 2589 pyc files generate lots of verify chaff
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 429
diff changeset
    77
5ffa5b7dac9c 2589 pyc files generate lots of verify chaff
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 429
diff changeset
    78
def timestamp_to_time(ts):
462
910600c14093 45 "move" action for files that are renamed, but must be preserved
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 461
diff changeset
    79
        """convert %Y%m%dT%H%M%SZ format to seconds since epoch"""
443
5ffa5b7dac9c 2589 pyc files generate lots of verify chaff
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 429
diff changeset
    80
        # XXX optimize?
5ffa5b7dac9c 2589 pyc files generate lots of verify chaff
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 429
diff changeset
    81
        return calendar.timegm(time.strptime(ts, "%Y%m%dT%H%M%SZ"))
5ffa5b7dac9c 2589 pyc files generate lots of verify chaff
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 429
diff changeset
    82
462
910600c14093 45 "move" action for files that are renamed, but must be preserved
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 461
diff changeset
    83
def copyfile(src_path, dst_path):
910600c14093 45 "move" action for files that are renamed, but must be preserved
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 461
diff changeset
    84
        """copy a file, preserving attributes, ownership, etc. where possible"""
873
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
    85
        fs = os.lstat(src_path)
462
910600c14093 45 "move" action for files that are renamed, but must be preserved
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 461
diff changeset
    86
        shutil.copy2(src_path, dst_path)
910600c14093 45 "move" action for files that are renamed, but must be preserved
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 461
diff changeset
    87
        try:
873
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
    88
                portable.chown(dst_path, fs.st_uid, fs.st_gid)
462
910600c14093 45 "move" action for files that are renamed, but must be preserved
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 461
diff changeset
    89
        except OSError, e:
910600c14093 45 "move" action for files that are renamed, but must be preserved
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 461
diff changeset
    90
                if e.errno != errno.EPERM:
910600c14093 45 "move" action for files that are renamed, but must be preserved
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 461
diff changeset
    91
                        raise
956
adf6bdfdb3b5 6904 image.installed_file_authority always tries to open installed file r+
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 941
diff changeset
    92
def expanddirs(dirs):
adf6bdfdb3b5 6904 image.installed_file_authority always tries to open installed file r+
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 941
diff changeset
    93
        """given a set of directories, return expanded set that includes
adf6bdfdb3b5 6904 image.installed_file_authority always tries to open installed file r+
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 941
diff changeset
    94
        all components"""
adf6bdfdb3b5 6904 image.installed_file_authority always tries to open installed file r+
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 941
diff changeset
    95
        out = set()
adf6bdfdb3b5 6904 image.installed_file_authority always tries to open installed file r+
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 941
diff changeset
    96
        for d in dirs:
adf6bdfdb3b5 6904 image.installed_file_authority always tries to open installed file r+
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 941
diff changeset
    97
                p = d
adf6bdfdb3b5 6904 image.installed_file_authority always tries to open installed file r+
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 941
diff changeset
    98
                while p != "":
adf6bdfdb3b5 6904 image.installed_file_authority always tries to open installed file r+
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 941
diff changeset
    99
                        out.add(p)
adf6bdfdb3b5 6904 image.installed_file_authority always tries to open installed file r+
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 941
diff changeset
   100
                        p = os.path.dirname(p)
adf6bdfdb3b5 6904 image.installed_file_authority always tries to open installed file r+
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 941
diff changeset
   101
        return out
462
910600c14093 45 "move" action for files that are renamed, but must be preserved
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 461
diff changeset
   102
46
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
   103
def hash_file_name(f):
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
   104
        """Return the two-level path fragment for the given filename, which is
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
   105
        assumed to be a content hash of at least 8 distinct characters."""
119
537d69114be4 Implement bundled file downloads using filelist
johansen <johansen@sun.com>
parents: 108
diff changeset
   106
        return os.path.join("%s" % f[0:2], "%s" % f[2:8], "%s" % f)
46
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
   107
310
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
   108
def url_affix_trailing_slash(u):
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
   109
        if u[-1] != '/':
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
   110
                u = u + '/'
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
   111
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
   112
        return u
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
   113
696
6bbfd2dece6f 4371 user-agent string needs to be different for different client front-ends
Danek Duvall <danek.duvall@sun.com>
parents: 670
diff changeset
   114
_client_version = "pkg/%s (%s %s; %s %s; %%s; %%s)" % \
319
39b8b5c538bf 1104 want custom user-agent string
Danek Duvall <danek.duvall@sun.com>
parents: 310
diff changeset
   115
    (VERSION, portable.util.get_canonical_os_name(), platform.machine(),
39b8b5c538bf 1104 want custom user-agent string
Danek Duvall <danek.duvall@sun.com>
parents: 310
diff changeset
   116
    portable.util.get_os_release(), platform.version())
39b8b5c538bf 1104 want custom user-agent string
Danek Duvall <danek.duvall@sun.com>
parents: 310
diff changeset
   117
556
1c3526ca7b9e 2022 client should provide operational intent to server
Shawn Walker <shawn.walker@sun.com>
parents: 551
diff changeset
   118
def versioned_urlopen(base_uri, operation, versions = None, tail = None,
551
233f0eeddd02 856 Image properties
Tom Mueller <Tom.Mueller@sun.com>
parents: 518
diff changeset
   119
    data = None, headers = None, ssl_creds = None, imgtype = IMG_NONE,
556
1c3526ca7b9e 2022 client should provide operational intent to server
Shawn Walker <shawn.walker@sun.com>
parents: 551
diff changeset
   120
    method = "GET", uuid = None):
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   121
        """Open the best URI for an operation given a set of versions.
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   122
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   123
        Both the client and the server may support multiple versions of
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   124
        the protocol of a particular operation.  The client will pass
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   125
        this method an ordered array of versions it understands, along
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   126
        with the base URI and the operation it wants.  This method will
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   127
        open the URL corresponding to the best version both the client
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   128
        and the server understand, returning a tuple of the open URL and
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   129
        the version used on success, and throwing an exception if no
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   130
        matching version can be found.
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   131
        """
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   132
        # Ignore http_proxy for localhost case, by overriding
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   133
        # default proxy behaviour of urlopen().
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   134
        netloc = urlparse.urlparse(base_uri)[1]
310
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
   135
285
538afd6a9d3e 763 pkg image-create /foo , pkg image-create /tmp/foo both yield (different) tracebacks
Danek Duvall <danek.duvall@sun.com>
parents: 260
diff changeset
   136
        if not netloc:
538afd6a9d3e 763 pkg image-create /foo , pkg image-create /tmp/foo both yield (different) tracebacks
Danek Duvall <danek.duvall@sun.com>
parents: 260
diff changeset
   137
                raise ValueError, "Malformed URL: %s" % base_uri
310
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
   138
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   139
        if urllib.splitport(netloc)[0] == "localhost":
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   140
                # XXX cache this opener?
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   141
                proxy_handler = urllib2.ProxyHandler({})
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   142
                opener_dir = urllib2.build_opener(proxy_handler)
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   143
                url_opener = opener_dir.open
310
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
   144
        elif ssl_creds and ssl_creds != (None, None):
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
   145
                cert_handler = urlhelpers.HTTPSCertHandler(
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
   146
                    key_file = ssl_creds[0], cert_file = ssl_creds[1])
779
35b869ed3334 4314 https proxy does not work
Tom Mueller <Tom.Mueller@sun.com>
parents: 770
diff changeset
   147
                opener_dir = urllib2.build_opener(
35b869ed3334 4314 https proxy does not work
Tom Mueller <Tom.Mueller@sun.com>
parents: 770
diff changeset
   148
                    urlhelpers.HTTPSProxyHandler, cert_handler)
310
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
   149
                url_opener = opener_dir.open
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   150
        else:
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   151
                url_opener = urllib2.urlopen
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   152
556
1c3526ca7b9e 2022 client should provide operational intent to server
Shawn Walker <shawn.walker@sun.com>
parents: 551
diff changeset
   153
        if not versions:
1c3526ca7b9e 2022 client should provide operational intent to server
Shawn Walker <shawn.walker@sun.com>
parents: 551
diff changeset
   154
                versions = []
1c3526ca7b9e 2022 client should provide operational intent to server
Shawn Walker <shawn.walker@sun.com>
parents: 551
diff changeset
   155
551
233f0eeddd02 856 Image properties
Tom Mueller <Tom.Mueller@sun.com>
parents: 518
diff changeset
   156
        if not headers:
233f0eeddd02 856 Image properties
Tom Mueller <Tom.Mueller@sun.com>
parents: 518
diff changeset
   157
                headers = {}
233f0eeddd02 856 Image properties
Tom Mueller <Tom.Mueller@sun.com>
parents: 518
diff changeset
   158
941
e7bff46da54e 6175 search needs to be moved to version 1
Brock Pytlik <bpytlik@sun.com>
parents: 926
diff changeset
   159
        for i, version in enumerate(versions):
351
9301d4d85349 767 pkg client can't talk to repo at a path other than / on a server
johansen <johansen@sun.com>
parents: 342
diff changeset
   160
                if base_uri[-1] != '/':
9301d4d85349 767 pkg client can't talk to repo at a path other than / on a server
johansen <johansen@sun.com>
parents: 342
diff changeset
   161
                        base_uri += '/'
9301d4d85349 767 pkg client can't talk to repo at a path other than / on a server
johansen <johansen@sun.com>
parents: 342
diff changeset
   162
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   163
                if tail:
941
e7bff46da54e 6175 search needs to be moved to version 1
Brock Pytlik <bpytlik@sun.com>
parents: 926
diff changeset
   164
                        tail_str = tail
e7bff46da54e 6175 search needs to be moved to version 1
Brock Pytlik <bpytlik@sun.com>
parents: 926
diff changeset
   165
                        if isinstance(tail, list):
e7bff46da54e 6175 search needs to be moved to version 1
Brock Pytlik <bpytlik@sun.com>
parents: 926
diff changeset
   166
                                tail_str = tail[i]
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   167
                        uri = urlparse.urljoin(base_uri, "%s/%s/%s" % \
941
e7bff46da54e 6175 search needs to be moved to version 1
Brock Pytlik <bpytlik@sun.com>
parents: 926
diff changeset
   168
                            (operation, version, tail_str))
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   169
                else:
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   170
                        uri = urlparse.urljoin(base_uri, "%s/%s" % \
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   171
                            (operation, version))
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   172
319
39b8b5c538bf 1104 want custom user-agent string
Danek Duvall <danek.duvall@sun.com>
parents: 310
diff changeset
   173
                headers["User-Agent"] = \
696
6bbfd2dece6f 4371 user-agent string needs to be different for different client front-ends
Danek Duvall <danek.duvall@sun.com>
parents: 670
diff changeset
   174
                    _client_version % (img_type_names[imgtype],
6bbfd2dece6f 4371 user-agent string needs to be different for different client front-ends
Danek Duvall <danek.duvall@sun.com>
parents: 670
diff changeset
   175
                        global_settings.client_name)
551
233f0eeddd02 856 Image properties
Tom Mueller <Tom.Mueller@sun.com>
parents: 518
diff changeset
   176
                if uuid:
233f0eeddd02 856 Image properties
Tom Mueller <Tom.Mueller@sun.com>
parents: 518
diff changeset
   177
                        headers["X-IPkg-UUID"] = uuid
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   178
                req = urllib2.Request(url = uri, headers = headers)
556
1c3526ca7b9e 2022 client should provide operational intent to server
Shawn Walker <shawn.walker@sun.com>
parents: 551
diff changeset
   179
                if method == "HEAD":
1c3526ca7b9e 2022 client should provide operational intent to server
Shawn Walker <shawn.walker@sun.com>
parents: 551
diff changeset
   180
                        # Must override urllib2's get_method since it doesn't
1c3526ca7b9e 2022 client should provide operational intent to server
Shawn Walker <shawn.walker@sun.com>
parents: 551
diff changeset
   181
                        # natively support this operation.
1c3526ca7b9e 2022 client should provide operational intent to server
Shawn Walker <shawn.walker@sun.com>
parents: 551
diff changeset
   182
                        req.get_method = lambda: "HEAD"
1c3526ca7b9e 2022 client should provide operational intent to server
Shawn Walker <shawn.walker@sun.com>
parents: 551
diff changeset
   183
                elif data is not None:
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   184
                        req.add_data(data)
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   185
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   186
                try:
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   187
                        c = url_opener(req)
153
05d90faecc40 Fix versioned_urlopen() to catch the right error, and catch URLError higher up.
Danek Duvall <danek.duvall@sun.com>
parents: 145
diff changeset
   188
                except urllib2.HTTPError, e:
941
e7bff46da54e 6175 search needs to be moved to version 1
Brock Pytlik <bpytlik@sun.com>
parents: 926
diff changeset
   189
                        if e.code != httplib.NOT_FOUND:
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   190
                                raise
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   191
                        continue
260
a1b77322abb2 255 Symbolic HTTP response codes should be used
Shawn Walker <swalker@opensolaris.org>
parents: 181
diff changeset
   192
                # XXX catch BadStatusLine and convert to INTERNAL_SERVER_ERROR?
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   193
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   194
                return c, version
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   195
        else:
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   196
                # Couldn't find a version that we liked.
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   197
                raise RuntimeError, \
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   198
                    "%s doesn't speak a known version of %s operation" % \
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   199
                    (base_uri, operation)
327
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   200
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   201
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   202
_hostname_re = re.compile("^[a-zA-Z0-9](?:[a-zA-Z0-9\-]*[a-zA-Z0-9]+\.?)*$")
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   203
_invalid_host_chars = re.compile(".*[^a-zA-Z0-9\-\.]+")
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   204
_valid_proto = ["http", "https"]
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   205
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   206
def valid_pub_prefix(prefix):
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   207
        """Verify that the publisher prefix only contains valid characters."""
327
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   208
1142
64d164b5bf04 9164 misc.valid_pub_prefix and misc.valid_pub_url should handle None
Shawn Walker <srw@sun.com>
parents: 1072
diff changeset
   209
        if not prefix:
64d164b5bf04 9164 misc.valid_pub_prefix and misc.valid_pub_url should handle None
Shawn Walker <srw@sun.com>
parents: 1072
diff changeset
   210
                return False
64d164b5bf04 9164 misc.valid_pub_prefix and misc.valid_pub_url should handle None
Shawn Walker <srw@sun.com>
parents: 1072
diff changeset
   211
327
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   212
        # This is a workaround for the the hostname_re being slow when
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   213
        # it comes to finding invalid characters in the prefix string.
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   214
        if _invalid_host_chars.match(prefix):
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   215
                # prefix bad chars
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   216
                return False
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   217
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   218
        if _hostname_re.match(prefix):
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   219
                return True
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   220
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   221
        return False
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   222
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   223
def valid_pub_url(url):
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   224
        """Verify that the publisher URL contains only valid characters."""
327
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   225
1142
64d164b5bf04 9164 misc.valid_pub_prefix and misc.valid_pub_url should handle None
Shawn Walker <srw@sun.com>
parents: 1072
diff changeset
   226
        if not url:
64d164b5bf04 9164 misc.valid_pub_prefix and misc.valid_pub_url should handle None
Shawn Walker <srw@sun.com>
parents: 1072
diff changeset
   227
                return False
64d164b5bf04 9164 misc.valid_pub_prefix and misc.valid_pub_url should handle None
Shawn Walker <srw@sun.com>
parents: 1072
diff changeset
   228
327
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   229
        # First split the URL and check if the scheme is one we support
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   230
        o = urlparse.urlsplit(url)
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   231
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   232
        if not o[0] in _valid_proto:
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   233
                return False
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   234
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   235
        # Next verify that the network location is valid
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   236
        host, port = urllib.splitport(o[1])
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   237
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   238
        if not host or _invalid_host_chars.match(host):
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   239
                return False
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   240
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   241
        if _hostname_re.match(host):
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   242
                return True
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   243
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   244
        return False
342
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   245
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   246
def gunzip_from_stream(gz, outfile):
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   247
        """Decompress a gzipped input stream into an output stream.
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   248
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   249
        The argument 'gz' is an input stream of a gzipped file (XXX make it do
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   250
        either a gzipped file or raw zlib compressed data), and 'outfile' is is
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   251
        an output stream.  gunzip_from_stream() decompresses data from 'gz' and
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   252
        writes it to 'outfile', and returns the hexadecimal SHA-1 sum of that
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   253
        data.
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   254
        """
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   255
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   256
        FHCRC = 2
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   257
        FEXTRA = 4
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   258
        FNAME = 8
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   259
        FCOMMENT = 16
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   260
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   261
        # Read the header
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   262
        magic = gz.read(2)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   263
        if magic != "\037\213":
621
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   264
                raise zlib.error, "Not a gzipped file"
342
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   265
        method = ord(gz.read(1))
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   266
        if method != 8:
621
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   267
                raise zlib.error, "Unknown compression method"
342
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   268
        flag = ord(gz.read(1))
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   269
        gz.read(6) # Discard modtime, extraflag, os
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   270
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   271
        # Discard an extra field
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   272
        if flag & FEXTRA:
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   273
                xlen = ord(gz.read(1))
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   274
                xlen = xlen + 256 * ord(gz.read(1))
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   275
                gz.read(xlen)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   276
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   277
        # Discard a null-terminated filename
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   278
        if flag & FNAME:
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   279
                while True:
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   280
                        s = gz.read(1)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   281
                        if not s or s == "\000":
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   282
                                break
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   283
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   284
        # Discard a null-terminated comment
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   285
        if flag & FCOMMENT:
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   286
                while True:
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   287
                        s = gz.read(1)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   288
                        if not s or s == "\000":
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   289
                                break
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   290
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   291
        # Discard a 16-bit CRC
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   292
        if flag & FHCRC:
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   293
                gz.read(2)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   294
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   295
        shasum = sha.new()
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   296
        dcobj = zlib.decompressobj(-zlib.MAX_WBITS)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   297
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   298
        while True:
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   299
                buf = gz.read(64 * 1024)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   300
                if buf == "":
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   301
                        ubuf = dcobj.flush()
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   302
                        shasum.update(ubuf)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   303
                        outfile.write(ubuf)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   304
                        break
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   305
                ubuf = dcobj.decompress(buf)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   306
                shasum.update(ubuf)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   307
                outfile.write(ubuf)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   308
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   309
        return shasum.hexdigest()
384
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   310
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   311
class PipeError(Exception):
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   312
        """ Pipe exception. """
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   313
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   314
        def __init__(self, args=None):
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   315
                self.args = args
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   316
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   317
def msg(*text):
429
6c9cbb6e6600 983 pkg search returns just one action per package/token-type combo
Brock Pytlik <bpytlik@sun.com>
parents: 409
diff changeset
   318
        """ Emit a message. """
384
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   319
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   320
        try:
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   321
                print ' '.join([str(l) for l in text])
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   322
        except IOError, e:
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   323
                if e.errno == errno.EPIPE:
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   324
                        raise PipeError, e
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   325
                raise
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   326
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   327
def emsg(*text):
429
6c9cbb6e6600 983 pkg search returns just one action per package/token-type combo
Brock Pytlik <bpytlik@sun.com>
parents: 409
diff changeset
   328
        """ Emit a message to sys.stderr. """
384
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   329
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   330
        try:
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   331
                print >> sys.stderr, ' '.join([str(l) for l in text])
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   332
        except IOError, e:
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   333
                if e.errno == errno.EPIPE:
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   334
                        raise PipeError, e
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   335
                raise
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   336
791
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   337
def setlocale(category, loc=None, printer=None):
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   338
        """Wraps locale.setlocale(), falling back to the C locale if the desired
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   339
        locale is broken or unavailable.  The 'printer' parameter should be a
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   340
        function which takes a string and displays it.  If 'None' (the default),
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   341
        setlocale() will print the message to stderr."""
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   342
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   343
        if printer is None:
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   344
                printer = emsg
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   345
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   346
        try:
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   347
                locale.setlocale(category, loc)
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   348
        except locale.Error:
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   349
                try:
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   350
                        dl = " '%s.%s'" % locale.getdefaultlocale()
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   351
                except ValueError:
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   352
                        dl = ""
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   353
                printer("Unable to set locale%s; locale package may be broken "
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   354
                    "or\nnot installed.  Reverting to C locale." % dl)
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   355
                locale.setlocale(category, "C")
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   356
386
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   357
def port_available(host, port):
451
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   358
        """Returns True if the indicated port is available to bind to;
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   359
        otherwise returns False."""
386
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   360
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   361
        port = int(port)
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   362
        if host is None:
451
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   363
                # None is the same as INADDR_ANY, which for our purposes,
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   364
                # should be the hostname.
386
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   365
                host = socket.gethostname()
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   366
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   367
        try:
404
e5329e84b9a8 2331 depot command-line parsing errors cause traceback
Shawn Walker <swalker@opensolaris.org>
parents: 388
diff changeset
   368
                sock = None
e5329e84b9a8 2331 depot command-line parsing errors cause traceback
Shawn Walker <swalker@opensolaris.org>
parents: 388
diff changeset
   369
386
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   370
                # Get the address family of our host (to allow for IPV6, etc.).
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   371
                for entry in socket.getaddrinfo(host, port, socket.AF_UNSPEC,
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   372
                    socket.SOCK_STREAM):
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   373
                        family, socktype, proto, canonname, sockaddr = entry
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   374
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   375
                        # First try to bind to the specified port to see if we
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   376
                        # have an access problem or some other issue.
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   377
                        sock = socket.socket(family, socktype, proto)
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   378
                        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   379
                            1)
494
102fb5979716 2695 misc.port_available fails on Mac/OS due to EINVAL problem
Tom Mueller <Tom.Mueller@sun.com>
parents: 487
diff changeset
   380
                        sock.bind(sockaddr)
386
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   381
                        sock.close()
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   382
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   383
                        # Now try to connect to the specified port to see if it
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   384
                        # is already in use.
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   385
                        sock = socket.socket(family, socktype, proto)
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   386
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   387
                        # Some systems timeout rather than refuse a connection.
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   388
                        # This avoids getting stuck on SYN_SENT for those
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   389
                        # systems (such as certain firewalls).
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   390
                        sock.settimeout(1.0)
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   391
494
102fb5979716 2695 misc.port_available fails on Mac/OS due to EINVAL problem
Tom Mueller <Tom.Mueller@sun.com>
parents: 487
diff changeset
   392
                        try:
102fb5979716 2695 misc.port_available fails on Mac/OS due to EINVAL problem
Tom Mueller <Tom.Mueller@sun.com>
parents: 487
diff changeset
   393
                                sock.connect(sockaddr)
102fb5979716 2695 misc.port_available fails on Mac/OS due to EINVAL problem
Tom Mueller <Tom.Mueller@sun.com>
parents: 487
diff changeset
   394
                        except socket.timeout:
102fb5979716 2695 misc.port_available fails on Mac/OS due to EINVAL problem
Tom Mueller <Tom.Mueller@sun.com>
parents: 487
diff changeset
   395
                                # handle this at the next level
102fb5979716 2695 misc.port_available fails on Mac/OS due to EINVAL problem
Tom Mueller <Tom.Mueller@sun.com>
parents: 487
diff changeset
   396
                                raise
102fb5979716 2695 misc.port_available fails on Mac/OS due to EINVAL problem
Tom Mueller <Tom.Mueller@sun.com>
parents: 487
diff changeset
   397
                        except socket.error, e:
102fb5979716 2695 misc.port_available fails on Mac/OS due to EINVAL problem
Tom Mueller <Tom.Mueller@sun.com>
parents: 487
diff changeset
   398
                                errnum = e[0]
102fb5979716 2695 misc.port_available fails on Mac/OS due to EINVAL problem
Tom Mueller <Tom.Mueller@sun.com>
parents: 487
diff changeset
   399
                                if errnum != errno.EINVAL:
102fb5979716 2695 misc.port_available fails on Mac/OS due to EINVAL problem
Tom Mueller <Tom.Mueller@sun.com>
parents: 487
diff changeset
   400
                                        raise
102fb5979716 2695 misc.port_available fails on Mac/OS due to EINVAL problem
Tom Mueller <Tom.Mueller@sun.com>
parents: 487
diff changeset
   401
                                # this BSD-based system has trouble with a 
102fb5979716 2695 misc.port_available fails on Mac/OS due to EINVAL problem
Tom Mueller <Tom.Mueller@sun.com>
parents: 487
diff changeset
   402
                                # non-blocking failed connect
102fb5979716 2695 misc.port_available fails on Mac/OS due to EINVAL problem
Tom Mueller <Tom.Mueller@sun.com>
parents: 487
diff changeset
   403
                                sock.close()
102fb5979716 2695 misc.port_available fails on Mac/OS due to EINVAL problem
Tom Mueller <Tom.Mueller@sun.com>
parents: 487
diff changeset
   404
                                sock = socket.socket(family, socktype, proto)
102fb5979716 2695 misc.port_available fails on Mac/OS due to EINVAL problem
Tom Mueller <Tom.Mueller@sun.com>
parents: 487
diff changeset
   405
                                sock.connect(sockaddr)
102fb5979716 2695 misc.port_available fails on Mac/OS due to EINVAL problem
Tom Mueller <Tom.Mueller@sun.com>
parents: 487
diff changeset
   406
                                
386
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   407
                        sock.close()
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   408
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   409
                        # If we successfully connected...
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   410
                        raise socket.error(errno.EBUSY,
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   411
                            'Port already in use')
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   412
494
102fb5979716 2695 misc.port_available fails on Mac/OS due to EINVAL problem
Tom Mueller <Tom.Mueller@sun.com>
parents: 487
diff changeset
   413
        except socket.timeout, t:
102fb5979716 2695 misc.port_available fails on Mac/OS due to EINVAL problem
Tom Mueller <Tom.Mueller@sun.com>
parents: 487
diff changeset
   414
                return True, None
102fb5979716 2695 misc.port_available fails on Mac/OS due to EINVAL problem
Tom Mueller <Tom.Mueller@sun.com>
parents: 487
diff changeset
   415
386
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   416
        except socket.error, e:
404
e5329e84b9a8 2331 depot command-line parsing errors cause traceback
Shawn Walker <swalker@opensolaris.org>
parents: 388
diff changeset
   417
                errnum = e[0]
e5329e84b9a8 2331 depot command-line parsing errors cause traceback
Shawn Walker <swalker@opensolaris.org>
parents: 388
diff changeset
   418
                try:
451
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   419
                        text = e[1]
404
e5329e84b9a8 2331 depot command-line parsing errors cause traceback
Shawn Walker <swalker@opensolaris.org>
parents: 388
diff changeset
   420
                except IndexError:
451
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   421
                        text = e[0]
386
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   422
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   423
                if sock:
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   424
                        sock.close()
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   425
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   426
                if errnum == errno.ECONNREFUSED:
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   427
                        # If we could not connect to the port, we know it isn't
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   428
                        # in use.
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   429
                        return True, None
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   430
451
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   431
                return False, text
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   432
1035
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   433
def bytes_to_str(bytes, format=None):
451
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   434
        """Returns a human-formatted string representing the number of bytes
1035
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   435
        in the largest unit possible.  If provided, 'format' should be a string
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   436
        which can be formatted with a dictionary containing a float 'num' and
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   437
        string 'unit'."""
451
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   438
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   439
        units = [
660
ea2809ad4582 4126 I10n update for IPS CLI PM and UM
John Rice <john.rice@sun.com>
parents: 641
diff changeset
   440
            (_("B"), 2**10),
ea2809ad4582 4126 I10n update for IPS CLI PM and UM
John Rice <john.rice@sun.com>
parents: 641
diff changeset
   441
            (_("kB"), 2**20),
ea2809ad4582 4126 I10n update for IPS CLI PM and UM
John Rice <john.rice@sun.com>
parents: 641
diff changeset
   442
            (_("MB"), 2**30),
ea2809ad4582 4126 I10n update for IPS CLI PM and UM
John Rice <john.rice@sun.com>
parents: 641
diff changeset
   443
            (_("GB"), 2**40),
ea2809ad4582 4126 I10n update for IPS CLI PM and UM
John Rice <john.rice@sun.com>
parents: 641
diff changeset
   444
            (_("TB"), 2**50),
ea2809ad4582 4126 I10n update for IPS CLI PM and UM
John Rice <john.rice@sun.com>
parents: 641
diff changeset
   445
            (_("PB"), 2**60),
ea2809ad4582 4126 I10n update for IPS CLI PM and UM
John Rice <john.rice@sun.com>
parents: 641
diff changeset
   446
            (_("EB"), 2**70)
451
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   447
        ]
386
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   448
451
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   449
        for uom, limit in units:
660
ea2809ad4582 4126 I10n update for IPS CLI PM and UM
John Rice <john.rice@sun.com>
parents: 641
diff changeset
   450
                if uom != _("EB") and bytes >= limit:
451
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   451
                        # Try the next largest unit of measure unless this is
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   452
                        # the largest or if the byte size is within the current
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   453
                        # unit of measure's range.
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   454
                        continue
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   455
                else:
1035
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   456
                        if not format:
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   457
                                format = "%(num).2f %(unit)s"
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   458
                        return format % {
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   459
                            "num": round(bytes / float(limit / 2**10), 2),
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   460
                            "unit": uom
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   461
                        }
451
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   462
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   463
def get_rel_path(request, uri):
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   464
        # Calculate the depth of the current request path relative to our base
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   465
        # uri. path_info always ends with a '/' -- so ignore it when
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   466
        # calculating depth.
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   467
        depth = request.path_info.count("/") - 1
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   468
        return ("../" * depth) + uri
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   469
487
9cb85c3d8491 2556 client should measure download progress by compressed size
johansen <johansen@sun.com>
parents: 462
diff changeset
   470
def get_pkg_otw_size(action):
9cb85c3d8491 2556 client should measure download progress by compressed size
johansen <johansen@sun.com>
parents: 462
diff changeset
   471
        """Takes a file action and returns the over-the-wire size of
9cb85c3d8491 2556 client should measure download progress by compressed size
johansen <johansen@sun.com>
parents: 462
diff changeset
   472
        a package as an integer.  The OTW size is the compressed size,
9cb85c3d8491 2556 client should measure download progress by compressed size
johansen <johansen@sun.com>
parents: 462
diff changeset
   473
        pkg.csize.  If that value isn't available, it returns pkg.size.
9cb85c3d8491 2556 client should measure download progress by compressed size
johansen <johansen@sun.com>
parents: 462
diff changeset
   474
        If pkg.size isn't available, return zero."""
9cb85c3d8491 2556 client should measure download progress by compressed size
johansen <johansen@sun.com>
parents: 462
diff changeset
   475
9cb85c3d8491 2556 client should measure download progress by compressed size
johansen <johansen@sun.com>
parents: 462
diff changeset
   476
        size = action.attrs.get("pkg.csize", 0)
9cb85c3d8491 2556 client should measure download progress by compressed size
johansen <johansen@sun.com>
parents: 462
diff changeset
   477
        if size == 0:
9cb85c3d8491 2556 client should measure download progress by compressed size
johansen <johansen@sun.com>
parents: 462
diff changeset
   478
                size = action.attrs.get("pkg.size", 0)
9cb85c3d8491 2556 client should measure download progress by compressed size
johansen <johansen@sun.com>
parents: 462
diff changeset
   479
9cb85c3d8491 2556 client should measure download progress by compressed size
johansen <johansen@sun.com>
parents: 462
diff changeset
   480
        return int(size)
9cb85c3d8491 2556 client should measure download progress by compressed size
johansen <johansen@sun.com>
parents: 462
diff changeset
   481
770
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   482
def get_inventory_list(image, pargs, all_known, all_versions):
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   483
        most_recent = {}
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   484
        installed = []
1068
9400aa8afd32 2557 catalog cache pickle file dependent on fmri and version object definitions
Shawn Walker <srw@sun.com>
parents: 1038
diff changeset
   485
        res = image.inventory(pargs, all_known, ordered=not all_versions)
770
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   486
        # All_Versions reduces the output so that only the most recent
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   487
        # version and installed version of packages appear.
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   488
        if all_versions:
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   489
                for pfmri, state in res:
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   490
                        if state["state"] == "installed":
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   491
                                installed.append((pfmri, state))
941
e7bff46da54e 6175 search needs to be moved to version 1
Brock Pytlik <bpytlik@sun.com>
parents: 926
diff changeset
   492
                        hv = pfmri.get_pkg_stem(include_scheme=False)
770
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   493
                        if hv in most_recent:
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   494
                                stored_pfmri, stored_state = \
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   495
                                    most_recent[hv]
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   496
                                if pfmri.is_successor(stored_pfmri):
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   497
                                        most_recent[hv] = (pfmri, state)
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   498
                        else:
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   499
                                most_recent[hv] = (pfmri, state)
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   500
                res = installed + most_recent.values()
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   501
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   502
                # This method is necessary because fmri.__cmp__ does
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   503
                # not provide the desired ordering. It uses the same
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   504
                # ordering on package names as fmri.__cmp__ but it
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   505
                # reverse sorts on version, so that 98 comes before 97.
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   506
                # Also, publishers are taken into account so that
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   507
                # preferred publishers come before others. Finally,
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   508
                # publishers are presented in alphabetical order.
770
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   509
                def __fmri_cmp((f1, s1), (f2, s2)):
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   510
                        t = cmp(f1.pkg_name, f2.pkg_name)
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   511
                        if t != 0:
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   512
                                return t
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   513
                        t = cmp(f2, f1)
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   514
                        if t != 0:
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   515
                                return t
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   516
                        if f1.preferred_publisher():
770
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   517
                                return -1
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   518
                        if f2.preferred_publisher():
770
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   519
                                return 1
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   520
                        return cmp(f1.get_publisher(),
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   521
                            f2.get_publisher())
770
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   522
                
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   523
                res.sort(cmp=__fmri_cmp)
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   524
        return res
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   525
873
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   526
def get_data_digest(data, length=None, return_content=False):
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   527
        """Returns a tuple of (SHA-1 hexdigest, content).
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   528
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   529
        'data' should be a file-like object or a pathname to a file.
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   530
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   531
        'length' should be an integer value representing the size of
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   532
        the contents of data in bytes.
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   533
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   534
        'return_content' is a boolean value indicating whether the
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   535
        second tuple value should contain the content of 'data' or
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   536
        if the content should be discarded during processing."""
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   537
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   538
        bufsz = 128 * 1024
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   539
        if isinstance(data, basestring):
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   540
                f = file(data, "rb", bufsz)
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   541
        else:
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   542
                f = data
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   543
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   544
        if length is None:
1038
2514d758e462 7908 publishing api and tools should use os.stat not os.lstat for file size
Shawn Walker <srw@sun.com>
parents: 1035
diff changeset
   545
                length = os.stat(data).st_size
873
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   546
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   547
        # Read the data in chunks and compute the SHA1 hash as it comes in.  A
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   548
        # large read on some platforms (e.g. Windows XP) may fail.
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   549
        content = cStringIO.StringIO()
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   550
        fhash = sha.new()
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   551
        while length > 0:
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   552
                data = f.read(min(bufsz, length))
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   553
                if return_content:
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   554
                        content.write(data)
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   555
                fhash.update(data)
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   556
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   557
                l = len(data)
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   558
                if l == 0:
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   559
                        break
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   560
                length -= l
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   561
        content.reset()
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   562
        f.close()
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   563
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   564
        return fhash.hexdigest(), content.read()
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   565
1035
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   566
def __getvmusage():
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   567
        """Return the amount of virtual memory in bytes currently in use."""
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   568
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   569
        # This works only on Solaris, in 32-bit mode.  It may not work on older
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   570
        # or newer versions than 5.11.  Ideally, we would use libproc, or check
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   571
        # sbrk(0), but this is expedient.  In most cases (there's a small chance
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   572
        # the file will decode, but incorrectly), failure will raise an
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   573
        # exception, and we'll fail safe.
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   574
        try:
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   575
                # Read just the psinfo_t, not the tacked-on lwpsinfo_t
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   576
                psinfo_arr = file("/proc/self/psinfo").read(232)
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   577
                psinfo = struct.unpack("6i5I4LHH6L16s80siiIIc3x7i", psinfo_arr)
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   578
                vsz = psinfo[11] * 1024
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   579
        except Exception:
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   580
                vsz = None
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   581
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   582
        return vsz
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   583
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   584
def out_of_memory():
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   585
        """Return an out of memory message, for use in a MemoryError handler."""
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   586
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   587
        vsz = bytes_to_str(__getvmusage(), format="%(num).0f%(unit)s")
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   588
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   589
        if vsz is not None:
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   590
                error = """\
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   591
There is not enough memory to complete the requested operation.  At least
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   592
%(vsz)s of virtual memory was in use by this command before it ran out of memory.
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   593
You must add more memory (swap or physical) or allow the system to access more
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   594
existing memory, or quit other programs that may be consuming memory, and try
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   595
the operation again."""
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   596
        else:
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   597
                error = """\
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   598
There is not enough memory to complete the requested operation.  You must
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   599
add more memory (swap or physical) or allow the system to access more existing
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   600
memory, or quit other programs that may be consuming memory, and try the
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   601
operation again."""
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   602
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   603
        return _(error) % locals()
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   604
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   605
835
34ec4401dc48 686 Client needs a way to tell that a response is actually from an IPS server
johansen <johansen@sun.com>
parents: 814
diff changeset
   606
class CfgCacheError(Exception):
34ec4401dc48 686 Client needs a way to tell that a response is actually from an IPS server
johansen <johansen@sun.com>
parents: 814
diff changeset
   607
        """Thrown when there are errors with the cfg cache."""
34ec4401dc48 686 Client needs a way to tell that a response is actually from an IPS server
johansen <johansen@sun.com>
parents: 814
diff changeset
   608
        def __init__(self, args=None):
34ec4401dc48 686 Client needs a way to tell that a response is actually from an IPS server
johansen <johansen@sun.com>
parents: 814
diff changeset
   609
                self.args = args
34ec4401dc48 686 Client needs a way to tell that a response is actually from an IPS server
johansen <johansen@sun.com>
parents: 814
diff changeset
   610
576
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   611
class TransportException(Exception):
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   612
        """ Abstract base class for various transport exceptions """
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   613
        def __init__(self):
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   614
                self.count = 1
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   615
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   616
class TransportFailures(TransportException):
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   617
        """ This exception encapsulates multiple transport exceptions """
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   618
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   619
        #
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   620
        # This class is a subclass of TransportException so that calling
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   621
        # code can reasonably 'except TransportException' and get either
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   622
        # a single-valued or in this case a multi-valued instance.
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   623
        #
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   624
        def __init__(self):
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   625
                TransportException.__init__(self)
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   626
                self.exceptions = []
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   627
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   628
        def append(self, exc):
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   629
                assert isinstance(exc, TransportException)
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   630
                for x in self.exceptions:
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   631
                        if cmp(x, exc) == 0:
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   632
                                x.count += 1
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   633
                                return
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   634
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   635
                self.exceptions.append(exc)
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   636
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   637
        def __str__(self):
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   638
                if len(self.exceptions) == 0:
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   639
                        return "[no errors accumulated]"
388
5a08791fb814 2188 Client must fail gracefully when network timeout occurs
johansen <johansen@sun.com>
parents: 386
diff changeset
   640
576
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   641
                s = ""
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   642
                for i, x in enumerate(self.exceptions):
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   643
                        if len(self.exceptions) > 1:
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   644
                                s += "%d: " % (i + 1)
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   645
                        s += str(x)
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   646
                        if x.count > 1:
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   647
                                s += " (happened %d times)" % x.count
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   648
                        s += "\n"
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   649
                return s
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   650
835
34ec4401dc48 686 Client needs a way to tell that a response is actually from an IPS server
johansen <johansen@sun.com>
parents: 814
diff changeset
   651
        def __len__(self):
34ec4401dc48 686 Client needs a way to tell that a response is actually from an IPS server
johansen <johansen@sun.com>
parents: 814
diff changeset
   652
                return len(self.exceptions)
34ec4401dc48 686 Client needs a way to tell that a response is actually from an IPS server
johansen <johansen@sun.com>
parents: 814
diff changeset
   653
670
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   654
class TransferIOException(TransportException):
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   655
        """Raised for retryable IO errors on underlying transport.
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   656
        Protocol errors are TransferContentExceptions, timeouts
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   657
        are TransferTimedOutExceptions."""
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   658
        def __init__(self, url, reason=None):
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   659
                TransportException.__init__(self)
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   660
                self.url = url
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   661
                self.reason = reason
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   662
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   663
        def __str__(self):
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   664
                s = "IO Error while communicating with '%s'" % self.url
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   665
                if self.reason:
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   666
                        s += ": %s" % self.reason
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   667
                s += "."
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   668
                return s
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   669
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   670
        def __cmp__(self, other):
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   671
                if not isinstance(other, TransferIOException):
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   672
                        return -1        
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   673
                r = cmp(self.url, other.url)
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   674
                if r != 0:
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   675
                        return r
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   676
                return cmp(self.reason, other.reason)
576
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   677
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   678
class TransferTimedOutException(TransportException):
621
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   679
        """Raised when the transfer times out, or is terminated with a
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   680
        retryable error."""
576
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   681
        def __init__(self, url, reason=None):
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   682
                TransportException.__init__(self)
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   683
                self.url = url
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   684
                self.reason = reason
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   685
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   686
        def __str__(self):
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   687
                s = "Transfer from '%s' timed out" % self.url
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   688
                if self.reason:
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   689
                        s += ": %s" % self.reason
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   690
                s += "."
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   691
                return s
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   692
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   693
        def __cmp__(self, other):
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   694
                if not isinstance(other, TransferTimedOutException):
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   695
                        return -1        
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   696
                r = cmp(self.url, other.url)
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   697
                if r != 0:
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   698
                        return r
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   699
                return cmp(self.reason, other.reason)
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   700
429
6c9cbb6e6600 983 pkg search returns just one action per package/token-type combo
Brock Pytlik <bpytlik@sun.com>
parents: 409
diff changeset
   701
518
1d9021e9f558 2584 pkg needs to handle proxy error
johansen <johansen@sun.com>
parents: 494
diff changeset
   702
# Retryable http errors.  These are the HTTP errors that we'll catch.  When we
1d9021e9f558 2584 pkg needs to handle proxy error
johansen <johansen@sun.com>
parents: 494
diff changeset
   703
# catch them, we throw a TransferTimedOutException instead re-raising the
1d9021e9f558 2584 pkg needs to handle proxy error
johansen <johansen@sun.com>
parents: 494
diff changeset
   704
# HTTPError and letting some other handler catch it.
1d9021e9f558 2584 pkg needs to handle proxy error
johansen <johansen@sun.com>
parents: 494
diff changeset
   705
576
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   706
# XXX consider moving to pkg.client module
518
1d9021e9f558 2584 pkg needs to handle proxy error
johansen <johansen@sun.com>
parents: 494
diff changeset
   707
retryable_http_errors = set((httplib.REQUEST_TIMEOUT, httplib.BAD_GATEWAY,
1d9021e9f558 2584 pkg needs to handle proxy error
johansen <johansen@sun.com>
parents: 494
diff changeset
   708
        httplib.GATEWAY_TIMEOUT))
621
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   709
retryable_socket_errors = set((errno.ECONNABORTED, errno.ECONNRESET,
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   710
        errno.ECONNREFUSED))
518
1d9021e9f558 2584 pkg needs to handle proxy error
johansen <johansen@sun.com>
parents: 494
diff changeset
   711
1d9021e9f558 2584 pkg needs to handle proxy error
johansen <johansen@sun.com>
parents: 494
diff changeset
   712
576
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   713
class TransferContentException(TransportException):
621
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   714
        """Raised when there are problems downloading the requested content."""
576
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   715
        def __init__(self, url, reason=None):
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   716
                TransportException.__init__(self)
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   717
                self.url = url
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   718
                self.reason = reason
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   719
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   720
        def __str__(self):
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   721
                s = "Transfer from '%s' failed" % self.url
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   722
                if self.reason:
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   723
                        s += ": %s" % self.reason
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   724
                s += "."
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   725
                return s
461
37cf3ac75e37 1018 actions with payloads should include all sizes and hashes
johansen <johansen@sun.com>
parents: 451
diff changeset
   726
576
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   727
        def __cmp__(self, other):
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   728
                if not isinstance(other, TransferContentException):
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   729
                        return -1        
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   730
                r = cmp(self.url, other.url)
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   731
                if r != 0:
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   732
                        return r
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   733
                return cmp(self.reason, other.reason)
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   734
621
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   735
class TruncatedTransferException(TransportException):
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   736
        """Raised when the transfer that was received doesn't match the
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   737
        expected length."""
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   738
        def __init__(self, url, recd=-1, expected=-1):
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   739
                TransportException.__init__(self)
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   740
                self.url = url
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   741
                self.recd = recd
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   742
                self.expected = expected
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   743
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   744
        def __str__(self):
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   745
                s = "Transfer from '%s' unexpectedly terminated" % self.url
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   746
                if self.recd > -1 and self.expected > -1:
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   747
                        s += ": received %d of %d bytes" % (self.recd,
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   748
                            self.expected)
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   749
                s += "."
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   750
                return s
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   751
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   752
        def __cmp__(self, other):
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   753
                if not isinstance(other, TruncatedTransferException):
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   754
                        return -1        
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   755
                r = cmp(self.url, other.url)
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   756
                if r != 0:
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   757
                        return r
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   758
                r = cmp(self.expected, other.expected)
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   759
                if r != 0:
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   760
                        return r
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   761
                return cmp(self.recd, other.recd)
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   762
576
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   763
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   764
class InvalidContentException(TransportException):
621
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   765
        """Raised when the content's hash/chash doesn't verify, or the
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   766
        content is received in an unreadable format."""
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   767
        def __init__(self, path, data):
576
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   768
                TransportException.__init__(self)
621
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   769
                self.path = path
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   770
                self.data = data
461
37cf3ac75e37 1018 actions with payloads should include all sizes and hashes
johansen <johansen@sun.com>
parents: 451
diff changeset
   771
37cf3ac75e37 1018 actions with payloads should include all sizes and hashes
johansen <johansen@sun.com>
parents: 451
diff changeset
   772
        def __str__(self):
621
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   773
                s = "Invalid content for action with path %s" % self.path
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   774
                if self.data:
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   775
                        s += " %s." % self.data
576
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   776
                return s
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   777
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   778
        def __cmp__(self, other):
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   779
                if not isinstance(other, InvalidContentException):
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   780
                        return -1        
621
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   781
                r = cmp(self.path, other.path)
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   782
                if r != 0:
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   783
                        return r
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   784
                return cmp(self.data, other.data)
576
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   785
838
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   786
# ImmutableDict and EmptyI for argument defaults
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   787
EmptyI = tuple()
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   788
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   789
class ImmutableDict(dict):
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   790
        def __init__(self, default=EmptyI):
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   791
                dict.__init__(self, default)
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   792
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   793
        def __setitem__(self, item, value):
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   794
                self.__oops()
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   795
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   796
        def __delitem__(self, item, value):
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   797
                self.__oops()
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   798
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   799
        def pop(self, item, default=None):
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   800
                self.__oops()
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   801
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   802
        def popitem(self):
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   803
                self.__oops()
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   804
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   805
        def setdefault(self, item, default=None):
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   806
                self.__oops()
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   807
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   808
        def update(self, d):
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   809
                self.__oops()
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   810
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   811
        def copy(self):
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   812
                return ImmutableDict()
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   813
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   814
        def clear(self):
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   815
                self.__oops()
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   816
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   817
        def __oops(self):
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   818
                raise TypeError, "Item assignment to ImmutableDict"
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   819
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   820
def get_sorted_publishers(pubs, preferred=None):
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   821
        spubs = []
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   822
        for p in sorted(pubs, key=operator.attrgetter("prefix")):
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   823
                if preferred and preferred == p.prefix:
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   824
                        spubs.insert(0, p)
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   825
                else:
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   826
                        spubs.append(p)
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   827
        return spubs
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   828
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   829
def build_cert(path, uri=None, pub=None):
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   830
        """Take the file given in path, open it, and use it to create
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   831
        an X509 certificate object.
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   832
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   833
        'uri' is an optional value indicating the uri associated with or that
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   834
        requires the certificate for access.
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   835
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   836
        'pub' is an optional string value containing the name (prefix) of a
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   837
        related publisher."""
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   838
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   839
        try:
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   840
                cf = file(path, "rb")
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   841
                certdata = cf.read()
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   842
                cf.close()
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   843
        except EnvironmentError, e:
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   844
                if e.errno == errno.ENOENT:
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   845
                        raise api_errors.NoSuchCertificate(path, uri=uri,
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   846
                            publisher=pub)
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   847
                if e.errno == errno.EACCES:
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   848
                        raise api_errors.PermissionsException(e.filename)
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   849
                raise
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   850
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   851
        try:
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   852
                return osc.load_certificate(osc.FILETYPE_PEM, certdata)
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   853
        except osc.Error, e:
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   854
                # OpenSSL.crypto.Error
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   855
                raise api_errors.InvalidCertificate(path, uri=uri,
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   856
                    publisher=pub)
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   857
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   858
def validate_ssl_cert(ssl_cert, prefix=None, uri=None):
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   859
        """Validates the indicated certificate and returns a pyOpenSSL object
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   860
        representing it if it is valid."""
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   861
        cert = build_cert(ssl_cert, uri=uri, pub=prefix)
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   862
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   863
        if cert.has_expired():
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   864
                raise api_errors.ExpiredCertificate(ssl_cert, uri=uri,
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   865
                    publisher=prefix)
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   866
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   867
        now = datetime.datetime.utcnow()
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   868
        nb = cert.get_notBefore()
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   869
        t = time.strptime(nb, "%Y%m%d%H%M%SZ")
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   870
        nbdt = datetime.datetime.utcfromtimestamp(
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   871
            calendar.timegm(t))
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   872
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   873
        # PyOpenSSL's has_expired() doesn't validate the notBefore
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   874
        # time on the certificate.  Don't ask me why.
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   875
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   876
        if nbdt > now:
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   877
                raise api_errors.NotYetValidCertificate(ssl_cert, uri=uri,
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   878
                    publisher=prefix)
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   879
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   880
        na = cert.get_notAfter()
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   881
        t = time.strptime(na, "%Y%m%d%H%M%SZ")
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   882
        nadt = datetime.datetime.utcfromtimestamp(
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   883
            calendar.timegm(t))
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   884
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   885
        diff = nadt - now
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   886
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   887
        if diff <= MIN_WARN_DAYS:
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   888
                raise api_errors.ExpiringCertificate(ssl_cert, uri=uri,
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   889
                    publisher=prefix, days=diff.days)
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   890
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   891
        return cert
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   892
838
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   893
EmptyDict = ImmutableDict()
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   894
1026
d4aa3ac69dc0 7878 token_byte_offset file not correctly sorted
Brock Pytlik <bpytlik@sun.com>
parents: 1023
diff changeset
   895
# Setting the python file buffer size to 128k gives substantial performance
d4aa3ac69dc0 7878 token_byte_offset file not correctly sorted
Brock Pytlik <bpytlik@sun.com>
parents: 1023
diff changeset
   896
# gains on certain files.
d4aa3ac69dc0 7878 token_byte_offset file not correctly sorted
Brock Pytlik <bpytlik@sun.com>
parents: 1023
diff changeset
   897
PKG_FILE_BUFSIZ = 128 * 1024