src/modules/client/history.py
author Shawn Walker <srw@sun.com>
Fri, 15 Jan 2010 12:51:17 -0600
changeset 1658 49b8cc06eecb
parent 1540 de040c9fd0c0
child 1710 139720e2e756
permissions -rw-r--r--
13360 client can traceback if corrupt catalogs exist
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
539
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
     2
#
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
     3
# CDDL HEADER START
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
     4
#
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
     5
# The contents of this file are subject to the terms of the
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
     6
# Common Development and Distribution License (the "License").
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
     7
# You may not use this file except in compliance with the License.
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
     8
#
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
     9
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
    10
# or http://www.opensolaris.org/os/licensing.
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
    11
# See the License for the specific language governing permissions
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
    12
# and limitations under the License.
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
    13
#
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
    14
# When distributing Covered Code, include this CDDL HEADER in each
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
    15
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
    16
# If applicable, add the following below this CDDL HEADER, with the
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
    17
# fields enclosed by brackets "[]" replaced with your own identifying
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
    18
# information: Portions Copyright [yyyy] [name of copyright owner]
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
    19
#
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
    20
# CDDL HEADER END
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
    21
#
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
    22
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
    23
#
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
    24
# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
539
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
    25
# Use is subject to license terms.
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
    26
#
539
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
    27
1027
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
    28
import copy
539
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
    29
import errno
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
    30
import os
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
    31
import shutil
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
    32
import sys
1032
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
    33
import traceback
539
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
    34
import xml.dom.minidom as xmini
732
9ea802fef2fb 3540 client should be resilient against corrupt history
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 696
diff changeset
    35
import xml.parsers.expat as expat
539
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
    36
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
    37
import pkg
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
    38
import pkg.client.api_errors as api_errors
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
    39
import pkg.fmri as fmri
539
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
    40
import pkg.misc as misc
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
    41
import pkg.portable as portable
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
    42
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
    43
# Constants for the (outcome, reason) combination for operation result.
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
    44
# Indicates that the user canceled the operation.
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
    45
RESULT_CANCELED = ["Canceled"]
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
    46
# Indicates that the operation had no work to perform or didn't need to make
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
    47
# any changes to the image.
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
    48
RESULT_NOTHING_TO_DO = ["Nothing to do"]
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
    49
# Indicates that the operation succeeded.
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
    50
RESULT_SUCCEEDED = ["Succeeded"]
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
    51
# Indicates that the user or client provided bad information which resulted in
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
    52
# operation failure.
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
    53
RESULT_FAILED_BAD_REQUEST = ["Failed", "Bad Request"]
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
    54
# Indicates that the operation failed due to a configuration error (such as an
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
    55
# invalid SSL Certificate, etc.).
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
    56
RESULT_FAILED_CONFIGURATION = ["Failed", "Configuration"]
539
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
    57
# Indicates that the operation failed due to package constraints or because of
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
    58
# a restriction enforced by the client (e.g. SUNWipkg out of date).
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
    59
RESULT_FAILED_CONSTRAINED = ["Failed", "Constrained"]
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
    60
# Indicates that a search operation failed.
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
    61
RESULT_FAILED_SEARCH = ["Failed", "Search"]
1658
49b8cc06eecb 13360 client can traceback if corrupt catalogs exist
Shawn Walker <srw@sun.com>
parents: 1540
diff changeset
    62
# Indicates that there was a problem reading, writing, or accessing a file.
539
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
    63
RESULT_FAILED_STORAGE = ["Failed", "Storage"]
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
    64
# Indicates that a transport error caused the operation to fail.
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
    65
RESULT_FAILED_TRANSPORT = ["Failed", "Transport"]
1019
e61c57c724c9 7663 disable_fmri should be synchronous
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 926
diff changeset
    66
# Indicates that the operation failed due to an actuator problem
e61c57c724c9 7663 disable_fmri should be synchronous
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 926
diff changeset
    67
RESULT_FAILED_ACTUATOR = ["Failed", "Actuator"]
1035
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1032
diff changeset
    68
# Indicates that the operation failed due to not enough memory
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1032
diff changeset
    69
RESULT_FAILED_OUTOFMEMORY = ["Failed", "Out of Memory"]
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
    70
# Indicates that the operation failed for an unknown reason.
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
    71
RESULT_FAILED_UNKNOWN = ["Failed", "Unknown"]
539
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
    72
556
1c3526ca7b9e 2022 client should provide operational intent to server
Shawn Walker <shawn.walker@sun.com>
parents: 539
diff changeset
    73
# Operations that are discarded, not saved, when recorded by history.
1c3526ca7b9e 2022 client should provide operational intent to server
Shawn Walker <shawn.walker@sun.com>
parents: 539
diff changeset
    74
DISCARDED_OPERATIONS = ["contents", "info", "list"]
1c3526ca7b9e 2022 client should provide operational intent to server
Shawn Walker <shawn.walker@sun.com>
parents: 539
diff changeset
    75
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
    76
# Cross-reference table for errors and results.  Entries should be ordered
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
    77
# most-specific to least-specific.
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
    78
error_results = {
1658
49b8cc06eecb 13360 client can traceback if corrupt catalogs exist
Shawn Walker <srw@sun.com>
parents: 1540
diff changeset
    79
    api_errors.InvalidCatalogFile: RESULT_FAILED_STORAGE,
1027
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
    80
    api_errors.BENamingNotSupported: RESULT_FAILED_BAD_REQUEST,
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
    81
    api_errors.InvalidBENameException: RESULT_FAILED_BAD_REQUEST,
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
    82
    api_errors.CertificateError: RESULT_FAILED_CONFIGURATION,
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
    83
    api_errors.PublisherError: RESULT_FAILED_BAD_REQUEST,
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
    84
    api_errors.CanceledException: RESULT_CANCELED,
1027
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
    85
    api_errors.ImageUpdateOnLiveImageException: RESULT_FAILED_BAD_REQUEST,
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
    86
    api_errors.ProblematicPermissionsIndexException: RESULT_FAILED_STORAGE,
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
    87
    api_errors.PermissionsException: RESULT_FAILED_STORAGE,
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
    88
    api_errors.MainDictParsingException: RESULT_FAILED_STORAGE,
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
    89
    api_errors.SearchException: RESULT_FAILED_SEARCH,
1505
cc598d70bbbe 4425 pkg install should deal w/ complex dependency changes in one install
Bart Smaalders <Bart.Smaalders@Sun.COM>
parents: 1271
diff changeset
    90
    api_errors.PlanCreationException: RESULT_FAILED_CONSTRAINED,
1027
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
    91
    api_errors.NonLeafPackageException: RESULT_FAILED_CONSTRAINED,
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
    92
    api_errors.IpkgOutOfDateException: RESULT_FAILED_CONSTRAINED,
1102
5ea5cdb4360d 5014 api sets successful result for image-create with failed catalog refresh
Shawn Walker <srw@sun.com>
parents: 1035
diff changeset
    93
    api_errors.InvalidDepotResponseException: RESULT_FAILED_TRANSPORT,
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
    94
    fmri.IllegalFmri: RESULT_FAILED_BAD_REQUEST,
1027
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
    95
    KeyboardInterrupt: RESULT_CANCELED,
1035
0e243b7eb121 2297 top level error handler for out of memory conditions needed
Danek Duvall <danek.duvall@sun.com>
parents: 1032
diff changeset
    96
    MemoryError: RESULT_FAILED_OUTOFMEMORY,
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
    97
}
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
    98
732
9ea802fef2fb 3540 client should be resilient against corrupt history
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 696
diff changeset
    99
class _HistoryException(Exception):
569
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   100
        """Private base exception class for all History exceptions."""
1540
de040c9fd0c0 13003 exception messages not always displayed correctly with python 2.6
Shawn Walker <srw@sun.com>
parents: 1516
diff changeset
   101
569
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   102
        def __init__(self, *args):
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   103
                Exception.__init__(self, *args)
732
9ea802fef2fb 3540 client should be resilient against corrupt history
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 696
diff changeset
   104
                self.error = args[0]
569
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   105
1540
de040c9fd0c0 13003 exception messages not always displayed correctly with python 2.6
Shawn Walker <srw@sun.com>
parents: 1516
diff changeset
   106
        def __unicode__(self):
de040c9fd0c0 13003 exception messages not always displayed correctly with python 2.6
Shawn Walker <srw@sun.com>
parents: 1516
diff changeset
   107
                # To workaround python issues 6108 and 2517, this provides a
de040c9fd0c0 13003 exception messages not always displayed correctly with python 2.6
Shawn Walker <srw@sun.com>
parents: 1516
diff changeset
   108
                # a standard wrapper for this class' exceptions so that they
de040c9fd0c0 13003 exception messages not always displayed correctly with python 2.6
Shawn Walker <srw@sun.com>
parents: 1516
diff changeset
   109
                # have a chance of being stringified correctly.
de040c9fd0c0 13003 exception messages not always displayed correctly with python 2.6
Shawn Walker <srw@sun.com>
parents: 1516
diff changeset
   110
                return str(self)
de040c9fd0c0 13003 exception messages not always displayed correctly with python 2.6
Shawn Walker <srw@sun.com>
parents: 1516
diff changeset
   111
569
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   112
        def __str__(self):
732
9ea802fef2fb 3540 client should be resilient against corrupt history
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 696
diff changeset
   113
                return str(self.error)
569
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   114
732
9ea802fef2fb 3540 client should be resilient against corrupt history
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 696
diff changeset
   115
class HistoryLoadException(_HistoryException):
569
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   116
        """Used to indicate that an unexpected error occurred while loading
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   117
        History operation information.
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   118
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   119
        The first argument should be an exception object related to the
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   120
        error encountered.
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   121
        """
732
9ea802fef2fb 3540 client should be resilient against corrupt history
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 696
diff changeset
   122
        def __init__(self, *args):
9ea802fef2fb 3540 client should be resilient against corrupt history
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 696
diff changeset
   123
                _HistoryException.__init__(self, *args)
9ea802fef2fb 3540 client should be resilient against corrupt history
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 696
diff changeset
   124
                self.parse_failure = isinstance(self.error, expat.ExpatError)
569
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   125
732
9ea802fef2fb 3540 client should be resilient against corrupt history
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 696
diff changeset
   126
class HistoryStoreException(_HistoryException):
569
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   127
        """Used to indicate that an unexpected error occurred while storing
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   128
        History operation information.
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   129
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   130
        The first argument should be an exception object related to the
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   131
        error encountered.
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   132
        """
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   133
        pass
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   134
732
9ea802fef2fb 3540 client should be resilient against corrupt history
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 696
diff changeset
   135
class HistoryPurgeException(_HistoryException):
569
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   136
        """Used to indicate that an unexpected error occurred while purging
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   137
        History operation information.
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   138
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   139
        The first argument should be an exception object related to the
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   140
        error encountered.
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   141
        """
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   142
        pass
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   143
539
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   144
class _HistoryOperation(object):
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   145
        """A _HistoryOperation object is a representation of data about an
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   146
        operation that a pkg(5) client has performed.  This class is private
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   147
        and not intended for use by classes other than History.
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   148
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   149
        This class provides an abstraction layer between the stack of
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   150
        operations that History manages should these values need to be
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   151
        manipulated as they are set or retrieved.
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   152
        """
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   153
1027
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   154
        def __copy__(self):
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   155
                h = _HistoryOperation()
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   156
                for attr in ("name", "start_time", "end_time", "start_state",
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   157
                    "end_state", "username", "userid", "result"):
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   158
                        setattr(h, attr, getattr(self, attr))
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   159
                h.errors = [copy.copy(e) for e in self.errors]
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   160
                return h
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   161
539
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   162
        def __setattr__(self, name, value):
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   163
                if name not in ("result", "errors"):
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   164
                        # Force all other attribute values to be a string
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   165
                        # to avoid issues with minidom.
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   166
                        value = str(value)
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   167
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   168
                return object.__setattr__(self, name, value)
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   169
569
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   170
        def __str__(self):
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   171
                return """\
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   172
Operation Name: %s
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   173
Operation Result: %s
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   174
Operation Start Time: %s
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   175
Operation End Time: %s
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   176
Operation Start State:
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   177
%s
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   178
Operation End State:
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   179
%s
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   180
Operation User: %s (%s)
1235
7c34ba6e5e4f 9287 history can log wrong exception information when operations fail
Shawn Walker <srw@sun.com>
parents: 1102
diff changeset
   181
Operation Errors:
7c34ba6e5e4f 9287 history can log wrong exception information when operations fail
Shawn Walker <srw@sun.com>
parents: 1102
diff changeset
   182
%s
569
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   183
""" % (self.name, self.result, self.start_time, self.end_time,
1235
7c34ba6e5e4f 9287 history can log wrong exception information when operations fail
Shawn Walker <srw@sun.com>
parents: 1102
diff changeset
   184
    self.start_state, self.end_state, self.username, self.userid,
7c34ba6e5e4f 9287 history can log wrong exception information when operations fail
Shawn Walker <srw@sun.com>
parents: 1102
diff changeset
   185
    self.errors)
