src/modules/updatelog.py
author johansen <johansen@sun.com>
Tue, 19 Feb 2008 11:28:03 -0800
changeset 258 b3b7592412ec
parent 239 20770afe33ec
child 260 a1b77322abb2
permissions -rw-r--r--
270 Need ability to rename packages
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
215
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
     1
#!/usr/bin/python
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
     2
#
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
     3
# CDDL HEADER START
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
     4
#
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
     5
# The contents of this file are subject to the terms of the
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
     6
# Common Development and Distribution License (the "License").
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
     7
# You may not use this file except in compliance with the License.
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
     8
#
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
     9
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    10
# or http://www.opensolaris.org/os/licensing.
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    11
# See the License for the specific language governing permissions
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    12
# and limitations under the License.
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    13
#
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    14
# When distributing Covered Code, include this CDDL HEADER in each
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    15
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    16
# If applicable, add the following below this CDDL HEADER, with the
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    17
# fields enclosed by brackets "[]" replaced with your own identifying
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    18
# information: Portions Copyright [yyyy] [name of copyright owner]
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    19
#
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    20
# CDDL HEADER END
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    21
#
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    22
# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    23
# Use is subject to license terms.
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    24
#
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    25
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    26
import os
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    27
import re
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    28
import time
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    29
import datetime
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    30
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    31
import pkg.fmri as fmri
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    32
import pkg.catalog as catalog
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    33
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    34
class UpdateLogException(Exception):
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    35
        def __init__(self, args=None):
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    36
                self.args = args
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    37
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    38
class UpdateLog(object):
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    39
        """The update log is a mechanism that allows clients and servers to make
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    40
        incremental updates to their package catalogs.  The server logs
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    41
        whether it has added or removed a package, the time when the action
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    42
        occurred, and the name of the package added or removed.  The client
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    43
        requests a list of actions that have been applied to the server's
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    44
        catalog since a particular time in the past.  The server is then able to
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    45
        send this list of actions, allowing the client to apply these changes to
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    46
        its catalog.
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    47
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    48
        This allows the client to obtain incremental updates to its catalog,
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    49
        instead of having to download an entire (and largely duplicated)
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    50
        catalog each time a refresh is requested.
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    51
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    52
        The UpdateLog must have an associated catalog; however,
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    53
        Catalogs are not required to have an UpdateLog.  The UpdateLog
220
afceea12576c 320 pkg should ignore catalog lines it doesn't recognize
johansen <johansen@sun.com>
parents: 215
diff changeset
    54
        allows catalogs to support incremental updates.
afceea12576c 320 pkg should ignore catalog lines it doesn't recognize
johansen <johansen@sun.com>
parents: 215
diff changeset
    55
        
afceea12576c 320 pkg should ignore catalog lines it doesn't recognize
johansen <johansen@sun.com>
parents: 215
diff changeset
    56
        The catalog format is a + or -, an isoformat timestamp, and a catalog
afceea12576c 320 pkg should ignore catalog lines it doesn't recognize
johansen <johansen@sun.com>
parents: 215
diff changeset
    57
        entry in server-side format.  They must be in order and separated by
afceea12576c 320 pkg should ignore catalog lines it doesn't recognize
johansen <johansen@sun.com>
parents: 215
diff changeset
    58
        spaces."""
215
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    59
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    60
        def __init__(self, update_root, catalog, maxfiles = 336):
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    61
                """Create an instance of the UpdateLog.  "update_root" is
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    62
                the root directory for the update log files.
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    63
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    64
                maxfiles is the maximum number of logfiles that
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    65
                the UpdateLog will keep.  A new file is added
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    66
                for each hour in which there is an update.  The
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    67
                default value of 336 means that we keep 336 hours, or
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    68
                14 days worth of log history."""
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    69
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    70
                self.rootdir = update_root
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    71
                self.logfd = None
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    72
                self.maxfiles = maxfiles
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    73
                self.catalog = catalog
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    74
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    75
                if not os.path.exists(update_root):
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    76
                        os.makedirs(update_root)
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    77
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    78
                self._setup_logfiles()
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    79
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    80
        def __del__(self):
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    81
                """Perform any last minute cleanup."""
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    82
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    83
                if self.logfd:
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    84
                        try:
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    85
                                self.logfd.close()
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    86
                        except:
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    87
                                pass
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    88
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    89
                        self.logfd = None
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    90
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    91
        def add_package(self, fmri, critical = False):
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    92
                """Record that the catalog has added "fmri"."""
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    93
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    94
                # First add FMRI to catalog
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    95
                ts = self.catalog.add_fmri(fmri, critical)
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    96
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    97
                # Now add update to updatelog
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    98
                self._check_logs()
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
    99
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   100
                if not self.logfd:
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   101
                        self._begin_log()
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   102
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   103
                if critical:
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   104
                        type = "C"
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   105
                else:
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   106
                        type = "V"
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   107
258
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   108
                # The format for catalog C and V records is described
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   109
                # in the docstrings for the Catalog class.
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   110
215
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   111
                logstr = "+ %s %s %s\n" % \
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   112
                    (ts.isoformat(), type, fmri.get_fmri(anarchy = True))
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   113
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   114
                self.logfd.write(logstr)
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   115
                self.logfd.flush()
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   116
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   117
                self.last_update = ts
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   118
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   119
                return ts
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   120
258
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   121
        def rename_package(self, srcname, srcvers, destname, destvers):
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   122
                """Record that package oldname has been renamed to newname,
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   123
                effective as of version vers."""
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   124
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   125
                # Record rename in catalog
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   126
                ts, rr = self.catalog.rename_package(srcname, srcvers, destname,
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   127
                    destvers)
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   128
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   129
                # Now add rename record to updatelog
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   130
                self._check_logs()
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   131
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   132
                if not self.logfd:
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   133
                        self._begin_log()
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   134
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   135
                # The format for a catalog rename record is described
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   136
                # in the docstring for the RenameRecord class.
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   137
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   138
                logstr = "+ %s %s\n" % (ts.isoformat(), rr)
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   139
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   140
                self.logfd.write(logstr)
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   141
                self.logfd.flush()
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   142
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   143
                self.last_update = ts
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   144
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   145
                return ts
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   146
215
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   147
        def _begin_log(self):
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   148
                """Open a log-file so that the UpdateLog can write updates
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   149
                into it."""
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   150
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   151
                filenm = time.strftime("%Y%m%d%H")
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   152
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   153
                ftime = datetime.datetime(
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   154
                    *time.strptime(filenm, "%Y%m%d%H")[0:6])
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   155
                delta = datetime.timedelta(hours=1)
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   156
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   157
                self.close_time = ftime + delta
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   158
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   159
                self.logfd = file(os.path.join(self.rootdir, filenm), "a")
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   160
258
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   161
                if filenm not in self.logfiles:
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   162
                        self.logfiles.append(filenm)
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   163
                        self.curfiles += 1
215
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   164
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   165
                if not self.first_update:
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   166
                        self.first_update = ftime
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   167
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   168
        def _check_logs(self):
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   169
                """Check to see if maximum number of logfiles has been exceeded.
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   170
                If so, rotate the logs.  Also, if a log is open, check to
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   171
                see if it needs to be closed."""
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   172
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   173
                if self.logfd and self.close_time < datetime.datetime.now():
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   174
                        self.logfd.close()
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   175
                        self.logfd = None
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   176
                        self.close_time = 0
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   177
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   178
                if self.curfiles < self.maxfiles:
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   179
                        return
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   180
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   181
                excess = self.curfiles - self.maxfiles
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   182
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   183
                to_remove = self.logfiles[0:excess]
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   184
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   185
                for r in to_remove:
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   186
                        filepath = os.path.join(self.rootdir, "%s" % r)
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   187
                        os.unlink(filepath)
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   188
                        self.curfiles -= 1 
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   189
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   190
                del self.logfiles[0:excess]
