src/modules/misc.py
author johansen <johansen@sun.com>
Wed, 01 Jul 2009 16:18:33 -0700
changeset 1191 a48bee2a4b2e
parent 1142 64d164b5bf04
child 1318 a12f41da2189
permissions -rw-r--r--
305 http_proxy value needs more checking for valid url syntax 2341 Client should be more conservative about closing sockets 4235 Misleading "node name" unknown messages when http_proxy set incorrectly 4495 Want ability to cancel individual file downloads 8902 Need a transport that downloads files by GET 9508 Captive portal test only run during catalog refresh 9613 Implicit refresh should raise InvalidDepotResponseException 9615 EOL clientside search v0 9629 EOL clientside support for filelist 9630 Hostile depot should live with other depot code 9631 HTTPS transport should be more rigorous in verification 9670 More specific error exceptions requested from search 9686 network operations should use accept-encoding when appropriate 9715 The info() operation should use the activity_lock
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
409
713e20963dc2 2314 shebang lines should use minimum python version
Shawn Walker <swalker@opensolaris.org>
parents: 404
diff changeset
     1
#!/usr/bin/python2.4
46
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
     2
#
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
     3
# CDDL HEADER START
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
     4
#
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
     5
# The contents of this file are subject to the terms of the
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
     6
# Common Development and Distribution License (the "License").
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
     7
# You may not use this file except in compliance with the License.
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
     8
#
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
     9
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    10
# or http://www.opensolaris.org/os/licensing.
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    11
# See the License for the specific language governing permissions
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    12
# and limitations under the License.
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    13
#
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    14
# When distributing Covered Code, include this CDDL HEADER in each
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    15
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    16
# If applicable, add the following below this CDDL HEADER, with the
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    17
# fields enclosed by brackets "[]" replaced with your own identifying
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    18
# information: Portions Copyright [yyyy] [name of copyright owner]
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    19
#
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    20
# CDDL HEADER END
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    21
#
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    22
814
76909c2cad8f 5603 server catalog permissions should be 644, not 600
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 791
diff changeset
    23
# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
46
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
    24
# Use is subject to license terms.
119
537d69114be4 Implement bundled file downloads using filelist
johansen <johansen@sun.com>
parents: 108
diff changeset
    25
873
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
    26
import calendar
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
    27
import cStringIO
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
    28
import datetime
384
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
    29
import errno
386
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
    30
import httplib
873
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
    31
import locale
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
    32
import OpenSSL.crypto as osc
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
    33
import operator
119
537d69114be4 Implement bundled file downloads using filelist
johansen <johansen@sun.com>
parents: 108
diff changeset
    34
import os
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
    35
import pkg.client.api_errors as api_errors
873
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
    36
import pkg.portable as portable
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
    37
import pkg.urlhelpers as urlhelpers
386
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
    38
import platform
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
    39
import re
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
    40
import sha
873
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
    41
import shutil
386
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
    42
import socket
1035
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
    43
import struct
873
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
    44
import sys
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
    45
import time
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
    46
import urllib
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
    47
import urllib2
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
    48
import urlparse
342
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
    49
import zlib
462
910600c14093 45 "move" action for files that are renamed, but must be preserved
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 461
diff changeset
    50
319
39b8b5c538bf 1104 want custom user-agent string
Danek Duvall <danek.duvall@sun.com>
parents: 310
diff changeset
    51
from pkg.client.imagetypes import img_type_names, IMG_NONE
696
6bbfd2dece6f 4371 user-agent string needs to be different for different client front-ends
Danek Duvall <danek.duvall@sun.com>
parents: 670
diff changeset
    52
from pkg.client import global_settings
319
39b8b5c538bf 1104 want custom user-agent string
Danek Duvall <danek.duvall@sun.com>
parents: 310
diff changeset
    53
from pkg import VERSION
310
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
    54
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
    55
# Minimum number of days to issue warning before a certificate expires
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
    56
MIN_WARN_DAYS = datetime.timedelta(days=30)
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
    57
1023
73f73773b4c9 6358 Release Notes message after Update All needs to be updated
John Rice <john.rice@sun.com>
parents: 956
diff changeset
    58
def get_release_notes_url():
73f73773b4c9 6358 Release Notes message after Update All needs to be updated
John Rice <john.rice@sun.com>
parents: 956
diff changeset
    59
        """Return a release note URL pointing to the correct release notes
73f73773b4c9 6358 Release Notes message after Update All needs to be updated
John Rice <john.rice@sun.com>
parents: 956
diff changeset
    60
           for this version"""
73f73773b4c9 6358 Release Notes message after Update All needs to be updated
John Rice <john.rice@sun.com>
parents: 956
diff changeset
    61
73f73773b4c9 6358 Release Notes message after Update All needs to be updated
John Rice <john.rice@sun.com>
parents: 956
diff changeset
    62
        # TBD: replace with a call to api.info() that can return a "release"
73f73773b4c9 6358 Release Notes message after Update All needs to be updated
John Rice <john.rice@sun.com>
parents: 956
diff changeset
    63
        # attribute of form YYYYMM against the SUNWsolnm package
