src/modules/pkgtarfile.py
author Shawn Walker <shawn.walker@oracle.com>
Wed, 09 Feb 2011 18:43:21 -0800
changeset 2219 60ad60f7592c
parent 1516 8c950a3b4171
child 3158 58c9c2c21e67
permissions -rw-r--r--
2152 standalone package support needed (on-disk format) 6576 pkg install/image-update support for temporary publisher origins desired 15450 pydoc for pkg.client.api needs to document reset usage requirement 16742 pkg manpage description of info -r not quite right 17761 repository append operation erroneously includes append file when closing transaction 17762 signing certs added to a repository do not have correct file permissions set 17786 .hgignore needs update for coverage 17787 api should allow publishers without origins 17788 pkg should allow relative paths and not require URI syntax for repositories 17789 pkg(1) arrangement and wording could be improved
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1516
8c950a3b4171 10485 move pkg(5) to Python 2.6
Rich Burridge <rich.burridge@sun.com>
parents: 1507
diff changeset
     1
#!/usr/bin/python
127
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
     2
#
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
     3
# CDDL HEADER START
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
     4
#
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
     5
# The contents of this file are subject to the terms of the
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
     6
# Common Development and Distribution License (the "License").
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
     7
# You may not use this file except in compliance with the License.
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
     8
#
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
     9
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    10
# or http://www.opensolaris.org/os/licensing.
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    11
# See the License for the specific language governing permissions
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    12
# and limitations under the License.
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    13
#
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    14
# When distributing Covered Code, include this CDDL HEADER in each
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    15
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    16
# If applicable, add the following below this CDDL HEADER, with the
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    17
# fields enclosed by brackets "[]" replaced with your own identifying
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    18
# information: Portions Copyright [yyyy] [name of copyright owner]
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    19
#
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    20
# CDDL HEADER END
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    21
#
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    22
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    23
#
2219
60ad60f7592c 2152 standalone package support needed (on-disk format)
Shawn Walker <shawn.walker@oracle.com>
parents: 1516
diff changeset
    24
# Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
127
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    25
#
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    26
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    27
import os
1507
b956ea23d3a6 11735 pkg history data files should not be executable
Richard Lowe <richlowe@richlowe.net>
parents: 576
diff changeset
    28
import stat
127
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    29
import tarfile
380
14c1f7bdf2df 2041 client performance hampered by unnecessary getpwuid/getgrgid calls
Shawn Walker <swalker@opensolaris.org>
parents: 273
diff changeset
    30
# Without the below statements, tarfile will trigger calls to getpwuid
14c1f7bdf2df 2041 client performance hampered by unnecessary getpwuid/getgrgid calls
Shawn Walker <swalker@opensolaris.org>
parents: 273
diff changeset
    31
# and getgrgid for every file extracted.  This in turn leads to nscd
14c1f7bdf2df 2041 client performance hampered by unnecessary getpwuid/getgrgid calls
Shawn Walker <swalker@opensolaris.org>
parents: 273
diff changeset
    32
# usage which slows down the install phase.  Setting these attributes
14c1f7bdf2df 2041 client performance hampered by unnecessary getpwuid/getgrgid calls
Shawn Walker <swalker@opensolaris.org>
parents: 273
diff changeset
    33
# to undefined causes tarfile to skip these calls in
14c1f7bdf2df 2041 client performance hampered by unnecessary getpwuid/getgrgid calls
Shawn Walker <swalker@opensolaris.org>
parents: 273
diff changeset
    34
# tarfile.gettarinfo().  This information is unnecesary as it will not
14c1f7bdf2df 2041 client performance hampered by unnecessary getpwuid/getgrgid calls
Shawn Walker <swalker@opensolaris.org>
parents: 273
diff changeset
    35
# be used by the client.
14c1f7bdf2df 2041 client performance hampered by unnecessary getpwuid/getgrgid calls
Shawn Walker <swalker@opensolaris.org>
parents: 273
diff changeset
    36
tarfile.pwd = None
14c1f7bdf2df 2041 client performance hampered by unnecessary getpwuid/getgrgid calls
Shawn Walker <swalker@opensolaris.org>
parents: 273
diff changeset
    37
tarfile.grp = None
127
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    38
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    39
class PkgTarFile(tarfile.TarFile):
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    40
        """PkgTarFile is a subclass of TarFile.  It implements
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    41
        a small number of additional instance methods to improve
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    42
        the functionality of the TarFile class for the packaging classes.
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    43
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    44
        XXX - Push these changes upstream to Python maintainers?
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    45
        """
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    46
2219
60ad60f7592c 2152 standalone package support needed (on-disk format)
Shawn Walker <shawn.walker@oracle.com>
parents: 1516
diff changeset
    47
        def __init__(self, *args, **kwargs):
