2339N/A# The contents of this file are subject to the terms of the 2339N/A# Common Development and Distribution License (the "License"). 2339N/A# You may not use this file except in compliance with the License. 2339N/A# See the License for the specific language governing permissions 2339N/A# and limitations under the License. 2339N/A# When distributing Covered Code, include this CDDL HEADER in each 2339N/A# If applicable, add the following below this CDDL HEADER, with the 2339N/A# fields enclosed by brackets "[]" replaced with your own identifying 2339N/A# information: Portions Copyright [yyyy] [name of copyright owner] 3339N/A# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved. 2339N/ALinked image module classes. 2339N/AThe following classes for manipulating linked images are defined here: 2339N/AThe following template classes which linked image plugins should inherit from 3234N/A# Redefining built-in 'reduce', 'zip'; pylint: disable=W0622 3455N/A# Imports from package six are not grouped: pylint: disable=C0412 2339N/A# linked image relationship types (returned by LinkedImage.list_related()) 2339N/A# properties that never get saved 2339N/A# special linked image name values (PROP_NAME) 2339N/A# linked image model values (PROP_MODEL) 2339N/A# files which contain linked image data 3020N/A# we define PATH_TRANSFORM_NONE as a tuple instead of just None because this 3464N/A# will prevent it from being accidentally serialized to json. 2690N/A """Sanity check a linked image operation return value tuple. 2690N/A The format of said tuple is: 2690N/A LinkedImageException exception (optional) 2690N/A json dictionary containing planned image changes 2690N/A # make sure we're using the LI_RVTuple class 2690N/A # any exception returned must be a LinkedImageException 2690N/A # if specified, p_dict must be a dictionary 2690N/A # some child return codes should never be associated with an exception 2690N/A # a p_dict can only be returned if the child returned EXIT_OK 2690N/A # return the value that was passed in 2690N/A """Given a linked image return value dictionary, sanity check all the 2690N/A (
"Unexpected rvdict key: ", k)
2690N/A # return the value that was passed in 2690N/A """Given a linked image return value dictionary, return a list of any 2690N/A exceptions that were encountered while processing children.""" 2690N/A """If an exception was encountered while operating on a linked 2690N/A child then raise that exception. If multiple exceptions were 2690N/A encountered while operating on multiple children, then bundle 2690N/A those exceptions together and raise them.""" 2690N/A # one exception encountered 2690N/A # multiple exceptions encountered 2339N/A """This class is a template that all linked image plugins should 2339N/A inherit from. Linked image plugins derived from this class are 2339N/A designed to manage linked aspects of the current image (vs managing 2339N/A linked aspects of a specific child of the current image). 2339N/A All the interfaces exported by this class and its descendants are 2339N/A private to the linked image subsystem and should not be called 2339N/A directly by any other subsystem.""" 2828N/A # Unused argument; pylint: disable=W0613 2339N/A """Initialize a linked image plugin. 2339N/A 'pname' is the name of the plugin class derived from this 2339N/A 'linked' is the LinkedImage object initializing this plugin. 2339N/A """Called when the path to the image that we're operating on 2339N/A is changing. This normally occurs when we clone an image 2339N/A after we've planned and prepared to do an operation.""" 2339N/A """If the linked image plugin is able to detect that we're 3020N/A operating on an image in an alternate root then return an 3020N/A transform that can be used to translate between the original 3020N/A image path and the current one.""" 2339N/A # return value: string or None 3020N/A """Return a list of the child images and paths associated with 3020N/A the current image. The paths that are returned should be 3020N/A absolute paths to the original child image locations.""" 2339N/A """Get the linked image properties associated with the 2339N/A """Attach the specified child image. This operation should 2339N/A only affect in-memory state of the current image. It should 2339N/A not update any persistent on-disk linked image state or access 2339N/A the child image in any way. This routine should assume that 2339N/A the linked image properties have already been validated.""" 2339N/A """Detach the specified child image. This operation should 2339N/A only affect in-memory state of the current image. It should 2339N/A not update any persistent on-disk linked image state or access 2339N/A the child image in any way.""" 2339N/A """Sync out the in-memory linked image state of this image to 2690N/A # return value: LI_RVTuple() 2339N/A """This class is a template that all linked image child plugins should 2339N/A inherit from. Linked image child plugins derived from this class are 2339N/A designed to manage linked aspects of children of the current image. 2339N/A (vs managing linked aspects of the current image itself). 2339N/A All the interfaces exported by this class and its descendants are 2339N/A private to the linked image subsystem and should not be called 2339N/A directly by any other subsystem.""" 2339N/A """Initialize a linked image child plugin. 2339N/A 'lic' is the LinkedImageChild object initializing this plugin. 2339N/A """Called before a parent image saves linked image properties 2339N/A into a child image. Gives the linked image child plugin a 2339N/A chance to update the properties that will be saved within the 2339N/A """A class for naming child linked images. Linked image names are 2339N/A used for all child images (and only child images), and they encode two 2339N/A pieces of information. The name of the plugin used to manage the 2339N/A image and a linked image name. Linked image names have the following 2339N/A format "<linked_image_plugin>:<linked_image_name>""" 2690N/A """Returns the serialized state of this object in a format 2690N/A that that can be easily stored using JSON, pickle, etc.""" 2828N/A # Unused argument; pylint: disable=W0613 2690N/A """Allocate a new object using previously serialized state 2690N/A obtained via getstate().""" 2828N/A # Unused argument; pylint: disable=W0613 2339N/A """A LinkedImage object is used to manage the linked image aspects of 2339N/A an image. This image could be a child image, a parent image, or both 2339N/A a parent and child. This object allows for access to linked image 2339N/A properties and also provides routines that allow operations to be 2339N/A performed on child images.""" 2339N/A # Properties that a parent image with push children should save locally. 2339N/A # Properties that a pull child image should save locally. 2339N/A # Properties that a parent image with push children should save in 2339N/A # make sure there is no invalid overlap 2339N/A """Initialize a new LinkedImage object.""" 2339N/A # variables reset by self.__update_props() 2690N/A # variables reset by self.__recursion_init() 2339N/A # variables reset by self._init_root() 2339N/A # initialize with no properties 2339N/A # initialize linked image plugin objects 2339N/A # if the image has a path setup, we can load data from it. 2339N/A """Get a pointer to the image object associated with this 2339N/A """Called during object initialization and by 2339N/A root location of the image. (The only time we change the root 2339N/A path is when changes BEs during operations which clone BEs. 2339N/A So when this happens most our metadata shouldn't actually 3020N/A # Check if this is our first time accessing the current image 3020N/A # or if we're just re-initializing ourselves. 2339N/A # figure out the new root image path 2339N/A # initialize paths for linked image data files 2339N/A # if this isn't a reset, then load data from the image 2925N/A # the first time around we load non-temporary data (if 2925N/A # there is any) so that we can audit ourselves and see 2925N/A # if we're in currently in sync. 2925N/A # now re-load all the data taking into account any 2925N/A # temporary new data associated with an in-progress 3020N/A # if we're not linked we're done 3020N/A # if this is a reset, update temporal properties 2339N/A # Tell linked image plugins about the updated paths 2828N/A # Unused variable 'plugin'; pylint: disable=W0612 2339N/A # Tell linked image children about the updated paths 2339N/A """Internal helper routine used when we want to update any 2339N/A linked image properties. This routine sanity check the 2339N/A new properties, updates them, and resets any cached state 2339N/A that is affected by property values.""" 2339N/A # all temporal properties must exist 3020N/A # PROP_CURRENT_PARENT_PATH can only be set if 3020N/A # we have PROP_PARENT_PATH. 2339N/A """Perform internal consistency checks for a set of linked 2339N/A image properties. Don't update any state.""" 2339N/A # if we're not a child image ourselves, then we're done 2339N/A # make sure PROP_MODEL was specified 2339N/A # validate the linked image name 2339N/A # make sure PROP_MODEL was specified 3020N/A """Given a new path_transform, update path properties.""" 3020N/A # Either 'path' or 'current_path' must be specified. 2339N/A """Given a set of linked image properties, the image paths 2339N/A stored within those properties may not match the actual image 2339N/A paths if we're executing within an alternate root environment. 3020N/A To deal with this situation we create temporal in-memory 3020N/A properties that represent the current path to the image, and a 3020N/A transform that allows us to translate between the current path 2339N/A """If we're initializing parent linked image properties for 2339N/A the first time (or if those properties somehow got deleted) 2339N/A then we need to know if the parent image that we're currently 2339N/A operating on is located within an alternate root. One way to 2339N/A do this is to ask our linked image plugins if they can 2339N/A determine this (the zones linked image plugin usually can 2339N/A if the image is a global zone).""" 2339N/A # ask each plugin if we're operating in an alternate root 3020N/A # no transform suggested by plugins 3020N/A # check for conflicting transforms 2828N/A # Unused variable; pylint: disable=W0612 3020N/A # we have a transform from our plugins 3020N/A # we have conflicting transforms, time to die 2339N/A """Fabricate the minimum set of properties required for a 3020N/A # ask our plugins if we're operating with alternate image paths 2339N/A """Load linked image properties from disk and return them to 2339N/A the caller. We sanity check the properties, but we don't 2339N/A update any internal linked image state. 2339N/A linked image metadata files, or if we should access temporary 2339N/A versions (which have ".<runid>" appended to them.""" 2339N/A # read the linked image properties from disk 2339N/A # make sure there are no saved temporal properties 2339N/A # convert PROP_NAME into a linked image name obj 2339N/A # sanity check our properties 2925N/A """Load linked image inherited facets from disk. 2339N/A Don't update any internal state. 2339N/A linked image metadata files, or if we should access temporary 2339N/A versions (which have ".<runid>" appended to them.""" 2925N/A # W0212 Access to a protected member 2925N/A """Load linked image parent packages from disk. 2925N/A Don't update any internal state. 2925N/A linked image metadata files, or if we should access temporary 2925N/A versions (which have ".<runid>" appended to them.""" 2339N/A """Load linked image parent publishers from disk. 2339N/A Don't update any internal state. 2339N/A linked image metadata files, or if we should access temporary 2339N/A versions (which have ".<runid>" appended to them.""" 2339N/A """Load linked image properties and constraints from disk. 2339N/A Update the linked image internal state with the loaded data.""" 2444N/A # Normally, if we're a parent image we'll have linked image 2444N/A # properties stored on disk. So load those now. 2444N/A # If no properties are loaded, we may still be a parent image 2444N/A # that is just missing it's metadata. (oops.) We attempt to 2444N/A # detect this situation by invoking __isparent(), which will 2444N/A # ask each child if there are any children. This is a best 2444N/A # effort attempt, so when we do this we ignore any plugin 2444N/A # runtime errors since we really want Image object 2444N/A # initialization to succeed. If we don't have any linked 2444N/A # image metadata, and we're having runtime errors querying for 2444N/A # children, then we'll allow initialization here, but any 2444N/A # subsequent operation that tries to access children will fail 2444N/A # and the caller will have to specify that they want to ignore 2444N/A # all children to allow the operation to succeed. 2444N/A # Oops. We're a parent image with no properties 2444N/A # stored on disk. Rather than throwing an exception 2444N/A # try to fabricate up some props with reasonably 2444N/A # guessed values which the user can subsequently 2925N/A # load parent packages. if parent package data is missing just 2925N/A # continue along and hope for the best. 2925N/A # load inherited facets. if inherited facet data is missing 2925N/A # just continue along and hope for the best. 2339N/A # load parent publisher data. if publisher data is missing 2339N/A # continue along and we'll just skip the publisher checks, 2339N/A # it's better than failing and preventing any image updates. 2339N/A """Verify property value for PROP_RECURSE.""" 2339N/A """Validate user supplied linked image attach properties. 2339N/A Don't update any internal state.""" 2339N/A # make sure that only attach time options have been 2339N/A # specified, and that they have allowed values. 2339N/A # check each property the user specified. 2339N/A # did the user specify an allowable property? 2339N/A # did the user specify a valid property value? 2339N/A # is this property valid for this type of image? 2339N/A """Initialize an Image object which can be used to access a 2339N/A """If our in-memory linked image state matches the on-disk 2339N/A linked image state then there's nothing to do. If the state 2339N/A differs then there is stuff to do since the new state needs 2925N/A # check if we're not a linked image. 2925N/A # if any linked image metadata files exist they need 2339N/A # compare in-memory and on-disk properties 2925N/A # linked image metadata files with inherited data 2925N/A # check if we're just a parent image. 2925N/A # parent images only have properties. if any linked 2925N/A # image metadata files that contain inherited 2925N/A # information exist they need to be deleted. 2925N/A # if we're missing any metadata files then there's work todo 2925N/A # compare in-memory and on-disk inherited facets 2925N/A # compare in-memory and on-disk parent packages 2339N/A # compare in-memory and on-disk parent publishers 2339N/A """If we're a child image's, verify that the parent image 2339N/A publisher configuration is a subset of the child images 2339N/A publisher configuration. This means that all publishers 2339N/A configured within the parent image must also be configured 2339N/A within the child image with the same: 2339N/A - sticky and disabled settings 2339N/A The child image may have additional publishers configured but 2339N/A they must all be lower ranked than the parent's publishers. 2339N/A # if we're not a child image then bail 2339N/A # if we're using the sysrepo then don't bother 2339N/A # parent publisher data is missing, press on and hope 2339N/A # child image needs at least as many publishers as the parent 2339N/A # check rank, sticky, and disabled settings 2339N/A """Update linked image constraint, publisher data, and 2339N/A state from our parent image.""" 2339N/A # we're not a child image, nothing to do 2339N/A # parent pushes data to us, nothing to do 2690N/A # initialize the parent image 2925N/A # get metadata from our parent image 2925N/A """Update linked image constraint, publisher data, and state 2925N/A from our parent image. If catch_exception is true catch any 2925N/A linked image exceptions and pack them up in a linked image 2339N/A """Write in-memory linked image state to disk.""" 2339N/A # create a list of metadata file paths 2339N/A # cleanup any temporary files 2339N/A # we're no longer linked; delete metadata 3020N/A # save our properties, but first remove any temporal properties 2925N/A # if we're not a child we don't have parent data 2339N/A # we're a child so save our latest constraints 2339N/A """If the current image is a child image, this function 2339N/A returns a linked image name object which represents the name 2339N/A """Indicates whether the current image is a child image.""" 2444N/A """Indicates whether the current image is a parent image. 2444N/A 'ignore_plugin_errors' ignore plugin runtime errors when 2444N/A trying to determine if we're a parent image. 2339N/A """Indicates whether the current image is a parent image.""" 3020N/A """Indicates wether the current image is already linked.""" 3020N/A """Return the current path transform property.""" 3020N/A """Check if we're accessing a linked image at an alternate 3020N/A """Report our current image path.""" 3020N/A """Report our current image path.""" 3020N/A """If we know where our parent should be, report it's expected 2339N/A """Return a dictionary which represents the linked image 2339N/A properties associated with a linked image. 2339N/A 'lin' is the name of the child image. If lin is None then 2339N/A the current image is assumed to be a linked image and it's 2339N/A Always returns a copy of the properties in case the caller 2339N/A # If we're not linked we'll return an empty 2339N/A # make sure the specified child exists 2339N/A # make a copy of the props in case they are updated 2339N/A """Raise an exception because the current image is not a child 2339N/A """Check if a specific child image exists.""" 2690N/A """Given a list of linked image name objects, make sure all 2925N/A """Facets inherited from our parent image.""" 2339N/A """A set of the fmris installed in our parent image.""" 2339N/A # We return None since frozenset() would indicate 2339N/A # that there are no packages installed in the parent 2339N/A """Given a string representing a linked image child name, 2339N/A returns linked image name object representing the same name. 2339N/A 'allow_unknown' indicates whether the name must represent 2339N/A actual children or simply be syntactically correct.""" 2339N/A """Returns a list of linked child images associated with the 2339N/A 'li_ignore' see list_related() for a description. 2339N/A The returned value is a list of tuples where each tuple 2339N/A contains (<li name>, <li path>).""" 2339N/A # sort by linked image name 2339N/A # don't ignore any children 2339N/A """Returns a list of linked images associated with the 2339N/A current image. This includes both child and parent images. 2339N/A 'li_ignore' is either None or a list. If it's None (the 2339N/A default), all children will be listed. If it's an empty list 2339N/A no children will be listed. Otherwise, any children listed 2339N/A in li_ignore will be ommited from the results. 2339N/A The returned value is a list of tuples where each tuple 2339N/A contains (<li name>, <relationship>, <li path>).""" 2339N/A # we're linked so append ourself to the list 2339N/A # if we have a path to our parent then append that as well. 2339N/A # sort by linked image name 2339N/A """We only update in-memory state; nothing is written to 2339N/A disk, to sync linked image state to disk call syncmd.""" 2339N/A # Path must be an absolute path. 2339N/A # we don't bother to cleanup the path to the parent image here 2339N/A # because when we allocate an Image object for the parent 2339N/A # image, it will do that work for us. 2339N/A # get the cleaned up parent image path. 3020N/A # Make sure our parent image is at it's default path. (We 3020N/A # don't allow attaching new images if an image is located at 3020N/A # make a copy of the properties and update them 2339N/A # If we're in an alternate root, the parent must also be within 3020N/A # Set path related properties. We use self.__root in place of 3020N/A # current_path() since we may not actually be linked yet. 2339N/A # this prop doesn't apply to pull images 2339N/A """We only update in memory state; nothing is written to 2339N/A disk, to sync linked image state to disk call syncmd.""" 2339N/A # Generate a new set of linked image properties. If we have 2339N/A # no children then we don't need any more properties. 2339N/A # If we have children we'll need to keep some properties. 2339N/A # Update our linked image properties. 2339N/A """Determine if an image is in sync with its constraints.""" 2339N/A # get parent dependencies from the catalog 2339N/A # create a dictionary of packages installed in the parent 2339N/A """If the current image is a child image, this function 2339N/A audits the current image to see if it's in sync with its 2925N/A # we don't use the latest linked image metadata. 2925N/A # instead return cached insync value which was 2925N/A # computed using the initial linked image metadata 2925N/A # that we loaded from disk. 2925N/A """A convenience wrapper for audit_self(). Note that we 2925N/A consider non-child images as always in sync and ignore 2339N/A """Internal helper function that takes a dictionary returned 2339N/A from an operations on multiple children and merges the results 2339N/A into a single return code.""" 2339N/A # keep track of all the return values that are mapped 2339N/A # the mappings better have included pkgdefs.EXIT_OK 2339N/A # if we had errors for unmapped return values, bundle them up 2339N/A # we have one consistent return value 2339N/A """Convenience function that takes a dictionary returned from 2339N/A an operations on multiple children and merges the results into 2339N/A """Convenience function that takes a dictionary returned from 2339N/A an operations on multiple children and merges the results into 2339N/A """Convenience function that takes a dictionary returned from 2339N/A an operations on multiple children and merges the results into 2339N/A """Sanity check the parameters associated with a child image 2339N/A that we are trying to attach.""" 2339N/A # check the name to make sure it doesn't already exist 2339N/A # Path must be an absolute path. 2339N/A # If we're in an alternate root, the child must also be within 2339N/A # Does the parent image (ourselves) reside in clonable BE? 2828N/A # Unused variable 'be_uuid'; pylint: disable=W0612 2339N/A # If the parent image is clonable then the new child image 2339N/A # must be nested within the parents filesystem namespace. 2339N/A # Child image should not already be linked 2339N/A # W0212 Access to a protected member 3020N/A """Make sure there are no additional images in between the 3020N/A parent and the child. For example, this prevents linking of 3020N/A images if one of the images is nested within another unrelated 3020N/A image. This is done by looking at all the parent directories 3020N/A for both the parent and the child image until we reach a 3020N/A # Make sure each path has a trailing '/'. 3020N/A # Make sure we're not linking to ourselves. 3020N/A # The parent image can't be nested nested within child. 3020N/A # Make sure we're not linking the root image as a child. 3020N/A # Make sure our current image is at it's default path. (We 3020N/A # don't allow attaching new images if an image is located at 3020N/A """Raise an exception if directory 'd' contains an 3020N/A # W0212 Access to a protected member 3020N/A # Find the common parent directory of the both parent and the 3020N/A # First check the parent directories of the child. 3020N/A # Then check the parent directories of the parent. 2339N/A """Attach an image as a child to the current image (the 2339N/A current image will become a parent image. This operation 2339N/A results in attempting to sync the child image with the parent 2444N/A For descriptions of parameters please see the descriptions in 2339N/A # Path must be an absolute path. 2339N/A # if the current image isn't linked yet then we need to 2339N/A # generate some linked image properties for ourselves 2339N/A # make a copy of the options and start updating them 3020N/A # set path related properties 2339N/A # fill in any missing defaults options 2339N/A # attach the child in memory 2339N/A # we've validated parameters, nothing else to do 2690N/A # commit child image property updates 2339N/A # save parent image properties 2690N/A # The recursive child operation may have returned NOP, but 2690N/A # since we always update our own image metadata, we always 2339N/A """Audit one or more children of the current image to see if 2339N/A they are in sync with this image.""" 2339N/A """Sync one or more children of the current image.""" 2339N/A """Detach one or more children from the current image. This 2339N/A operation results in the removal of any constraint package 2690N/A # check if we support detach for these children. we don't use 2690N/A # iteritems() when walking lic_dict because we might modify 2690N/A # we can't detach this type of image. 2690N/A # if any of the children successfully detached, then we want 2690N/A # to discard our metadata for that child. 2339N/A # if the detach failed leave metadata in parent 2339N/A # detach the child in memory 2690N/A # commit child image property updates 2690N/A # don't overwrite previous errors 2339N/A # we're not linked anymore, so delete all our linked 3025N/A """Wrapper for __children_op_vec() to stay compatible with old 3025N/A callers which only support one operation for all linked images. 2690N/A '_pkg_op' is the pkg.1 operation that we're going to perform 2690N/A '_lic_list' is a list of linked image child objects to perform 3025N/A '_ignore_syncmd_nop' a boolean that indicates if we should 3025N/A always recurse into a child even if the linked image meta data 3025N/A See __children_op_vec() for an explanation of the remaining 3025N/A """An iterator function which performs a linked image 3025N/A operation on multiple children in parallel. 3025N/A '_lic_op_vectors' is a list of tuples containing the operation 3025N/A to perform, the list of linked images the operation is to be 3025N/A performed on, the kwargs for this operation and if the metadata 3025N/A sync nop should be ignored in the following form: 3025N/A [(pkg_op, lin_list, kwargs, ignore_syncmd_nop), ...] 2690N/A '_rvdict' is a dictionary, indexed by linked image name, which 2690N/A contains rvtuples of the result of the operation for each 2690N/A '_prograck' is a ProgressTracker pointer. 2690N/A '_failfast' is a boolean. If True and we encounter a failure 2690N/A operating on a child then we raise an exception immediately. 2690N/A If False then we'll attempt to perform the operation on all 2690N/A children and rvdict will contain a LI_RVTuple result for all 2690N/A '_expect_plan' is a boolean that indicates if we expect this 2690N/A operation to generate an image plan. 2925N/A '_syncmd_tmp' a boolean that indicates if we should write 2925N/A linked image metadata in a temporary location in child images, 2925N/A or just overwrite any existing data. 2690N/A '_pd' a PlanDescription pointer.""" 3025N/A # make sure we don't have any duplicate LICs or duplicate LINs 3025N/A # At the moment the PT doesn't seem to really use the operation 3025N/A # type for display reasons. It only uses it to treat pubcheck 3025N/A # differently. Therefore it should be sufficient to skip the 3025N/A # operation type in case we have different operations going on 3025N/A # Additionally, if the operation is the same for all children 3025N/A # we can use some optimizations. 3025N/A # These operations are cheap so ideally we'd 3025N/A # like to use full parallelism. But if the user 3025N/A # specified a concurrency limit we should 3025N/A # No limit was specified, use full 2925N/A # If we have a plan for the current image that means linked 2925N/A # image metadata is probably changing so we always save it to 2925N/A # a temporary file (and we don't overwrite the existing 2925N/A # metadata until after we execute the plan). 3025N/A # get parent metadata common to all child images 3025N/A # setup operation for each child 2690N/A # if _failfast is true, then throw an exception if we failed 2690N/A # to setup any of the children. if _failfast is false we'll 2690N/A # continue to perform the operation on any children that 2690N/A # successfully initialized and we'll report setup errors along 2690N/A # with the final results for all children. 2690N/A # before we raise an exception we need to cleanup any 2690N/A """An iterator function invoked when a child has 2690N/A 'lic' is the child that has finished execution. 2690N/A 'lic_list' a list of children to remove 'lic' from. 2690N/A See __children_op() for an explanation of the other 2690N/A # check if we should raise an exception 2690N/A # we're going to raise an exception. abort 2690N/A # only display child output if there was no 2690N/A # error (otherwise the exception includes the 2690N/A # output so we'll display it twice.) 2690N/A # check if we should yield a plan. 2690N/A # check if we did everything we needed to do during child 2690N/A # setup. (this can happen if we're just doing an implicit 2690N/A # syncmd during setup we discover the linked image metadata 2690N/A # isn't changing.) we iterate over a copy of lic_setup to 2690N/A # allow __child_op_finish() to remove elements from lic_setup 2690N/A # while we're walking through it. 2690N/A # keep track of currently running children 2690N/A # keep going as long as there are children to process 2690N/A # start processing on a child 2690N/A # display progress on children 2896N/A # poll on all the linked image children and see which 2896N/A # ones have pending output. 2690N/A # a child finished processing 2690N/A """Initialize LinkedImageChild objects for children specified 2690N/A in 'lin_list'. If 'lin_list' is not specified, then 2690N/A initialize objects for all children (excluding any being 2690N/A ignored via 'li_ignore').""" 2690N/A # you can't specify children to operate on and children to be 2690N/A # if no children we listed, build a list of children 2690N/A """Initialize child objects used during recursive packaging 2690N/A """Initialize planning state. If we're a child image we save 2690N/A our current state (which may reflect a planned state that we 2690N/A have not committed to disk) into the plan. We also initialize 2690N/A all our children to prepare to recurse into them.""" 2690N/A # if we have any children we don't support operations using 2690N/A """Do a recursive publisher check""" 2690N/A # get a list of of children to recurse into. 2690N/A # do a publisher check on all of them 2690N/A # raise an exception if one or more children failed the 2690N/A """This is an iterator function. It recurses into linked 2690N/A image children to perform the specified operation. 2690N/A # get a pointer to the current image plan 2690N/A # get a list of of children to recurse into. 2690N/A # if we're ignoring all children then we can't be recursing 2690N/A # sanity check the plan description state 2690N/A # the state should be uninitialized 2690N/A # if we ignored all children, we better not have 2690N/A # recursed into any children. 3464N/A # there shouldn't be any overlap between sets of 2690N/A # make sure set of child handles matches the set of 2690N/A # previously planned children. 2690N/A # if we're in the planning stage, we should pass the current 2690N/A # image plan onto the child and also expect an image plan from 3025N/A # Assemble list of LICs from LINs in pd.child_op_vectors and 3025N/A # create new lic_op_vectors to pass to __children_op_vec(). 3025N/A # For the prepare and execute phase we 3025N/A # remove children for which there is 3025N/A # nothing to do from self.__lic_dict. 3025N/A # So ignore those we can't find. 2690N/A # check for children that don't need any updates 2690N/A # record the children that are done planning 2690N/A """Determine what pkg command to use when recursing into child 2401N/A # given the api operation being performed on the current 2401N/A # image, figure out what api operation should be performed on 2401N/A # the recursion policy which hard coded here is that if we do 2401N/A # an pkg update in the parent image without any packages 2401N/A # specified (ie, we want to update everything) then when we 2401N/A # recurse we'll also do an update of everything. but if we're 2401N/A # doing any other operation like install, uninstall, an update 2401N/A # of specific packages, etc, then when we recurse we'll do a 3025N/A # To improve performance we assume the child is already in sync, 3025N/A # so if its linked image metadata isn't changing then the child 3025N/A # won't need any updates so there will be no need to recurse 3464N/A # If we are doing an explicit sync, we do have to make 3025N/A # sure we actually recurse into the child and sync 2690N/A """Determine what pkg command arguments to use when recursing 2690N/A # when we recurse we always accept all new licenses (for now). 2690N/A # ultimately (when start yielding back plan descriptions for 2690N/A # children) in addition to accepting licenses on the plan for 2690N/A # the current image the api client will also have to 2690N/A # explicitly accept licenses for all child images. but until 2690N/A # that happens we'll just assume that the parent image license 2690N/A # space is a superset of the child image license space (and 2690N/A # since the api consumer must accept licenses in the parent 2690N/A # before we'll do anything, we'll assume licenses in the child 2690N/A # option specific to: attach, set-property-linked, sync 3025N/A # option specific to: install 3025N/A # option specific to: change-variant 3025N/A # option specific to: change-facet 3025N/A # option specific to: uninstall 2690N/A # skip ipkg up to date check for child images 2690N/A """Plan child image updates.""" 3025N/A # Get LinkedImageNames of all children 3025N/A # Prepare op vector for explicit recurse operations 3025N/A # remove recurse children from sync list 3025N/A # Prepare op vector for implicit recurse operations 2690N/A """Prepare child image updates.""" 2690N/A """Execute child image updates.""" 2690N/A """Initialize our state in the PlanDescription.""" 2690N/A # if we're a child, save our parent package state into the 2690N/A """Reload a previously created plan.""" 3020N/A # make a copy of the linked image properties 3020N/A # generate temporal properties 2690N/A # load linked image state from the plan 2690N/A # now initialize our recursion state, this involves allocating 2690N/A # handles to operate on children. we don't need handles for 2690N/A # children that were either ignored during planning, or which 2690N/A # return EXIT_NOP after planning (since these children don't 2690N/A # merge the children that returned nop into li_ignore (since 2690N/A # we don't need to recurse into them). if li_ignore is [], 2690N/A # then we ignored all children during planning 2690N/A # no children were ignored during planning 2339N/A """Return True if there is no planned work to do on child 2339N/A """A LinkedImageChild object is used when a parent image wants to 2339N/A access a child image. These accesses may include things like: 2339N/A auditing a child image, or recursing into a child image to keep it in 2339N/A sync with planned changes in the parent image.""" 2339N/A # initialize paths for linked image data files 2339N/A # initialize a linked image child plugin 3025N/A """Get the name associated with a child image.""" 2339N/A """Get the path associated with a child image.""" 2339N/A """Get a pointer to the parent image object associated with 2339N/A """Write data to a child image.""" 3020N/A # first save our data to a temporary file 3020N/A # Check if the data is changing. To do this 3020N/A # comparison we load the serialized on-disk json data 3020N/A # into memory because there are no guarantees about 3020N/A # data ordering during serialization. When loading 3020N/A # the data we don't bother decoding it into objects. 3339N/A # We regard every combination of the same 3339N/A # elements in a list being the same data, for 3339N/A # example, ["a", "b"] equals ["b", "a"], so we 3339N/A # need to sort the list first before comparison 3339N/A # because ["a", "b"] != ["b", "a"] in Python. 3020N/A # If we're not actually updating any data, or if we 3020N/A # were just doing a test to see if the data has 3020N/A # changed, then delete the temporary data file. 2339N/A """Sync linked image parent constraint data to a child image. 2339N/A linked image metadata files, or if we should access temporary 2339N/A versions (which have ".<runid>" appended to them.""" 2925N/A # save the planned parent packages 2925N/A """Sync linked image parent facet data to a child image. 2925N/A linked image metadata files, or if we should access temporary 2925N/A versions (which have ".<runid>" appended to them.""" 2925N/A # save the planned parent facets 2339N/A """Sync linked image properties data to a child image. 2339N/A linked image metadata files, or if we should access temporary 2339N/A versions (which have ".<runid>" appended to them.""" 2339N/A # make a copy of the props we want to push 2339N/A # delete temporal properties 2339N/A """Sync linked image parent publisher data to a child image. 2339N/A linked image metadata files, or if we should access temporary 2339N/A versions (which have ".<runid>" appended to them.""" 2339N/A """Sync linked image data to a child image. 2339N/A linked image metadata files, or if we should access temporary 2339N/A versions (which have ".<runid>" appended to them.""" 2925N/A # unpack parent metadata tuple 2690N/A """Prepare to perform an operation on a child image by syncing 2690N/A the latest linked image data to that image. As part of this 2690N/A operation, if we discover that the meta data hasn't changed we 2690N/A may report back that there is nothing to do (EXIT_NOP). 2925N/A 'pmd' is a tuple that contains parent metadata that we will 2925N/A sync to the child image. Note this is not all the metadata 2925N/A that we will sync, just the set which is common to all 2690N/A 'ignore_syncmd_nop' a boolean that indicates if we should 2690N/A always recurse into a child even if the linked image meta data 2690N/A 'tmp' a boolean that indicates if we should save the child 2690N/A image meta data into temporary files (instead of overwriting 2690N/A the persistent meta data files). 2690N/A 'test' a boolean that indicates we shouldn't save any child 2690N/A image meta data, instead we should just test to see if the 2690N/A 'stage' indicates which stage of execution we should be 2690N/A performing on a child image.""" 2925N/A # we don't update metadata during all stages of operation 2690N/A # we successfully updated the metadata 2690N/A # if the metadata changed then report success 2690N/A # the metadata didn't change, so this operation is a NOP 2690N/A """Prepare to sync a child image. This involves updating the 2690N/A linked image metadata in the child and then possibly recursing 2690N/A into the child to actually update packages. 2444N/A For descriptions of parameters please see the descriptions in 2339N/A # we're not going to recurse into the child image, 2339N/A # we're just going to update its metadata. 2690N/A # we don't support updating packages in the parent 2690N/A # during attach metadata only sync. 2690N/A # if we're doing this sync as part of an attach, then 2690N/A # temporarily sync the metadata since we don't know yet if the 2690N/A # attach will succeed. if the attach doesn't succeed this 2690N/A # means we don't have to delete any metadata. if the attach 2690N/A # succeeds the child will make the temporary metadata 2690N/A # permanent as part of the commit. 2690N/A # we don't support updating packages in the parent 2690N/A # the update failed or the metadata didn't change 2690N/A """Prepare to update a child image.""" 2690N/A # the update failed or the metadata didn't change 3025N/A # We need to make sure we don't pass None as pargs in 3025N/A """Prepare to install a pkg in a child image.""" 3025N/A # the update failed or the metadata didn't change 3025N/A """Prepare to install a pkg in a child image.""" 3025N/A # the update failed or the metadata didn't change 3025N/A """Prepare to install a pkg in a child image.""" 3025N/A # the update failed or the metadata didn't change 3025N/A # need to transform varcets back to string list 2690N/A """Prepare to detach a child image.""" 2690N/A """Prepare to a check if a child's publishers are in sync.""" 2925N/A # a pubcheck should never update persistent meta data 2690N/A # setup recursion into the child image 2690N/A """Prepare to a child image to see if it's in sync with its 2690N/A # setup recursion into the child image 2690N/A """Public interface to abort an operation on a child image.""" 2690N/A """Public interface to setup an operation that we'd like to 2690N/A perform on a child image.""" 2690N/A """Public interface to start an operation on a child image.""" 2690N/A # if we have a return value this operation is done 2690N/A """Public interface to query if an operation on a child image 2690N/A # if we have a return value this operation is done 2690N/A # make sure there is some data from the child 2690N/A """Public interface to get the result of an operation on a 2690N/A 'expect_plan' boolean indicating if the child is performing a 2690N/A planning operation. this is needed because if we're running 2690N/A in parsable output mode then the child will emit a parsable 2690N/A json version of the plan on stdout, and we'll verify it by 2690N/A running it through the json parser. 3025N/A # The child op is now done, so we reset __child_op to make sure 3025N/A # we don't accidentally reuse the LIC without properly setting 3025N/A # it up again. However, we still need the op type in this 3025N/A # function so we make a copy. 2690N/A # if we have a return value this operation is done 2690N/A # make sure we're not going to block 2690N/A # if we got an exception, or a return value other than OK or 2690N/A # NOP, then return an exception. 2690N/A # If a plan was created and we're in parsable output mode then 2690N/A # parse the plan that should have been displayed to stdout. 2690N/A # JSON raises a subclass of ValueError when it 2690N/A """Return the progress pipe associated with the PkgRemote 2690N/A instance that is operating on a child image.""" 2339N/A """Our image path is being updated, so figure out our new 2339N/A child image paths. This interface only gets invoked when: 2339N/A - We're doing a packaging operation on a parent image and 2339N/A we've just cloned that parent to create a new BE that we're 2339N/A going to update. This clone also cloned all the children 2339N/A and so now we need to update our paths to point to the newly 2339N/A - We tried to update a cloned image (as described above) and 2339N/A our update failed, hence we're changing paths back to the 2339N/A original images that were the source of the clone.""" 3020N/A # PROP_PARENT_PATH better not be present because 3020N/A # LinkedImageChild objects are only used with push child 3020N/A # Remove any path transform and reapply. 2339N/A# --------------------------------------------------------------------------- 2925N/A# Interfaces to obtain linked image metadata from an image 2925N/A """Return publisher information for the specified image. 2925N/A Publisher information is returned in a sorted list of lists 2925N/A <publisher name> is a string 2925N/A The tuples are sorted by publisher rank. 2925N/A """Figure out the current (or planned) list of packages in img.""" 2925N/A # if there's an image plan the we need to update the installed 2925N/A # packages based on that plan. 2925N/A """Get Facets from an image that a child should inherit. 2925N/A We only want to sync facets which affect packages that have parent 2925N/A dependencies on themselves. In practice this essentially limits us to 2925N/A "facet.version-lock.*" facets.""" 2925N/A # get installed (or planned) parent packages and facets 2925N/A # create a packages dictionary indexed by package stem. 3464N/A # For performance reasons see if we can limit ourselves to using the 3464N/A # installed catalog. If this is a non-image modifying operation then 3464N/A # the installed catalog should be sufficient. If this is an image 3464N/A # modifying operation that is installing new packages, then we'll need 3464N/A # to use the known catalog (which should already have been initialized 3464N/A # and used during the image planning operation) to lookup information 3464N/A # about the packages being installed. 2925N/A # iterate through all installed (or planned) package incorporation 2925N/A # dependency actions and find those that are affected by image facets. 2925N/A # we don't check for package-wide facets here because they don't do 2925N/A # anything. (ie, facets defined via "set" actions in a package have 2925N/A # no effect on other actions within that package.) 2925N/A # we're only interested in incorporate dependencies 2925N/A # check if any image facets affect this dependency 2925N/A # W0212 Access to a protected member 2925N/A # if all the matching facets are true we don't care 2925N/A # For each faceted incorporation dependency, check if it affects a 2925N/A # package that has parent dependencies on itself. This is really a 2925N/A # best effort in that we don't follow package renames or obsoletions, 2925N/A # To limit the number of packages we inspect, we'll try to match the 2925N/A # incorporation dependency fmri targets packages by stem to packages 2925N/A # which are installed (or planned) within the parent image. This 2925N/A # allows us to quickly get a fully qualified fmri and check against a 2925N/A # package for which we have already downloaded a manifest. 2925N/A # If we can't match the dependency fmri package stem against packages 2925N/A # installed (or planned) in the parent image, we don't bother 2925N/A # searching for allowable packages in the catalog, because even if we 2925N/A # found them in the catalog and they did have a parent dependency, 2925N/A # they'd all still be uninstallable in any children because there 2925N/A # would be no way to satisfy the parent dependency. (as we already 2925N/A # stated the package is not installed in the parent.) 2925N/A # check if this package has a dependency on itself in 2925N/A # Create a set of all facets which affect incorporation dependencies 2925N/A # Note that we can't limit ourselves to only passing on facets that 2925N/A # affect dependencies which have been disabled. Doing this could lead 2925N/A # to incorrect results because facets allow for pattern matching. So 2925N/A # for example say we had the following dependencies on synced 2925N/A # depend type=incorporation fmri=some_synced_pkg1 facet.123456=true 2925N/A # depend type=incorporation fmri=some_synced_pkg2 facet.456789=true 2925N/A # and the following image facets: 2925N/A # if we only passed through facets which affected disabled packages 2925N/A # we'd just pass through "facet.*456*", but this would result in 2925N/A # disabling both dependencies above, not just the second dependency. 2925N/A # W0212 Access to a protected member 2925N/A# --------------------------------------------------------------------------- 2339N/A """Save JSON encoded linked image metadata to a file.""" 2339N/A # make sure the directory we're about to save data into exists. 2339N/A # write the output to a temporary file 2339N/A # atomically create the desired file 2339N/A # W0212 Access to a protected member 2339N/A """Load JSON encoded linked image metadata from a file.""" 2339N/A # W0212 Access to a protected member 2339N/A """Utility class used when json encoding linked image metadata.""" 2339N/A # E0202 An attribute inherited from JSONEncoder hide this method 2339N/A """Required routine that overrides the default base 2339N/A class version. This routine must serialize 'obj' when 2339N/A attempting to save 'obj' json format.""" 2339N/A """Utility class used when json decoding linked image metadata.""" 2339N/A # convert boolean strings values back into booleans 2339N/A """Remove a set of keys from a dictionary.""" 2339N/A """Oops. We hit a runtime error. Die with a nice informative 2339N/A message. Note that runtime errors should never happen and usually 2339N/A indicate bugs (or possibly corrupted linked image metadata), so they 2339N/A are not localized (just like asserts are not localized).""" 3020N/A err =
"Multiple plugins reported different path transforms:" 2339N/A# --------------------------------------------------------------------------- 2339N/A# Functions for accessing files in the current root 2339N/A """Simple wrapper for accessing files in the current root.""" 2339N/A # W0212 Access to a protected member 2339N/A """Simple wrapper for accessing files in the current root.""" 2339N/A # W0212 Access to a protected member 2339N/A """Simple wrapper for accessing files in the current root.""" 2339N/A # W0212 Access to a protected member 2339N/A """Simple wrapper for accessing files in the current root.""" 2339N/A # W0212 Access to a protected member 2339N/A# --------------------------------------------------------------------------- 2339N/A# Functions for managing images which may be in alternate roots 3020N/A """Check if 'path_transform' can be applied to 'path'.""" 3020N/A # Make sure path has a leading and trailing os.sep. 3020N/A # If there is no transform, then any any translation is valid. 2339N/A # check for nested or equal paths 3020N/A """Check if 'path_transform' has been applied to 'path'.""" 3020N/A # Make sure path has a leading and trailing os.sep. 3020N/A """Apply the 'path_transform' to 'path'.""" 3020N/A # Make sure path has a leading and trailing os.sep. 3020N/A """Unapply the 'path_transform' from 'path'.""" 3020N/A """Given an two paths create a transform that can be used to translate 3020N/A # Make sure all paths have a leading and trailing os.sep. 3020N/A # Remove the longest common path suffix. Do this by reversing the 3020N/A # path strings, finding the longest common prefix, removing the common 3020N/A # prefix, and reversing the paths strings again. Make sure there is a 3020N/A # Old root and new root should start and end with a '/'. 3020N/A # Return the altroot transform tuple.