pkgplan.py revision 2470
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#!/usr/bin/python
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen# CDDL HEADER START
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen# The contents of this file are subject to the terms of the
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen# Common Development and Distribution License (the "License").
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen# You may not use this file except in compliance with the License.
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen# or http://www.opensolaris.org/os/licensing.
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen# See the License for the specific language governing permissions
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen# and limitations under the License.
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#
f16c114c20bbd7d292d93415d1e56c8dd6abd3e7Timo Sirainen# When distributing Covered Code, include this CDDL HEADER in each
f16c114c20bbd7d292d93415d1e56c8dd6abd3e7Timo Sirainen# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
f16c114c20bbd7d292d93415d1e56c8dd6abd3e7Timo Sirainen# If applicable, add the following below this CDDL HEADER, with the
f16c114c20bbd7d292d93415d1e56c8dd6abd3e7Timo Sirainen# fields enclosed by brackets "[]" replaced with your own identifying
f16c114c20bbd7d292d93415d1e56c8dd6abd3e7Timo Sirainen# information: Portions Copyright [yyyy] [name of copyright owner]
f16c114c20bbd7d292d93415d1e56c8dd6abd3e7Timo Sirainen#
f16c114c20bbd7d292d93415d1e56c8dd6abd3e7Timo Sirainen# CDDL HEADER END
f16c114c20bbd7d292d93415d1e56c8dd6abd3e7Timo Sirainen#
f16c114c20bbd7d292d93415d1e56c8dd6abd3e7Timo Sirainen
f16c114c20bbd7d292d93415d1e56c8dd6abd3e7Timo Sirainen#
f16c114c20bbd7d292d93415d1e56c8dd6abd3e7Timo Sirainen# Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
f16c114c20bbd7d292d93415d1e56c8dd6abd3e7Timo Sirainen#
f16c114c20bbd7d292d93415d1e56c8dd6abd3e7Timo Sirainen
f16c114c20bbd7d292d93415d1e56c8dd6abd3e7Timo Sirainenimport itertools
f16c114c20bbd7d292d93415d1e56c8dd6abd3e7Timo Sirainenimport cPickle as pickle
f16c114c20bbd7d292d93415d1e56c8dd6abd3e7Timo Sirainen
f16c114c20bbd7d292d93415d1e56c8dd6abd3e7Timo Sirainenfrom pkg.client import global_settings
f16c114c20bbd7d292d93415d1e56c8dd6abd3e7Timo Sirainenlogger = global_settings.logger
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenimport pkg.actions
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenimport pkg.actions.directory as directory
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainenimport pkg.client.api_errors as apx
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenimport pkg.manifest as manifest
98c1cf256927e254f0c092acd2ddcd7ea50bd009Timo Sirainenfrom pkg.misc import expanddirs, get_pkg_otw_size, EmptyI
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenimport os.path
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenclass PkgPlan(object):
98c1cf256927e254f0c092acd2ddcd7ea50bd009Timo Sirainen """A package plan takes two package FMRIs and an Image, and produces the
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen set of actions required to take the Image from the origin FMRI to the
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen destination FMRI.
98c1cf256927e254f0c092acd2ddcd7ea50bd009Timo Sirainen
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen If the destination FMRI is None, the package is removed.
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen """
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen __slots__ = [
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen "actions", "check_cancelation", "destination_fmri", "image",
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen "origin_fmri", "pkg_summary", "__destination_mfst",
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen "__license_status", "__origin_mfst", "__progtrack",
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen "__repair_actions", "__xferfiles", "__xfersize",
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen "_autofix_pkgs", "__executed"
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen ]
98c1cf256927e254f0c092acd2ddcd7ea50bd009Timo Sirainen
98c1cf256927e254f0c092acd2ddcd7ea50bd009Timo Sirainen def __init__(self, image, progtrack, check_cancelation):
f7d43647acc6dc80064c8c4cacf5bf86f754c530Timo Sirainen self.destination_fmri = None
98c1cf256927e254f0c092acd2ddcd7ea50bd009Timo Sirainen self.__destination_mfst = manifest.NullFactoredManifest
98c1cf256927e254f0c092acd2ddcd7ea50bd009Timo Sirainen
98c1cf256927e254f0c092acd2ddcd7ea50bd009Timo Sirainen self.origin_fmri = None
98c1cf256927e254f0c092acd2ddcd7ea50bd009Timo Sirainen self.__origin_mfst = manifest.NullFactoredManifest
98c1cf256927e254f0c092acd2ddcd7ea50bd009Timo Sirainen
02b79f9c2636da1829eee5b92753602bba8b67edTimo Sirainen self.actions = manifest.ManifestDifference([], [], [])
02b79f9c2636da1829eee5b92753602bba8b67edTimo Sirainen self.check_cancelation = check_cancelation
02b79f9c2636da1829eee5b92753602bba8b67edTimo Sirainen self.image = image
02b79f9c2636da1829eee5b92753602bba8b67edTimo Sirainen self.pkg_summary = None
02b79f9c2636da1829eee5b92753602bba8b67edTimo Sirainen
02b79f9c2636da1829eee5b92753602bba8b67edTimo Sirainen self.__executed = False
02b79f9c2636da1829eee5b92753602bba8b67edTimo Sirainen self.__license_status = {}
02b79f9c2636da1829eee5b92753602bba8b67edTimo Sirainen self.__progtrack = progtrack
02b79f9c2636da1829eee5b92753602bba8b67edTimo Sirainen self.__repair_actions = {}
02b79f9c2636da1829eee5b92753602bba8b67edTimo Sirainen self.__xferfiles = -1
02b79f9c2636da1829eee5b92753602bba8b67edTimo Sirainen self.__xfersize = -1
02b79f9c2636da1829eee5b92753602bba8b67edTimo Sirainen self._autofix_pkgs = []
659fe5d24825b160cae512538088020d97a60239Timo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen def __str__(self):
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen s = "%s -> %s\n" % (self.origin_fmri, self.destination_fmri)
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen for src, dest in itertools.chain(*self.actions):
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen s += " %s -> %s\n" % (src, dest)
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen return s
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen def __add_license(self, src, dest):
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen """Adds a license status entry for the given src and dest
445f9e31c6c3aa6c0a72be8565da8f6e594d24fbTimo Sirainen license actions.
445f9e31c6c3aa6c0a72be8565da8f6e594d24fbTimo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen 'src' should be None or the source action for a license.
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen 'dest' must be the destination action for a license."""
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen self.__license_status[dest.attrs["license"]] = {
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen "src": src,
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen "dest": dest,
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen "accepted": False,
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen "displayed": False,
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen }
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen @staticmethod
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen def __pickle_actions(actions):
9e59a1f3f095b3099478562cf3f3970a24736970Timo Sirainen """Return a list of pickled actions."""
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen action_list = []
178511b57faa7c3f8203dd8b7e4059d00cbfc23aTimo Sirainen for pair in actions:
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen newpair = [None, None]
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen if pair[0]:
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen newpair[0] = pickle.dumps(pair[0])
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen if pair[1]:
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen newpair[1] = pickle.dumps(pair[1])
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen action_list.append(newpair)
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen return action_list
4d25408732be27e91f0430f71e87242760c2517cTimo Sirainen
e68309fcfa2eaa88217fd51e7b4900fc9c20ef5dTimo Sirainen @staticmethod
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen def __unpickle_actions(pickled_actions):
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen """Return a list of unpickled actions."""
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen action_list = []
9e59a1f3f095b3099478562cf3f3970a24736970Timo Sirainen for pair in pickled_actions:
9e59a1f3f095b3099478562cf3f3970a24736970Timo Sirainen newpair = [None, None]
96c253a039f102fa78a313ee05200ab3970112dcTimo Sirainen if pair[0]:
e5c08648676d1989f6e70b95e5990c26b3e8b96bTimo Sirainen newpair[0] = pickle.loads(str(pair[0]))
4d25408732be27e91f0430f71e87242760c2517cTimo Sirainen if pair[1]:
c3412ddeb9abc13f99d3caf50faf76cd99f7e9d2Timo Sirainen newpair[1] = pickle.loads(str(pair[1]))
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen action_list.append(newpair)
268fe0fe3e748ae313e08b0918aa114815cf9d7cTimo Sirainen return action_list
268fe0fe3e748ae313e08b0918aa114815cf9d7cTimo Sirainen
268fe0fe3e748ae313e08b0918aa114815cf9d7cTimo Sirainen def setstate(self, state):
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen """Update the state of this object using the contents of
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen the supplied dictionary."""
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
02b79f9c2636da1829eee5b92753602bba8b67edTimo Sirainen import pkg.fmri
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
b9ac6179d3aee0d1641a4ee1d78da28628929c61Timo Sirainen # if there is no origin, don't allocate an fmri obj
9a06cabdfdf4d5e2f19a07e506c3c7d08a7e7038Timo Sirainen if state["src"]:
9a06cabdfdf4d5e2f19a07e506c3c7d08a7e7038Timo Sirainen state["src"] = pkg.fmri.PkgFmri(state["src"])
9a06cabdfdf4d5e2f19a07e506c3c7d08a7e7038Timo Sirainen
9a06cabdfdf4d5e2f19a07e506c3c7d08a7e7038Timo Sirainen # if there is no destination, don't allocate an fmri obj
e8a35266a5ceacdfafeeffd6bddae77931ff97ebTimo Sirainen if state["dst"]:
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen state["dst"] = pkg.fmri.PkgFmri(state["dst"])
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen self.origin_fmri = state["src"]
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen self.destination_fmri = state["dst"]
b3febb0933fdce10394d25093e23ce0a5aadddd3Timo Sirainen self.pkg_summary = state["summary"]
b3febb0933fdce10394d25093e23ce0a5aadddd3Timo Sirainen self.actions = manifest.ManifestDifference([], [], [])
b3febb0933fdce10394d25093e23ce0a5aadddd3Timo Sirainen self.actions.added.extend(
b3febb0933fdce10394d25093e23ce0a5aadddd3Timo Sirainen self.__unpickle_actions(state["add"]))
b3febb0933fdce10394d25093e23ce0a5aadddd3Timo Sirainen self.actions.changed.extend(
b3febb0933fdce10394d25093e23ce0a5aadddd3Timo Sirainen self.__unpickle_actions(state["change"]))
b3febb0933fdce10394d25093e23ce0a5aadddd3Timo Sirainen self.actions.removed.extend(
b3febb0933fdce10394d25093e23ce0a5aadddd3Timo Sirainen self.__unpickle_actions(state["remove"]))
b3febb0933fdce10394d25093e23ce0a5aadddd3Timo Sirainen for src, dest in itertools.chain(self.gen_update_actions(),
b3febb0933fdce10394d25093e23ce0a5aadddd3Timo Sirainen self.gen_install_actions()):
b3febb0933fdce10394d25093e23ce0a5aadddd3Timo Sirainen if dest.name == "license":
b3febb0933fdce10394d25093e23ce0a5aadddd3Timo Sirainen self.__add_license(src, dest)
b3febb0933fdce10394d25093e23ce0a5aadddd3Timo Sirainen
b3febb0933fdce10394d25093e23ce0a5aadddd3Timo Sirainen def getstate(self):
b3febb0933fdce10394d25093e23ce0a5aadddd3Timo Sirainen """Returns a dictionary containing the state of this object
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen so that it can be easily stored using JSON, pickle, etc."""
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen state = {}
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen state["src"] = self.origin_fmri
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen state["dst"] = self.destination_fmri
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen state["summary"] = self.pkg_summary
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen state["add"] = self.__pickle_actions(self.actions.added)
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen state["change"] = self.__pickle_actions(self.actions.changed)
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen state["remove"] = self.__pickle_actions(self.actions.removed)
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen return state
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen def propose(self, of, om, df, dm):
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen """Propose origin and dest fmri, manifest"""
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen self.origin_fmri = of
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen self.__origin_mfst = om
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen self.destination_fmri = df
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen self.__destination_mfst = dm
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
755fe6da51ab7f54aa1d86913cb344bffef60e79Timo Sirainen def propose_repair(self, fmri, mfst, install, remove, autofix=False):
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen self.propose(fmri, mfst, fmri, mfst)
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen # self.origin_fmri = None
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen # I'd like a cleaner solution than this; we need to actually
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen # construct a list of actions as things currently are rather
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen # than just re-applying the current set of actions.
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen #
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen # Create a list of (src, dst) pairs for the actions to send to
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen # execute_repair.
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen self.__repair_actions = {
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen # src is none for repairs.
36e2fa21c22452470c1509cc63de20f7415c7b5eTimo Sirainen "install": [(None, x) for x in install],
36e2fa21c22452470c1509cc63de20f7415c7b5eTimo Sirainen # dest is none for removals.
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen "remove": [(x, None) for x in remove],
36e2fa21c22452470c1509cc63de20f7415c7b5eTimo Sirainen }
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen if autofix:
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen self._autofix_pkgs.append(fmri)
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen def get_actions(self):
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen raise NotImplementedError()
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen def get_nactions(self):
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen return len(self.actions.added) + len(self.actions.changed) + \
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen len(self.actions.removed)
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen def update_pkg_set(self, fmri_set):
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen """ updates a set of installed fmris to reflect
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen proposed new state"""
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
b3febb0933fdce10394d25093e23ce0a5aadddd3Timo Sirainen if self.origin_fmri:
b3febb0933fdce10394d25093e23ce0a5aadddd3Timo Sirainen fmri_set.discard(self.origin_fmri)
b3febb0933fdce10394d25093e23ce0a5aadddd3Timo Sirainen
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen if self.destination_fmri:
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen fmri_set.add(self.destination_fmri)
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen def evaluate(self, old_excludes=EmptyI, new_excludes=EmptyI):
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen """Determine the actions required to transition the package."""
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen # If new actions are being installed, check the destination
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen # manifest for signatures.
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen if self.destination_fmri is not None:
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen try:
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen dest_pub = self.image.get_publisher(
db7c9201c88e3d9bee10485194ee5b0c67249916Timo Sirainen prefix=self.destination_fmri.publisher)
db7c9201c88e3d9bee10485194ee5b0c67249916Timo Sirainen except apx.UnknownPublisher:
db7c9201c88e3d9bee10485194ee5b0c67249916Timo Sirainen # Since user removed publisher, assume this is
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen # the same as if they had set signature-policy
db7c9201c88e3d9bee10485194ee5b0c67249916Timo Sirainen # ignore for the publisher.
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen sig_pol = None
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen else:
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen sig_pol = self.image.signature_policy.combine(
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen dest_pub.signature_policy)
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen sigs = list(self.__destination_mfst.gen_actions_by_type(
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen "signature", new_excludes))
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen if sig_pol and (sigs or sig_pol.name != "ignore"):
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen # Only perform signature verification logic if
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen # there are signatures or if signature-policy
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen # is not 'ignore'.
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen
a393d9d6dabdc46cf724f8cb004a652b4036d53dTimo Sirainen try:
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen sig_pol.process_signatures(sigs,
a393d9d6dabdc46cf724f8cb004a652b4036d53dTimo Sirainen self.__destination_mfst.gen_actions(),
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen dest_pub, self.image.trust_anchors,
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen self.image.cfg.get_policy(
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen "check-certificate-revocation"))
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen self.__destination_mfst.exclude_content(
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen new_excludes)
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen except apx.SigningException, e:
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen e.pfmri = self.destination_fmri
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen raise
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen self.actions = self.__destination_mfst.difference(
a393d9d6dabdc46cf724f8cb004a652b4036d53dTimo Sirainen self.__origin_mfst, old_excludes, new_excludes)
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen # figure out how many implicit directories disappear in this
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen # transition and add directory remove actions. These won't
9a06cabdfdf4d5e2f19a07e506c3c7d08a7e7038Timo Sirainen # do anything unless no pkgs reference that directory in
9a06cabdfdf4d5e2f19a07e506c3c7d08a7e7038Timo Sirainen # new state....
9a06cabdfdf4d5e2f19a07e506c3c7d08a7e7038Timo Sirainen
9a06cabdfdf4d5e2f19a07e506c3c7d08a7e7038Timo Sirainen # Retrieving origin_dirs first and then checking it for any
9a06cabdfdf4d5e2f19a07e506c3c7d08a7e7038Timo Sirainen # entries allows avoiding an unnecessary expanddirs for the
9a06cabdfdf4d5e2f19a07e506c3c7d08a7e7038Timo Sirainen # destination manifest when it isn't needed.
2ae575a66f2a302f047f6de062a70b75f8bebc7bTimo Sirainen origin_dirs = expanddirs(self.__origin_mfst.get_directories(
9a06cabdfdf4d5e2f19a07e506c3c7d08a7e7038Timo Sirainen old_excludes))
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen # No longer needed.
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainen self.__origin_mfst = None
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainen
484efa22e65c509f787dbbc892351146c726c257Timo Sirainen # Manifest.get_directories() returns implicit directories, which
9a06cabdfdf4d5e2f19a07e506c3c7d08a7e7038Timo Sirainen # means that this computation ends up re-adding all the explicit
9a06cabdfdf4d5e2f19a07e506c3c7d08a7e7038Timo Sirainen # directories getting removed to the removed list. This is
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen # ugly, but safe.
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen if origin_dirs:
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen absent_dirs = origin_dirs - \
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen expanddirs(self.__destination_mfst.get_directories(
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen new_excludes))
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen for a in absent_dirs:
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen self.actions.removed.append(
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen [directory.DirectoryAction(path=a), None])
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen # Stash information needed by legacy actions.
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen self.pkg_summary = \
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen self.__destination_mfst.get("pkg.summary",
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen self.__destination_mfst.get("description", "none provided"))
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen # No longer needed.
df4018ae2f0a95be602f724ca70df7e0e3bd6a7dTimo Sirainen self.__destination_mfst = None
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen # Add any install repair actions to the update list
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen self.actions.changed.extend(self.__repair_actions.get("install",
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen EmptyI))
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen self.actions.removed.extend(self.__repair_actions.get("remove",
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen EmptyI))
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen # No longer needed.
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen self.__repair_actions = None
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen for src, dest in itertools.chain(self.gen_update_actions(),
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen self.gen_install_actions()):
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen if dest.name == "license":
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen self.__add_license(src, dest)
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen if not src:
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen # Initial installs require acceptance.
f0f9c8e94abac18f8acd91b9e724c4c32863723aTimo Sirainen continue
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen src_ma = src.attrs.get("must-accept", False)
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen dest_ma = dest.attrs.get("must-accept", False)
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen if (dest_ma and src_ma) and \
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen src.hash == dest.hash:
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen # If src action required acceptance,
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen # then license was already accepted
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen # before, and if the hashes are the
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen # same for the license payload, then
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen # it doesn't need to be accepted again.
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen self.set_license_status(
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen dest.attrs["license"],
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen accepted=True)
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen def get_licenses(self):
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen """A generator function that yields tuples of the form (license,
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen entry). Where 'entry' is a dict containing the license status
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen information."""
4d25408732be27e91f0430f71e87242760c2517cTimo Sirainen
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen for lic, entry in self.__license_status.iteritems():
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen yield lic, entry
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
4d25408732be27e91f0430f71e87242760c2517cTimo Sirainen def set_license_status(self, plicense, accepted=None, displayed=None):
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen """Sets the license status for the given license entry.
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen 'plicense' should be the value of the license attribute for the
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen destination license action.
4d25408732be27e91f0430f71e87242760c2517cTimo Sirainen
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen 'accepted' is an optional parameter that can be one of three
4d25408732be27e91f0430f71e87242760c2517cTimo Sirainen values:
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen None leaves accepted status unchanged
4d25408732be27e91f0430f71e87242760c2517cTimo Sirainen False sets accepted status to False
4d25408732be27e91f0430f71e87242760c2517cTimo Sirainen True sets accepted status to True
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen 'displayed' is an optional parameter that can be one of three
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen values:
8af07808ba203f8709e2ff9eaf2291e1c4a4d53dTimo Sirainen None leaves displayed status unchanged
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen False sets displayed status to False
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen True sets displayed status to True"""
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen entry = self.__license_status[plicense]
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen if accepted is not None:
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen entry["accepted"] = accepted
33d63688ed8b26dc333e3c2edbfb2fe6e412604dTimo Sirainen if displayed is not None:
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen entry["displayed"] = displayed
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
33d63688ed8b26dc333e3c2edbfb2fe6e412604dTimo Sirainen def get_xferstats(self):
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen if self.__xfersize != -1:
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen return (self.__xferfiles, self.__xfersize)
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen self.__xfersize = 0
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen self.__xferfiles = 0
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen for src, dest in itertools.chain(*self.actions):
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen if dest and dest.needsdata(src, self):
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen self.__xfersize += get_pkg_otw_size(dest)
b9ac6179d3aee0d1641a4ee1d78da28628929c61Timo Sirainen self.__xferfiles += 1
b9ac6179d3aee0d1641a4ee1d78da28628929c61Timo Sirainen if dest.name == "signature":
b9ac6179d3aee0d1641a4ee1d78da28628929c61Timo Sirainen self.__xfersize += \
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen dest.get_action_chain_csize()
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen self.__xferfiles += \
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen len(dest.attrs.get("chain",
6e71799ee07bfd2289beae77c9bb5d7f1d30dccaTimo Sirainen "").split())
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen return (self.__xferfiles, self.__xfersize)
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen
7f3be7d885c75cdd77f536929a45bc9764595960Timo Sirainen def get_bytes_added(self):
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen """Return tuple of compressed bytes possibly downloaded
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen and number of bytes laid down; ignore removals
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen because they're usually pinned by snapshots"""
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen def sum_dest_size(a, b):
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen if b[1]:
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen return (a[0] + int(b[1].attrs.get("pkg.csize" ,0)),
77af8c68c416179e717fc2d551f72ec50b499c13Timo Sirainen a[1] + int(b[1].attrs.get("pkg.size", 0)))
77af8c68c416179e717fc2d551f72ec50b499c13Timo Sirainen return (a[0], a[1])
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen
77af8c68c416179e717fc2d551f72ec50b499c13Timo Sirainen return reduce(sum_dest_size, itertools.chain(*self.actions),
77af8c68c416179e717fc2d551f72ec50b499c13Timo Sirainen (0, 0))
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen def get_xfername(self):
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen if self.destination_fmri:
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen return self.destination_fmri.get_name()
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen if self.origin_fmri:
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen return self.origin_fmri.get_name()
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen return None
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen
e5ee67f18b03015c88b579c8c1f17ebe6ce19b76Timo Sirainen def preexecute(self):
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen """Perform actions required prior to installation or removal of
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen a package.
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen This method executes each action's preremove() or preinstall()
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen methods, as well as any package-wide steps that need to be taken
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen at such a time.
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen """
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen # Determine if license acceptance requirements have been met as
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen # early as possible.
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen errors = []
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen for lic, entry in self.get_licenses():
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen dest = entry["dest"]
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen if (dest.must_accept and not entry["accepted"]) or \
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen (dest.must_display and not entry["displayed"]):
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen errors.append(apx.LicenseAcceptanceError(
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen self.destination_fmri, **entry))
88553367d677170a4b703b9d52aac9eabf91c656Timo Sirainen
88553367d677170a4b703b9d52aac9eabf91c656Timo Sirainen if errors:
88553367d677170a4b703b9d52aac9eabf91c656Timo Sirainen raise apx.PkgLicenseErrors(errors)
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen for src, dest in itertools.chain(*self.actions):
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen if dest:
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen dest.preinstall(self, src)
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen else:
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen src.preremove(self)
3023fb352cbc2052b156f6d325c2629531a1b5b4Timo Sirainen
3023fb352cbc2052b156f6d325c2629531a1b5b4Timo Sirainen def download(self):
3023fb352cbc2052b156f6d325c2629531a1b5b4Timo Sirainen """Download data for any actions that need it."""
e8a35266a5ceacdfafeeffd6bddae77931ff97ebTimo Sirainen self.__progtrack.download_start_pkg(self.get_xfername())
e8a35266a5ceacdfafeeffd6bddae77931ff97ebTimo Sirainen mfile = self.image.transport.multi_file(self.destination_fmri,
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen self.__progtrack, self.check_cancelation)
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen if mfile is None:
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen self.__progtrack.download_end_pkg()
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen return
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen for src, dest in itertools.chain(*self.actions):
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen if dest and dest.needsdata(src, self):
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen mfile.add_action(dest)
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
e68309fcfa2eaa88217fd51e7b4900fc9c20ef5dTimo Sirainen mfile.wait_files()
e68309fcfa2eaa88217fd51e7b4900fc9c20ef5dTimo Sirainen self.__progtrack.download_end_pkg()
e68309fcfa2eaa88217fd51e7b4900fc9c20ef5dTimo Sirainen
e68309fcfa2eaa88217fd51e7b4900fc9c20ef5dTimo Sirainen def gen_install_actions(self):
e68309fcfa2eaa88217fd51e7b4900fc9c20ef5dTimo Sirainen for src, dest in self.actions.added:
e68309fcfa2eaa88217fd51e7b4900fc9c20ef5dTimo Sirainen yield src, dest
e68309fcfa2eaa88217fd51e7b4900fc9c20ef5dTimo Sirainen
4d25408732be27e91f0430f71e87242760c2517cTimo Sirainen def gen_removal_actions(self):
e68309fcfa2eaa88217fd51e7b4900fc9c20ef5dTimo Sirainen for src, dest in self.actions.removed:
4d25408732be27e91f0430f71e87242760c2517cTimo Sirainen yield src, dest
e68309fcfa2eaa88217fd51e7b4900fc9c20ef5dTimo Sirainen
e68309fcfa2eaa88217fd51e7b4900fc9c20ef5dTimo Sirainen def gen_update_actions(self):
e68309fcfa2eaa88217fd51e7b4900fc9c20ef5dTimo Sirainen for src, dest in self.actions.changed:
e68309fcfa2eaa88217fd51e7b4900fc9c20ef5dTimo Sirainen yield src, dest
e68309fcfa2eaa88217fd51e7b4900fc9c20ef5dTimo Sirainen
e68309fcfa2eaa88217fd51e7b4900fc9c20ef5dTimo Sirainen def execute_install(self, src, dest):
e68309fcfa2eaa88217fd51e7b4900fc9c20ef5dTimo Sirainen """ perform action for installation of package"""
e68309fcfa2eaa88217fd51e7b4900fc9c20ef5dTimo Sirainen self.__executed = True
e68309fcfa2eaa88217fd51e7b4900fc9c20ef5dTimo Sirainen try:
e68309fcfa2eaa88217fd51e7b4900fc9c20ef5dTimo Sirainen dest.install(self, src)
e68309fcfa2eaa88217fd51e7b4900fc9c20ef5dTimo Sirainen except (pkg.actions.ActionError, EnvironmentError):
e68309fcfa2eaa88217fd51e7b4900fc9c20ef5dTimo Sirainen # Don't log these as they're expected, and should be
e68309fcfa2eaa88217fd51e7b4900fc9c20ef5dTimo Sirainen # handled by the caller.
e68309fcfa2eaa88217fd51e7b4900fc9c20ef5dTimo Sirainen raise
e68309fcfa2eaa88217fd51e7b4900fc9c20ef5dTimo Sirainen except Exception, e:
e68309fcfa2eaa88217fd51e7b4900fc9c20ef5dTimo Sirainen logger.error("Action install failed for '%s' (%s):\n "
e68309fcfa2eaa88217fd51e7b4900fc9c20ef5dTimo Sirainen "%s: %s" % (dest.attrs.get(dest.key_attr, id(dest)),
e68309fcfa2eaa88217fd51e7b4900fc9c20ef5dTimo Sirainen self.destination_fmri.get_pkg_stem(),
e68309fcfa2eaa88217fd51e7b4900fc9c20ef5dTimo Sirainen e.__class__.__name__, e))
e68309fcfa2eaa88217fd51e7b4900fc9c20ef5dTimo Sirainen raise
064bfeee2f9156683b191cc0f3f7b242720942f7Timo Sirainen
e68309fcfa2eaa88217fd51e7b4900fc9c20ef5dTimo Sirainen def execute_update(self, src, dest):
e68309fcfa2eaa88217fd51e7b4900fc9c20ef5dTimo Sirainen """ handle action updates"""
e68309fcfa2eaa88217fd51e7b4900fc9c20ef5dTimo Sirainen self.__executed = True
e68309fcfa2eaa88217fd51e7b4900fc9c20ef5dTimo Sirainen try:
064bfeee2f9156683b191cc0f3f7b242720942f7Timo Sirainen dest.install(self, src)
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen except (pkg.actions.ActionError, EnvironmentError):
e68309fcfa2eaa88217fd51e7b4900fc9c20ef5dTimo Sirainen # Don't log these as they're expected, and should be
e68309fcfa2eaa88217fd51e7b4900fc9c20ef5dTimo Sirainen # handled by the caller.
e68309fcfa2eaa88217fd51e7b4900fc9c20ef5dTimo Sirainen raise
e68309fcfa2eaa88217fd51e7b4900fc9c20ef5dTimo Sirainen except Exception, e:
e68309fcfa2eaa88217fd51e7b4900fc9c20ef5dTimo Sirainen logger.error("Action upgrade failed for '%s' (%s):\n "
e68309fcfa2eaa88217fd51e7b4900fc9c20ef5dTimo Sirainen "%s: %s" % (dest.attrs.get(dest.key_attr, id(dest)),
e68309fcfa2eaa88217fd51e7b4900fc9c20ef5dTimo Sirainen self.destination_fmri.get_pkg_stem(),
8907d617ce7c4f390c0f42f6f694db2fecdd5775Timo Sirainen e.__class__.__name__, e))
01cbf4ac5d44137ab434791be7f838d98d0fcf3bTimo Sirainen raise
01cbf4ac5d44137ab434791be7f838d98d0fcf3bTimo Sirainen
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen def execute_removal(self, src, dest):
ab3c1eab9ca13916358a9e8b12df8212fefb7dbfTimo Sirainen """ handle action removals"""
99be58a447b69d62cbd9e764000a06226b9c9c89Timo Sirainen self.__executed = True
01cbf4ac5d44137ab434791be7f838d98d0fcf3bTimo Sirainen try:
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen src.remove(self)
3021a062b16ff0138408be6107d6bcd0ced280b9Timo Sirainen except (pkg.actions.ActionError, EnvironmentError):
e5c08648676d1989f6e70b95e5990c26b3e8b96bTimo Sirainen # Don't log these as they're expected, and should be
e5c08648676d1989f6e70b95e5990c26b3e8b96bTimo Sirainen # handled by the caller.
01cbf4ac5d44137ab434791be7f838d98d0fcf3bTimo Sirainen raise
3021a062b16ff0138408be6107d6bcd0ced280b9Timo Sirainen except Exception, e:
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen logger.error("Action removal failed for '%s' (%s):\n "
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen "%s: %s" % (src.attrs.get(src.key_attr, id(src)),
e5c08648676d1989f6e70b95e5990c26b3e8b96bTimo Sirainen self.origin_fmri.get_pkg_stem(),
e5c08648676d1989f6e70b95e5990c26b3e8b96bTimo Sirainen e.__class__.__name__, e))
ff640b54224881abbc21141f217c881d6ba5cd28Timo Sirainen raise
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen
6a19e109ee8c5a6f688da83a86a7f6abeb71abddTimo Sirainen def postexecute(self):
01cbf4ac5d44137ab434791be7f838d98d0fcf3bTimo Sirainen """Perform actions required after install or remove of a pkg.
01cbf4ac5d44137ab434791be7f838d98d0fcf3bTimo Sirainen
01cbf4ac5d44137ab434791be7f838d98d0fcf3bTimo Sirainen This method executes each action's postremove() or postinstall()
8907d617ce7c4f390c0f42f6f694db2fecdd5775Timo Sirainen methods, as well as any package-wide steps that need to be taken
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen at such a time.
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen """
4d25408732be27e91f0430f71e87242760c2517cTimo Sirainen # record that package states are consistent
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen for src, dest in itertools.chain(*self.actions):
4d25408732be27e91f0430f71e87242760c2517cTimo Sirainen if dest:
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen dest.postinstall(self, src)
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen else:
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen src.postremove(self)
1276e0340fe29495b6694dc7508f070cf6fca1cfTimo Sirainen
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen def salvage(self, path):
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen """Used to save unexpected files or directories found during
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen plan execution. Salvaged items are tracked in the imageplan.
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen """
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen assert self.__executed
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen spath = self.image.salvage(path)
b2ecd50bb98c44816cb07c17aa17fae2b425f941Timo Sirainen # get just the file path that was salvaged
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen fpath = path[len(self.image.get_root()) + 1:]
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen self.image.imageplan.salvaged.append((fpath, spath))
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen def salvage_from(self, local_path, full_destination):
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen """move unpackaged contents to specified destination"""
8fcff4c5b52f24d9c681805fdf06b486f1d0fcbeTimo Sirainen # remove leading / if present
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen if local_path.startswith(os.path.sep):
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen local_path = local_path[1:]
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen
b2ecd50bb98c44816cb07c17aa17fae2b425f941Timo Sirainen for fpath, spath in self.image.imageplan.salvaged[:]:
7fd72a47d7ddfbd38c8697e228b6951f495dfb61Timo Sirainen if fpath.startswith(local_path):
7fd72a47d7ddfbd38c8697e228b6951f495dfb61Timo Sirainen self.image.imageplan.salvaged.remove((fpath, spath))
7fd72a47d7ddfbd38c8697e228b6951f495dfb61Timo Sirainen break
7fd72a47d7ddfbd38c8697e228b6951f495dfb61Timo Sirainen else:
7fd72a47d7ddfbd38c8697e228b6951f495dfb61Timo Sirainen return
7fd72a47d7ddfbd38c8697e228b6951f495dfb61Timo Sirainen
7fd72a47d7ddfbd38c8697e228b6951f495dfb61Timo Sirainen self.image.recover(spath, full_destination)
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen