I'm going to be picking up the publication changes, so I wanted to revisit this based on where I remember Danek and I ending up as well as recent conversations I've had with Shawn where he made a case to put all of the processing in the client as opposed to the server.

The one change I want to call out for review is that I've changed how manifests are compared.(Basically, the new step 7 differs from the previous step 6.) Take the following example:
A@1 is published. B@1 is published. B@1 depends on A@1.
A@2 and B@2 are being considered for publication. A@2 has substantial content changes compared to A@1. B@2 still depends on A, and is otherwise completely identical to B@1.

In the previous scheme, B@2 would be published with a dependency on A@2. I think that's a flaw. B@2 shouldn't be published. A@2 satisfies B@1's dependency on A, and B@2 hasn't changed in any way to depend on the specific changes in A@2 (otherwise the content that B@2 delivers must have changed).

Here are the the new steps:
1) Do pkdep generate on all manifests. This step is unchanged from current practice or the previous proposal.

2) Do pkdep resolve -P. This is unchanged from the previous proposal.

3) Use pkgsend publish-all to conditionally publish all packages. (I've included the rough addition to the manpage that we'd make below.) The steps to "conditionally publish all packages" are described in 4-7.

4) Collect the name and version of every package to be published.
5) Find the correct version of the package to compare against and retrieve its manifest (this could be delayed till later, or all manifest retrievals aggregated, but eventually we're going to need all the manifests we're comparing against). 5.1) If the package name is incorporated by any package given to -i, then search, first the destination repo, and then the reference repos in order until a package with that name that matches the incorporate dependency is found. If multiple versions of the package in that repository match, take the latest one. If the package found is a successor to the package being published, that's an error and publication stops. 5.2) If the package name is not incorporated by an package given to -i, then search the destination and then each reference repository until a package is found which has the same name as the package being published and a version that's less than or equal to the version of the package being published. If multiple packages in the repository satisfy that criteria, choose the latest one.

6) For each manifest:
6.1) Fill in hashes and other attributes related to file content.
6.2) Compare the manifest of the package being published with the manifest of the package ignoring the specified actions (see 6.2.X). If at least one relevant action is different, the manifest goes in the "different set", otherwise it goes in the "identical set".
6.2.1) Attribute actions with the name pkg.fmri
6.2.2) Signature actions
6.2.3) Depend actions where the only difference is that in the manifest to be published, the version is '@current' and in the manifest being compared against, the version less than or equal to the version of the package that that package is being compared against.

7) For each manifest in the different set:
7.1) Replace each <pkg_name>@current with the correct version.
7.1.1) If pkg_name is in the different set, then replace @current with the version of that package that's going to be published. 7.1.2) If pkg_name isn't in the different set, then replace @current with the version of that package that was being compared against.
7.2) Collapse and coalesce depend actions.
7.3) Publish the package


Rough spec of the command, please ignore formating and poor wording.

pkgsend publish-all [-r <reference_repo> ...] -s destination_repo [-d source ...] [-b bundle ...] [-T pattern] [-i pkg_fmri ...] [-f file ...] -v path_to_manifest ...

-s, -d, -b, and -T are exactly the same as the options to pkgsend publish.
-v With -v print to stdout a list of all the packages that were published and all the packages that were omitted from publication. -r These options create an ordered list of repositories which will be used as sources to compare the packages to be published against. Each repository will be searched in order until a package is found that "matches". The first package found will be used, even if a package in a later repository also satisfies the matches and was published later. -i These options create an ordered list of incorporations to compare the packages being published against. If package A is being published, then the first package given as an option to i which incorporates A will be used as the restriction. If none of the packages used as -i options incorporates A, then the package "immediately less" than the version A is going to be published at will be used. (Please see previous long email exchange for the definition of "immediately less than".) Path_to_manifest. Unlike pkgsend publish which merges all manifests provided to produce a single package, each manifest provided must completely define a single package. Passing N manifests causes N packages to be published.

The following options are ideas about how to handle the fact that we might want to pass one or two thousand paths to the command at one time. -f This option takes a file which contains paths to manifests. This option because a large enough number of packages might need to be published at a single time that we'll run into shell issues. Each line in the file is expected to be a path to a manifest and will be treated identically to any paths passed on the command line. --directory This option takes a path to a directory, assumes every file/link inside that directory points to a manifest and attempts to publish all of them.

Thanks for taking the time to review this,
Brock

On 03/05/12 12:00, Brock Pytlik wrote:
As part of Danek's design for the publication changes, we need a way to defer dependency resolution until it's known whether a new version of a package is going to be published or not. I've been struggling with how to do it for a little while, but I think I've got things nailed down now. What follows is a rough idea of how I envision the publication process happening. I've written this as if the processing was being done on the client side of things, but from step 3 on, it could be happening on the server side.

1) Do pkgdep generate on all manifests to be published. This step is unchanged from the present.

2) Do pkgdep resolve -P. -P is a new option which means "postpone dependency versions." It also eliminates the dependency collapsing and coalescing which currently happens during the resolve phase. Dependencies inferred on system packages during this phase will have versions attached to them, but those inferred on other packages also being resolved will have versions of "@current."

3) Use pkgsend (in some possibly new form) to fill in file hashes and possibly pkgmog to apply other transformations so that the all the actions except for dependency actions, signature actions, and attribute actions with the name pkg.fmri are what they would be when the package is finally published. This step may or may not move file data across to the repo.

4) Grab the repo lock. I'm being deliberately vague here. Since we're comparing the manifest we're considering publishing with one in the repository, if another package got published after we compared, but before we published, we might make incorrect decisions about whether to publish a package. This could be as simple as a convention of not allowing multiple people to publish to the same repository at the same time. It could be accomplished by comparing the catalog at comparison time with the catalog when the packages are being published to ensure the state of the world is what's expected. It could be an actual lock on publishing to the repository.

5) For each manifest to be published compare all actions except attributes whose name is pkg.fmri, signature actions (though if the signing cert is different, might want to mark it as being different anyway), and dependency actions with the version of the package immediately less than the version to be published. Put all manifests with at least one different action in the "different manifests" set. Put the rest in the "identical manifests" set.

6) For all depend actions in manifests to be published which use <pkg-name>@current in the target or predicate, if <pkg-name> is in the set of "different manifests", replace @current with the version of the package in the package to be published, otherwise replace @current with the version of the previously published manifest

7) Now that all dependencies have fixed versions, collapse and coalesce the dependencies for all the packages to be published.

8) For each manifest to be published, compare all actions except attributes whose name is pkg.fmri and signature actions with the version of the package immediately less than the version to be published. Put all manifests which are different in the "actually to be published" set.

9) Publish each manifest in the "actually to be published" set.

10) Release the repo lock.

I believe this approach will work. Please let me know if you see any issues with the proposal.

Thanks,
Brock
_______________________________________________
pkg-discuss mailing list
[email protected]
http://mail.opensolaris.org/mailman/listinfo/pkg-discuss

_______________________________________________
pkg-discuss mailing list
[email protected]
http://mail.opensolaris.org/mailman/listinfo/pkg-discuss

Reply via email to