73f73773b4c9 6358 Release Notes message after Update All needs to be updated
John Rice <john.rice@sun.com>
parents: 956
diff changeset
    64
        release_str = \
73f73773b4c9 6358 Release Notes message after Update All needs to be updated
John Rice <john.rice@sun.com>
parents: 956
diff changeset
    65
                "http://opensolaris.org/os/project/indiana/resources/relnotes/200906/"
73f73773b4c9 6358 Release Notes message after Update All needs to be updated
John Rice <john.rice@sun.com>
parents: 956
diff changeset
    66
        if platform.processor() == 'sparc':
73f73773b4c9 6358 Release Notes message after Update All needs to be updated
John Rice <john.rice@sun.com>
parents: 956
diff changeset
    67
                release_str += 'sparc/'
73f73773b4c9 6358 Release Notes message after Update All needs to be updated
John Rice <john.rice@sun.com>
parents: 956
diff changeset
    68
        else:
73f73773b4c9 6358 Release Notes message after Update All needs to be updated
John Rice <john.rice@sun.com>
parents: 956
diff changeset
    69
                release_str += 'x86/'
73f73773b4c9 6358 Release Notes message after Update All needs to be updated
John Rice <john.rice@sun.com>
parents: 956
diff changeset
    70
73f73773b4c9 6358 Release Notes message after Update All needs to be updated
John Rice <john.rice@sun.com>
parents: 956
diff changeset
    71
        return release_str
73f73773b4c9 6358 Release Notes message after Update All needs to be updated
John Rice <john.rice@sun.com>
parents: 956
diff changeset
    72
443
5ffa5b7dac9c 2589 pyc files generate lots of verify chaff
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 429
diff changeset
    73
def time_to_timestamp(t):
462
910600c14093 45 "move" action for files that are renamed, but must be preserved
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 461
diff changeset
    74
        """convert seconds since epoch to %Y%m%dT%H%M%SZ format"""
443
5ffa5b7dac9c 2589 pyc files generate lots of verify chaff
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 429
diff changeset
    75
        # XXX optimize?
5ffa5b7dac9c 2589 pyc files generate lots of verify chaff
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 429
diff changeset
    76
        return time.strftime("%Y%m%dT%H%M%SZ", time.gmtime(t))
5ffa5b7dac9c 2589 pyc files generate lots of verify chaff
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 429
diff changeset
    77
5ffa5b7dac9c 2589 pyc files generate lots of verify chaff
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 429
diff changeset
    78
def timestamp_to_time(ts):
462
910600c14093 45 "move" action for files that are renamed, but must be preserved
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 461
diff changeset
    79
        """convert %Y%m%dT%H%M%SZ format to seconds since epoch"""
443
5ffa5b7dac9c 2589 pyc files generate lots of verify chaff
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 429
diff changeset
    80
        # XXX optimize?
5ffa5b7dac9c 2589 pyc files generate lots of verify chaff
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 429
diff changeset
    81
        return calendar.timegm(time.strptime(ts, "%Y%m%dT%H%M%SZ"))
5ffa5b7dac9c 2589 pyc files generate lots of verify chaff
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 429
diff changeset
    82
462
910600c14093 45 "move" action for files that are renamed, but must be preserved
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 461
diff changeset
    83
def copyfile(src_path, dst_path):
910600c14093 45 "move" action for files that are renamed, but must be preserved
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 461
diff changeset
    84
        """copy a file, preserving attributes, ownership, etc. where possible"""
873
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
    85
        fs = os.lstat(src_path)
462
910600c14093 45 "move" action for files that are renamed, but must be preserved
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 461
diff changeset
    86
        shutil.copy2(src_path, dst_path)
910600c14093 45 "move" action for files that are renamed, but must be preserved
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 461
diff changeset
    87
        try:
873
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
    88
                portable.chown(dst_path, fs.st_uid, fs.st_gid)
462
910600c14093 45 "move" action for files that are renamed, but must be preserved
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 461
diff changeset
    89
        except OSError, e:
910600c14093 45 "move" action for files that are renamed, but must be preserved
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 461
diff changeset
    90
                if e.errno != errno.EPERM:
910600c14093 45 "move" action for files that are renamed, but must be preserved
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 461
diff changeset
    91
                        raise
956
adf6bdfdb3b5 6904 image.installed_file_authority always tries to open installed file r+
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 941
diff changeset
    92
def expanddirs(dirs):
adf6bdfdb3b5 6904 image.installed_file_authority always tries to open installed file r+
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 941
diff changeset
    93
        """given a set of directories, return expanded set that includes
adf6bdfdb3b5 6904 image.installed_file_authority always tries to open installed file r+
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 941
diff changeset
    94
        all components"""
adf6bdfdb3b5 6904 image.installed_file_authority always tries to open installed file r+
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 941
diff changeset
    95
        out = set()
adf6bdfdb3b5 6904 image.installed_file_authority always tries to open installed file r+
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 941
diff changeset
    96
        for d in dirs:
