13241 pkg install triggers system incorporation update
authorBart Smaalders <Bart.Smaalders@Sun.COM>
Fri, 05 Feb 2010 13:07:38 -0800
changeset 1731 a76f8a1fc049
parent 1730 c12580e62699
child 1732 05e756645b7f
13241 pkg install triggers system incorporation update 13968 WOS_PKGS path in distro-import/Makefile doesn't exist after build 130
src/modules/catalog.py
src/modules/client/pkg_solver.py
src/tests/api/t_catalog.py
src/tests/cli/t_pkg_install.py
src/util/distro-import/Makefile
src/util/distro-import/importer.py
--- a/src/modules/catalog.py	Thu Feb 04 23:50:08 2010 -0800
+++ b/src/modules/catalog.py	Fri Feb 05 13:07:38 2010 -0800
@@ -1519,6 +1519,7 @@
                         if (a.name == "depend" or \
                             attr_name.startswith("variant") or \
                             attr_name.startswith("facet") or \
+                            attr_name.startswith("pkg.depend.") or \
                             attr_name in ("pkg.obsolete",
                                 "pkg.renamed")):
                                 if Catalog.DEPENDENCY in info_needed:
@@ -1858,6 +1859,7 @@
                                 name = act.attrs["name"]
                                 if name.startswith("variant") or \
                                     name.startswith("facet") or \
+                                    name.startswith("pkg.depend.") or \
                                     name in ("pkg.obsolete", "pkg.renamed"):
                                         # variant and facet data goes to the
                                         # dependency catalog part.
--- a/src/modules/client/pkg_solver.py	Thu Feb 04 23:50:08 2010 -0800
+++ b/src/modules/client/pkg_solver.py	Fri Feb 05 13:07:38 2010 -0800
@@ -955,32 +955,65 @@
                                 raise TypeError, "List of integers, not %s, expected" % c
 
         def __get_installed_unbound_inc_list(self, proposed_fmris, excludes=EmptyI):
-                """Return the list of incorporations that are installed and do not
-                have any other pkg depending on any specific version being installed,
-                along w/ the list of constrained fmris"""
-                pkgs = {}
+                """Return the list of incorporations that are to not to change 
+                during this install operation, and the lists of fmris they constrain."""
+
                 incorps = set()
                 versioned_dependents = set()
-                proposed_names = proposed_fmris.keys()
                 pkg_cons = {}
+                install_holds = {}
+
+                # determine installed packages that contain incorporation dependencies, 
+                # determine those packages that are depended on by explict version, 
+                # and those that have pkg.depend.install-hold values.
 
                 for f in self.__installed_fmris.values():
-                        pkgs[f.pkg_name] = f
-                        for d in self.__get_dependency_actions(f, excludes):
-                                fmri = pkg.fmri.PkgFmri(d.attrs["fmri"], "5.11")
-                                if d.attrs["type"] == "incorporate":
-                                        incorps.add(f.pkg_name)
-                                        pkg_cons.setdefault(f, []).append(fmri)
-                                if "@" in d.attrs["fmri"]:
-                                        versioned_dependents.add(fmri.pkg_name)
+                        for d in self.__catalog.get_entry_actions(f,
+                            [catalog.Catalog.DEPENDENCY],
+                            excludes=excludes):
+                                if d.name == "depend":
+                                        fmri = pkg.fmri.PkgFmri(d.attrs["fmri"], "5.11")
+                                        if d.attrs["type"] == "incorporate":
+                                                incorps.add(f.pkg_name)
+                                                pkg_cons.setdefault(f, []).append(fmri)
+                                        if "@" in d.attrs["fmri"]:
+                                                versioned_dependents.add(fmri.pkg_name)
+                                elif d.name == "set" and d.attrs["name"] == "pkg.depend.install-hold":
+                                        install_holds[f.pkg_name] = d.attrs["value"]
 
+                # find install holds that appear on command line and are thus relaxed
+                relaxed_holds = set([
+                        install_holds[name]
+                        for name in proposed_fmris
+                        if name in install_holds
+                        ])
+                # add any other install holds that are relaxed because they have values
+                # that start w/ the relaxed ones...
+                relaxed_holds |= set([
+                        hold
+                        for hold in install_holds.values()
+                        if [ r for r in relaxed_holds if hold.startswith(r + ".") ]
+                        ])
+                # versioned_dependents contains all the packages that are depended on
+                # w/ a explicit version.  We now modify this list so that it does not
+                # contain any packages w/ install_holds, unless those holds were 
+                # relaxed.  
+                versioned_dependents -= set([
+                    pkg_name
+                    for pkg_name, hold_value in install_holds.iteritems()
+                    if hold_value not in relaxed_holds
+                    ])
+                # Build the list of fmris that 1) contain incorp. dependencies
+                # 2) are not in the set of versioned_dependents and 3) do
+                # not explicitly appear on the install command line.
                 ret = [
-                    pkgs[f] 
-                    for f in incorps - versioned_dependents
-                    if f not in proposed_names
+                    self.__installed_fmris[pkg_name] 
+                    for pkg_name in incorps - versioned_dependents 
+                    if pkg_name not in proposed_fmris
                 ]