258
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   191
215
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   192
                self.first_update = datetime.datetime(*time.strptime(
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   193
                    self.logfiles[0], "%Y%m%d%H")[0:6])
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   194
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   195
        def enough_history(self, ts):
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   196
                """Returns true if the timestamp is so far behind the
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   197
                update log, that there is not enough log history to bring
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   198
                the client up to date."""
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   199
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   200
                # Absence of server-side log history also counts as
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   201
                # not enough history.
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   202
                if not self.last_update or not self.first_update:
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   203
                        return False
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   204
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   205
                if ts < self.first_update:
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   206
                        return False
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   207
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   208
                return True
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   209
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   210
        @staticmethod
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   211
        def recv(c, path, ts):
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   212
                """Take a connection object and a catalog path.  This method
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   213
                receives a catalog from the server.  If it is an incremental
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   214
                update, it is processed by the updatelog.  If it is a full
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   215
                update, we call the catalog to handle the request.
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   216
                Ts is the timestamp when the local copy of the catalog
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   217
                was last modified."""
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   218
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   219
                
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   220
                update_type = c.info().getheader("X-Catalog-Type", "full")
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   221
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   222
                if update_type == 'incremental':
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   223
                        UpdateLog._recv_updates(c, path, ts)
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   224
                else:
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   225
                        catalog.recv(c, path)
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   226
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   227
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   228
        @staticmethod
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   229
        def _recv_updates(filep, path, cts):
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   230
                """A static method that takes a file-like object,
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   231
                a path, and a timestamp.  This is the other half of
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   232
                send_updates().  It reads a stream as an incoming updatelog and
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   233
                modifies the catalog on disk."""
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   234
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   235
                if not os.path.exists(path):
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   236
                        os.makedirs(path)
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   237
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   238
                # Build a list of FMRIs that this update would add, check to
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   239
                # make sure that they aren't present in the catalog, then append
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   240
                # the fmris.
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   241
                mts = catalog.ts_to_datetime(cts)
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   242
                cts = mts
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   243
                added = 0
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   244
                npkgs = 0
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   245
                add_lines = []
220
afceea12576c 320 pkg should ignore catalog lines it doesn't recognize
johansen <johansen@sun.com>
parents: 215
diff changeset
   246
                unknown_lines = []
215
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   247
                attrs = {}
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   248
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   249
                for s in filep:
258
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   250
                        l = s.split(None, 3)
215
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   251
                        if len(l) < 4:
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   252
                                continue
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   253
220
afceea12576c 320 pkg should ignore catalog lines it doesn't recognize
johansen <johansen@sun.com>
parents: 215
diff changeset
   254
                        elif l[2] not in catalog.known_prefixes:
afceea12576c 320 pkg should ignore catalog lines it doesn't recognize
johansen <johansen@sun.com>
parents: 215
diff changeset
   255
                                # Add unknown line directly to catalog.
afceea12576c 320 pkg should ignore catalog lines it doesn't recognize
johansen <johansen@sun.com>
parents: 215
diff changeset
   256
                                # This can be post-processed later, when it
afceea12576c 320 pkg should ignore catalog lines it doesn't recognize
johansen <johansen@sun.com>
parents: 215
diff changeset
   257
                                # becomes known.
afceea12576c 320 pkg should ignore catalog lines it doesn't recognize
johansen <johansen@sun.com>
parents: 215
diff changeset
   258
                                #
afceea12576c 320 pkg should ignore catalog lines it doesn't recognize
johansen <johansen@sun.com>
parents: 215
diff changeset
   259
                                # XXX Notify user that unknown entry was added?
afceea12576c 320 pkg should ignore catalog lines it doesn't recognize
johansen <johansen@sun.com>
parents: 215
diff changeset
   260
                                ts = catalog.ts_to_datetime(l[1])
afceea12576c 320 pkg should ignore catalog lines it doesn't recognize
johansen <johansen@sun.com>
parents: 215
diff changeset
   261
                                if ts > cts:
afceea12576c 320 pkg should ignore catalog lines it doesn't recognize
johansen <johansen@sun.com>
parents: 215
diff changeset
   262
                                        if ts > mts:
afceea12576c 320 pkg should ignore catalog lines it doesn't recognize
johansen <johansen@sun.com>
parents: 215
diff changeset
   263
                                                mts = ts
afceea12576c 320 pkg should ignore catalog lines it doesn't recognize
johansen <johansen@sun.com>
parents: 215
diff changeset
   264
                                        str = "%s %s\n" % (l[2], l[3])
afceea12576c 320 pkg should ignore catalog lines it doesn't recognize
johansen <johansen@sun.com>
parents: 215
diff changeset
   265
                                        unknown_lines.append(str)
afceea12576c 320 pkg should ignore catalog lines it doesn't recognize
johansen <johansen@sun.com>
parents: 215
diff changeset
   266
afceea12576c 320 pkg should ignore catalog lines it doesn't recognize
johansen <johansen@sun.com>
parents: 215
diff changeset
   267
                        elif l[0] == "+":
afceea12576c 320 pkg should ignore catalog lines it doesn't recognize
johansen <johansen@sun.com>
parents: 215
diff changeset
   268
                                # This is a known entry type.
afceea12576c 320 pkg should ignore catalog lines it doesn't recognize
johansen <johansen@sun.com>
parents: 215
diff changeset
   269
                                # Create a list of FMRIs to add, since
