Update commands to handle multiple components repositories. #36

This commit is contained in:
Andrey Smirnov
2014-06-04 17:43:16 +04:00
parent d218159455
commit 9a34b4ff1f
5 changed files with 177 additions and 64 deletions

View File

@@ -15,6 +15,12 @@ Command publishes current state of local repository ready to be consumed
by apt tools. Published repostiories appear under rootDir/public directory.
Valid GPG key is required for publishing.
Multiple component repository could be published by specifying several
components split by commas via -component flag and multiple local
repositories as the arguments:
aptly publish repo -component=main,contrib repo-main repo-contrib
It is not recommended to publish local repositories directly unless the
repository is for testing purposes and changes happen frequently. For
production usage please take snapshot of repository and publish it
@@ -27,7 +33,7 @@ Example:
Flag: *flag.NewFlagSet("aptly-publish-repo", flag.ExitOnError),
}
cmd.Flag.String("distribution", "", "distribution name to publish")
cmd.Flag.String("component", "", "component name to publish")
cmd.Flag.String("component", "", "component name to publish (for multi-component publishing, separate components with commas)")
cmd.Flag.String("gpg-key", "", "GPG key ID to use when signing the release")
cmd.Flag.Var(&keyRingsFlag{}, "keyring", "GPG keyring to use (instead of default)")
cmd.Flag.String("secret-keyring", "", "GPG secret keyring to use (instead of default)")

View File

@@ -11,69 +11,106 @@ import (
func aptlyPublishSnapshotOrRepo(cmd *commander.Command, args []string) error {
var err error
if len(args) < 1 || len(args) > 2 {
components := strings.Split(context.flags.Lookup("component").Value.String(), ",")
if len(args) < len(components) || len(args) > len(components)+1 {
cmd.Usage()
return commander.ErrCommandError
}
name := args[0]
var prefix string
if len(args) == 2 {
prefix = args[1]
if len(args) == len(components)+1 {
prefix = args[len(components)]
args = args[0 : len(args)-1]
} else {
prefix = ""
}
var (
source interface{}
sources = []interface{}{}
message string
)
if cmd.Name() == "snapshot" {
var snapshot *deb.Snapshot
snapshot, err = context.CollectionFactory().SnapshotCollection().ByName(name)
if err != nil {
return fmt.Errorf("unable to publish: %s", err)
var (
snapshot *deb.Snapshot
emptyWarning = false
parts = []string{}
)
for _, name := range args {
snapshot, err = context.CollectionFactory().SnapshotCollection().ByName(name)
if err != nil {
return fmt.Errorf("unable to publish: %s", err)
}
err = context.CollectionFactory().SnapshotCollection().LoadComplete(snapshot)
if err != nil {
return fmt.Errorf("unable to publish: %s", err)
}
sources = append(sources, snapshot)
parts = append(parts, snapshot.Name)
if snapshot.NumPackages() == 0 {
emptyWarning = true
}
}
err = context.CollectionFactory().SnapshotCollection().LoadComplete(snapshot)
if err != nil {
return fmt.Errorf("unable to publish: %s", err)
if len(parts) == 1 {
message = fmt.Sprintf("Snapshot %s", parts[0])
} else {
message = fmt.Sprintf("Snapshots %s", strings.Join(parts, ", "))
}
source = snapshot
message = fmt.Sprintf("Snapshot %s", snapshot.Name)
if snapshot.NumPackages() == 0 {
if emptyWarning {
context.Progress().Printf("Warning: publishing from empty source, architectures list should be complete, it can't be changed after publishing (use -architectures flag)\n")
}
} else if cmd.Name() == "repo" {
var localRepo *deb.LocalRepo
localRepo, err = context.CollectionFactory().LocalRepoCollection().ByName(name)
if err != nil {
return fmt.Errorf("unable to publish: %s", err)
var (
localRepo *deb.LocalRepo
emptyWarning = false
parts = []string{}
)
for _, name := range args {
localRepo, err = context.CollectionFactory().LocalRepoCollection().ByName(name)
if err != nil {
return fmt.Errorf("unable to publish: %s", err)
}
err = context.CollectionFactory().LocalRepoCollection().LoadComplete(localRepo)
if err != nil {
return fmt.Errorf("unable to publish: %s", err)
}
sources = append(sources, localRepo)
parts = append(parts, localRepo.Name)
if localRepo.NumPackages() == 0 {
emptyWarning = true
}
}
err = context.CollectionFactory().LocalRepoCollection().LoadComplete(localRepo)
if err != nil {
return fmt.Errorf("unable to publish: %s", err)
if len(parts) == 1 {
message = fmt.Sprintf("Local repo %s", parts[0])
} else {
message = fmt.Sprintf("Local repos %s", strings.Join(parts, ", "))
}
source = localRepo
message = fmt.Sprintf("Local repo %s", localRepo.Name)
if localRepo.NumPackages() == 0 {
if emptyWarning {
context.Progress().Printf("Warning: publishing from empty source, architectures list should be complete, it can't be changed after publishing (use -architectures flag)\n")
}
} else {
panic("unknown command")
}
component := context.flags.Lookup("component").Value.String()
distribution := context.flags.Lookup("distribution").Value.String()
published, err := deb.NewPublishedRepo(prefix, distribution, context.ArchitecturesList(), []string{component}, []interface{}{source}, context.CollectionFactory())
published, err := deb.NewPublishedRepo(prefix, distribution, context.ArchitecturesList(), components, sources, context.CollectionFactory())
if err != nil {
return fmt.Errorf("unable to publish: %s", err)
}
@@ -101,7 +138,8 @@ func aptlyPublishSnapshotOrRepo(cmd *commander.Command, args []string) error {
return fmt.Errorf("unable to save to DB: %s", err)
}
prefix, component, distribution = published.Prefix, strings.Join(published.Components(), " "), published.Distribution
var repoComponents string
prefix, repoComponents, distribution = published.Prefix, strings.Join(published.Components(), " "), published.Distribution
if prefix == "." {
prefix = ""
} else if !strings.HasSuffix(prefix, "/") {
@@ -111,9 +149,9 @@ func aptlyPublishSnapshotOrRepo(cmd *commander.Command, args []string) error {
context.Progress().Printf("\n%s has been successfully published.\nPlease setup your webserver to serve directory '%s' with autoindexing.\n",
message, context.PublishedStorage().PublicPath())
context.Progress().Printf("Now you can add following line to apt sources:\n")
context.Progress().Printf(" deb http://your-server/%s %s %s\n", prefix, distribution, component)
context.Progress().Printf(" deb http://your-server/%s %s %s\n", prefix, distribution, repoComponents)
if utils.StrSliceHasItem(published.Architectures, "source") {
context.Progress().Printf(" deb-src http://your-server/%s %s %s\n", prefix, distribution, component)
context.Progress().Printf(" deb-src http://your-server/%s %s %s\n", prefix, distribution, repoComponents)
}
context.Progress().Printf("Don't forget to add your GPG key to apt with apt-key.\n")
context.Progress().Printf("\nYou can also use `aptly serve` to publish your repositories over HTTP quickly.\n")
@@ -131,6 +169,12 @@ Command publishes snapshot as Debian repository ready to be consumed
by apt tools. Published repostiories appear under rootDir/public directory.
Valid GPG key is required for publishing.
Multiple component repository could be published by specifying several
components split by commas via -component flag and multiple snapshots
as the arguments:
aptly publish snapshot -component=main,contrib snap-main snap-contrib
Example:
$ aptly publish snapshot wheezy-main
@@ -138,7 +182,7 @@ Example:
Flag: *flag.NewFlagSet("aptly-publish-snapshot", flag.ExitOnError),
}
cmd.Flag.String("distribution", "", "distribution name to publish")
cmd.Flag.String("component", "", "component name to publish")
cmd.Flag.String("component", "", "component name to publish (for multi-component publishing, separate components with commas)")
cmd.Flag.String("gpg-key", "", "GPG key ID to use when signing the release")
cmd.Flag.Var(&keyRingsFlag{}, "keyring", "GPG keyring to use (instead of default)")
cmd.Flag.String("secret-keyring", "", "GPG secret keyring to use (instead of default)")

View File

@@ -5,11 +5,15 @@ import (
"github.com/smira/aptly/deb"
"github.com/smira/commander"
"github.com/smira/flag"
"strings"
)
func aptlyPublishSwitch(cmd *commander.Command, args []string) error {
var err error
if len(args) < 2 || len(args) > 3 {
components := strings.Split(context.flags.Lookup("component").Value.String(), ",")
if len(args) < len(components)+1 || len(args) > len(components)+2 {
cmd.Usage()
return commander.ErrCommandError
}
@@ -18,25 +22,15 @@ func aptlyPublishSwitch(cmd *commander.Command, args []string) error {
prefix := "."
var (
name string
names []string
snapshot *deb.Snapshot
)
if len(args) == 3 {
if len(args) == len(components)+2 {
prefix = args[1]
name = args[2]
names = args[2:]
} else {
name = args[1]
}
snapshot, err = context.CollectionFactory().SnapshotCollection().ByName(name)
if err != nil {
return fmt.Errorf("unable to switch: %s", err)
}
err = context.CollectionFactory().SnapshotCollection().LoadComplete(snapshot)
if err != nil {
return fmt.Errorf("unable to switch: %s", err)
names = args[1:]
}
var published *deb.PublishedRepo
@@ -55,13 +49,28 @@ func aptlyPublishSwitch(cmd *commander.Command, args []string) error {
return fmt.Errorf("unable to update: %s", err)
}
components := published.Components()
if len(components) > 1 {
panic("TODO: NOT IMPLEMENTED YET")
publishedComponents := published.Components()
if len(components) == 1 && len(publishedComponents) == 1 && components[0] == "" {
components = publishedComponents
}
component := components[0]
published.UpdateSnapshot(component, snapshot)
if len(names) != len(components) {
return fmt.Errorf("mismatch in number of components (%d) and snapshots (%d)", len(components), len(names))
}
for i, component := range components {
snapshot, err = context.CollectionFactory().SnapshotCollection().ByName(names[i])
if err != nil {
return fmt.Errorf("unable to switch: %s", err)
}
err = context.CollectionFactory().SnapshotCollection().LoadComplete(snapshot)
if err != nil {
return fmt.Errorf("unable to switch: %s", err)
}
published.UpdateSnapshot(component, snapshot)
}
signer, err := getSigner(context.flags)
if err != nil {
@@ -96,7 +105,14 @@ func makeCmdPublishSwitch() *commander.Command {
Short: "update published repository by switching to new snapshot",
Long: `
Command switches in-place published repository with new snapshot contents. All
publishing parameters are preserved (architecture list, distribution, component).
publishing parameters are preserved (architecture list, distribution,
component).
For multiple component repositories, flag -component should be given with
list of components to update. Corresponding snapshots should be given in the
same order, e.g.:
aptly publish update -component=main,contrib wheezy wh-main wh-contrib
Example:
@@ -108,6 +124,7 @@ Example:
cmd.Flag.Var(&keyRingsFlag{}, "keyring", "GPG keyring to use (instead of default)")
cmd.Flag.String("secret-keyring", "", "GPG secret keyring to use (instead of default)")
cmd.Flag.Bool("skip-signing", false, "don't sign Release files with GPG")
cmd.Flag.String("component", "", "component names to update (for multi-component publishing, separate components with commas)")
return cmd
}

View File

@@ -38,12 +38,9 @@ func aptlyPublishUpdate(cmd *commander.Command, args []string) error {
}
components := published.Components()
if len(components) > 1 {
panic("TODO: NOT IMPLEMENTED YET")
for _, component := range components {
published.UpdateLocalRepo(component)
}
component := components[0]
published.UpdateLocalRepo(component)
signer, err := getSigner(context.flags)
if err != nil {
@@ -82,6 +79,9 @@ and <prefix> should be occupied with local repository published
using command aptly publish repo. Update happens in-place with
minimum possible downtime for published repository.
For multiple component published repositories, all local repositories
are updated.
Example:
$ aptly publish update wheezy ppa

View File

@@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "APTLY" "1" "May 2014" "" ""
.TH "APTLY" "1" "June 2014" "" ""
.
.SH "NAME"
\fBaptly\fR \- Debian repository management tool
@@ -744,6 +744,19 @@ display list in machine\-readable format
Command publishes current state of local repository ready to be consumed by apt tools\. Published repostiories appear under rootDir/public directory\. Valid GPG key is required for publishing\.
.
.P
Multiple component repository could be published by specifying several components split by commas via \-component flag and multiple local repositories as the arguments:
.
.IP "" 4
.
.nf
aptly publish repo \-component=main,contrib repo\-main repo\-contrib
.
.fi
.
.IP "" 0
.
.P
It is not recommended to publish local repositories directly unless the repository is for testing purposes and changes happen frequently\. For production usage please take snapshot of repository and publish it using publish snapshot command\.
.
.P
@@ -764,7 +777,7 @@ Options:
.
.TP
\-\fBcomponent\fR=
component name to publish
component name to publish (for multi\-component publishing, separate components with commas)
.
.TP
\-\fBdistribution\fR=
@@ -801,6 +814,19 @@ don\(cqt sign Release files with GPG
Command publishes snapshot as Debian repository ready to be consumed by apt tools\. Published repostiories appear under rootDir/public directory\. Valid GPG key is required for publishing\.
.
.P
Multiple component repository could be published by specifying several components split by commas via \-component flag and multiple snapshots as the arguments:
.
.IP "" 4
.
.nf
aptly publish snapshot \-component=main,contrib snap\-main snap\-contrib
.
.fi
.
.IP "" 0
.
.P
Example:
.
.IP "" 4
@@ -818,7 +844,7 @@ Options:
.
.TP
\-\fBcomponent\fR=
component name to publish
component name to publish (for multi\-component publishing, separate components with commas)
.
.TP
\-\fBdistribution\fR=
@@ -855,6 +881,19 @@ don\(cqt sign Release files with GPG
Command switches in\-place published repository with new snapshot contents\. All publishing parameters are preserved (architecture list, distribution, component)\.
.
.P
For multiple component repositories, flag \-component should be given with list of components to update\. Corresponding snapshots should be given in the same order, e\.g\.:
.
.IP "" 4
.
.nf
aptly publish update \-component=main,contrib wheezy wh\-main wh\-contrib
.
.fi
.
.IP "" 0
.
.P
Example:
.
.IP "" 4
@@ -871,6 +910,10 @@ $ aptly publish update wheezy ppa wheezy\-7\.5
Options:
.
.TP
\-\fBcomponent\fR=
component names to update (for multi\-component publishing, separate components with commas)
.
.TP
\-\fBgpg\-key\fR=
GPG key ID to use when signing the release
.
@@ -893,6 +936,9 @@ don\(cqt sign Release files with GPG
Command re\-publishes (updates) published local repository\. \fIdistribution\fR and \fIprefix\fR should be occupied with local repository published using command aptly publish repo\. Update happens in\-place with minimum possible downtime for published repository\.
.
.P
For multiple component published repositories, all local repositories are updated\.
.
.P
Example:
.
.IP "" 4