src/modules/misc.py
author Shawn Walker <Shawn.Walker@Sun.COM>
Mon, 09 Mar 2009 16:09:13 -0500
changeset 926 6ee411c9026a
parent 873 b95d76c53b5e
child 941 e7bff46da54e
permissions -rw-r--r--
5871 publisher apis desired 3682 pkg publisher should show mirrors in default listing 5071 provide direct way to change publisher to not use certificate 5373 pkg commands shouldn't traceback when client can't read a key/cert file 6843 problems with empty string for ssl_cert, ssl_key 6897 "authority" should be "publisher" 7046 client intent is not sent if same api object used for multiple operations / reasons
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
873
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
    43
import sys
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
    44
import time
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
    45
import urllib
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
    46
import urllib2
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
    47
import urlparse
342
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
    48
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
    49
319
39b8b5c538bf 1104 want custom user-agent string
Danek Duvall <danek.duvall@sun.com>
parents: 310
diff changeset
    50
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
    51
from pkg.client import global_settings
319
39b8b5c538bf 1104 want custom user-agent string
Danek Duvall <danek.duvall@sun.com>
parents: 310
diff changeset
    52
from pkg import VERSION
310
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
    53
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
    54
# 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
    55
MIN_WARN_DAYS = datetime.timedelta(days=30)
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
    56
443
5ffa5b7dac9c 2589 pyc files generate lots of verify chaff
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 429
diff changeset
    57
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
    58
        """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
    59
        # XXX optimize?
5ffa5b7dac9c 2589 pyc files generate lots of verify chaff
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 429
diff changeset
    60
        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
    61
5ffa5b7dac9c 2589 pyc files generate lots of verify chaff
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 429
diff changeset
    62
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
    63
        """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
    64
        # XXX optimize?
5ffa5b7dac9c 2589 pyc files generate lots of verify chaff
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 429
diff changeset
    65
        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
    66
462
910600c14093 45 "move" action for files that are renamed, but must be preserved
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 461
diff changeset
    67
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
    68
        """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
    69
        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
    70
        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
    71
        try:
873
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
    72
                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
    73
        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
    74
                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
    75
                        raise
910600c14093 45 "move" action for files that are renamed, but must be preserved
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 461
diff changeset
    76
46
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    77
def hash_file_name(f):
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    78
        """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
    79
        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
    80
        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
    81
310
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
    82
def url_affix_trailing_slash(u):
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
    83
        if u[-1] != '/':
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
    84
                u = u + '/'
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
    85
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
    86
        return u
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
    87
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
    88
_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
    89
    (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
    90
    portable.util.get_os_release(), platform.version())
39b8b5c538bf 1104 want custom user-agent string
Danek Duvall <danek.duvall@sun.com>
parents: 310
diff changeset
    91
556
1c3526ca7b9e 2022 client should provide operational intent to server
Shawn Walker <shawn.walker@sun.com>
parents: 551
diff changeset
    92
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
    93
    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
    94
    method = "GET", uuid = None):
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
    95
        """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
    96
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
    97
        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
    98
        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
    99
        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
   100
        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
   101
        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
   102
        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
   103
        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
   104
        matching version can be found.
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   105
        """
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   106
        # Ignore http_proxy for localhost case, by overriding
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   107
        # default proxy behaviour of urlopen().
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   108
        netloc = urlparse.urlparse(base_uri)[1]
310
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
   109
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
   110
        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
   111
                raise ValueError, "Malformed URL: %s" % base_uri
310
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
   112
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   113
        if urllib.splitport(netloc)[0] == "localhost":
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   114
                # XXX cache this opener?
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   115
                proxy_handler = urllib2.ProxyHandler({})
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   116
                opener_dir = urllib2.build_opener(proxy_handler)
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   117
                url_opener = opener_dir.open
