src/modules/misc.py
author Brock Pytlik <bpytlik@sun.com>
Wed, 28 Oct 2009 17:49:56 -0700
changeset 1452 bd6ffa78fed9
parent 1431 62b6033670e4
child 1505 cc598d70bbbe
permissions -rw-r--r--
7960 client and depot need different organization of files
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
1352
5c92c9d342ef 11065 client v1 catalog support for v0 catalogs
Shawn Walker <srw@sun.com>
parents: 1318
diff changeset
    58
# Copied from image.py as image.py can't be imported here (circular reference).
5c92c9d342ef 11065 client v1 catalog support for v0 catalogs
Shawn Walker <srw@sun.com>
parents: 1318
diff changeset
    59
PKG_STATE_INSTALLED = 2
5c92c9d342ef 11065 client v1 catalog support for v0 catalogs
Shawn Walker <srw@sun.com>
parents: 1318
diff changeset
    60
1023
73f73773b4c9 6358 Release Notes message after Update All needs to be updated
John Rice <john.rice@sun.com>
parents: 956
diff changeset
    61
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
    62
        """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
    63
           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
    64
73f73773b4c9 6358 Release Notes message after Update All needs to be updated
John Rice <john.rice@sun.com>
parents: 956
diff changeset
    65
        # 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
    66
        # 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
    67
        release_str = \
73f73773b4c9 6358 Release Notes message after Update All needs to be updated
John Rice <john.rice@sun.com>
parents: 956
diff changeset
    68
                "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
    69
        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
    70
                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
    71
        else:
73f73773b4c9 6358 Release Notes message after Update All needs to be updated
John Rice <john.rice@sun.com>
parents: 956
diff changeset
    72
                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
    73
73f73773b4c9 6358 Release Notes message after Update All needs to be updated
John Rice <john.rice@sun.com>
parents: 956
diff changeset
    74
        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
    75
443
5ffa5b7dac9c 2589 pyc files generate lots of verify chaff
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 429
diff changeset
    76
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
    77
        """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
    78
        # XXX optimize?
5ffa5b7dac9c 2589 pyc files generate lots of verify chaff
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 429
diff changeset
    79
        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
    80
5ffa5b7dac9c 2589 pyc files generate lots of verify chaff
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 429
diff changeset
    81
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
    82
        """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
    83
        # XXX optimize?
5ffa5b7dac9c 2589 pyc files generate lots of verify chaff
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 429
diff changeset
    84
        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
    85
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
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
    87
        """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
    88
        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
    89
        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
    90
        try:
873
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
    91
                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
    92
        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
    93
                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
    94
                        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
    95
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
    96
        """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
    97
        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
    98
        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
    99
        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
   100
                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
   101
                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
   102
                        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
   103
                        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
   104
        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
   105
310
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
   106
def url_affix_trailing_slash(u):
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
   107
        if u[-1] != '/':
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
   108
                u = u + '/'
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
   109
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
   110
        return u
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
   111
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
   112
_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
   113
    (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
   114
    portable.util.get_os_release(), platform.version())
39b8b5c538bf 1104 want custom user-agent string
Danek Duvall <danek.duvall@sun.com>
parents: 310
diff changeset
   115
1191
a48bee2a4b2e 305 http_proxy value needs more checking for valid url syntax
johansen <johansen@sun.com>
parents: 1142
diff changeset
   116
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
   117
a48bee2a4b2e 305 http_proxy value needs more checking for valid url syntax
johansen <johansen@sun.com>
parents: 1142
diff changeset
   118
        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
   119
                imgtype = IMG_NONE
a48bee2a4b2e 305 http_proxy value needs more checking for valid url syntax
johansen <johansen@sun.com>
parents: 1142
diff changeset
   120
        else:
a48bee2a4b2e 305 http_proxy value needs more checking for valid url syntax
johansen <johansen@sun.com>
parents: 1142
diff changeset
   121
                imgtype = img.type
a48bee2a4b2e 305 http_proxy value needs more checking for valid url syntax
johansen <johansen@sun.com>
parents: 1142
diff changeset
   122
a48bee2a4b2e 305 http_proxy value needs more checking for valid url syntax
johansen <johansen@sun.com>
parents: 1142
diff changeset
   123
        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
   124
a48bee2a4b2e 305 http_proxy value needs more checking for valid url syntax
johansen <johansen@sun.com>
parents: 1142
diff changeset
   125
        return useragent
a48bee2a4b2e 305 http_proxy value needs more checking for valid url syntax
johansen <johansen@sun.com>
parents: 1142
diff changeset
   126
556
1c3526ca7b9e 2022 client should provide operational intent to server
Shawn Walker <shawn.walker@sun.com>
parents: 551
diff changeset
   127
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
   128
    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
   129
    method = "GET", uuid = None):
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   130
        """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
   131
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   132
        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
   133
        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
   134
        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
   135
        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
   136
        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
   137
        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
   138
        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
   139
        matching version can be found.
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   140
        """
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   141
        # Ignore http_proxy for localhost case, by overriding
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   142
        # default proxy behaviour of urlopen().
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   143
        netloc = urlparse.urlparse(base_uri)[1]
310
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
   144
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
   145
        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
   146
                raise ValueError, "Malformed URL: %s" % base_uri
310
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
   147
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   148
        if urllib.splitport(netloc)[0] == "localhost":
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   149
                # XXX cache this opener?
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   150
                proxy_handler = urllib2.ProxyHandler({})
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   151
                opener_dir = urllib2.build_opener(proxy_handler)
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   152
                url_opener = opener_dir.open
310
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
   153
        elif ssl_creds and ssl_creds != (None, None):
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
   154
                cert_handler = urlhelpers.HTTPSCertHandler(
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
   155
                    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
   156
                opener_dir = urllib2.build_opener(
35b869ed3334 4314 https proxy does not work
Tom Mueller <Tom.Mueller@sun.com>
parents: 770
diff changeset
   157
                    urlhelpers.HTTPSProxyHandler, cert_handler)
310
8fa744df663a 975 Catalogs need to know their origins
johansen <johansen@sun.com>
parents: 285
diff changeset
   158
                url_opener = opener_dir.open
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   159
        else:
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   160
                url_opener = urllib2.urlopen
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   161
556
1c3526ca7b9e 2022 client should provide operational intent to server
Shawn Walker <shawn.walker@sun.com>
parents: 551
diff changeset
   162
        if not versions:
1c3526ca7b9e 2022 client should provide operational intent to server
Shawn Walker <shawn.walker@sun.com>
parents: 551
diff changeset
   163
                versions = []
1c3526ca7b9e 2022 client should provide operational intent to server
Shawn Walker <shawn.walker@sun.com>
parents: 551
diff changeset
   164
551
233f0eeddd02 856 Image properties
Tom Mueller <Tom.Mueller@sun.com>
parents: 518
diff changeset
   165
        if not headers:
233f0eeddd02 856 Image properties
Tom Mueller <Tom.Mueller@sun.com>
parents: 518
diff changeset
   166
                headers = {}
233f0eeddd02 856 Image properties
Tom Mueller <Tom.Mueller@sun.com>
parents: 518
diff changeset
   167
941
e7bff46da54e 6175 search needs to be moved to version 1
Brock Pytlik <bpytlik@sun.com>
parents: 926
diff changeset
   168
        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
   169
                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
   170
                        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
   171
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   172
                if tail:
941
e7bff46da54e 6175 search needs to be moved to version 1
Brock Pytlik <bpytlik@sun.com>
parents: 926
diff changeset
   173
                        tail_str = tail
e7bff46da54e 6175 search needs to be moved to version 1
Brock Pytlik <bpytlik@sun.com>
parents: 926
diff changeset
   174
                        if isinstance(tail, list):
e7bff46da54e 6175 search needs to be moved to version 1
Brock Pytlik <bpytlik@sun.com>
parents: 926
diff changeset
   175
                                tail_str = tail[i]
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   176
                        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
   177
                            (operation, version, tail_str))
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   178
                else:
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   179
                        uri = urlparse.urljoin(base_uri, "%s/%s" % \
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   180
                            (operation, version))
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   181
319
39b8b5c538bf 1104 want custom user-agent string
Danek Duvall <danek.duvall@sun.com>
parents: 310
diff changeset
   182
                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
   183
                    _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
   184
                        global_settings.client_name)
551
233f0eeddd02 856 Image properties
Tom Mueller <Tom.Mueller@sun.com>
parents: 518
diff changeset
   185
                if uuid:
233f0eeddd02 856 Image properties
Tom Mueller <Tom.Mueller@sun.com>
parents: 518
diff changeset
   186
                        headers["X-IPkg-UUID"] = uuid
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   187
                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
   188
                if method == "HEAD":
1c3526ca7b9e 2022 client should provide operational intent to server
Shawn Walker <shawn.walker@sun.com>
parents: 551
diff changeset
   189
                        # 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
   190
                        # natively support this operation.
1c3526ca7b9e 2022 client should provide operational intent to server
Shawn Walker <shawn.walker@sun.com>
parents: 551
diff changeset
   191
                        req.get_method = lambda: "HEAD"
1c3526ca7b9e 2022 client should provide operational intent to server
Shawn Walker <shawn.walker@sun.com>
parents: 551
diff changeset
   192
                elif data is not None:
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   193
                        req.add_data(data)
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   194
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   195
                try:
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   196
                        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
   197
                except urllib2.HTTPError, e:
941
e7bff46da54e 6175 search needs to be moved to version 1
Brock Pytlik <bpytlik@sun.com>
parents: 926
diff changeset
   198
                        if e.code != httplib.NOT_FOUND:
145
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   199
                                raise
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   200
                        continue
260
a1b77322abb2 255 Symbolic HTTP response codes should be used
Shawn Walker <swalker@opensolaris.org>
parents: 181
diff changeset
   201
                # 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
   202
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   203
                return c, version
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   204
        else:
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   205
                # Couldn't find a version that we liked.
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   206
                raise RuntimeError, \
08bee7fd13f6 Add versioning to the protocols
Danek Duvall <danek.duvall@sun.com>
parents: 119
diff changeset
   207
                    "%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
   208
                    (base_uri, operation)
327
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   209
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   210
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   211
_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
   212
_invalid_host_chars = re.compile(".*[^a-zA-Z0-9\-\.]+")
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   213
_valid_proto = ["http", "https"]
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   214
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   215
def valid_pub_prefix(prefix):
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   216
        """Verify that the publisher prefix only contains valid characters."""
327
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   217
1142
64d164b5bf04 9164 misc.valid_pub_prefix and misc.valid_pub_url should handle None
Shawn Walker <srw@sun.com>
parents: 1072
diff changeset
   218
        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
   219
                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
   220
327
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   221
        # 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
   222
        # it comes to finding invalid characters in the prefix string.
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   223
        if _invalid_host_chars.match(prefix):
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   224
                # prefix bad chars
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   225
                return False
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   226
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   227
        if _hostname_re.match(prefix):
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   228
                return True
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   229
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   230
        return False
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   231
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   232
def valid_pub_url(url):
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   233
        """Verify that the publisher URL contains only valid characters."""
327
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   234
1142
64d164b5bf04 9164 misc.valid_pub_prefix and misc.valid_pub_url should handle None
Shawn Walker <srw@sun.com>
parents: 1072
diff changeset
   235
        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
   236
                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
   237
327
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   238
        # 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
   239
        o = urlparse.urlsplit(url)
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   240
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   241
        if not o[0] in _valid_proto:
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   242
                return False
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   243
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   244
        # Next verify that the network location is valid
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   245
        host, port = urllib.splitport(o[1])
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   246
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   247
        if not host or _invalid_host_chars.match(host):
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   248
                return False
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   249
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   250
        if _hostname_re.match(host):
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   251
                return True
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   252
6c6bd07efe8d 1031 authority prefix needs validation
johansen <johansen@sun.com>
parents: 319
diff changeset
   253
        return False
342
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   254
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   255
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
   256
        """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
   257
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   258
        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
   259
        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
   260
        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
   261
        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
   262
        data.
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   263
        """
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   264
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   265
        FHCRC = 2
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   266
        FEXTRA = 4
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   267
        FNAME = 8
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   268
        FCOMMENT = 16
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   269
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   270
        # Read the header
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   271
        magic = gz.read(2)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   272
        if magic != "\037\213":
621
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   273
                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
   274
        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
   275
        if method != 8:
621
6c144915eed1 551 IPS should handle socket errors
johansen <johansen@sun.com>
parents: 576
diff changeset
   276
                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
   277
        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
   278
        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
   279
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   280
        # Discard an extra field
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   281
        if flag & FEXTRA:
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   282
                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
   283
                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
   284
                gz.read(xlen)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   285
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   286
        # 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
   287
        if flag & FNAME:
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   288
                while True:
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   289
                        s = gz.read(1)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   290
                        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
   291
                                break
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   292
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   293
        # 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
   294
        if flag & FCOMMENT:
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   295
                while True:
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   296
                        s = gz.read(1)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   297
                        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
   298
                                break
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   299
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   300
        # 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
   301
        if flag & FHCRC:
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   302
                gz.read(2)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   303
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   304
        shasum = sha.new()
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   305
        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
   306
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   307
        while True:
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   308
                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
   309
                if buf == "":
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   310
                        ubuf = dcobj.flush()
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   311
                        shasum.update(ubuf)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   312
                        outfile.write(ubuf)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   313
                        break
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   314
                ubuf = dcobj.decompress(buf)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   315
                shasum.update(ubuf)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   316
                outfile.write(ubuf)
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   317
5e1f4d8429bf 669 Need method to print package licenses before installation
Danek Duvall <danek.duvall@sun.com>
parents: 327
diff changeset
   318
        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
   319
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   320
class PipeError(Exception):
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   321
        """ Pipe exception. """
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   322
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   323
        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
   324
                self.args = args
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   325
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   326
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
   327
        """ 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
   328
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   329
        try:
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   330
                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
   331
        except IOError, e:
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   332
                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
   333
                        raise PipeError, e
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   334
                raise
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   335
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   336
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
   337
        """ 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
   338
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   339
        try:
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   340
                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
   341
        except IOError, e:
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   342
                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
   343
                        raise PipeError, e
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   344
                raise
9d4746e5dd3e 115 pkg needs to not have a cow on a SIGPIPE
Shawn Walker <swalker@opensolaris.org>
parents: 351
diff changeset
   345
791
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   346
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
   347
        """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
   348
        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
   349
        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
   350
        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
   351
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   352
        if printer is None:
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   353
                printer = emsg
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   354
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   355
        try:
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   356
                locale.setlocale(category, loc)