adf6bdfdb3b5 6904 image.installed_file_authority always tries to open installed file r+
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 941
diff changeset
    97
                p = d
adf6bdfdb3b5 6904 image.installed_file_authority always tries to open installed file r+
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 941
diff changeset
    98
                while p != "":
adf6bdfdb3b5 6904 image.installed_file_authority always tries to open installed file r+
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 941
diff changeset
    99
                        out.add(p)
adf6bdfdb3b5 6904 image.installed_file_authority always tries to open installed file r+
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 941
diff changeset
   100
                        p = os.path.dirname(p)
adf6bdfdb3b5 6904 image.installed_file_authority always tries to open installed file r+
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 941
diff changeset
   101
        return out
462
910600c14093 45 "move" action for files that are renamed, but must be preserved
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 461
diff changeset
   102
46
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
   103
def hash_file_name(f):
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
   104
        """Return the two-level path fragment for the given filename, which is
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
   105
        assumed to be a content hash of at least 8 distinct characters."""
119
537d69114be4 Implement bundled file downloads using filelist
johansen <johansen@sun.com>
parents: 108
diff changeset
   106
        return os.path.join("%s" % f[0:2], "%s" % f[2:8], "%s" % f)
46
86a10bea7bb6 commonize file/ prefix handling; sketch manifest difference algorithm
Stephen Hahn <sch@sun.com>
parents:
diff changeset
   107
310
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
   108
def url_affix_trailing_slash(u):
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
   109
        if u[-1] != '/':
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
   110
                u = u + '/'
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
   111
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
   112
        return u
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
   113
696
6bbfd2dece6f 4371 user-agent string needs to be different for different client front-ends
Danek Duvall <danek.duvall@sun.com>
parents: 670
diff changeset
   114
_client_version = "pkg/%s (%s %s; %s %s; %%s; %%s)" % \
319
39b8b5c538bf 1104 want custom user-agent string
Danek Duvall <danek.duvall@sun.com>
parents: 310
diff changeset
   115
    (VERSION, portable.util.get_canonical_os_name(), platform.machine(),
39b8b5c538bf 1104 want custom user-agent string
Danek Duvall <danek.duvall@sun.com>
parents: 310
diff changeset
   116
    portable.util.get_os_release(), platform.version())
39b8b5c538bf 1104 want custom user-agent string
Danek Duvall <danek.duvall@sun.com>
parents: 310
diff changeset
   117
1191
a48bee2a4b2e 305 http_proxy value needs more checking for valid url syntax
johansen <johansen@sun.com>
parents: 1142
diff changeset
   118
def user_agent_str(img, client_name):
a48bee2a4b2e 305 http_proxy value needs more checking for valid url syntax
johansen <johansen@sun.com>
parents: 1142
diff changeset
   119
a48bee2a4b2e 305 http_proxy value needs more checking for valid url syntax
johansen <johansen@sun.com>
parents: 1142
diff changeset
   120
        if not img or img.type is None:
a48bee2a4b2e 305 http_proxy value needs more checking for valid url syntax
johansen <johansen@sun.com>
parents: 1142
diff changeset
   121
                imgtype = IMG_NONE
a48bee2a4b2e 305 http_proxy value needs more checking for valid url syntax
johansen <johansen@sun.com>
parents: 1142
diff changeset
   122
        else:
a48bee2a4b2e 305 http_proxy value needs more checking for valid url syntax
johansen <johansen@sun.com>
parents: 1142
diff changeset
   123
                imgtype = img.type
a48bee2a4b2e 305 http_proxy value needs more checking for valid url syntax
johansen <johansen@sun.com>
parents: 1142
diff changeset
   124
a48bee2a4b2e 305 http_proxy value needs more checking for valid url syntax
johansen <johansen@sun.com>
parents: 1142
diff changeset
   125
        useragent = _client_version % (img_type_names[imgtype], client_name)
a48bee2a4b2e 305 http_proxy value needs more checking for valid url syntax
johansen <johansen@sun.com>
parents: 1142
diff changeset
   126
a48bee2a4b2e 305 http_proxy value needs more checking for valid url syntax
johansen <johansen@sun.com>
parents: 1142
diff changeset
   127
        return useragent
a48bee2a4b2e 305 http_proxy value needs more checking for valid url syntax
johansen <johansen@sun.com>
parents: 1142
diff changeset
   128
556
1c3526ca7b9e 2022 client should provide operational intent to server
Shawn Walker <shawn.walker@sun.com>
parents: 551
diff changeset
   129
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
   130
    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
   131
    method = "GET", uuid = None):
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   132
        """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
   133
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   134
        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
   135
        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
   136
        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
   137
        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
   138
        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
   139
        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
   140
        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
   141
        matching version can be found.
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   142
        """
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   143
        # Ignore http_proxy for localhost case, by overriding
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   144
        # default proxy behaviour of urlopen().
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   145
        netloc = urlparse.urlparse(base_uri)[1]
310
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
   146
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
   147
        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
   148
                raise ValueError, "Malformed URL: %s" % base_uri
310
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
   149
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   150
        if urllib.splitport(netloc)[0] == "localhost":
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   151
                # XXX cache this opener?
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   152
                proxy_handler = urllib2.ProxyHandler({})
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   153
                opener_dir = urllib2.build_opener(proxy_handler)
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   154
                url_opener = opener_dir.open
310
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
   155
        elif ssl_creds and ssl_creds != (None, None):
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
   156
                cert_handler = urlhelpers.HTTPSCertHandler(
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
   157
                    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
   158
                opener_dir = urllib2.build_opener(
35b869ed3334 4314 https proxy does not work
Tom Mueller <Tom.Mueller@sun.com>
parents: 770
diff changeset
   159
                    urlhelpers.HTTPSProxyHandler, cert_handler)
310
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
   160
                url_opener = opener_dir.open
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   161
        else:
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   162
                url_opener = urllib2.urlopen
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   163
556
1c3526ca7b9e 2022 client should provide operational intent to server
Shawn Walker <shawn.walker@sun.com>
parents: 551
diff changeset
   164
        if not versions:
1c3526ca7b9e 2022 client should provide operational intent to server
Shawn Walker <shawn.walker@sun.com>
parents: 551
diff changeset
   165
                versions = []
1c3526ca7b9e 2022 client should provide operational intent to server
Shawn Walker <shawn.walker@sun.com>
parents: 551
diff changeset
   166
551
233f0eeddd02 856 Image properties
Tom Mueller <Tom.Mueller@sun.com>
parents: 518
diff changeset
   167
        if not headers:
233f0eeddd02 856 Image properties
Tom Mueller <Tom.Mueller@sun.com>
parents: 518
diff changeset
   168
                headers = {}
233f0eeddd02 856 Image properties
Tom Mueller <Tom.Mueller@sun.com>
parents: 518
diff changeset
   169
941
e7bff46da54e 6175 search needs to be moved to version 1
Brock Pytlik <bpytlik@sun.com>
parents: 926
diff changeset
   170
        for i, version in enumerate(versions):
351
9301d4d85349 767 pkg client can't talk to repo at a path other than / on a server
johansen <johansen@sun.com>
parents: 342
diff changeset
   171
                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
   172
                        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
   173
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   174
                if tail:
941
e7bff46da54e 6175 search needs to be moved to version 1
Brock Pytlik <bpytlik@sun.com>
parents: 926
diff changeset
   175
                        tail_str = tail
e7bff46da54e 6175 search needs to be moved to version 1
Brock Pytlik <bpytlik@sun.com>
parents: 926
diff changeset
   176
                        if isinstance(tail, list):
e7bff46da54e 6175 search needs to be moved to version 1
Brock Pytlik <bpytlik@sun.com>
parents: 926
diff changeset
   177
                                tail_str = tail[i]
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   178
                        uri = urlparse.urljoin(base_uri, "%s/%s/%s" % \
941
e7bff46da54e 6175 search needs to be moved to version 1
Brock Pytlik <bpytlik@sun.com>
parents: 926
diff changeset
   179
                            (operation, version, tail_str))
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   180
                else:
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   181
                        uri = urlparse.urljoin(base_uri, "%s/%s" % \
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   182
                            (operation, version))
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   183
319
39b8b5c538bf 1104 want custom user-agent string
Danek Duvall <danek.duvall@sun.com>
parents: 310
diff changeset
   184
                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
   185
                    _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
   186
                        global_settings.client_name)
551
233f0eeddd02 856 Image properties
Tom Mueller <Tom.Mueller@sun.com>
parents: 518
diff changeset
   187
                if uuid:
233f0eeddd02 856 Image properties
Tom Mueller <Tom.Mueller@sun.com>
parents: 518
diff changeset
   188
                        headers["X-IPkg-UUID"] = uuid
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   189
                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
   190
                if method == "HEAD":
1c3526ca7b9e 2022 client should provide operational intent to server
Shawn Walker <shawn.walker@sun.com>
parents: 551
diff changeset
   191
                        # 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
   192
                        # natively support this operation.
1c3526ca7b9e 2022 client should provide operational intent to server
Shawn Walker <shawn.walker@sun.com>
parents: 551
diff changeset
   193
                        req.get_method = lambda: "HEAD"
1c3526ca7b9e 2022 client should provide operational intent to server
Shawn Walker <shawn.walker@sun.com>
parents: 551
diff changeset
   194
                elif data is not None:
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   195
                        req.add_data(data)
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   196
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   197
                try:
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   198
                        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
   199
                except urllib2.HTTPError, e:
941
e7bff46da54e 6175 search needs to be moved to version 1
Brock Pytlik <bpytlik@sun.com>
parents: 926
diff changeset
   200
                        if e.code != httplib.NOT_FOUND:
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   201
                                raise
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   202
                        continue
260
a1b77322abb2 255 Symbolic HTTP response codes should be used
Shawn Walker <swalker@opensolaris.org>
parents: 181
diff changeset
   203
                # 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
   204
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   205
                return c, version
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   206
        else:
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   207
                # Couldn't find a version that we liked.
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   208
                raise RuntimeError, \
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   209
                    "%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
   210
                    (base_uri, operation)