569
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   186
539
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   187
        # All "time" values should be in UTC, using ISO 8601 as the format.
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   188
        # Name of the operation performed (e.g. install, image-update, etc.).
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   189
        name = None
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   190
        # When the operation started.
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   191
        start_time = None
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   192
        # When the operation ended.
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   193
        end_time = None
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   194
        # The starting state of the operation (e.g. image plan pre-evaluation).
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   195
        start_state = None
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   196
        # The ending state of the operation (e.g. image plan post-evaluation).
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   197
        end_state = None
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   198
        # Errors encountered during an operation.
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   199
        errors = None
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   200
        # username of the user that performed the operation.
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   201
        username = None
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   202
        # id of the user that performed the operation.
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   203
        userid = None
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   204
        # The result of the operation (must be a list indicating (outcome,
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   205
        # reason)).
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   206
        result = None
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   207
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   208
        def __init__(self):
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   209
                self.errors = []
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   210
1027
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   211
539
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   212
class History(object):
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   213
        """A History object is a representation of data about a pkg(5) client
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   214
        and about operations that the client is executing or has executed.  It
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   215
        uses the _HistoryOperation class to represent the data about an
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   216
        operation.
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   217
        """
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   218
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   219
        # The directory where the history directory can be found (or
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   220
        # created if it doesn't exist).
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   221
        root_dir = None
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   222
        # The name of the client (e.g. pkg, packagemanager, etc.)
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   223
        client_name = None
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   224
        # The version of the client (e.g. 093ca22da67c).
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   225
        client_version = None
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   226
        # How the client was invoked (e.g. 'pkg install -n foo').
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   227
        client_args = None
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   228
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   229
        # A stack where operation data will actually be stored.
1271
036d87b0bd44 6831 need 'pkg change-variant' command
Edward Pilatowicz <Edward.Pilatowicz@Sun.COM>
parents: 1235
diff changeset
   230
        __operations = []
539
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   231
1027
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   232
        # A private property used by preserve() and restore() to store snapshots
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   233
        # of history and operation state information.
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   234
        __snapshot = None
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   235
539
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   236
        # These attributes exist to fake access to the operations stack.
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   237
        operation_name = None
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   238
        operation_username = None
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   239
        operation_userid = None
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   240
        operation_start_time = None
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   241
        operation_end_time = None
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   242
        operation_start_state = None
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   243
        operation_end_state = None
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   244
        operation_errors = None
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   245
        operation_result = None
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   246
1027
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   247
        def __copy__(self):
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   248
                h = History()
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   249
                for attr in ("root_dir", "client_name", "client_version"):
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   250
                        setattr(h, attr, getattr(self, attr))
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   251
                object.__setattr__(self, "client_args",
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   252
                    [copy.copy(a) for a in self.client_args])
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   253
                # A deepcopy has to be performed here since this a list of dicts
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   254
                # and not just History operation objects.
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   255
                h.__operations = [copy.deepcopy(o) for o in self.__operations]
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   256
                return h
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   257
539
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   258
        def __getattribute__(self, name):
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   259
                if name == "client_args":
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   260
                        return object.__getattribute__(self, name)[:]
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   261
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   262
                if not name.startswith("operation_"):
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   263
                        return object.__getattribute__(self, name)
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   264
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   265
                ops = object.__getattribute__(self, "_History__operations")
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   266
                if not ops:
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   267
                        return None
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   268
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   269
                return getattr(ops[-1]["operation"], name[len("operation_"):])
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   270
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   271
        def __setattr__(self, name, value):
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   272
                if name == "client_args":
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   273
                        raise AttributeError("'history' object attribute '%s' "
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   274
                            "is read-only." % name)
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   275
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   276
                if not name.startswith("operation_"):
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   277
                        return object.__setattr__(self, name, value)
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   278
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   279
                ops = object.__getattribute__(self, "_History__operations")
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   280
                if name == "operation_name":
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   281
                        if not ops:
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   282
                                ops = []
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   283
                                object.__setattr__(self,
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   284
                                    "_History__operations", ops)
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   285
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   286
                        ops.append({
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   287
                            "pathname": None,
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   288
                            "operation": _HistoryOperation()
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   289
                        })
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   290
                elif not ops:
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   291
                        raise AttributeError("'history' object attribute '%s' "
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   292
                            "cannot be set before 'operation_name'." % name)
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   293
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   294
                op = ops[-1]["operation"]
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   295
                setattr(op, name[len("operation_"):], value)
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   296
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   297
                # Access to the class attributes is done through object instead
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   298
                # of just referencing self to avoid any of the special logic in
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   299
                # place interfering with logic here.
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   300
                if name == "operation_name":
1235
7c34ba6e5e4f 9287 history can log wrong exception information when operations fail
Shawn Walker <srw@sun.com>
parents: 1102
diff changeset
   301
                        # Before a new operation starts, clear exception state
7c34ba6e5e4f 9287 history can log wrong exception information when operations fail
Shawn Walker <srw@sun.com>
parents: 1102
diff changeset
   302
                        # for the current one so that when this one ends, the