310
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
   118
        elif ssl_creds and ssl_creds != (None, None):
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
   119
                cert_handler = urlhelpers.HTTPSCertHandler(
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
   120
                    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
   121
                opener_dir = urllib2.build_opener(
35b869ed3334 4314 https proxy does not work
Tom Mueller <Tom.Mueller@sun.com>
parents: 770
diff changeset
   122
                    urlhelpers.HTTPSProxyHandler, cert_handler)
310
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
   123
                url_opener = opener_dir.open
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   124
        else:
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   125
                url_opener = urllib2.urlopen
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   126
556
1c3526ca7b9e 2022 client should provide operational intent to server
Shawn Walker <shawn.walker@sun.com>
parents: 551
diff changeset
   127
        if not versions:
1c3526ca7b9e 2022 client should provide operational intent to server
Shawn Walker <shawn.walker@sun.com>
parents: 551
diff changeset
   128
                versions = []
1c3526ca7b9e 2022 client should provide operational intent to server
Shawn Walker <shawn.walker@sun.com>
parents: 551
diff changeset
   129
551
233f0eeddd02 856 Image properties
Tom Mueller <Tom.Mueller@sun.com>
parents: 518
diff changeset
   130
        if not headers:
233f0eeddd02 856 Image properties
Tom Mueller <Tom.Mueller@sun.com>
parents: 518
diff changeset
   131
                headers = {}
233f0eeddd02 856 Image properties
Tom Mueller <Tom.Mueller@sun.com>
parents: 518
diff changeset
   132
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   133
        for version in 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
   134
                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
   135
                        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
   136
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   137
                if tail:
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   138
                        uri = urlparse.urljoin(base_uri, "%s/%s/%s" % \
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   139
                            (operation, version, tail))
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   140
                else:
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   141
                        uri = urlparse.urljoin(base_uri, "%s/%s" % \
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   142
                            (operation, version))
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   143
319
39b8b5c538bf 1104 want custom user-agent string
Danek Duvall <danek.duvall@sun.com>
parents: 310
diff changeset
   144
                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
   145
                    _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
   146
                        global_settings.client_name)
551
233f0eeddd02 856 Image properties
Tom Mueller <Tom.Mueller@sun.com>
parents: 518
diff changeset
   147
                if uuid:
233f0eeddd02 856 Image properties
Tom Mueller <Tom.Mueller@sun.com>
parents: 518
diff changeset
   148
                        headers["X-IPkg-UUID"] = uuid
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   149
                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
   150
                if method == "HEAD":
1c3526ca7b9e 2022 client should provide operational intent to server
Shawn Walker <shawn.walker@sun.com>
parents: 551
diff changeset
   151
                        # 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
   152
                        # natively support this operation.
1c3526ca7b9e 2022 client should provide operational intent to server
Shawn Walker <shawn.walker@sun.com>
parents: 551
diff changeset
   153
                        req.get_method = lambda: "HEAD"
1c3526ca7b9e 2022 client should provide operational intent to server
Shawn Walker <shawn.walker@sun.com>
parents: 551
diff changeset
   154
                elif data is not None:
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   155
                        req.add_data(data)
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   156
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   157
                try:
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   158
                        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
   159
                except urllib2.HTTPError, e:
386
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   160
                        if e.code != httplib.NOT_FOUND or \
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   161
                            e.msg != "Version not supported":
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   162
                                raise
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   163
                        continue
260
a1b77322abb2 255 Symbolic HTTP response codes should be used
Shawn Walker <swalker@opensolaris.org>
parents: 181
diff changeset
   164
                # 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
   165
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   166
                return c, version
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   167
        else:
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   168
                # Couldn't find a version that we liked.
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   169
                raise RuntimeError, \
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   170
                    "%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
   171
                    (base_uri, operation)
327
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   172
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   173
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   174
_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
   175
_invalid_host_chars = re.compile(".*[^a-zA-Z0-9\-\.]+")
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   176
_valid_proto = ["http", "https"]
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   177
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   178
def valid_pub_prefix(prefix):
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   179
        """Verify that the publisher prefix only contains valid characters."""
327
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   180
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   181
        # 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
   182
        # it comes to finding invalid characters in the prefix string.
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   183
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   184
        if _invalid_host_chars.match(prefix):
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   185
                # prefix bad chars
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   186
                return False
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   187
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   188
        if _hostname_re.match(prefix):
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   189
                return True
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   190
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   191
        return False
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   192
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   193
def valid_pub_url(url):
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   194
        """Verify that the publisher URL contains only valid characters."""