60ad60f7592c 2152 standalone package support needed (on-disk format)
Shawn Walker <shawn.walker@oracle.com>
parents: 1516
diff changeset
    48
                kwargs.setdefault("errorlevel", 2)
60ad60f7592c 2152 standalone package support needed (on-disk format)
Shawn Walker <shawn.walker@oracle.com>
parents: 1516
diff changeset
    49
                tarfile.TarFile.__init__(self, *args, **kwargs)
273
ca9993d3aaea 440 pkgtarfile doesn't prevent tarfile ignoring real errors
johansen <johansen@sun.com>
parents: 239
diff changeset
    50
127
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    51
        def extract_to(self, member, path="", filename=""):
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    52
                """Extract a member from the TarFile archive.  This
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    53
                method allows you to specify a new filename and path, using
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    54
                the filename and path arguments, where the file will be
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    55
                extracted.  This method is similar to extract().
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    56
                Extract() only allows the caller to prepend a directory path
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    57
                to the filename specified in the TarInfo object,
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    58
                whereas this method allows the caller to additionally
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    59
                specify a file name.
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    60
                """
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    61
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    62
                self._check("r")
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    63
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    64
                if isinstance(member, tarfile.TarInfo):
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    65
                        tarinfo = member
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    66
                else:
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    67
                        tarinfo = self.getmember(member)
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    68
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    69
                if tarinfo.islnk():
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    70
                        tarinfo._link_target = \
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    71
                            os.path.join(path, tarinfo.linkname)
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    72
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    73
                if not filename:
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    74
                        filename = tarinfo.name
151
16ef057413db Fix directory permissions problem in images (temp. fix)
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 142
diff changeset
    75
16ef057413db Fix directory permissions problem in images (temp. fix)
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 142
diff changeset
    76
16ef057413db Fix directory permissions problem in images (temp. fix)
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 142
diff changeset
    77
                upperdirs = os.path.dirname(os.path.join(path, filename))
16ef057413db Fix directory permissions problem in images (temp. fix)
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 142
diff changeset
    78
16ef057413db Fix directory permissions problem in images (temp. fix)
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 142
diff changeset
    79
                if upperdirs and not os.path.exists(upperdirs):
576
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
    80
                        # The tarfile we receive contains only files, and none
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
    81
                        # of the containing directories.  The tarfile code will
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
    82
                        # create the directories as necessary, but with mode
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
    83
                        # 777, which is insuffficiently secure.  Thus we create
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
    84
                        # these directories in advance with tighter permissions;
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
    85
                        # they'll be fixed up later, when the action execute
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
    86
                        # methods run.  If proper directory actions
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
    87
                        # don't exist for these directories, the permissions
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
    88
                        # will be wrong.
565
1fb4f05220b9 3443 An api needs to be provided for safe interaction of front-ends
Brock Pytlik <bpytlik@sun.com>
parents: 409
diff changeset
    89
                        try:
1507
b956ea23d3a6 11735 pkg history data files should not be executable
Richard Lowe <richlowe@richlowe.net>
parents: 576
diff changeset
    90
                                os.makedirs(upperdirs, stat.S_IRWXU)
576
6ee6de304041 3777 PKG_TIMEOUT_MAX is a placebo setting
Dan Price <dp@eng.sun.com>
parents: 565
diff changeset
    91
                        except EnvironmentError:
565
1fb4f05220b9 3443 An api needs to be provided for safe interaction of front-ends
Brock Pytlik <bpytlik@sun.com>
parents: 409
diff changeset
    92
                                pass
127
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    93
                try:
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    94
                        self._extract_member(tarinfo, os.path.join(
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    95
                            path, filename))
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    96
                except EnvironmentError, e:
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    97
                        if self.errorlevel > 0:
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    98
                                raise
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
    99
                        else:
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
   100
                                if e.filename is None:
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
   101
                                        self._dbg(1, "tarfile %s" % e.strerror)
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
   102
                                else:
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
   103
                                        self._dbg(1, "tarfile: %s %r" % (
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
   104
                                            e.strerror, e.filename))
142
d7bf5f420609 ExtractError in pkgtarfile needs to include name of tarfile module
johansen <johansen@sun.com>
parents: 127
diff changeset
   105
                except tarfile.ExtractError, e:
127
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
   106
                        if self.errorlevel > 1:
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
   107
                                raise
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
   108
                        else:
70470e719257 Eliminate duplicate file renames in filelist.
johansen <johansen@sun.com>
parents:
diff changeset
   109
                                self._dbg(1, "tarfile: %s" % e)