7c34ba6e5e4f 9287 history can log wrong exception information when operations fail
Shawn Walker <srw@sun.com>
parents: 1102
diff changeset
   303
                        # last operation's exception won't be recorded to this
7c34ba6e5e4f 9287 history can log wrong exception information when operations fail
Shawn Walker <srw@sun.com>
parents: 1102
diff changeset
   304
                        # one.  If the error hasn't been recorded by now, it
7c34ba6e5e4f 9287 history can log wrong exception information when operations fail
Shawn Walker <srw@sun.com>
parents: 1102
diff changeset
   305
                        # doesn't matter anyway, so should be safe to clear.
7c34ba6e5e4f 9287 history can log wrong exception information when operations fail
Shawn Walker <srw@sun.com>
parents: 1102
diff changeset
   306
                        sys.exc_clear()
7c34ba6e5e4f 9287 history can log wrong exception information when operations fail
Shawn Walker <srw@sun.com>
parents: 1102
diff changeset
   307
539
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   308
                        # Mark the operation as having started and record
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   309
                        # other, relevant information.
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   310
                        op.start_time = misc.time_to_timestamp(None)
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   311
                        op.username = portable.get_username()
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   312
                        op.userid = portable.get_userid()
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   313
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   314
                        ca = None
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   315
                        if sys.argv[0]:
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   316
                                ca = [sys.argv[0]]
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   317
                        else:
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   318
                                # Fallback for clients that provide no value.
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   319
                                ca = [self.client_name]
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   320
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   321
                        ca.extend(sys.argv[1:])
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   322
                        object.__setattr__(self, "client_args", ca)
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   323
                        object.__setattr__(self, "client_version", pkg.VERSION)
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   324
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   325
                elif name == "operation_result":
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   326
                        # Record when the operation ended.
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   327
                        op.end_time = misc.time_to_timestamp(None)
556
1c3526ca7b9e 2022 client should provide operational intent to server
Shawn Walker <shawn.walker@sun.com>
parents: 539
diff changeset
   328
1c3526ca7b9e 2022 client should provide operational intent to server
Shawn Walker <shawn.walker@sun.com>
parents: 539
diff changeset
   329
                        # Some operations shouldn't be saved -- they're merely
1c3526ca7b9e 2022 client should provide operational intent to server
Shawn Walker <shawn.walker@sun.com>
parents: 539
diff changeset
   330
                        # included in the stack for completeness or to support
1c3526ca7b9e 2022 client should provide operational intent to server
Shawn Walker <shawn.walker@sun.com>
parents: 539
diff changeset
   331
                        # client functionality.
1c3526ca7b9e 2022 client should provide operational intent to server
Shawn Walker <shawn.walker@sun.com>
parents: 539
diff changeset
   332
                        if op.name not in DISCARDED_OPERATIONS:
1c3526ca7b9e 2022 client should provide operational intent to server
Shawn Walker <shawn.walker@sun.com>
parents: 539
diff changeset
   333
                                # Write current history and last operation to a
1c3526ca7b9e 2022 client should provide operational intent to server
Shawn Walker <shawn.walker@sun.com>
parents: 539
diff changeset
   334
                                # file.
1c3526ca7b9e 2022 client should provide operational intent to server
Shawn Walker <shawn.walker@sun.com>
parents: 539
diff changeset
   335
                                self.__save()
1c3526ca7b9e 2022 client should provide operational intent to server
Shawn Walker <shawn.walker@sun.com>
parents: 539
diff changeset
   336
1c3526ca7b9e 2022 client should provide operational intent to server
Shawn Walker <shawn.walker@sun.com>
parents: 539
diff changeset
   337
                        # Discard it now that it is no longer needed.
569
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   338
                        del ops[-1]
539
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   339
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   340
        def __init__(self, root_dir=".", filename=None):
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   341
                """'root_dir' should be the path of the directory where the
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   342
                history directory can be found (or created if it doesn't
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   343
                exist).  'filename' should be the name of an XML file
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   344
                containing serialized history information to load.
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   345
                """
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   346
                # Since this is a read-only attribute normally, we have to
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   347
                # bypass our setattr override by calling object.
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   348
                object.__setattr__(self, "client_args", [])
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   349
696
6bbfd2dece6f 4371 user-agent string needs to be different for different client front-ends
Danek Duvall <danek.duvall@sun.com>
parents: 593
diff changeset
   350
                # Initialize client_name to what the client thinks it is.  This
6bbfd2dece6f 4371 user-agent string needs to be different for different client front-ends
Danek Duvall <danek.duvall@sun.com>
parents: 593
diff changeset
   351
                # will be overridden if we load history entries off disk.
6bbfd2dece6f 4371 user-agent string needs to be different for different client front-ends
Danek Duvall <danek.duvall@sun.com>
parents: 593
diff changeset
   352
                self.client_name = pkg.client.global_settings.client_name
6bbfd2dece6f 4371 user-agent string needs to be different for different client front-ends
Danek Duvall <danek.duvall@sun.com>
parents: 593
diff changeset
   353
539
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   354
                self.root_dir = root_dir
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   355
                if filename:
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   356
                        self.__load(filename)
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   357
569
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   358
        def __str__(self):
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   359
                ops = self.__operations
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   360
                return "\n".join([str(op["operation"]) for op in ops])
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   361
539
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   362
        @property
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   363
        def path(self):
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   364
                """The directory where history files will be written to or
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   365
                read from.
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   366
                """
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   367
                return os.path.join(self.root_dir, "history")
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   368
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   369
        @property
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   370
        def pathname(self):
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   371
                """Returns the pathname that the history information was read
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   372
                from or will attempted to be written to.  Returns None if no
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   373
                operation has started yet or if no operation has been loaded.
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   374
                """
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   375
                if not self.operation_start_time:
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   376
                        return None
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   377
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   378
                ops = self.__operations
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   379
                pathname = ops[-1]["pathname"]
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   380
                if not pathname:
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   381
                        return os.path.join(self.path,
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   382
                            "%s-01.xml" % ops[-1]["operation"].start_time)
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   383
                return pathname
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   384
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   385
        def clear(self):
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   386
                """Discards all information related to the current history
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   387
                object.
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   388
                """
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   389
                self.client_name = None
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   390
                self.client_version = None
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   391
                object.__setattr__(self, "client_args", [])
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   392
                self.__operations = []
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   393
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   394
        def __load_client_data(self, node):
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   395
                """Internal function to load the client data from the given XML
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   396
                'node' object.
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   397
                """
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   398
                self.client_name = node.getAttribute("name")
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   399
                self.client_version = node.getAttribute("version")
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   400
                try:
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   401
                        args = node.getElementsByTagName("args")[0]
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   402
                except IndexError:
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   403
                        # There might not be any.
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   404
                        pass
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   405
                else:
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   406
                        ca = object.__getattribute__(self, "client_args")
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   407
                        for cnode in args.getElementsByTagName("arg"):