327
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   211
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   212
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   213
_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
   214
_invalid_host_chars = re.compile(".*[^a-zA-Z0-9\-\.]+")
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   215
_valid_proto = ["http", "https"]
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   216
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   217
def valid_pub_prefix(prefix):
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   218
        """Verify that the publisher prefix only contains valid characters."""
327
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   219
1142
64d164b5bf04 9164 misc.valid_pub_prefix and misc.valid_pub_url should handle None
Shawn Walker <srw@sun.com>
parents: 1072
diff changeset
   220
        if not prefix:
64d164b5bf04 9164 misc.valid_pub_prefix and misc.valid_pub_url should handle None
Shawn Walker <srw@sun.com>
parents: 1072
diff changeset
   221
                return False
64d164b5bf04 9164 misc.valid_pub_prefix and misc.valid_pub_url should handle None
Shawn Walker <srw@sun.com>
parents: 1072
diff changeset
   222
327
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   223
        # 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
   224
        # it comes to finding invalid characters in the prefix string.
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   225
        if _invalid_host_chars.match(prefix):
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   226
                # prefix bad chars
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   227
                return False
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   228
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   229
        if _hostname_re.match(prefix):
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   230
                return True
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   231
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   232
        return False
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   233
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   234
def valid_pub_url(url):
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   235
        """Verify that the publisher URL contains only valid characters."""
327
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   236
1142
64d164b5bf04 9164 misc.valid_pub_prefix and misc.valid_pub_url should handle None
Shawn Walker <srw@sun.com>
parents: 1072
diff changeset
   237
        if not url:
64d164b5bf04 9164 misc.valid_pub_prefix and misc.valid_pub_url should handle None
Shawn Walker <srw@sun.com>
parents: 1072
diff changeset
   238
                return False
64d164b5bf04 9164 misc.valid_pub_prefix and misc.valid_pub_url should handle None
Shawn Walker <srw@sun.com>
parents: 1072
diff changeset
   239
327
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   240
        # 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
   241
        o = urlparse.urlsplit(url)
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   242
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   243
        if not o[0] in _valid_proto:
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   244
                return False
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   245
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   246
        # Next verify that the network location is valid
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   247
        host, port = urllib.splitport(o[1])
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   248
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   249
        if not host or _invalid_host_chars.match(host):
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   250
                return False
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   251
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   252
        if _hostname_re.match(host):
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   253
                return True
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   254
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   255
        return False
342
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   256
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   257
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
   258
        """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
   259
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   260
        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
   261
        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
   262
        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
   263
        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
   264
        data.
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   265
        """
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   266
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   267
        FHCRC = 2
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   268
        FEXTRA = 4
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   269
        FNAME = 8
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   270
        FCOMMENT = 16
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
        # Read the header
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   273
        magic = gz.read(2)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   274
        if magic != "\037\213":
621
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   275
                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
   276
        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
   277
        if method != 8:
621
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   278
                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
   279
        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
   280
        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
   281
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   282
        # Discard an extra field
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   283
        if flag & FEXTRA:
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   284
                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
   285
                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
   286
                gz.read(xlen)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   287
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   288
        # 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
   289
        if flag & FNAME:
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   290
                while True:
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   291
                        s = gz.read(1)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   292
                        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
   293
                                break
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   294
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   295
        # 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
   296
        if flag & FCOMMENT:
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   297
                while True:
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   298
                        s = gz.read(1)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   299
                        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
   300
                                break
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   301
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   302
        # 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
   303
        if flag & FHCRC:
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   304
                gz.read(2)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   305
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   306
        shasum = sha.new()
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   307
        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
   308
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   309
        while True:
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   310
                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
   311
                if buf == "":
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   312
                        ubuf = dcobj.flush()
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   313
                        shasum.update(ubuf)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   314
                        outfile.write(ubuf)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   315
                        break
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   316
                ubuf = dcobj.decompress(buf)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   317
                shasum.update(ubuf)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   318
                outfile.write(ubuf)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   319
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   320
        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
   321
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   322
class PipeError(Exception):
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   323
        """ Pipe exception. """
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   324
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   325
        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
   326
                self.args = args
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   327
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   328
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
   329
        """ 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
   330
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   331
        try:
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   332
                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
   333
        except IOError, e:
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   334
                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
   335
                        raise PipeError, e
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   336
                raise
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   337
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   338
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
   339
        """ 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
   340
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   341
        try:
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   342
                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
   343
        except IOError, e:
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   344
                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
   345
                        raise PipeError, e
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   346
                raise
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   347
791
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   348
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
   349
        """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
   350
        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
   351
        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
   352
        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
   353
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   354
        if printer is None:
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   355
                printer = emsg
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   356
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   357
        try:
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   358
                locale.setlocale(category, loc)
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   359
        except locale.Error:
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   360
                try:
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   361
                        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
   362
                except ValueError:
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   363
                        dl = ""
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   364
                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
   365
                    "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
   366
                locale.setlocale(category, "C")
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   367
386
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   368
def port_available(host, port):
451
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   369
        """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
   370
        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
   371
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   372
        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
   373
        if host is None:
