manifest.py revision 202
2e37d45867d081db150ab78dad303b9077aea24fTimo Sirainen#!/usr/bin/python
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen# CDDL HEADER START
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen# The contents of this file are subject to the terms of the
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen# Common Development and Distribution License (the "License").
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen# You may not use this file except in compliance with the License.
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen# or http://www.opensolaris.org/os/licensing.
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen# See the License for the specific language governing permissions
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen# and limitations under the License.
300e4e43ed1ca46d0614459161ca2fb460ef661aTimo Sirainen#
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen# When distributing Covered Code, include this CDDL HEADER in each
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen# If applicable, add the following below this CDDL HEADER, with the
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen# fields enclosed by brackets "[]" replaced with your own identifying
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen# information: Portions Copyright [yyyy] [name of copyright owner]
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#
ae46f6ba5bb9eee8900254d3042e89d490023be0Timo Sirainen# CDDL HEADER END
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen#
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
3f3ad16ff74d694796d22501250a9a29997c0729Timo Sirainen# Use is subject to license terms.
b4ddb5b3c3722620a8fef387dd8c47bb411a5643Timo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenimport bisect
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenimport os
300e4e43ed1ca46d0614459161ca2fb460ef661aTimo Sirainenimport sha
b4ddb5b3c3722620a8fef387dd8c47bb411a5643Timo Sirainenimport shutil
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenimport time
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenimport urllib
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenimport cPickle
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenfrom itertools import groupby
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenimport pkg.actions as actions
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenimport pkg.fmri as fmri
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenimport pkg.client.retrieve as retrieve
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainenimport pkg.client.filter as filter
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen# The type member is used for the ordering of actions.
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo SirainenACTION_DIR = 10
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo SirainenACTION_FILE = 20
db693bf6fcae96d834567f1782257517b7207655Timo SirainenACTION_LINK = 50
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo SirainenACTION_HARDLINK = 55
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo SirainenACTION_DEVICE = 100
b4ddb5b3c3722620a8fef387dd8c47bb411a5643Timo SirainenACTION_USER = 200
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo SirainenACTION_GROUP = 210
5801ce4da7d807ab85d02051ece5969e7175eebaTimo SirainenACTION_SERVICE = 300
b4ddb5b3c3722620a8fef387dd8c47bb411a5643Timo SirainenACTION_RESTART = 310
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo SirainenACTION_DEPEND = 400
300e4e43ed1ca46d0614459161ca2fb460ef661aTimo Sirainen
300e4e43ed1ca46d0614459161ca2fb460ef661aTimo SirainenDEPEND_REQUIRE = 0
300e4e43ed1ca46d0614459161ca2fb460ef661aTimo SirainenDEPEND_OPTIONAL = 1
300e4e43ed1ca46d0614459161ca2fb460ef661aTimo SirainenDEPEND_INCORPORATE =10
300e4e43ed1ca46d0614459161ca2fb460ef661aTimo Sirainen
db693bf6fcae96d834567f1782257517b7207655Timo Sirainendepend_str = { DEPEND_REQUIRE : "require",
300e4e43ed1ca46d0614459161ca2fb460ef661aTimo Sirainen DEPEND_OPTIONAL : "optional",
300e4e43ed1ca46d0614459161ca2fb460ef661aTimo Sirainen DEPEND_INCORPORATE : "incorporate"
300e4e43ed1ca46d0614459161ca2fb460ef661aTimo Sirainen}
300e4e43ed1ca46d0614459161ca2fb460ef661aTimo Sirainen
5801ce4da7d807ab85d02051ece5969e7175eebaTimo Sirainenclass Manifest(object):
5801ce4da7d807ab85d02051ece5969e7175eebaTimo Sirainen """A Manifest is the representation of the actions composing a specific
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen package version on both the client and the repository. Both purposes
861f53be0cc2fa5665f3c107a7576e2a53bb2eb0Timo Sirainen utilize the same storage format.
5801ce4da7d807ab85d02051ece5969e7175eebaTimo Sirainen
db693bf6fcae96d834567f1782257517b7207655Timo Sirainen The serialized structure of a manifest is an unordered list of package
861f53be0cc2fa5665f3c107a7576e2a53bb2eb0Timo Sirainen attributes, followed by an unordered list of actions (such as files to
861f53be0cc2fa5665f3c107a7576e2a53bb2eb0Timo Sirainen install).
861f53be0cc2fa5665f3c107a7576e2a53bb2eb0Timo Sirainen
861f53be0cc2fa5665f3c107a7576e2a53bb2eb0Timo Sirainen The special action, "set", represents an attribute setting.
861f53be0cc2fa5665f3c107a7576e2a53bb2eb0Timo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen The reserved attribute, "fmri", represents the package and version
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen described by this manifest. It is available as a string via the
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen attributes dictionary, and as an FMRI object from the fmri member.
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen The list of manifest-wide reserved attributes is
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen base_directory Default base directory, for non-user images.
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen fmri Package FMRI.
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen isa Package is intended for a list of ISAs.
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen licenses Package contains software available under a list
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen of license terms.
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen platform Package is intended for a list of platforms.
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen relocatable Suitable for User Image.
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen All non-prefixed attributes are reserved to the framework. Third
db693bf6fcae96d834567f1782257517b7207655Timo Sirainen parties may prefix their attributes with a reversed domain name, domain
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen name, or stock symbol. An example might be
b4ddb5b3c3722620a8fef387dd8c47bb411a5643Timo Sirainen
b4ddb5b3c3722620a8fef387dd8c47bb411a5643Timo Sirainen com.example,supported
b4ddb5b3c3722620a8fef387dd8c47bb411a5643Timo Sirainen
b4ddb5b3c3722620a8fef387dd8c47bb411a5643Timo Sirainen as an indicator that a specific package version is supported by the
b4ddb5b3c3722620a8fef387dd8c47bb411a5643Timo Sirainen vendor, example.com.
b4ddb5b3c3722620a8fef387dd8c47bb411a5643Timo Sirainen
b4ddb5b3c3722620a8fef387dd8c47bb411a5643Timo Sirainen manifest.null is provided as the null manifest. Differences against the
b4ddb5b3c3722620a8fef387dd8c47bb411a5643Timo Sirainen null manifest result in the complete set of attributes and actions of
b4ddb5b3c3722620a8fef387dd8c47bb411a5643Timo Sirainen the non-null manifest, meaning that all operations can be viewed as
b4ddb5b3c3722620a8fef387dd8c47bb411a5643Timo Sirainen tranitions between the manifest being installed and the manifest already
b4ddb5b3c3722620a8fef387dd8c47bb411a5643Timo Sirainen present in the image (which may be the null manifest).
b4ddb5b3c3722620a8fef387dd8c47bb411a5643Timo Sirainen """
b4ddb5b3c3722620a8fef387dd8c47bb411a5643Timo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen def __init__(self):
b4ddb5b3c3722620a8fef387dd8c47bb411a5643Timo Sirainen self.img = None
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen self.fmri = None
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen self.actions = []
fa87f0ef3636fa52ce42513533ee500c0bf29910Timo Sirainen self.attributes = {}
fa87f0ef3636fa52ce42513533ee500c0bf29910Timo Sirainen return
fa87f0ef3636fa52ce42513533ee500c0bf29910Timo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen def __str__(self):
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen r = ""
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if self.fmri != None:
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen r = r + "set fmri = %s\n" % self.fmri
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen for att in sorted(self.attributes.keys()):
fa87f0ef3636fa52ce42513533ee500c0bf29910Timo Sirainen r = r + "set %s = %s\n" % (att, self.attributes[att])
fa87f0ef3636fa52ce42513533ee500c0bf29910Timo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen for act in self.actions:
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen r = r + "%s\n" % act
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen return r
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen def difference(self, origin):
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen """Return a list of action pairs representing origin and
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen destination actions."""
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen # XXX Do we need to find some way to assert that the keys are
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen # all unique?
242abe3ad2423776e9cf05e1304eb8fda4831b23Timo Sirainen
cf9d67e4a9bfee31cf3be05244555d51a3d1b9feTimo Sirainen sdict = dict(
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen ((a.name, a.attrs.get(a.key_attr, id(a))), a)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen for a in self.actions
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen )
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen odict = dict(
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen ((a.name, a.attrs.get(a.key_attr, id(a))), a)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen for a in origin.actions
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen )
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen sset = set(sdict.keys())
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen oset = set(odict.keys())
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen added = [(None, sdict[i]) for i in sset - oset]
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen removed = [(odict[i], None) for i in oset - sset]
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen changed = [
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen (odict[i], sdict[i])
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen for i in oset & sset
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if odict[i].different(sdict[i])
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen ]
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen # XXX Do changed actions need to be sorted at all? This is
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen # likely to be the largest list, so we might save significant
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen # time by not sorting. Should we sort above? Insert into a
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen # sorted list?
b4ddb5b3c3722620a8fef387dd8c47bb411a5643Timo Sirainen
b4ddb5b3c3722620a8fef387dd8c47bb411a5643Timo Sirainen # singlesort = lambda x: x[0] or x[1]
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen addsort = lambda x: x[1]
fa87f0ef3636fa52ce42513533ee500c0bf29910Timo Sirainen remsort = lambda x: x[0]
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen removed.sort(key = remsort, reverse = True)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen added.sort(key = addsort)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen changed.sort(key = addsort)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen return (added, changed, removed)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen def humanized_differences(self, other):
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen """Output expects that self is newer than other. Use of sets
cf9d67e4a9bfee31cf3be05244555d51a3d1b9feTimo Sirainen requires that we convert the action objects into some marshalled
cf9d67e4a9bfee31cf3be05244555d51a3d1b9feTimo Sirainen form, otherwise set member identities are derived from the
cf9d67e4a9bfee31cf3be05244555d51a3d1b9feTimo Sirainen object pointers, rather than the contents."""
edd318d5866ac3fbc6e8df28fb24a4dfef93c884Timo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen l = self.difference(other)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen out = ""
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen for src, dest in l:
8dd76854cc680053986142d5f5e823f637447929Timo Sirainen if not src:
8dd76854cc680053986142d5f5e823f637447929Timo Sirainen out += "+ %s\n" % str(dest)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen elif not dest:
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen out += "- %s\n" + str(src)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen else:
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen out += "%s -> %s\n" % (src, dest)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen return out
b4ddb5b3c3722620a8fef387dd8c47bb411a5643Timo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen def filter(self, filters):
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen """Filter out actions from the manifest based on filters."""
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen self.actions = [
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen a
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen for a in self.actions
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen if filter.apply_filters(a, filters)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen ]
412b772c337428b72149605c1410524c2353e5d4Timo Sirainen
412b772c337428b72149605c1410524c2353e5d4Timo Sirainen def duplicates(self):
412b772c337428b72149605c1410524c2353e5d4Timo Sirainen """Find actions in the manifest which are duplicates (i.e.,
0a53eb0283d7ec28c6105f61e118b96fce8ecb95Timo Sirainen represent the same object) but which are not identical (i.e.,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen have all the same attributes)."""
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen def fun(a):
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen """Return a key on which actions can be sorted."""
412b772c337428b72149605c1410524c2353e5d4Timo Sirainen return a.name, a.attrs.get(a.key_attr, id(a))
f9f77e06a148fd0816004e0e1b0f585307148a7dTimo Sirainen
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen alldups = []
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen for k, g in groupby(sorted(self.actions, key = fun), fun):
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen glist = list(g)
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen dups = set()
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen for i in range(len(glist) - 1):
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen if glist[i].different(glist[i + 1]):
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen dups.add(glist[i])
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen dups.add(glist[i + 1])
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen if dups:
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen alldups.append((k, dups))
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen return alldups
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen def set_fmri(self, img, fmri):
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen self.img = img
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen self.fmri = fmri
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen @staticmethod
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen def make_opener(img, fmri, action):
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen def opener():
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen return retrieve.get_datastream(img, fmri, action.hash)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen return opener
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen def set_content(self, str):
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen """str is the text representation of the manifest"""
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen # So we could build up here the type/key_attr dictionaries like
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen # sdict and odict in difference() above, and have that be our
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen # main datastore, rather than the simple list we have now. If
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen # we do that here, we can even assert that the "same" action
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen # can't be in a manifest twice. (The problem of having the same
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen # action more than once in packages that can be installed
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen # together has to be solved somewhere else, though.)
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen for l in str.splitlines():
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen l = l.lstrip()
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen if not l or l[0] == "#":
00e7c3010f7da4a49881a7feb05e413af353af0aTimo Sirainen continue
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen try:
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen action = actions.fromstr(l)
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen except KeyError:
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen raise SyntaxError, \
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen "unknown action '%s'" % l.split()[0]
if action.attrs.has_key("path"):
np = action.attrs["path"].lstrip(os.path.sep)
action.attrs["path"] = np
if hasattr(action, "hash"):
action.data = \
self.make_opener(self.img, self.fmri, action)
if not self.actions:
self.actions.append(action)
else:
bisect.insort(self.actions, action)
return
def search_dict(self):
"""Return the dictionary used for searching."""
action_dict = {}
for a in self.actions:
for k, v in a.generate_indices().iteritems():
if isinstance(v, list):
if k in action_dict:
action_dict[k].update(
dict((i, True) for i in v))
else:
action_dict[k] = \
dict((i, True) for i in v)
else:
if k in action_dict:
action_dict[k][v] = True
else:
action_dict[k] = { v: True }
return action_dict
def pickle(self, file):
"""Pickle the indices of the manifest's actions to the 'file'.
"""
cPickle.dump(self.search_dict(), file,
protocol = cPickle.HIGHEST_PROTOCOL)
null = Manifest()