327
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   195
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   196
        # 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
   197
        o = urlparse.urlsplit(url)
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   198
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   199
        if not o[0] in _valid_proto:
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   200
                return False
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
        # Next verify that the network location is valid
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   203
        host, port = urllib.splitport(o[1])
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   204
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   205
        if not host or _invalid_host_chars.match(host):
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   206
                return False
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   207
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   208
        if _hostname_re.match(host):
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   209
                return True
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   210
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   211
        return False
342
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   212
565
1fb4f05220b9 3443 An api needs to be provided for safe interaction of front-ends
Brock Pytlik <bpytlik@sun.com>
parents: 556
diff changeset
   213
class FilelikeString(object):
1fb4f05220b9 3443 An api needs to be provided for safe interaction of front-ends
Brock Pytlik <bpytlik@sun.com>
parents: 556
diff changeset
   214
        def __init__(self):
1fb4f05220b9 3443 An api needs to be provided for safe interaction of front-ends
Brock Pytlik <bpytlik@sun.com>
parents: 556
diff changeset
   215
                self.buf = ""
1fb4f05220b9 3443 An api needs to be provided for safe interaction of front-ends
Brock Pytlik <bpytlik@sun.com>
parents: 556
diff changeset
   216
1fb4f05220b9 3443 An api needs to be provided for safe interaction of front-ends
Brock Pytlik <bpytlik@sun.com>
parents: 556
diff changeset
   217
        def write(self, o):
1fb4f05220b9 3443 An api needs to be provided for safe interaction of front-ends
Brock Pytlik <bpytlik@sun.com>
parents: 556
diff changeset
   218
                self.buf += o
1fb4f05220b9 3443 An api needs to be provided for safe interaction of front-ends
Brock Pytlik <bpytlik@sun.com>
parents: 556
diff changeset
   219
342
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   220
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
   221
        """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
   222
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   223
        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
   224
        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
   225
        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
   226
        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
   227
        data.
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   228
        """
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   229
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   230
        FHCRC = 2
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   231
        FEXTRA = 4
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   232
        FNAME = 8
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   233
        FCOMMENT = 16
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   234
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   235
        # Read the header
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   236
        magic = gz.read(2)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   237
        if magic != "\037\213":
621
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   238
                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
   239
        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
   240
        if method != 8:
621
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   241
                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
   242
        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
   243
        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
   244
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   245
        # Discard an extra field
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   246
        if flag & FEXTRA:
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   247
                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
   248
                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
   249
                gz.read(xlen)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   250
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   251
        # 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
   252
        if flag & FNAME:
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   253
                while True:
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   254
                        s = gz.read(1)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   255
                        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
   256
                                break
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   257
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   258
        # 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
   259
        if flag & FCOMMENT:
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   260
                while True:
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   261
                        s = gz.read(1)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   262
                        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
   263
                                break
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   264
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   265
        # 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
   266
        if flag & FHCRC:
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   267
                gz.read(2)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   268
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   269
        shasum = sha.new()
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   270
        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
   271
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   272
        while True:
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   273
                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
   274
                if buf == "":
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   275
                        ubuf = dcobj.flush()
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   276
                        shasum.update(ubuf)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   277
                        outfile.write(ubuf)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   278
                        break
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   279
                ubuf = dcobj.decompress(buf)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   280
                shasum.update(ubuf)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   281
                outfile.write(ubuf)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   282
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   283
        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
   284
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   285
class PipeError(Exception):
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   286
        """ Pipe exception. """
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   287
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   288
        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
   289
                self.args = args
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   290
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   291
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
   292
        """ 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
   293
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   294
        try:
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   295
                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
   296
        except IOError, e:
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   297
                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
   298
                        raise PipeError, e
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   299
                raise
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   300
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   301
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
   302
        """ 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
   303
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   304
        try:
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   305
                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
   306
        except IOError, e:
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   307
                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
   308
                        raise PipeError, e
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   309
                raise
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   310
791
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   311
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
   312
        """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
   313
        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
   314
        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
   315
        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
   316
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   317
        if printer is None:
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   318
                printer = emsg
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   319
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   320
        try:
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   321
                locale.setlocale(category, loc)
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   322
        except locale.Error:
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   323
                try:
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   324
                        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
   325
                except ValueError:
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   326
                        dl = ""
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   327
                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
   328
                    "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
   329
                locale.setlocale(category, "C")
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   330
386
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   331
def port_available(host, port):
451
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   332
        """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
   333
        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
   334
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   335
        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
   336
        if host is None:
451
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   337
                # 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
   338
                # 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
   339
                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
   340
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   341
        try:
404
e5329e84b9a8 2331 depot command-line parsing errors cause traceback
Shawn Walker <swalker@opensolaris.org>
parents: 388
diff changeset
   342
                sock = None
e5329e84b9a8 2331 depot command-line parsing errors cause traceback
Shawn Walker <swalker@opensolaris.org>
parents: 388
diff changeset
   343
386
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   344
                # 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
   345
                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
   346
                    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
   347
                        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
   348
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   349
                        # 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
   350
                        # 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
   351
                        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
   352
                        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
   353
                            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
   354
                        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
   355
                        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
   356
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   357
                        # 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
   358
                        # 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
   359
                        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
   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
                        # 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
   362
                        # 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
   363
                        # 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
   364
                        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
   365
494
102fb5979716 2695 misc.port_available fails on Mac/OS due to EINVAL problem
Tom Mueller <Tom.Mueller@sun.com>
parents: 487
diff changeset
   366
                        try:
102fb5979716 2695 misc.port_available fails on Mac/OS due to EINVAL problem
Tom Mueller <Tom.Mueller@sun.com>
parents: 487
diff changeset
   367
                                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
   368
                        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
   369
                                # 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
   370
                                raise
102fb5979716 2695 misc.port_available fails on Mac/OS due to EINVAL problem
Tom Mueller <Tom.Mueller@sun.com>
parents: 487
diff changeset
   371
                        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
   372
                                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
   373
                                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
   374
                                        raise
102fb5979716 2695 misc.port_available fails on Mac/OS due to EINVAL problem
Tom Mueller <Tom.Mueller@sun.com>
parents: 487
diff changeset
   375
                                # 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
   376
                                # 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
   377
                                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
   378
                                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
   379
                                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
   380
                                
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
                        # 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
   384
                        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
   385
                            '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
   386
494
102fb5979716 2695 misc.port_available fails on Mac/OS due to EINVAL problem
Tom Mueller <Tom.Mueller@sun.com>
parents: 487
diff changeset
   387
        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
   388
                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
   389
386
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   390
        except socket.error, e:
404
e5329e84b9a8 2331 depot command-line parsing errors cause traceback
Shawn Walker <swalker@opensolaris.org>
parents: 388
diff changeset
   391
                errnum = e[0]
e5329e84b9a8 2331 depot command-line parsing errors cause traceback
Shawn Walker <swalker@opensolaris.org>
parents: 388
diff changeset
   392
                try:
451
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   393
                        text = e[1]
404
e5329e84b9a8 2331 depot command-line parsing errors cause traceback
Shawn Walker <swalker@opensolaris.org>
parents: 388
diff changeset
   394
                except IndexError:
451
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   395
                        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
   396
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   397
                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
   398
                        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
   399
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   400
                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
   401
                        # 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
   402
                        # 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
   403
                        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
   404
451
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   405
                return False, text
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   406
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   407
def bytes_to_str(bytes):
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   408
        """Returns a human-formatted string representing the number of bytes
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   409
        in the largest unit possible."""
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   410
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   411
        units = [
660
ea2809ad4582 4126 I10n update for IPS CLI PM and UM
John Rice <john.rice@sun.com>
parents: 641
diff changeset
   412
            (_("B"), 2**10),
ea2809ad4582 4126 I10n update for IPS CLI PM and UM
John Rice <john.rice@sun.com>
parents: 641
diff changeset
   413
            (_("kB"), 2**20),
ea2809ad4582 4126 I10n update for IPS CLI PM and UM
John Rice <john.rice@sun.com>
parents: 641
diff changeset
   414
            (_("MB"), 2**30),
ea2809ad4582 4126 I10n update for IPS CLI PM and UM
John Rice <john.rice@sun.com>
parents: 641
diff changeset
   415
            (_("GB"), 2**40),
ea2809ad4582 4126 I10n update for IPS CLI PM and UM
John Rice <john.rice@sun.com>
parents: 641
diff changeset
   416
            (_("TB"), 2**50),
ea2809ad4582 4126 I10n update for IPS CLI PM and UM
John Rice <john.rice@sun.com>
parents: 641
diff changeset
   417
            (_("PB"), 2**60),
ea2809ad4582 4126 I10n update for IPS CLI PM and UM
John Rice <john.rice@sun.com>
parents: 641
diff changeset
   418
            (_("EB"), 2**70)
451
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   419
        ]