1032
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   408
                                try:
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   409
                                        ca.append(cnode.childNodes[0].wholeText)
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   410
                                except (AttributeError, IndexError):
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   411
                                        # There may be no childNodes, or
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   412
                                        # wholeText may not be defined.
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   413
                                        pass
539
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   414
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   415
        @staticmethod
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   416
        def __load_operation_data(node):
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   417
                """Internal function to load the operation data from the given
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   418
                XML 'node' object and return a _HistoryOperation object.
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   419
                """
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   420
                op = _HistoryOperation()
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   421
                op.name = node.getAttribute("name")
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   422
                op.start_time = node.getAttribute("start_time")
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   423
                op.end_time = node.getAttribute("end_time")
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   424
                op.username = node.getAttribute("username")
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   425
                op.userid = node.getAttribute("userid")
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   426
                op.result = node.getAttribute("result").split(", ")
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   427
1032
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   428
                def get_node_values(parent_name, child_name=None):
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   429
                        try:
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   430
                                parent = node.getElementsByTagName(parent_name)[0]
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   431
                                if child_name:
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   432
                                        cnodes = parent.getElementsByTagName(
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   433
                                            child_name)
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   434
                                        return [
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   435
                                            cnode.childNodes[0].wholeText
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   436
                                            for cnode in cnodes
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   437
                                        ]
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   438
                                return parent.childNodes[0].wholeText
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   439
                        except (AttributeError, IndexError):
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   440
                                # Assume no values are present for the node.
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   441
                                pass
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   442
                        if child_name:
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   443
                                return []
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   444
                        return
539
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   445
1032
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   446
                op.start_state = get_node_values("start_state")
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   447
                op.end_state = get_node_values("end_state")
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   448
                op.errors.extend(get_node_values("errors", child_name="error"))
1507
b956ea23d3a6 11735 pkg history data files should not be executable
Richard Lowe <richlowe@richlowe.net>
parents: 1505
diff changeset
   449
539
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   450
                return op
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   451
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   452
        def __load(self, filename):
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   453
                """Loads the history from a file located in self.path/history/
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   454
                {filename}.  The file should contain a serialized history
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   455
                object in XML format.
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   456
                """
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   457
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   458
                # Ensure all previous information is discarded.
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   459
                self.clear()
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   460
569
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   461
                try:
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   462
                        pathname = os.path.join(self.path, filename)
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   463
                        d = xmini.parse(pathname)
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   464
                        root = d.documentElement
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   465
                        for cnode in root.childNodes:
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   466
                                if cnode.nodeName == "client":
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   467
                                        self.__load_client_data(cnode)
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   468
                                elif cnode.nodeName == "operation":
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   469
                                        # Operations load differently due to
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   470
                                        # the stack.
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   471
                                        self.__operations.append({
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   472
                                            "pathname": pathname,
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   473
                                            "operation":
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   474
                                                self.__load_operation_data(
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   475
                                                cnode)
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   476
                                            })
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   477
                except KeyboardInterrupt:
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   478
                        raise
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   479
                except Exception, e:
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   480
                        raise HistoryLoadException(e)
539
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   481
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   482
        def __serialize_client_data(self, d):
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   483
                """Internal function used to serialize current client data
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   484
                using the supplied 'd' (xml.dom.minidom) object.
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   485
                """
569
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   486
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   487
                assert self.client_name is not None
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   488
                assert self.client_version is not None
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   489
539
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   490
                root = d.documentElement
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   491
                client = d.createElement("client")
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   492
                client.setAttribute("name", self.client_name)
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   493
                client.setAttribute("version", self.client_version)
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   494
                root.appendChild(client)
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   495
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   496
                if self.client_args:
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   497
                        args = d.createElement("args")
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   498
                        client.appendChild(args)
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   499
                        for entry in self.client_args:
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   500
                                arg = d.createElement("arg")
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   501
                                args.appendChild(arg)
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   502
                                arg.appendChild(
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   503
                                    d.createCDATASection(str(entry)))
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   504
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   505
        def __serialize_operation_data(self, d):
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   506
                """Internal function used to serialize current operation data
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   507
                using the supplied 'd' (xml.dom.minidom) object.
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   508
                """