afceea12576c 320 pkg should ignore catalog lines it doesn't recognize
johansen <johansen@sun.com>
parents: 215
diff changeset
   270
                                # additional inspection is required
215
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   271
                                ts = catalog.ts_to_datetime(l[1])
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   272
                                if ts > cts:
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   273
                                        if ts > mts:
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   274
                                                mts = ts
258
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   275
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   276
                                        # The format for C and V records
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   277
                                        # is described in the Catalog's
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   278
                                        # docstring.
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   279
                                        if l[2] in tuple("CV"):
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   280
                                                f = fmri.PkgFmri(l[3])
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   281
                                                str = "%s %s %s %s\n" % \
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   282
                                                    (l[2], "pkg", f.pkg_name,
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   283
                                                    f.version)
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   284
                                                add_lines.append(str)
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   285
                                                added += 1
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   286
                                        # The format for R records is
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   287
                                        # described in the docstring for
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   288
                                        # RenameRecords
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   289
                                        elif l[2] == "R":
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   290
                                                sf, sv, rf, rv = l[3].split()
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   291
                                                str = "%s %s %s %s %s\n" % \
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   292
                                                    (l[2], sf, sv, rf, rv)
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   293
                                                add_lines.append(str)
215
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   294
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   295
                # Verify that they aren't already in the catalog
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   296
                catf = file(os.path.normpath(
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   297
                    os.path.join(path, "catalog")), "a+")
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   298
                catf.seek(0)
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   299
                for c in catf:
258
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   300
                        if c[0] in tuple("CV"):
b3b7592412ec 270 Need ability to rename packages
johansen <johansen@sun.com>
parents: 239
diff changeset
   301
                                npkgs += 1
215
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   302
                        if c in add_lines:
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   303
                                catf.close()
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   304
                                raise UpdateLogException, \
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   305
                                    "Package %s is already in the catalog" % \
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   306
                                        c
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   307
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   308
                # Write the new entries to the catalog
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   309
                catf.seek(0, 2)
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   310
                catf.writelines(add_lines)
220
afceea12576c 320 pkg should ignore catalog lines it doesn't recognize
johansen <johansen@sun.com>
parents: 215
diff changeset
   311
                if len(unknown_lines) > 0:
afceea12576c 320 pkg should ignore catalog lines it doesn't recognize
johansen <johansen@sun.com>
parents: 215
diff changeset
   312
                        catf.writelines(unknown_lines)