386
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   420
451
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   421
        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
   422
                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
   423
                        # 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
   424
                        # 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
   425
                        # unit of measure's range.
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   426
                        continue
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   427
                else:
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   428
                        return "%.2f %s" % (round(bytes / float(
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   429
                            limit / 2**10), 2), uom)
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   430
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   431
def get_rel_path(request, uri):
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   432
        # 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
   433
        # 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
   434
        # calculating depth.
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   435
        depth = request.path_info.count("/") - 1
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   436
        return ("../" * depth) + uri
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   437
487
9cb85c3d8491 2556 client should measure download progress by compressed size
johansen <johansen@sun.com>
parents: 462
diff changeset
   438
def get_pkg_otw_size(action):
9cb85c3d8491 2556 client should measure download progress by compressed size
johansen <johansen@sun.com>
parents: 462
diff changeset
   439
        """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
   440
        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
   441
        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
   442
        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
   443
9cb85c3d8491 2556 client should measure download progress by compressed size
johansen <johansen@sun.com>
parents: 462
diff changeset
   444
        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
   445
        if size == 0:
9cb85c3d8491 2556 client should measure download progress by compressed size
johansen <johansen@sun.com>
parents: 462
diff changeset
   446
                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
   447
9cb85c3d8491 2556 client should measure download progress by compressed size
johansen <johansen@sun.com>
parents: 462
diff changeset
   448
        return int(size)
9cb85c3d8491 2556 client should measure download progress by compressed size
johansen <johansen@sun.com>
parents: 462
diff changeset
   449
770
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   450
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
   451
        most_recent = {}
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   452
        installed = []
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   453
        res = image.inventory(pargs, all_known)
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   454
        # 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
   455
        # 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
   456
        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
   457
                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
   458
                        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
   459
                                installed.append((pfmri, state))
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   460
                        hv = pfmri.get_pkg_stem(include_pkg=False)
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   461
                        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
   462
                                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
   463
                                    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
   464
                                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
   465
                                        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
   466
                        else:
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   467
                                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
   468
                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
   469
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   470
                # 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
   471
                # 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
   472
                # 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
   473
                # 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
   474
                # Also, publishers are taken into account so that
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   475
                # preferred publishers come before others. Finally,
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   476
                # 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
   477
                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
   478
                        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
   479
                        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
   480
                                return t
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   481
                        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
   482
                        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
   483
                                return t
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   484
                        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
   485
                                return -1
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   486
                        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
   487
                                return 1
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   488
                        return cmp(f1.get_publisher(),
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   489
                            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
   490
                
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   491
                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
   492
        return res
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   493
873
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   494
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
   495
        """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
   496
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   497
        '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
   498
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   499
        '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
   500
        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
   501
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   502
        '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
   503
        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
   504
        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
   505
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   506
        bufsz = 128 * 1024
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   507
        if isinstance(data, basestring):
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   508
                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
   509
        else:
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   510
                f = data
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   511
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   512
        if length is None:
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   513
                length = os.lstat(data).st_size
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   514
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   515
        # 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
   516
        # 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
   517
        content = cStringIO.StringIO()
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   518
        fhash = sha.new()
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   519
        while length > 0:
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   520
                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
   521
                if return_content:
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   522
                        content.write(data)
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   523
                fhash.update(data)
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   524
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   525
                l = len(data)
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   526
                if l == 0:
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   527
                        break
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   528
                length -= l
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   529
        content.reset()
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   530
        f.close()
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   531
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   532
        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
   533
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
   534
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
   535
        """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
   536
        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
   537
                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
   538
576
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   539
class TransportException(Exception):
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   540
        """ 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
   541
        def __init__(self):
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   542
                self.count = 1
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   543
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   544
class TransportFailures(TransportException):
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   545
        """ 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
   546
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   547
        #
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   548
        # 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
   549
        # 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
   550
        # 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
   551
        #
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   552
        def __init__(self):
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   553
                TransportException.__init__(self)
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   554
                self.exceptions = []
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   555
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   556
        def append(self, exc):
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   557
                assert isinstance(exc, TransportException)
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   558
                for x in self.exceptions:
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   559
                        if cmp(x, exc) == 0:
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   560
                                x.count += 1
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   561
                                return
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   562
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   563
                self.exceptions.append(exc)
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   564
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   565
        def __str__(self):
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   566
                if len(self.exceptions) == 0:
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   567
                        return "[no errors accumulated]"
388
5a08791fb814 2188 Client must fail gracefully when network timeout occurs
johansen <johansen@sun.com>
parents: 386
diff changeset
   568
576
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   569
                s = ""
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   570
                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
   571
                        if len(self.exceptions) > 1:
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   572
                                s += "%d: " % (i + 1)
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   573
                        s += str(x)
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   574
                        if x.count > 1:
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   575
                                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
   576
                        s += "\n"
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   577
                return s
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   578
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
   579
        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
   580
                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
   581
670
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   582
class TransferIOException(TransportException):
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   583
        """Raised for retryable IO errors on underlying transport.
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   584
        Protocol errors are TransferContentExceptions, timeouts
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   585
        are TransferTimedOutExceptions."""
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   586
        def __init__(self, url, reason=None):
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   587
                TransportException.__init__(self)
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   588
                self.url = url
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   589
                self.reason = reason
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   590
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   591
        def __str__(self):
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   592
                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
   593
                if self.reason:
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   594
                        s += ": %s" % self.reason
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   595
                s += "."
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   596
                return s
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   597
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   598
        def __cmp__(self, other):
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   599
                if not isinstance(other, TransferIOException):
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   600
                        return -1        
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   601
                r = cmp(self.url, other.url)
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   602
                if r != 0:
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   603
                        return r
2785b97791ed 4400 Remove redundant transport error handling logic
johansen <johansen@sun.com>
parents: 660
diff changeset
   604
                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
   605
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   606
class TransferTimedOutException(TransportException):
621
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   607
        """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
   608
        retryable error."""
576
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   609
        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
   610
                TransportException.__init__(self)
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   611
                self.url = url
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   612
                self.reason = reason
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   613
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   614
        def __str__(self):
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   615
                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
   616
                if self.reason:
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   617
                        s += ": %s" % self.reason
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   618
                s += "."
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   619
                return s
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   620
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   621
        def __cmp__(self, other):
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   622
                if not isinstance(other, TransferTimedOutException):
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   623
                        return -1        
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   624
                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
   625
                if r != 0:
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   626
                        return r
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   627
                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
   628
429
6c9cbb6e6600 983 pkg search returns just one action per package/token-type combo
Brock Pytlik <bpytlik@sun.com>
parents: 409
diff changeset
   629
518
1d9021e9f558 2584 pkg needs to handle proxy error
johansen <johansen@sun.com>
parents: 494
diff changeset
   630
# 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
   631
# 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
   632
# HTTPError and letting some other handler catch it.
1d9021e9f558 2584 pkg needs to handle proxy error
johansen <johansen@sun.com>
parents: 494
diff changeset
   633
576
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   634
# XXX consider moving to pkg.client module
518
1d9021e9f558 2584 pkg needs to handle proxy error
johansen <johansen@sun.com>
parents: 494
diff changeset
   635
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
   636
        httplib.GATEWAY_TIMEOUT))
621
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   637
retryable_socket_errors = set((errno.ECONNABORTED, errno.ECONNRESET,
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   638
        errno.ECONNREFUSED))
518
1d9021e9f558 2584 pkg needs to handle proxy error
johansen <johansen@sun.com>
parents: 494
diff changeset
   639
1d9021e9f558 2584 pkg needs to handle proxy error
johansen <johansen@sun.com>
parents: 494
diff changeset
   640
576
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   641
class TransferContentException(TransportException):
621
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   642
        """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
   643
        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
   644
                TransportException.__init__(self)
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   645
                self.url = url
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   646
                self.reason = reason
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   647
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   648
        def __str__(self):
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   649
                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
   650
                if self.reason:
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   651
                        s += ": %s" % self.reason
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   652
                s += "."
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   653
                return s