569
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   509
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   510
                if self.operation_userid is None:
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   511
                        raise HistoryStoreException("Unable to determine the "
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   512
                            "id of the user that performed the current "
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   513
                            "operation; unable to store history information.")
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   514
                elif self.operation_username is None:
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   515
                        raise HistoryStoreException("Unable to determine the "
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   516
                            "username of the user that performed the current "
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   517
                            "operation; unable to store history information.")
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   518
539
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   519
                root = d.documentElement
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   520
                op = d.createElement("operation")
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   521
                op.setAttribute("name", self.operation_name)
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   522
                # Must explictly convert values to a string due to minidom bug
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   523
                # that causes a fatal whenever using types other than str.
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   524
                op.setAttribute("username", str(self.operation_username))
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   525
                op.setAttribute("userid", str(self.operation_userid))
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   526
                op.setAttribute("result", ", ".join(self.operation_result))
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   527
                op.setAttribute("start_time", self.operation_start_time)
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   528
                op.setAttribute("end_time", self.operation_end_time)
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   529
                root.appendChild(op)
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   530
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   531
                if self.operation_start_state:
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   532
                        state = d.createElement("start_state")
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   533
                        op.appendChild(state)
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   534
                        state.appendChild(d.createCDATASection(
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   535
                            str(self.operation_start_state)))
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   536
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   537
                if self.operation_end_state:
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   538
                        state = d.createElement("end_state")
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   539
                        op.appendChild(state)
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   540
                        state.appendChild(d.createCDATASection(
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   541
                            str(self.operation_end_state)))
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   542
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   543
                if self.operation_errors:
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   544
                        errors = d.createElement("errors")
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   545
                        op.appendChild(errors)
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   546
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   547
                        for entry in self.operation_errors:
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   548
                                error = d.createElement("error")
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   549
                                errors.appendChild(error)
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   550
                                error.appendChild(
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   551
                                    d.createCDATASection(str(entry)))
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   552
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   553
        def __save(self):
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   554
                """Serializes the current history information and writes it to
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   555
                a file in self.path/{operation_start_time}-{sequence}.xml.
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   556
                """
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   557
                d = xmini.Document()
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   558
                d.appendChild(d.createElement("history"))
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   559
                self.__serialize_client_data(d)
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   560
                self.__serialize_operation_data(d)
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   561
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   562
                if not os.path.exists(self.path):
593
f4305c5f2602 3823 no perms to create /var/pkg/history results in stack trace, even with -n
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 569
diff changeset
   563
                        try:
1102
5ea5cdb4360d 5014 api sets successful result for image-create with failed catalog refresh
Shawn Walker <srw@sun.com>
parents: 1035
diff changeset
   564
                                # Only the right-most directory should be
5ea5cdb4360d 5014 api sets successful result for image-create with failed catalog refresh
Shawn Walker <srw@sun.com>
parents: 1035
diff changeset
   565
                                # created.  Assume that if the parent structure
5ea5cdb4360d 5014 api sets successful result for image-create with failed catalog refresh
Shawn Walker <srw@sun.com>
parents: 1035
diff changeset
   566
                                # does not exist, it shouldn't be created.
1507
b956ea23d3a6 11735 pkg history data files should not be executable
Richard Lowe <richlowe@richlowe.net>
parents: 1505
diff changeset
   567
                                os.mkdir(self.path, misc.PKG_DIR_MODE)
593
f4305c5f2602 3823 no perms to create /var/pkg/history results in stack trace, even with -n
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 569
diff changeset
   568
                        except EnvironmentError, e:
1102
5ea5cdb4360d 5014 api sets successful result for image-create with failed catalog refresh
Shawn Walker <srw@sun.com>
parents: 1035
diff changeset
   569
                                if e.errno not in (errno.EROFS, errno.EACCES,
5ea5cdb4360d 5014 api sets successful result for image-create with failed catalog refresh
Shawn Walker <srw@sun.com>
parents: 1035
diff changeset
   570
                                    errno.ENOENT):
593
f4305c5f2602 3823 no perms to create /var/pkg/history results in stack trace, even with -n
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 569
diff changeset
   571
                                        # Ignore read-only file system and
f4305c5f2602 3823 no perms to create /var/pkg/history results in stack trace, even with -n
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 569
diff changeset
   572
                                        # access errors as it isn't critical
f4305c5f2602 3823 no perms to create /var/pkg/history results in stack trace, even with -n
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 569
diff changeset
   573
                                        # to the image that this data is
f4305c5f2602 3823 no perms to create /var/pkg/history results in stack trace, even with -n
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 569
diff changeset
   574
                                        # written.
1102
5ea5cdb4360d 5014 api sets successful result for image-create with failed catalog refresh
Shawn Walker <srw@sun.com>
parents: 1035
diff changeset
   575
                                        raise HistoryStoreException(e)
593
f4305c5f2602 3823 no perms to create /var/pkg/history results in stack trace, even with -n
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 569
diff changeset
   576
                                # Return, since without the directory, the rest
f4305c5f2602 3823 no perms to create /var/pkg/history results in stack trace, even with -n
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 569
diff changeset
   577
                                # of this will fail.
f4305c5f2602 3823 no perms to create /var/pkg/history results in stack trace, even with -n
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 569
diff changeset
   578
                                return
f4305c5f2602 3823 no perms to create /var/pkg/history results in stack trace, even with -n
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 569
diff changeset
   579
                        except KeyboardInterrupt:
f4305c5f2602 3823 no perms to create /var/pkg/history results in stack trace, even with -n
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 569
diff changeset
   580
                                raise
f4305c5f2602 3823 no perms to create /var/pkg/history results in stack trace, even with -n
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 569
diff changeset
   581
                        except Exception, e:
f4305c5f2602 3823 no perms to create /var/pkg/history results in stack trace, even with -n
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 569
diff changeset
   582
                                raise HistoryStoreException(e)
539
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   583
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   584
                # Repeatedly attempt to write the history (only if it's because
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   585
                # the file already exists).  This is necessary due to multiple
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   586
                # operations possibly occuring within the same second (but not
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   587
                # microsecond).
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   588
                pathname = self.pathname
569
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   589
                for i in range(1, 100):
539
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   590
                        try:
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   591
                                f = os.fdopen(os.open(pathname,
1507
b956ea23d3a6 11735 pkg history data files should not be executable
Richard Lowe <richlowe@richlowe.net>
parents: 1505
diff changeset
   592
                                    os.O_CREAT|os.O_EXCL|os.O_WRONLY,
b956ea23d3a6 11735 pkg history data files should not be executable
Richard Lowe <richlowe@richlowe.net>
parents: 1505
diff changeset
   593
                                    misc.PKG_FILE_MODE), "w")
539
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   594
                                d.writexml(f,
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   595
                                    encoding=sys.getdefaultencoding())
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   596
                                f.close()
569
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   597
                                return
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   598
                        except EnvironmentError, e:
539
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   599
                                if e.errno == errno.EEXIST:
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   600
                                        name, ext = os.path.splitext(
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   601
                                            os.path.basename(pathname))
569
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   602
                                        name = name.split("-", 1)[0]
539
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   603
                                        # Pick the next name in our sequence
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   604
                                        # and try again.
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   605
                                        pathname = os.path.join(self.path,
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   606
                                            "%s-%02d%s" % (name, i + 1, ext))
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   607
                                        continue
569
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   608
                                elif e.errno not in (errno.EROFS,
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   609
                                    errno.EACCES):
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   610
                                        # Ignore read-only file system and
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   611
                                        # access errors as it isn't critical
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   612
                                        # to the image that this data is
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   613
                                        # written.
1507
b956ea23d3a6 11735 pkg history data files should not be executable
Richard Lowe <richlowe@richlowe.net>
parents: 1505
diff changeset
   614
                                        raise HistoryStoreException(e)
593
f4305c5f2602 3823 no perms to create /var/pkg/history results in stack trace, even with -n
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 569
diff changeset
   615
                                # For all other failures, return, and avoid any
f4305c5f2602 3823 no perms to create /var/pkg/history results in stack trace, even with -n
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 569
diff changeset
   616
                                # further attempts.
f4305c5f2602 3823 no perms to create /var/pkg/history results in stack trace, even with -n
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 569
diff changeset
   617
                                return
569
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   618
                        except KeyboardInterrupt:
539
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   619
                                raise
569
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   620
                        except Exception, e:
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   621
                                raise HistoryStoreException(e)
593
f4305c5f2602 3823 no perms to create /var/pkg/history results in stack trace, even with -n
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 569
diff changeset
   622
539
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   623
        def purge(self):
569
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   624
                """Removes all history information by deleting the directory
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   625
                indicated by the value self.path and then creates a new history
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   626
                entry to record that this purge occurred.
539
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   627
                """
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   628
                self.operation_name = "purge-history"
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   629
                try:
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   630
                        shutil.rmtree(self.path)
569
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   631
                except KeyboardInterrupt:
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   632
                        raise
732
9ea802fef2fb 3540 client should be resilient against corrupt history
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 696
diff changeset
   633
                except EnvironmentError, e:
834
f8b3396500b3 4883 import failure for non-sunos platforms due to missing pspawn
Tom Mueller <Tom.Mueller@sun.com>
parents: 732
diff changeset
   634
                        if e.errno in (errno.ENOENT, errno.ESRCH):
732
9ea802fef2fb 3540 client should be resilient against corrupt history
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 696
diff changeset
   635
                                # History already purged; record as successful.
9ea802fef2fb 3540 client should be resilient against corrupt history
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 696
diff changeset
   636
                                self.operation_result = RESULT_SUCCEEDED
9ea802fef2fb 3540 client should be resilient against corrupt history
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 696
diff changeset
   637
                                return
9ea802fef2fb 3540 client should be resilient against corrupt history
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 696
diff changeset
   638
                        raise HistoryPurgeException(e)
569
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   639
                except Exception, e:
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   640
                        raise HistoryPurgeException(e)
539
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   641
                else:
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   642
                        self.operation_result = RESULT_SUCCEEDED
7486304966c5 1449 pkg requires operational history
Shawn Walker <shawn.walker@sun.com>
parents:
diff changeset
   643
569
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   644
        def abort(self, result):
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   645
                """Intended to be used by the client during top-level error
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   646
                handling to indicate that an unrecoverable error occurred
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   647
                during the current operation(s).  This allows History to end
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   648
                all of the current operations properly and handle any possible
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   649
                errors that might be encountered in History itself.
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   650
                """
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   651
                try:
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   652
                        # Ensure that all operations in the current stack are
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   653
                        # ended properly.
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   654
                        while self.operation_name:
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   655
                                self.operation_result = result
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   656
                except HistoryStoreException:
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   657
                        # Ignore storage errors as it's likely that whatever
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   658
                        # caused the client to abort() also caused the storage
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   659
                        # of the history information to fail.
48f7e9d2b1ac 3715 permission or read-only filesystem errors cause history traceback
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 556
diff changeset
   660
                        return
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
   661
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
   662
        def log_operation_start(self, name):
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
   663
                """Marks the start of an operation to be recorded in image
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
   664
                history."""
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
   665
                self.operation_name = name
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
   666
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
   667
        def log_operation_end(self, error=None, result=None):
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
   668
                """Marks the end of an operation to be recorded in image
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
   669
                history.
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
   670
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
   671
                'result' should be a pkg.client.history constant value
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
   672
                representing the outcome of an operation.  If not provided,
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
   673
                and 'error' is provided, the final result of the operation will
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
   674
                be based on the class of 'error' and 'error' will be recorded
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
   675
                for the current operation.  If 'result' and 'error' is not
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
   676
                provided, success is assumed."""
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
   677
1027
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   678
                if error:
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   679
                        self.log_operation_error(error)
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   680
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
   681
                if error and not result:
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
   682
                        try:
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
   683
                                # Attempt get an exact error match first.
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
   684
                                result = error_results[error.__class__]
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
   685
                        except (AttributeError, KeyError):
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
   686
                                # Failing an exact match, determine if this
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
   687
                                # error is a subclass of an existing one.
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
   688
                                for entry, val in error_results.iteritems():
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
   689
                                        if isinstance(error, entry):
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
   690
                                                result = val
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
   691
                                                break
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
   692
                        if not result:
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
   693
                                # If a result could still not be determined,
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
   694
                                # assume unknown failure case.
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
   695
                                result = RESULT_FAILED_UNKNOWN
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
   696
                elif not result:
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
   697
                        # Assume success if no error and no result.
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
   698
                        result = RESULT_SUCCEEDED
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
   699
                self.operation_result = result
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
   700
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
   701
        def log_operation_error(self, error):
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
   702
                """Adds an error to the list of errors to be recorded in image
1032
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   703
                history for the current operation."""
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   704
926
6ee411c9026a 5871 publisher apis desired
Shawn Walker <Shawn.Walker@Sun.COM>
parents: 834
diff changeset
   705
                if self.operation_name:
1032
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   706
                        out_stack = None
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   707
                        out_err = None
1235
7c34ba6e5e4f 9287 history can log wrong exception information when operations fail
Shawn Walker <srw@sun.com>
parents: 1102
diff changeset
   708
                        use_current_stack = True
