Example #1
0
    def __save(self):
        """Serializes the current history information and writes it to
                a file in self.path/{operation_start_time}-{sequence}.xml.
                """
        d = xmini.Document()
        d.appendChild(d.createElement("history"))
        self.__serialize_client_data(d)
        self.__serialize_operation_data(d)

        if not os.path.exists(self.path):
            try:
                # Only the right-most directory should be
                # created.  Assume that if the parent structure
                # does not exist, it shouldn't be created.
                os.mkdir(self.path, misc.PKG_DIR_MODE)
            except EnvironmentError as e:
                if e.errno not in (errno.EROFS, errno.EACCES, errno.ENOENT):
                    # Ignore read-only file system and
                    # access errors as it isn't critical
                    # to the image that this data is
                    # written.
                    raise apx.HistoryStoreException(e)
                # Return, since without the directory, the rest
                # of this will fail.
                return
            except KeyboardInterrupt:
                raise
            except Exception as e:
                raise apx.HistoryStoreException(e)

        # Repeatedly attempt to write the history (only if it's because
        # the file already exists).  This is necessary due to multiple
        # operations possibly occuring within the same second (but not
        # microsecond).
        pathname = self.pathname
        for i in range(1, 100):
            try:
                f = os.fdopen(
                    os.open(pathname, os.O_CREAT | os.O_EXCL | os.O_WRONLY,
                            misc.PKG_FILE_MODE), "w")
                d.writexml(f, encoding=sys.getdefaultencoding())
                f.close()
                return
            except EnvironmentError as e:
                if e.errno == errno.EEXIST:
                    name, ext = os.path.splitext(os.path.basename(pathname))
                    name = name.split("-", 1)[0]
                    # Pick the next name in our sequence
                    # and try again.
                    pathname = os.path.join(
                        self.path, "{0}-{1:>02d}{2}".format(name, i + 1, ext))
                    continue
                elif e.errno not in (errno.EROFS, errno.EACCES):
                    # Ignore read-only file system and
                    # access errors as it isn't critical
                    # to the image that this data is
                    # written.
                    raise apx.HistoryStoreException(e)
                # For all other failures, return, and avoid any
                # further attempts.
                return
            except KeyboardInterrupt:
                raise
            except Exception as e:
                raise apx.HistoryStoreException(e)
Example #2
0
    def __serialize_operation_data(self, d):
        """Internal function used to serialize current operation data
                using the supplied 'd' (xml.dom.minidom) object.
                """

        if self.operation_userid is None:
            raise apx.HistoryStoreException(
                "Unable to determine "
                "the id of the user that performed the current "
                "operation; unable to store history information.")
        elif self.operation_username is None:
            raise apx.HistoryStoreException(
                "Unable to determine "
                "the username of the user that performed the "
                "current operation; unable to store history "
                "information.")

        root = d.documentElement
        op = d.createElement("operation")
        op.setAttribute("name", self.operation_name)
        # Must explictly convert values to a string due to minidom bug
        # that causes a fatal whenever using types other than str.
        op.setAttribute("username", str(self.operation_username))
        op.setAttribute("userid", str(self.operation_userid))
        op.setAttribute("result", ", ".join(self.operation_result))
        op.setAttribute("start_time", self.operation_start_time)
        op.setAttribute("end_time", self.operation_end_time)

        if self.operation_be:
            op.setAttribute("be", self.operation_be)
        if self.operation_be_uuid:
            op.setAttribute("be_uuid", self.operation_be_uuid)
        if self.operation_new_be:
            op.setAttribute("new_be", self.operation_new_be)
        if self.operation_new_be_uuid:
            op.setAttribute("new_be_uuid", self.operation_new_be_uuid)
        if self.operation_snapshot:
            op.setAttribute("snapshot", self.operation_snapshot)
        if self.operation_release_notes:
            op.setAttribute("release-notes", self.operation_release_notes)

        root.appendChild(op)

        if self.operation_start_state:
            state = d.createElement("start_state")
            op.appendChild(state)
            state.appendChild(
                d.createCDATASection(str(self.operation_start_state)))

        if self.operation_end_state:
            state = d.createElement("end_state")
            op.appendChild(state)
            state.appendChild(
                d.createCDATASection(str(self.operation_end_state)))

        if self.operation_errors:
            errors = d.createElement("errors")
            op.appendChild(errors)

            for entry in self.operation_errors:
                error = d.createElement("error")
                errors.appendChild(error)
                error.appendChild(d.createCDATASection(str(entry)))