1318
a12f41da2189 8263 misc.setlocale should handle locale.getdefaultlocale failure
Tom Mueller <Tom.Mueller@sun.com>
parents: 1191
diff changeset
   357
                # Because of Python bug 813449, getdefaultlocale may fail
a12f41da2189 8263 misc.setlocale should handle locale.getdefaultlocale failure
Tom Mueller <Tom.Mueller@sun.com>
parents: 1191
diff changeset
   358
                # with a ValueError even if setlocale succeeds. So we call
a12f41da2189 8263 misc.setlocale should handle locale.getdefaultlocale failure
Tom Mueller <Tom.Mueller@sun.com>
parents: 1191
diff changeset
   359
                # it here to prevent having this error raised if it is 
a12f41da2189 8263 misc.setlocale should handle locale.getdefaultlocale failure
Tom Mueller <Tom.Mueller@sun.com>
parents: 1191
diff changeset
   360
                # called later by other non-pkg(5) code.
a12f41da2189 8263 misc.setlocale should handle locale.getdefaultlocale failure
Tom Mueller <Tom.Mueller@sun.com>
parents: 1191
diff changeset
   361
                locale.getdefaultlocale()
a12f41da2189 8263 misc.setlocale should handle locale.getdefaultlocale failure
Tom Mueller <Tom.Mueller@sun.com>
parents: 1191
diff changeset
   362
        except (locale.Error, ValueError):