451
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   374
                # 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
   375
                # 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
   376
                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
   377
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   378
        try:
404
e5329e84b9a8 2331 depot command-line parsing errors cause traceback
Shawn Walker <swalker@opensolaris.org>
parents: 388
diff changeset
   379
                sock = None
e5329e84b9a8 2331 depot command-line parsing errors cause traceback
Shawn Walker <swalker@opensolaris.org>
parents: 388
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
                # 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
   382
                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
   383
                    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
   384
                        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
   385
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   386
                        # 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
   387
                        # 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
   388
                        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
   389
                        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
   390
                            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
   391
                        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
   392
                        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
   393
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   394
                        # 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
   395
                        # 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
   396
                        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
   397
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   398
                        # 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
   399
                        # 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
   400
                        # 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
   401
                        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
   402
494
102fb5979716 2695 misc.port_available fails on Mac/OS due to EINVAL problem
Tom Mueller <Tom.Mueller@sun.com>
parents: 487
diff changeset
   403
                        try:
102fb5979716 2695 misc.port_available fails on Mac/OS due to EINVAL problem
Tom Mueller <Tom.Mueller@sun.com>
parents: 487
diff changeset
   404
                                sock.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
   405
                        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
   406
                                # 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
   407
                                raise
102fb5979716 2695 misc.port_available fails on Mac/OS due to EINVAL problem
Tom Mueller <Tom.Mueller@sun.com>
parents: 487
diff changeset
   408
                        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
   409
                                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
   410
                                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
   411
                                        raise
102fb5979716 2695 misc.port_available fails on Mac/OS due to EINVAL problem
Tom Mueller <Tom.Mueller@sun.com>
parents: 487
diff changeset
   412
                                # 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
   413
                                # 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
   414
                                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
   415
                                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
   416
                                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
   417
                                
386
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   418
                        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
   419
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   420
                        # 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
   421
                        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
   422
                            '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
   423
494
102fb5979716 2695 misc.port_available fails on Mac/OS due to EINVAL problem
Tom Mueller <Tom.Mueller@sun.com>
parents: 487
diff changeset
   424
        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
   425
                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
   426
386
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   427
        except socket.error, e:
404
e5329e84b9a8 2331 depot command-line parsing errors cause traceback
Shawn Walker <swalker@opensolaris.org>
parents: 388
diff changeset
   428
                errnum = e[0]
e5329e84b9a8 2331 depot command-line parsing errors cause traceback
Shawn Walker <swalker@opensolaris.org>
parents: 388
diff changeset
   429
                try:
451
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   430
                        text = e[1]
404
e5329e84b9a8 2331 depot command-line parsing errors cause traceback
Shawn Walker <swalker@opensolaris.org>
parents: 388
diff changeset
   431
                except IndexError:
451
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   432
                        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
   433
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   434
                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
   435
                        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
   436
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   437
                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
   438
                        # 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
   439
                        # 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
   440
                        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
   441
451
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   442
                return False, text
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   443
1035
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   444
def bytes_to_str(bytes, format=None):
451
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   445
        """Returns a human-formatted string representing the number of bytes
1035
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   446
        in the largest unit possible.  If provided, 'format' should be a string
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   447
        which can be formatted with a dictionary containing a float 'num' and
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   448
        string 'unit'."""
451
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   449
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   450
        units = [
660
ea2809ad4582 4126 I10n update for IPS CLI PM and UM
John Rice <john.rice@sun.com>
parents: 641
diff changeset
   451
            (_("B"), 2**10),
ea2809ad4582 4126 I10n update for IPS CLI PM and UM
John Rice <john.rice@sun.com>
parents: 641
diff changeset
   452
            (_("kB"), 2**20),
ea2809ad4582 4126 I10n update for IPS CLI PM and UM
John Rice <john.rice@sun.com>
parents: 641
diff changeset
   453
            (_("MB"), 2**30),
ea2809ad4582 4126 I10n update for IPS CLI PM and UM
John Rice <john.rice@sun.com>
parents: 641
diff changeset
   454
            (_("GB"), 2**40),
ea2809ad4582 4126 I10n update for IPS CLI PM and UM
John Rice <john.rice@sun.com>
parents: 641
diff changeset
   455
            (_("TB"), 2**50),
ea2809ad4582 4126 I10n update for IPS CLI PM and UM
John Rice <john.rice@sun.com>
parents: 641
diff changeset
   456
            (_("PB"), 2**60),
ea2809ad4582 4126 I10n update for IPS CLI PM and UM
John Rice <john.rice@sun.com>
parents: 641
diff changeset
   457
            (_("EB"), 2**70)
451
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   458
        ]
386
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   459
451
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   460
        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
   461
                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
   462
                        # 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
   463
                        # 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
   464
                        # unit of measure's range.
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   465
                        continue
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   466
                else:
1035
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   467
                        if not format:
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   468
                                format = "%(num).2f %(unit)s"
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   469
                        return format % {
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   470
                            "num": round(bytes / float(limit / 2**10), 2),
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   471
                            "unit": uom
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   472
                        }
451
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   473
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   474
def get_rel_path(request, uri):
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   475
        # 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
   476
        # 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
   477
        # calculating depth.
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   478
        depth = request.path_info.count("/") - 1
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   479
        return ("../" * depth) + uri
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   480
487
9cb85c3d8491 2556 client should measure download progress by compressed size
johansen <johansen@sun.com>
parents: 462
diff changeset
   481
def get_pkg_otw_size(action):
9cb85c3d8491 2556 client should measure download progress by compressed size
johansen <johansen@sun.com>
parents: 462
diff changeset
   482
        """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
   483
        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
   484
        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
   485
        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
   486
9cb85c3d8491 2556 client should measure download progress by compressed size
johansen <johansen@sun.com>
parents: 462
diff changeset
   487
        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
   488
        if size == 0:
9cb85c3d8491 2556 client should measure download progress by compressed size
johansen <johansen@sun.com>
parents: 462
diff changeset
   489
                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
   490
9cb85c3d8491 2556 client should measure download progress by compressed size
johansen <johansen@sun.com>
parents: 462
diff changeset
   491
        return int(size)
9cb85c3d8491 2556 client should measure download progress by compressed size
johansen <johansen@sun.com>
parents: 462
diff changeset
   492
770
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   493
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
   494
        most_recent = {}
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   495
        installed = []
1068
9400aa8afd32 2557 catalog cache pickle file dependent on fmri and version object definitions
Shawn Walker <srw@sun.com>
parents: 1038
diff changeset
   496
        res = image.inventory(pargs, all_known, ordered=not all_versions)
770
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   497
        # 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
   498
        # 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
   499
        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
   500
                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
   501
                        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
   502
                                installed.append((pfmri, state))
941
e7bff46da54e 6175 search needs to be moved to version 1
Brock Pytlik <bpytlik@sun.com>
parents: 926
diff changeset
   503
                        hv = pfmri.get_pkg_stem(include_scheme=False)
770
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   504
                        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
   505
                                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
   506
                                    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
   507
                                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
   508
                                        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
   509
                        else:
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   510
                                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
   511
                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
   512
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   513
                # 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
   514
                # 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
   515
                # 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
   516
                # 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
   517
                # Also, publishers are taken into account so that
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   518
                # preferred publishers come before others. Finally,
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   519
                # 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
   520
                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
   521
                        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
   522
                        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
   523
                                return t
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   524
                        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
   525
                        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
   526
                                return t
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   527
                        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
   528
                                return -1
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   529
                        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
   530
                                return 1
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   531
                        return cmp(f1.get_publisher(),
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   532
                            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
   533
                
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   534
                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
   535
        return res
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   536
873
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   537
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
   538
        """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
   539
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   540
        '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
   541
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   542
        '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
   543
        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
   544
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   545
        '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
   546
        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
   547
        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
   548
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   549
        bufsz = 128 * 1024
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   550
        if isinstance(data, basestring):
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   551
                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
   552
        else:
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   553
                f = data
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   554
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   555
        if length is None:
1038
2514d758e462 7908 publishing api and tools should use os.stat not os.lstat for file size
Shawn Walker <srw@sun.com>
parents: 1035
diff changeset
   556
                length = os.stat(data).st_size
873
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   557
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   558
        # 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
   559
        # 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
   560
        content = cStringIO.StringIO()
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   561
        fhash = sha.new()
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   562
        while length > 0:
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   563
                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
   564
                if return_content:
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   565
                        content.write(data)
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   566
                fhash.update(data)
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   567
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   568
                l = len(data)
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   569
                if l == 0:
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   570
                        break
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   571
                length -= l
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   572
        content.reset()
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   573
        f.close()
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   574
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   575
        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
   576