1032
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   709
                        if isinstance(error, Exception):
1235
7c34ba6e5e4f 9287 history can log wrong exception information when operations fail
Shawn Walker <srw@sun.com>
parents: 1102
diff changeset
   710
                                # Attempt to get the exception's stack trace
7c34ba6e5e4f 9287 history can log wrong exception information when operations fail
Shawn Walker <srw@sun.com>
parents: 1102
diff changeset
   711
                                # from the stack.  If the exception on the stack
7c34ba6e5e4f 9287 history can log wrong exception information when operations fail
Shawn Walker <srw@sun.com>
parents: 1102
diff changeset
   712
                                # isn't the same object as the one being logged,
7c34ba6e5e4f 9287 history can log wrong exception information when operations fail
Shawn Walker <srw@sun.com>
parents: 1102
diff changeset
   713
                                # then we have to use the current stack (which
7c34ba6e5e4f 9287 history can log wrong exception information when operations fail
Shawn Walker <srw@sun.com>
parents: 1102
diff changeset
   714
                                # is somewhat less useful) instead of being able
7c34ba6e5e4f 9287 history can log wrong exception information when operations fail
Shawn Walker <srw@sun.com>
parents: 1102
diff changeset
   715
                                # to find the code location of the original
7c34ba6e5e4f 9287 history can log wrong exception information when operations fail
Shawn Walker <srw@sun.com>
parents: 1102
diff changeset
   716
                                # error.
7c34ba6e5e4f 9287 history can log wrong exception information when operations fail
Shawn Walker <srw@sun.com>
parents: 1102
diff changeset
   717
                                type, val, tb = sys.exc_info()
7c34ba6e5e4f 9287 history can log wrong exception information when operations fail
Shawn Walker <srw@sun.com>
parents: 1102
diff changeset
   718
                                if error == val:
7c34ba6e5e4f 9287 history can log wrong exception information when operations fail
Shawn Walker <srw@sun.com>
parents: 1102
diff changeset
   719
                                        output = traceback.format_exc()
7c34ba6e5e4f 9287 history can log wrong exception information when operations fail
Shawn Walker <srw@sun.com>
parents: 1102
diff changeset
   720
                                        use_current_stack = False
7c34ba6e5e4f 9287 history can log wrong exception information when operations fail
Shawn Walker <srw@sun.com>
parents: 1102
diff changeset
   721
7c34ba6e5e4f 9287 history can log wrong exception information when operations fail
Shawn Walker <srw@sun.com>
parents: 1102
diff changeset
   722
                        if use_current_stack:
1032
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   723
                                # Assume the current stack is more useful if
1235
7c34ba6e5e4f 9287 history can log wrong exception information when operations fail
Shawn Walker <srw@sun.com>
parents: 1102
diff changeset
   724
                                # the error doesn't inherit from Exception or
7c34ba6e5e4f 9287 history can log wrong exception information when operations fail
Shawn Walker <srw@sun.com>
parents: 1102
diff changeset
   725
                                # we can't use the last exception's stack.
1032
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   726
                                out_stack = "".join(traceback.format_stack())
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   727
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   728
                                if error:
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   729
                                        # This may result in the text
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   730
                                        # of the error itself being written
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   731
                                        # twice, but that is necessary in case
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   732
                                        # it is not contained within the
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   733
                                        # output of format_exc().
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   734
                                        out_err = str(error)
1235
7c34ba6e5e4f 9287 history can log wrong exception information when operations fail
Shawn Walker <srw@sun.com>
parents: 1102
diff changeset
   735
                                        if not out_err or out_err == "None":
7c34ba6e5e4f 9287 history can log wrong exception information when operations fail
Shawn Walker <srw@sun.com>
parents: 1102
diff changeset
   736
                                                out_err = \
7c34ba6e5e4f 9287 history can log wrong exception information when operations fail
Shawn Walker <srw@sun.com>
parents: 1102
diff changeset
   737
                                                    error.__class__.__name__
1032
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   738
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   739
                                output = "".join([
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   740
                                    item for item in [out_stack, out_err]
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   741
                                    if item
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   742
                                ])
1235
7c34ba6e5e4f 9287 history can log wrong exception information when operations fail
Shawn Walker <srw@sun.com>
parents: 1102
diff changeset
   743
1032
ff3c6b09f430 8072 history load code needs to be more resilient against unexpected data format
Shawn Walker <srw@sun.com>
parents: 1027
diff changeset
   744
                        self.operation_errors.append(output.strip())
1027
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   745
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   746
        def create_snapshot(self):
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   747
                """Stores a snapshot of the current history and operation state
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   748
                information in memory so that it can be restored in the event of
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   749
                client failure (such as inability to store history information
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   750
                or the failure of a boot environment operation).  Each call to
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   751
                this function will overwrite the previous snapshot."""
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   752
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   753
                attrs = self.__snapshot = {}
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   754
                for attr in ("root_dir", "client_name", "client_version"):
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   755
                        attrs[attr] = getattr(self, attr)
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   756
                attrs["client_args"] = [copy.copy(a) for a in self.client_args]
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   757
                # A deepcopy has to be performed here since this a list of dicts
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   758
                # and not just History operation objects.
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   759
                attrs["__operations"] = \
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   760
                    [copy.deepcopy(o) for o in self.__operations]
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   761
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   762
        def discard_snapshot(self):
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   763
                """Discards the current history and operation state information
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   764
                snapshot."""
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   765
                self.__snapshot = None
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   766
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   767
        def restore_snapshot(self):
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   768
                """Restores the last snapshot taken of history and operation
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   769
                state information completely discarding the existing history and
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   770
                operation state information.  If nothing exists to restore, this
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   771
                this function will silently return."""
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   772
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   773
                if not self.__snapshot:
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   774
                        return
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   775
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   776
                for name, val in self.__snapshot.iteritems():
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   777
                        if not name.startswith("__"):
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   778
                                object.__setattr__(self, name, val)
e827313523d8 7774 image history discarded when bootenv operations fail or succeed
Shawn Walker <srw@sun.com>
parents: 1019
diff changeset
   779
                self.__operations = self.__snapshot["__operations"]