791
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   363
                try:
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   364
                        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
   365
                except ValueError:
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   366
                        dl = ""
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   367
                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
   368
                    "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
   369
                locale.setlocale(category, "C")
123e9401e939 5778 Inability to set locale leads to stack trace
Danek Duvall <danek.duvall@sun.com>
parents: 779
diff changeset
   370
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
def port_available(host, port):
451
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   372
        """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
   373
        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
   374
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   375
        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
   376
        if host is None:
451
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   377
                # 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
   378
                # 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
   379
                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
   380
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   381
        try:
404
e5329e84b9a8 2331 depot command-line parsing errors cause traceback
Shawn Walker <swalker@opensolaris.org>
parents: 388
diff changeset
   382
                sock = None
e5329e84b9a8 2331 depot command-line parsing errors cause traceback
Shawn Walker <swalker@opensolaris.org>
parents: 388
diff changeset
   383
386
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   384
                # 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
   385
                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
   386
                    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
   387
                        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
   388
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   389
                        # 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
   390
                        # 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
   391
                        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
   392
                        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
   393
                            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
   394
                        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
   395
                        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
   396
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   397
                        # 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
   398
                        # 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
   399
                        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
   400
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   401
                        # 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
   402
                        # 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
   403
                        # 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
   404
                        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
   405
494
102fb5979716 2695 misc.port_available fails on Mac/OS due to EINVAL problem
Tom Mueller <Tom.Mueller@sun.com>
parents: 487
diff changeset
   406
                        try:
102fb5979716 2695 misc.port_available fails on Mac/OS due to EINVAL problem
Tom Mueller <Tom.Mueller@sun.com>
parents: 487
diff changeset
   407
                                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
   408
                        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
   409
                                # 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
   410
                                raise
102fb5979716 2695 misc.port_available fails on Mac/OS due to EINVAL problem
Tom Mueller <Tom.Mueller@sun.com>
parents: 487
diff changeset
   411
                        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
   412
                                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
   413
                                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
   414
                                        raise
102fb5979716 2695 misc.port_available fails on Mac/OS due to EINVAL problem
Tom Mueller <Tom.Mueller@sun.com>
parents: 487
diff changeset
   415
                                # 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
   416
                                # 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
   417
                                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
   418
                                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
   419
                                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
   420
                                
386
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   421
                        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
   422
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   423
                        # If 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
   424
                        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
   425
                            '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
   426
494
102fb5979716 2695 misc.port_available fails on Mac/OS due to EINVAL problem
Tom Mueller <Tom.Mueller@sun.com>
parents: 487
diff changeset
   427
        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
   428
                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
   429
386
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   430
        except socket.error, e:
404
e5329e84b9a8 2331 depot command-line parsing errors cause traceback
Shawn Walker <swalker@opensolaris.org>
parents: 388
diff changeset
   431
                errnum = e[0]
e5329e84b9a8 2331 depot command-line parsing errors cause traceback
Shawn Walker <swalker@opensolaris.org>
parents: 388
diff changeset
   432
                try:
451
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   433
                        text = e[1]
404
e5329e84b9a8 2331 depot command-line parsing errors cause traceback
Shawn Walker <swalker@opensolaris.org>
parents: 388
diff changeset
   434
                except IndexError:
451
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   435
                        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
   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 sock:
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   438
                        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
   439
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   440
                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
   441
                        # 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
   442
                        # 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
   443
                        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
   444
451
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   445
                return False, text
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   446
1035
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   447
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
   448
        """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
   449
        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
   450
        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
   451
        string 'unit'."""
451
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   452
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   453
        units = [
660
ea2809ad4582 4126 I10n update for IPS CLI PM and UM
John Rice <john.rice@sun.com>
parents: 641
diff changeset
   454
            (_("B"), 2**10),
ea2809ad4582 4126 I10n update for IPS CLI PM and UM
John Rice <john.rice@sun.com>
parents: 641
diff changeset
   455
            (_("kB"), 2**20),
ea2809ad4582 4126 I10n update for IPS CLI PM and UM
John Rice <john.rice@sun.com>
parents: 641
diff changeset
   456
            (_("MB"), 2**30),
ea2809ad4582 4126 I10n update for IPS CLI PM and UM
John Rice <john.rice@sun.com>
parents: 641
diff changeset
   457
            (_("GB"), 2**40),
ea2809ad4582 4126 I10n update for IPS CLI PM and UM
John Rice <john.rice@sun.com>
parents: 641
diff changeset
   458
            (_("TB"), 2**50),
ea2809ad4582 4126 I10n update for IPS CLI PM and UM
John Rice <john.rice@sun.com>
parents: 641
diff changeset
   459
            (_("PB"), 2**60),
ea2809ad4582 4126 I10n update for IPS CLI PM and UM
John Rice <john.rice@sun.com>
parents: 641
diff changeset
   460
            (_("EB"), 2**70)
451
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   461
        ]
386
5cd680466abe 2147 depot should check port instead of showing traceback if port binding fails
Shawn Walker <swalker@opensolaris.org>
parents: 384
diff changeset
   462
451
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   463
        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
   464
                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
   465
                        # 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
   466
                        # 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
   467
                        # unit of measure's range.
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   468
                        continue
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   469
                else:
1035
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   470
                        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
   471
                                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
   472
                        return format % {
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   473
                            "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
   474
                            "unit": uom
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   475
                        }
451
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   476
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   477
def get_rel_path(request, uri):
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   478
        # 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
   479
        # 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
   480
        # calculating depth.
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   481
        depth = request.path_info.count("/") - 1
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   482
        return ("../" * depth) + uri
74f1fe85fe2d 1324 RSS / Atom feeds of repository updates
Shawn Walker <shawn.walker@sun.com>
parents: 443
diff changeset
   483
487
9cb85c3d8491 2556 client should measure download progress by compressed size
johansen <johansen@sun.com>
parents: 462
diff changeset
   484
def get_pkg_otw_size(action):
9cb85c3d8491 2556 client should measure download progress by compressed size
johansen <johansen@sun.com>
parents: 462
diff changeset
   485
        """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
   486
        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
   487
        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
   488
        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
   489
9cb85c3d8491 2556 client should measure download progress by compressed size
johansen <johansen@sun.com>
parents: 462
diff changeset
   490
        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
   491
        if size == 0:
9cb85c3d8491 2556 client should measure download progress by compressed size
johansen <johansen@sun.com>
parents: 462
diff changeset
   492
                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
   493
9cb85c3d8491 2556 client should measure download progress by compressed size
johansen <johansen@sun.com>
parents: 462
diff changeset
   494
        return int(size)
9cb85c3d8491 2556 client should measure download progress by compressed size
johansen <johansen@sun.com>
parents: 462
diff changeset
   495
770
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   496
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
   497
        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
        installed = []
1068
9400aa8afd32 2557 catalog cache pickle file dependent on fmri and version object definitions
Shawn Walker <srw@sun.com>
parents: 1038
diff changeset
   499
        res = image.inventory(pargs, all_known, ordered=not all_versions)
1352
5c92c9d342ef 11065 client v1 catalog support for v0 catalogs
Shawn Walker <srw@sun.com>
parents: 1318
diff changeset
   500
        ppub = image.get_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
   501
        # 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
   502
        # 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
   503
        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
   504
                for pfmri, state in res:
1352
5c92c9d342ef 11065 client v1 catalog support for v0 catalogs
Shawn Walker <srw@sun.com>
parents: 1318
diff changeset
   505
                        if state["state"] == PKG_STATE_INSTALLED:
770
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   506
                                installed.append((pfmri, state))
941
e7bff46da54e 6175 search needs to be moved to version 1
Brock Pytlik <bpytlik@sun.com>
parents: 926
diff changeset
   507
                        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
   508
                        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
   509
                                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
   510
                                    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
   511
                                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
   512
                                        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
   513
                        else:
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   514
                                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
   515
                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
   516
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   517
                # 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
   518
                # 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
   519
                # 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
   520
                # 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
   521
                # Also, publishers are taken into account so that
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   522
                # preferred publishers come before others. Finally,
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   523
                # 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
   524
                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
   525
                        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
   526
                        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
   527
                                return t
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   528
                        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
   529
                        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
   530
                                return t
1352
5c92c9d342ef 11065 client v1 catalog support for v0 catalogs
Shawn Walker <srw@sun.com>
parents: 1318
diff changeset
   531
                        if f1.get_publisher() == ppub:
770
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   532
                                return -1
1352
5c92c9d342ef 11065 client v1 catalog support for v0 catalogs
Shawn Walker <srw@sun.com>
parents: 1318
diff changeset
   533
                        if f2.get_publisher() == ppub:
770
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   534
                                return 1
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   535
                        return cmp(f1.get_publisher(),
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   536
                            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
   537
                
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   538
                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
   539
        return res
51cc59540c42 4341 IPS GUI and CLI list different status for some packages
Michal Pryc <Michal.Pryc@Sun.Com>
parents: 742
diff changeset
   540
873
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   541
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
   542
        """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
   543
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   544
        '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
   545
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   546
        '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
   547
        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
   548
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   549
        '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
   550
        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
   551
        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
   552
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   553
        bufsz = 128 * 1024
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   554
        if isinstance(data, basestring):
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   555
                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
   556
        else:
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   557
                f = data
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   558
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   559
        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
   560
                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
   561
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   562
        # 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
   563
        # 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
   564
        content = cStringIO.StringIO()
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   565
        fhash = sha.new()
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   566
        while length > 0:
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   567
                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
   568
                if return_content:
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   569
                        content.write(data)
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   570
                fhash.update(data)
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   571
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   572
                l = len(data)
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   573
                if l == 0:
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   574
                        break
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   575
                length -= l
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   576
        content.reset()
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   577
        f.close()
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   578
b95d76c53b5e 2691 ability to publish packages to local disk repository
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 838
diff changeset
   579
        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
   580
1035
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   581
def __getvmusage():
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   582
        """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
   583
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   584
        # 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
   585
        # 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
   586
        # 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
   587
        # 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
   588
        # 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
   589
        try:
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   590
                # 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
   591
                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
   592
                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
   593
                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
   594
        except Exception:
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   595
                vsz = None
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   596
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   597
        return vsz
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   598
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   599
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
   600
        """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
   601
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   602
        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
   603
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   604
        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
   605
                error = """\
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   606
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
   607
%(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
   608
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
   609
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
   610
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
   611
        else:
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   612
                error = """\
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   613
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
   614
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
   615
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
   616
operation again."""
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   617
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   618
        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
   619
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1026
diff changeset
   620
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
   621
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
   622
        """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
   623
        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
   624
                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
   625
838
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   626
# 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
   627
EmptyI = tuple()
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
class ImmutableDict(dict):
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   630
        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
   631
                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
   632
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   633
        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
   634
                self.__oops()
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   635
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   636
        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
   637
                self.__oops()
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   638
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   639
        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
   640
                self.__oops()
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   641
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   642
        def popitem(self):
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   643
                self.__oops()
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   644
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   645
        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
   646
                self.__oops()
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   647
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   648
        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
   649
                self.__oops()
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   650
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   651
        def copy(self):
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   652
                return ImmutableDict()
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   653
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   654
        def clear(self):
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   655
                self.__oops()
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   656
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   657
        def __oops(self):
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   658
                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
   659
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   660
def get_sorted_publishers(pubs, preferred=None):
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   661
        spubs = []
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   662
        for p in sorted(pubs, key=operator.attrgetter("prefix")):
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   663
                if preferred and preferred == p.prefix:
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   664
                        spubs.insert(0, p)
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   665
                else:
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   666
                        spubs.append(p)
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   667
        return spubs
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
def build_cert(path, uri=None, pub=None):
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   670
        """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
   671
        an X509 certificate object.
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   672
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   673
        '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
   674
        requires the certificate for access.
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   675
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   676
        '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
   677
        related publisher."""
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   678
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   679
        try:
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   680
                cf = file(path, "rb")
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   681
                certdata = cf.read()
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   682
                cf.close()
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   683
        except EnvironmentError, e:
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   684
                if e.errno == errno.ENOENT:
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   685
                        raise api_errors.NoSuchCertificate(path, uri=uri,
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   686
                            publisher=pub)
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   687
                if e.errno == errno.EACCES:
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   688
                        raise api_errors.PermissionsException(e.filename)
1431
62b6033670e4 10416 server catalog v1 support desired
Shawn Walker <srw@sun.com>
parents: 1352
diff changeset
   689
                if e.errno == errno.EROFS:
62b6033670e4 10416 server catalog v1 support desired
Shawn Walker <srw@sun.com>
parents: 1352
diff changeset
   690
                        raise api_errors.ReadOnlyFileSystemException(e.filename)
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   691
                raise
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   692
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   693
        try:
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   694
                return osc.load_certificate(osc.FILETYPE_PEM, certdata)
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   695
        except osc.Error, e:
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   696
                # OpenSSL.crypto.Error
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   697
                raise api_errors.InvalidCertificate(path, uri=uri,
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   698
                    publisher=pub)
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   699
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   700
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
   701
        """Validates the indicated certificate and returns a pyOpenSSL object
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   702
        representing it if it is valid."""
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   703
        cert = build_cert(ssl_cert, uri=uri, pub=prefix)
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   704
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   705
        if cert.has_expired():
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   706
                raise api_errors.ExpiredCertificate(ssl_cert, uri=uri,
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   707
                    publisher=prefix)
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
        now = datetime.datetime.utcnow()
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   710
        nb = cert.get_notBefore()
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   711
        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
   712
        nbdt = datetime.datetime.utcfromtimestamp(
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   713
            calendar.timegm(t))
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   714
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   715
        # PyOpenSSL's has_expired() doesn't validate the notBefore
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   716
        # time on the certificate.  Don't ask me why.
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   717
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   718
        if nbdt > now:
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   719
                raise api_errors.NotYetValidCertificate(ssl_cert, uri=uri,
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   720
                    publisher=prefix)
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   721
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   722
        na = cert.get_notAfter()
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   723
        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
   724
        nadt = datetime.datetime.utcfromtimestamp(
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   725
            calendar.timegm(t))
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
        diff = nadt - now
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   728
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   729
        if diff <= MIN_WARN_DAYS:
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   730
                raise api_errors.ExpiringCertificate(ssl_cert, uri=uri,
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   731
                    publisher=prefix, days=diff.days)
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   732
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   733
        return cert
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 873
diff changeset
   734
838
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   735
EmptyDict = ImmutableDict()
aafbe4737188 3245 need to support creation of multi-architecture (fat) packages
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 835
diff changeset
   736
1026
d4aa3ac69dc0 7878 token_byte_offset file not correctly sorted
Brock Pytlik <bpytlik@sun.com>
parents: 1023
diff changeset
   737
# 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
   738
# gains on certain files.
d4aa3ac69dc0 7878 token_byte_offset file not correctly sorted
Brock Pytlik <bpytlik@sun.com>
parents: 1023
diff changeset
   739
PKG_FILE_BUFSIZ = 128 * 1024