215
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   313
                catf.close()
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   314
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   315
                # Now re-write npkgs and Last-Modified in attributes file
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   316
                afile = file(os.path.normpath(os.path.join(path, "attrs")), "r")
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   317
                attrre = re.compile('^S ([^:]*): (.*)')
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   318
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   319
                for entry in afile:
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   320
                        m = attrre.match(entry)
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   321
                        if m != None:
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   322
                                attrs[m.group(1)] = m.group(2)
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   323
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   324
                afile.close()
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   325
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   326
                # Update the attributes we care about
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   327
                attrs["npkgs"] = npkgs + added
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   328
                attrs["Last-Modified"] = mts.isoformat()
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   329
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   330
                # Write attributes back out
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   331
                afile = file(os.path.normpath(os.path.join(path, "attrs")), "w")
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   332
                for a in attrs.keys():
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   333
                        s = "S %s: %s\n" % (a, attrs[a])
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   334
                        afile.write(s)
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   335
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   336
                afile.close()
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   337
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   338
                return True
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   339
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   340
        def send(self, request):
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   341
                """This method takes a http request and sends a catalog
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   342
                to the client.  If the client it capable of receiving an
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   343
                incremental update, we'll send that.  Otherwise, it calls
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   344
                into the catalog to send a full copy."""
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   345
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   346
                modified = request.headers.getheader("If-Modified-Since")
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   347
                ts = None
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   348
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   349
                if modified:
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   350
                        try:
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   351
                                ts = catalog.ts_to_datetime(modified)
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   352
                        except ValueError:
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   353
                                ts = None
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   354
                
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   355
                # Incremental catalog updates
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   356
                if ts and self.up_to_date(ts):
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   357
                        request.send_response(304)
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   358
                        request.send_header('Content-type', 'text/plain')
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   359
                        request.send_header('Last-Modified',
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   360
                            self.catalog.last_modified())
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   361
                        request.send_header('X-Catalog-Type', 'incremental')
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   362
                        request.end_headers()
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   363
                        return
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   364
                elif ts and self.enough_history(ts):
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   365
                        request.send_response(200)
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   366
                        request.send_header('Content-type', 'text/plain')
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   367
                        request.send_header('Last-Modified',
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   368
                            self.catalog.last_modified())
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   369
                        request.send_header('X-Catalog-Type', 'incremental')
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   370
                        request.end_headers()
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   371
                        self._send_updates(ts, request.wfile)
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   372
                        return
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   373
                else:
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   374
                        # Not enough history, or full catalog requested
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   375
                        request.send_response(200)
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   376
                        request.send_header('Content-type', 'text/plain')
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   377
                        request.send_header('X-Catalog-Type', 'full')
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   378
                        request.end_headers()
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   379
                        self.catalog.send(request.wfile)
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   380
                        return
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   381
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   382
        def _send_updates(self, ts, filep):
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   383
                """Look through the logs for updates that have occurred
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   384
                after timestamp.  Write these changes to the file-like object
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   385
                supplied in filep."""
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   386
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   387
                # The files that need to be examined depend upon the timestamp
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   388
                # supplied by the client, and the log files actually present.
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   389
                #
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   390
                # The following cases exist:
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   391
                #
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   392
                # 1. No updates have occurred since timestamp.  Send nothing.
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   393
                #
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   394
                # 2. Timestamp is older than oldest log record.  Client needs to
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   395
                # download full catalog.
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   396
                #
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   397
                # 3. Timestamp falls within a range for which update records
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   398
                # exist.  If the timestamp is in the middle of a log-file, open
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   399
                # that file, send updates newer than timestamp, and then send
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   400
                # all newer files.  Otherwise, just send updates from the newer
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   401
                # log files.
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   402
                
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   403
                if self.up_to_date(ts) or not self.enough_history(ts):
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   404
                       return
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   405
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   406
                # Remove minutes, seconds, and microsec from timestamp
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   407
                rts = datetime.datetime(ts.year, ts.month, ts.day, ts.hour)
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   408
                assert rts < ts
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   409
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   410
                # send data from logfiles newer or equal to rts
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   411
                for lf in self.logfiles:
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   412
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   413
                        lf_time = datetime.datetime(
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   414
                            *time.strptime(lf, "%Y%m%d%H")[0:6])
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   415
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   416
                        if lf_time >= rts:
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   417
                                fn = "%s" % lf
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   418
                                logf = file(os.path.join(self.rootdir, fn), "r")
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   419
                                for line in logf:
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   420
                                        filep.write(line)
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   421
                                logf.close()
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   422
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   423
        def _setup_logfiles(self):
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   424
                """Scans the directory containing the update log's files.
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   425
                Sets up any necessary state for the UpdateLog."""
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   426
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   427
                # Store names of logfiles as integers for easier comparison
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   428
                self.logfiles = [f for f in os.listdir(self.rootdir)]
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   429
                self.logfiles.sort()
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   430
                self.curfiles = len(self.logfiles)
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   431
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   432
                if self.curfiles == 0:
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   433
                        self.last_update = None
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   434
                        self.first_update = None
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   435
                        return
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   436
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   437
                # Find the last update by opening the most recent logfile
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   438
                # and finding its last entry
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   439
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   440
                filenm = self.logfiles[self.curfiles - 1]
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   441
                logf = file(os.path.join(self.rootdir, filenm), "r")
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   442
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   443
                last_update = None
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   444
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   445
                for ln in logf:
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   446
                        lspl = ln.split(" ", 4)
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   447
                        if len(lspl) < 4:
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   448
                                continue
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   449
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   450
                        current_ts = catalog.ts_to_datetime(lspl[1])
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   451
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   452
                        if not last_update or current_ts > last_update:
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   453
                                last_update = current_ts
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   454
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   455
                logf.close()
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   456
                self.last_update = last_update
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   457
                self.first_update = datetime.datetime(
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   458
                    *time.strptime(self.logfiles[0], "%Y%m%d%H")[0:6])
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   459
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   460
        def up_to_date(self, ts):
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   461
                """Returns true if the timestamp is up to date."""
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   462
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   463
                if self.last_update and ts >= self.last_update:
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   464
                        return True
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   465
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   466
                return False
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   467
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   468
# Allow these methods to be invoked without explictly naming the UpdateLog
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   469
# class.
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   470
recv = UpdateLog.recv
c10719939c6d 245 Need incremental update mechanism for the catalog
johansen <johansen@sun.com>
parents:
diff changeset
   471