-
-                con_list = [
+                # For each incorporation above that will not change, return a list
+                # of the fmris that incorporation constrains
+                con_lists = [
                         [
                         i
                         for i in pkg_cons[inc]
@@ -988,7 +1021,7 @@
                         for inc in ret
                         ]
 
-                return ret, con_list                
+                return ret, con_lists
 
         def __filter_publishers(self, pkg_name):
                 """Given a list of fmris for various versions of
--- a/src/tests/api/t_catalog.py	Thu Feb 04 23:50:08 2010 -0800
+++ b/src/tests/api/t_catalog.py	Fri Feb 05 13:07:38 2010 -0800
@@ -128,6 +128,7 @@
                     (f, f, f, f, f))
 
                 if f.pkg_name == "zpkg":
+                        lines += "set name=pkg.depend.install-hold value=test\n"
                         lines += "set name=pkg.renamed value=true\n"
                 else:
                         lines += "set name=pkg.obsolete value=true\n"
@@ -144,6 +145,8 @@
                         ]
 
                         if f.pkg_name == "zpkg":
+                                expected.append("set name=pkg.depend.install-hold "
+                                    "value=test")
                                 expected.append("set name=pkg.renamed "
                                     "value=true")
                         else:
--- a/src/tests/cli/t_pkg_install.py	Thu Feb 04 23:50:08 2010 -0800
+++ b/src/tests/cli/t_pkg_install.py	Fri Feb 05 13:07:38 2010 -0800
@@ -2316,29 +2316,51 @@
 
         leaf_template = """
             open pkg%s%s@%s,5.11-0
-            add depend type=require fmri=pkg:/%s_incorp
+            add depend type=require fmri=pkg:/%s_incorp%s
             close
         """
+        install_hold = "add set name=pkg.depend.install-hold value=test"
+
         leaf_expansion = [
-                ("A","_0", "1.0", "A"),
-                ("A","_1", "1.0", "A"),
-                ("A","_2", "1.0", "A"),
-                ("A","_3", "1.0", "A"),
-
-                ("B","_0", "1.0", "B"),
-                ("B","_1", "1.0", "B"),
-                ("B","_2", "1.0", "B"),
-                ("B","_3", "1.0", "B"),
-
-                ("A","_0", "1.1", "A"),
-                ("A","_1", "1.1", "A"),
-                ("A","_2", "1.1", "A"),
-                ("A","_3", "1.1", "A"),
-
-                ("B","_0", "1.1", "B"),
-                ("B","_1", "1.1", "B"),
-                ("B","_2", "1.1", "B"),
-                ("B","_3", "1.1", "B")
+                ("A","_0", "1.0", "A", ""),
+                ("A","_1", "1.0", "A", ""),
+                ("A","_2", "1.0", "A", ""),
+                ("A","_3", "1.0", "A", ""),
+
+                ("B","_0", "1.0", "B", ""),
+                ("B","_1", "1.0", "B", ""),
+                ("B","_2", "1.0", "B", ""),
+                ("B","_3", "1.0", "B", ""),
+
+                ("A","_0", "1.1", "A", "@1.1"),
+                ("A","_1", "1.1", "A", "@1.1"),
+                ("A","_2", "1.1", "A", "@1.1"),
+                ("A","_3", "1.1", "A", "@1.1"),
+
+                ("B","_0", "1.1", "B", "@1.1"),
+                ("B","_1", "1.1", "B", "@1.1"),
+                ("B","_2", "1.1", "B", "@1.1"),
+                ("B","_3", "1.1", "B", "@1.1"),
+
+                ("A","_0", "1.2", "A", "@1.2"),
+                ("A","_1", "1.2", "A", "@1.2"),
+                ("A","_2", "1.2", "A", "@1.2"),
+                ("A","_3", "1.2", "A", "@1.2"),
+
+                ("B","_0", "1.2", "B", "@1.2"),
+                ("B","_1", "1.2", "B", "@1.2"),
+                ("B","_2", "1.2", "B", "@1.2"),
+                ("B","_3", "1.2", "B", "@1.2"),
+
+                ("A","_0", "1.3", "A", ""),
+                ("A","_1", "1.3", "A", ""),
+                ("A","_2", "1.3", "A", ""),
+                ("A","_3", "1.3", "A", ""),
+
+                ("B","_0", "1.3", "B", ""),
+                ("B","_1", "1.3", "B", ""),
+                ("B","_2", "1.3", "B", ""),
+                ("B","_3", "1.3", "B", "")
                 ]
 
         incorps = [ """
@@ -2365,6 +2387,7 @@
             add depend type=incorporate fmri=pkg:/[email protected]
             add depend type=incorporate fmri=pkg:/[email protected]
             add depend type=incorporate fmri=pkg:/[email protected]
+            add set name=pkg.depend.install-hold value=test
             close
         """, 
 
@@ -2374,6 +2397,47 @@
             add depend type=incorporate fmri=pkg:/[email protected]
             add depend type=incorporate fmri=pkg:/[email protected]
             add depend type=incorporate fmri=pkg:/[email protected]
+            add set name=pkg.depend.install-hold value=test
+            close
+        """, 
+
+        """
+            open [email protected],5.11-0
+            add depend type=incorporate fmri=pkg:/[email protected]
+            add depend type=incorporate fmri=pkg:/[email protected]
+            add depend type=incorporate fmri=pkg:/[email protected]
+            add depend type=incorporate fmri=pkg:/[email protected]
+            add set name=pkg.depend.install-hold value=test.A
+            close
+        """, 
+
+        """
+            open [email protected],5.11-0
+            add depend type=incorporate fmri=pkg:/[email protected]
+            add depend type=incorporate fmri=pkg:/[email protected]
+            add depend type=incorporate fmri=pkg:/[email protected]
+            add depend type=incorporate fmri=pkg:/[email protected]
+            add set name=pkg.depend.install-hold value=test.B
+            close
+        """, 
+
+        """
+            open [email protected],5.11-0
+            add depend type=incorporate fmri=pkg:/[email protected]
+            add depend type=incorporate fmri=pkg:/[email protected]
+            add depend type=incorporate fmri=pkg:/[email protected]
+            add depend type=incorporate fmri=pkg:/[email protected]
+            add set name=pkg.depend.install-hold value=test.A
+            close
+        """, 
+
+        """
+            open [email protected],5.11-0
+            add depend type=incorporate fmri=pkg:/[email protected]
+            add depend type=incorporate fmri=pkg:/[email protected]
+            add depend type=incorporate fmri=pkg:/[email protected]
+            add depend type=incorporate fmri=pkg:/[email protected]
+            add set name=pkg.depend.install-hold value=test.B
             close
         """, 
 
@@ -2381,6 +2445,7 @@
             open [email protected],5.11-0
             add depend type=incorporate fmri=pkg:/[email protected]
             add depend type=incorporate fmri=pkg:/[email protected]
+            add set name=pkg.depend.install-hold value=test
             close
         """,
 
@@ -2388,8 +2453,25 @@
             open [email protected],5.11-0
             add depend type=incorporate fmri=pkg:/[email protected]
             add depend type=incorporate fmri=pkg:/[email protected]
+            add set name=pkg.depend.install-hold value=test
             close
-        """]
+        """,
+
+        """
+            open [email protected],5.11-0
+            add depend type=incorporate fmri=pkg:/[email protected]
+            add depend type=incorporate fmri=pkg:/[email protected]
+            add set name=pkg.depend.install-hold value=test
+            close
+        """, 
+        """
+            open [email protected],5.11-0
+            add depend type=incorporate fmri=pkg:/[email protected]
+            add depend type=exclude fmri=pkg:/pkgB_0
+            add set name=pkg.depend.install-hold value=test
+            close
+        """
+        ]
                     
         bug_7394_incorp = """
             open [email protected],5.11-0
@@ -2503,7 +2585,7 @@
                 self.pkg("install -v [email protected] pkgA_1")
                 self.pkg("list")
                 self.pkg("verify [email protected] [email protected] [email protected]")
-                self.pkg("image-update -v")
+                self.pkg("install [email protected]")
                 self.pkg("list [email protected] [email protected] [email protected]")
                 self.pkg("uninstall '*'")
                 # try nested incorporations
@@ -2514,12 +2596,39 @@
                 self.pkg("install -v [email protected]", exit=1) # fixed by [email protected]
                 # try image update
                 self.pkg("image-update -v")
-                self.pkg("list [email protected] [email protected] [email protected] [email protected] [email protected]")
+                self.pkg("list [email protected]")
+                self.pkg("list [email protected]")
+                self.pkg("list [email protected]")
+                self.pkg("list [email protected]")
+                self.pkg("list [email protected]")
                 self.pkg("uninstall '*'")
                 # what happens when incorporation specified
                 # a package that isn't in the catalog
                 self.pkg("install bug_7394_incorp")
                 self.pkg("install pkg1", exit=1)
+                self.pkg("uninstall '*'")
+                # test pkg.depend.install-hold feature
+                self.pkg("install -v [email protected]  pkgA_1")
+                self.pkg("list [email protected]")
+                self.pkg("list [email protected]")
+                # next attempt will fail because incorporations prevent motion even though
+                # explicit dependency exists from pkg to incorporation.
+                self.pkg("install [email protected]", exit=1)
+                # test to see if we could install both; presence of incorp causes relaxation
+                # of pkg.depend.install-hold
+                self.pkg("install -nv [email protected] [email protected]")
+                # this attempt also succeeds because pkg.depend.install-hold is relaxed 
+                # since A_incorp is on command line
+                self.pkg("install [email protected]")
+                self.pkg("list [email protected]")
+                self.pkg("list [email protected]")
+                # now demonstrate w/ version 1.2 subincorps that master incorp
+                # prevents upgrade since pkg.depend.install-hold of master != other incorps
+                self.pkg("install [email protected]")
+                self.pkg("install [email protected]", exit=1)
+                self.pkg("install [email protected]")
+                self.pkg("list [email protected]")
+                self.pkg("list [email protected]")
 
 class TestMultipleDepots(pkg5unittest.ManyDepotTestCase):
         # Only start/stop the depot once (instead of for every test)
--- a/src/util/distro-import/Makefile	Thu Feb 04 23:50:08 2010 -0800
+++ b/src/util/distro-import/Makefile	Fri Feb 05 13:07:38 2010 -0800
@@ -26,6 +26,9 @@
 
 #set default
 ARCH=i386
+ARCH_INITIAL_i386=x
+ARCH_INITIAL_sparc=s
+ARCH_INITIAL=$(ARCH_INITIAL_$(ARCH))
 NATIVE_ARCH:sh = uname -p
 PROTO_AREA=../../../proto/root_$(NATIVE_ARCH)
 
@@ -33,7 +36,9 @@
 # Needs to point to filesystem on Solaris install dvd
 # replace as needed with a local solaris install image
 #
-WOS_PKGS=/net/netinstall.sfbay/export/nv/x/$(BUILDID)/Solaris_11/Product
+WOS_PKGS_BASE=/net/paradise.sfbay/export/integrate_dock/nv/nv$(ARCH_INITIAL)_wos_$(BUILDID)
+WOS_PKGS=$(WOS_PKGS_BASE)/$(ARCH)
+WOS_EXTRA_PKGS=$(WOS_PKGS_BASE)/all
 NONWOS_DOCK=nv_osoldev
 NONWOS_PKGS=/net/paradise.sfbay/export/integrate_dock/nv/$(NONWOS_DOCK)/all \
             /net/paradise.sfbay/export/integrate_dock/nv/$(NONWOS_DOCK)/$(ARCH)
@@ -51,6 +56,7 @@
 ALL_PKGS=	../../../packages/$(ARCH)	\
 		$(TEST_PKGS)			\
 		$(NONWOS_PKGS)			\
+		$(WOS_EXTRA_PKGS)		\
 		$(WOS_PKGS) .
 
 POUND_SIGN:sh=				echo \\043
--- a/src/util/distro-import/importer.py	Thu Feb 04 23:50:08 2010 -0800
+++ b/src/util/distro-import/importer.py	Fri Feb 05 13:07:38 2010 -0800
@@ -1523,6 +1523,8 @@
 
                 # Add packages that aren't renamed or obsoleted
                 or_pkgs = or_pkgs_per_con.get(cons, {})
+                curpkg.actions.append(actions.fromstr(
+                    "set name=pkg.depend.install-hold value=core-os.%s" % cons))
 
                 for depend in cons_dict[cons]:
                         if depend not in or_pkgs:
@@ -1556,6 +1558,8 @@
                     "system update and correct package selection depend on the " \
                     "presence of this incorporation.  Removing this package will " \
                     "result in an unsupported system."
+                curpkg.actions.append(actions.fromstr(
+                    "set name=pkg.depend.install-hold value=core-os"))
 
                 for incorp in consolidation_incorporations:
                         action = actions.fromstr("depend fmri=%s type=incorporate" % incorp)