1035
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   577
def __getvmusage():
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   578
        """Return the amount of virtual memory in bytes currently in use."""
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   579
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   580
        # This works only on Solaris, in 32-bit mode.  It may not work on older
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   581
        # or newer versions than 5.11.  Ideally, we would use libproc, or check
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   582
        # sbrk(0), but this is expedient.  In most cases (there's a small chance
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   583
        # the file will decode, but incorrectly), failure will raise an
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   584
        # exception, and we'll fail safe.
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   585
        try:
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   586
                # Read just the psinfo_t, not the tacked-on lwpsinfo_t
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   587
                psinfo_arr = file("/proc/self/psinfo").read(232)
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   588
                psinfo = struct.unpack("6i5I4LHH6L16s80siiIIc3x7i", psinfo_arr)
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   589
                vsz = psinfo[11] * 1024
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   590
        except Exception:
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   591
                vsz = None
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   592
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   593
        return vsz
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   594
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   595
def out_of_memory():
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   596
        """Return an out of memory message, for use in a MemoryError handler."""
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   597
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   598
        vsz = bytes_to_str(__getvmusage(), format="%(num).0f%(unit)s")
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   599
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   600
        if vsz is not None:
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   601
                error = """\
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   602
There is not enough memory to complete the requested operation.  At least
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   603
%(vsz)s of virtual memory was in use by this command before it ran out of memory.
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   604
You must add more memory (swap or physical) or allow the system to access more
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   605
existing memory, or quit other programs that may be consuming memory, and try
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   606
the operation again."""
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   607
        else:
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   608
                error = """\
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   609
There is not enough memory to complete the requested operation.  You must
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   610
add more memory (swap or physical) or allow the system to access more existing
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   611
memory, or quit other programs that may be consuming memory, and try the
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   612
operation again."""
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   613
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   614
        return _(error) % locals()
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   615
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   616
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
   617
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
   618
        """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
   619
        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
   620
                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
   621
838
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   622
# 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
   623
EmptyI = tuple()
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   624
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   625
class ImmutableDict(dict):
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   626
        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
   627
                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
   628
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   629
        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
   630
                self.__oops()
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   631
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   632
        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
   633
                self.__oops()
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   634
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   635
        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
   636
                self.__oops()
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   637
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   638
        def popitem(self):
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   639
                self.__oops()
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   640
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   641
        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
   642
                self.__oops()
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   643
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   644
        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
   645
                self.__oops()
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   646
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   647
        def copy(self):
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   648
                return ImmutableDict()
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   649
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   650
        def clear(self):
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   651
                self.__oops()
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   652
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   653
        def __oops(self):
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   654
                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
   655
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   656
def get_sorted_publishers(pubs, preferred=None):
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   657
        spubs = []
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   658
        for p in sorted(pubs, key=operator.attrgetter("prefix")):
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   659
                if preferred and preferred == p.prefix:
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   660
                        spubs.insert(0, p)
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   661
                else:
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   662
                        spubs.append(p)
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   663
        return spubs
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   664
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   665
def build_cert(path, uri=None, pub=None):
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   666
        """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
   667
        an X509 certificate object.
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   668
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   669
        '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
   670
        requires the certificate for access.
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   671
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   672
        '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
   673
        related publisher."""
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   674
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   675
        try:
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   676
                cf = file(path, "rb")
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   677
                certdata = cf.read()
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   678
                cf.close()
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   679
        except EnvironmentError, e:
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   680
                if e.errno == errno.ENOENT:
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   681
                        raise api_errors.NoSuchCertificate(path, uri=uri,
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   682
                            publisher=pub)
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   683
                if e.errno == errno.EACCES:
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   684
                        raise api_errors.PermissionsException(e.filename)
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   685
                raise
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   686
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   687
        try:
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   688
                return osc.load_certificate(osc.FILETYPE_PEM, certdata)
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   689
        except osc.Error, e:
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   690
                # OpenSSL.crypto.Error
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   691
                raise api_errors.InvalidCertificate(path, uri=uri,
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   692
                    publisher=pub)
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   693
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   694
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
   695
        """Validates the indicated certificate and returns a pyOpenSSL object
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   696
        representing it if it is valid."""
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   697
        cert = build_cert(ssl_cert, uri=uri, pub=prefix)
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   698
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   699
        if cert.has_expired():
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   700
                raise api_errors.ExpiredCertificate(ssl_cert, uri=uri,
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   701
                    publisher=prefix)
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   702
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   703
        now = datetime.datetime.utcnow()
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   704
        nb = cert.get_notBefore()
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   705
        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
   706
        nbdt = datetime.datetime.utcfromtimestamp(
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   707
            calendar.timegm(t))
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   708
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   709
        # PyOpenSSL's has_expired() doesn't validate the notBefore
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   710
        # time on the certificate.  Don't ask me why.
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   711
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   712
        if nbdt > now:
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   713
                raise api_errors.NotYetValidCertificate(ssl_cert, uri=uri,
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   714
                    publisher=prefix)
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   715
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   716
        na = cert.get_notAfter()
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   717
        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
   718
        nadt = datetime.datetime.utcfromtimestamp(
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   719
            calendar.timegm(t))
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   720
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   721
        diff = nadt - now
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   722
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   723
        if diff <= MIN_WARN_DAYS:
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   724
                raise api_errors.ExpiringCertificate(ssl_cert, uri=uri,
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   725
                    publisher=prefix, days=diff.days)
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   726
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   727
        return cert
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   728
838
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   729
EmptyDict = ImmutableDict()
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   730
1026
d4aa3ac69dc0 7878 token_byte_offset file not correctly sorted
Brock Pytlik <bpytlik@sun.com>
parents: 1023
diff changeset
   731
# Setting the python file buffer size to 128k gives substantial performance
d4aa3ac69dc0 7878 token_byte_offset file not correctly sorted
Brock Pytlik <bpytlik@sun.com>
parents: 1023
diff changeset
   732
# gains on certain files.
d4aa3ac69dc0 7878 token_byte_offset file not correctly sorted
Brock Pytlik <bpytlik@sun.com>
parents: 1023
diff changeset
   733
PKG_FILE_BUFSIZ = 128 * 1024