461
37cf3ac75e37 1018 actions with payloads should include all sizes and hashes
johansen <johansen@sun.com>
parents: 451
diff changeset
   654
576
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   655
        def __cmp__(self, other):
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   656
                if not isinstance(other, TransferContentException):
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   657
                        return -1        
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   658
                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
   659
                if r != 0:
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   660
                        return r
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   661
                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
   662
621
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   663
class TruncatedTransferException(TransportException):
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   664
        """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
   665
        expected length."""
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   666
        def __init__(self, url, recd=-1, expected=-1):
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   667
                TransportException.__init__(self)
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   668
                self.url = url
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   669
                self.recd = recd
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   670
                self.expected = expected
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   671
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   672
        def __str__(self):
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   673
                s = "Transfer from '%s' unexpectedly terminated" % self.url
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   674
                if self.recd > -1 and self.expected > -1:
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   675
                        s += ": received %d of %d bytes" % (self.recd,
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   676
                            self.expected)
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   677
                s += "."
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   678
                return s
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   679
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   680
        def __cmp__(self, other):
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   681
                if not isinstance(other, TruncatedTransferException):
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   682
                        return -1        
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   683
                r = cmp(self.url, other.url)
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   684
                if r != 0:
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   685
                        return r
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   686
                r = cmp(self.expected, other.expected)
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   687
                if r != 0:
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   688
                        return r
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   689
                return cmp(self.recd, other.recd)
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   690
576
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   691
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   692
class InvalidContentException(TransportException):
621
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   693
        """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
   694
        content is received in an unreadable format."""
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   695
        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
   696
                TransportException.__init__(self)
621
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   697
                self.path = path
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   698
                self.data = data
461
37cf3ac75e37 1018 actions with payloads should include all sizes and hashes
johansen <johansen@sun.com>
parents: 451
diff changeset
   699
37cf3ac75e37 1018 actions with payloads should include all sizes and hashes
johansen <johansen@sun.com>
parents: 451
diff changeset
   700
        def __str__(self):
621
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   701
                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
   702
                if self.data:
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   703
                        s += " %s." % self.data
576
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   704
                return s
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   705
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   706
        def __cmp__(self, other):
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   707
                if not isinstance(other, InvalidContentException):
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
   708
                        return -1        
621
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   709
                r = cmp(self.path, other.path)
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   710
                if r != 0:
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   711
                        return r
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   712
                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
   713
429
6c9cbb6e6600 983 pkg search returns just one action per package/token-type combo
Brock Pytlik <bpytlik@sun.com>
parents: 409
diff changeset
   714
# Default maximum memory useage during indexing
6c9cbb6e6600 983 pkg search returns just one action per package/token-type combo
Brock Pytlik <bpytlik@sun.com>
parents: 409
diff changeset
   715
# This is a soft cap since memory usage is estimated.
6c9cbb6e6600 983 pkg search returns just one action per package/token-type combo
Brock Pytlik <bpytlik@sun.com>
parents: 409
diff changeset
   716
try:
6c9cbb6e6600 983 pkg search returns just one action per package/token-type combo
Brock Pytlik <bpytlik@sun.com>
parents: 409
diff changeset
   717
        phys_pages = os.sysconf("SC_PHYS_PAGES")
6c9cbb6e6600 983 pkg search returns just one action per package/token-type combo
Brock Pytlik <bpytlik@sun.com>
parents: 409
diff changeset
   718
        page_size = os.sysconf("SC_PAGE_SIZE")
6c9cbb6e6600 983 pkg search returns just one action per package/token-type combo
Brock Pytlik <bpytlik@sun.com>
parents: 409
diff changeset
   719
        SERVER_DEFAULT_MEM_USE_KB = (phys_pages / 1024.0) * page_size / 3
6c9cbb6e6600 983 pkg search returns just one action per package/token-type combo
Brock Pytlik <bpytlik@sun.com>
parents: 409
diff changeset
   720
        CLIENT_DEFAULT_MEM_USE_KB = SERVER_DEFAULT_MEM_USE_KB / 2.0
565
1fb4f05220b9 3443 An api needs to be provided for safe interaction of front-ends
Brock Pytlik <bpytlik@sun.com>
parents: 556
diff changeset
   721
except KeyboardInterrupt:
1fb4f05220b9 3443 An api needs to be provided for safe interaction of front-ends
Brock Pytlik <bpytlik@sun.com>
parents: 556
diff changeset
   722
        raise
429
6c9cbb6e6600 983 pkg search returns just one action per package/token-type combo
Brock Pytlik <bpytlik@sun.com>
parents: 409
diff changeset
   723
except:
6c9cbb6e6600 983 pkg search returns just one action per package/token-type combo
Brock Pytlik <bpytlik@sun.com>
parents: 409
diff changeset
   724
        CLIENT_DEFAULT_MEM_USE_KB = 100
6c9cbb6e6600 983 pkg search returns just one action per package/token-type combo
Brock Pytlik <bpytlik@sun.com>
parents: 409
diff changeset
   725
        SERVER_DEFAULT_MEM_USE_KB = 500
838
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   726
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   727
# 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
   728
EmptyI = tuple()
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   729
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   730
class ImmutableDict(dict):
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   731
        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
   732
                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
   733
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   734
        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
   735
                self.__oops()
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   736
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   737
        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
   738
                self.__oops()
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   739
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   740
        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
   741
                self.__oops()
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   742
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   743
        def popitem(self):
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   744
                self.__oops()
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   745
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   746
        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
   747
                self.__oops()
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   748
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   749
        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
   750
                self.__oops()
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   751
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   752
        def copy(self):
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   753
                return ImmutableDict()
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   754
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   755
        def clear(self):
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   756
                self.__oops()
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   757
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   758
        def __oops(self):
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   759
                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
   760
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   761
def get_sorted_publishers(pubs, preferred=None):
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   762
        spubs = []
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   763
        for p in sorted(pubs, key=operator.attrgetter("prefix")):
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   764
                if preferred and preferred == p.prefix:
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   765
                        spubs.insert(0, p)
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   766
                else:
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   767
                        spubs.append(p)
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   768
        return spubs
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   769
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   770
def build_cert(path, uri=None, pub=None):
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   771
        """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
   772
        an X509 certificate object.
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   773
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   774
        '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
   775
        requires the certificate for access.
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   776
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   777
        '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
   778
        related publisher."""
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   779
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   780
        try:
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   781
                cf = file(path, "rb")
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   782
                certdata = cf.read()
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   783
                cf.close()
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   784
        except EnvironmentError, e:
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   785
                if e.errno == errno.ENOENT:
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   786
                        raise api_errors.NoSuchCertificate(path, uri=uri,
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   787
                            publisher=pub)
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   788
                if e.errno == errno.EACCES:
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   789
                        raise api_errors.PermissionsException(e.filename)
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   790
                raise
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   791
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   792
        try:
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   793
                return osc.load_certificate(osc.FILETYPE_PEM, certdata)
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   794
        except osc.Error, e:
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   795
                # OpenSSL.crypto.Error
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   796
                raise api_errors.InvalidCertificate(path, uri=uri,
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   797
                    publisher=pub)
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   798
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   799
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
   800
        """Validates the indicated certificate and returns a pyOpenSSL object
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   801
        representing it if it is valid."""
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   802
        cert = build_cert(ssl_cert, uri=uri, pub=prefix)
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   803
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   804
        if cert.has_expired():
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   805
                raise api_errors.ExpiredCertificate(ssl_cert, uri=uri,
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   806
                    publisher=prefix)
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   807
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   808
        now = datetime.datetime.utcnow()
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   809
        nb = cert.get_notBefore()
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   810
        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
   811
        nbdt = datetime.datetime.utcfromtimestamp(
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   812
            calendar.timegm(t))
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   813
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   814
        # PyOpenSSL's has_expired() doesn't validate the notBefore
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   815
        # time on the certificate.  Don't ask me why.
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   816
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   817
        if nbdt > now:
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   818
                raise api_errors.NotYetValidCertificate(ssl_cert, uri=uri,
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   819
                    publisher=prefix)
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   820
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   821
        na = cert.get_notAfter()
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   822
        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
   823
        nadt = datetime.datetime.utcfromtimestamp(
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   824
            calendar.timegm(t))
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   825
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   826
        diff = nadt - now
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   827
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   828
        if diff <= MIN_WARN_DAYS:
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   829
                raise api_errors.ExpiringCertificate(ssl_cert, uri=uri,
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   830
                    publisher=prefix, days=diff.days)
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   831
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   832
        return cert
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   833
838
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   834
EmptyDict = ImmutableDict()
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   835