// DELETE /publish/:prefix/:distribution func apiPublishDrop(c *gin.Context) { force := c.Request.URL.Query().Get("force") == "1" param := parseEscapedPath(c.Params.ByName("prefix")) storage, prefix := deb.ParsePrefix(param) distribution := c.Params.ByName("distribution") // published.LoadComplete would touch local repo collection localRepoCollection := context.CollectionFactory().LocalRepoCollection() localRepoCollection.RLock() defer localRepoCollection.RUnlock() collection := context.CollectionFactory().PublishedRepoCollection() collection.Lock() defer collection.Unlock() err := collection.Remove(context, storage, prefix, distribution, context.CollectionFactory(), context.Progress(), force) if err != nil { c.Fail(500, fmt.Errorf("unable to drop: %s", err)) return } c.JSON(200, gin.H{}) }
func aptlyPublishDrop(cmd *commander.Command, args []string) error { var err error if len(args) < 1 || len(args) > 2 { cmd.Usage() return commander.ErrCommandError } distribution := args[0] param := "." if len(args) == 2 { param = args[1] } storage, prefix := deb.ParsePrefix(param) err = context.CollectionFactory().PublishedRepoCollection().Remove(context, storage, prefix, distribution, context.CollectionFactory(), context.Progress(), context.Flags().Lookup("force-drop").Value.Get().(bool)) if err != nil { return fmt.Errorf("unable to remove: %s", err) } context.Progress().Printf("\nPublished repository has been removed successfully.\n") return err }
func (a *Api) PublishDrop(prefix, distribution string, force bool) error { param := parseEscapedPath(prefix) storage, prefix := deb.ParsePrefix(param) // published.LoadComplete would touch local repo collection localRepoCollection := a.Ctx().CollectionFactory().LocalRepoCollection() localRepoCollection.RLock() defer localRepoCollection.RUnlock() collection := a.Ctx().CollectionFactory().PublishedRepoCollection() collection.Lock() defer collection.Unlock() err := collection.Remove(a.Ctx(), storage, prefix, distribution, a.Ctx().CollectionFactory(), a.Ctx().Progress(), force) if err != nil { return fmt.Errorf("unable to drop: %s", err) } return nil }
func aptlyPublishSnapshotOrRepo(cmd *commander.Command, args []string) error { var err error components := strings.Split(context.Flags().Lookup("component").Value.String(), ",") if len(args) < len(components) || len(args) > len(components)+1 { cmd.Usage() return commander.ErrCommandError } var param string if len(args) == len(components)+1 { param = args[len(components)] args = args[0 : len(args)-1] } else { param = "" } storage, prefix := deb.ParsePrefix(param) var ( sources = []interface{}{} message string ) if cmd.Name() == "snapshot" { 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 } } if len(parts) == 1 { message = fmt.Sprintf("Snapshot %s has", parts[0]) } else { message = fmt.Sprintf("Snapshots %s have", strings.Join(parts, ", ")) } 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 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 } } if len(parts) == 1 { message = fmt.Sprintf("Local repo %s has", parts[0]) } else { message = fmt.Sprintf("Local repos %s have", strings.Join(parts, ", ")) } 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") } distribution := context.Flags().Lookup("distribution").Value.String() published, err := deb.NewPublishedRepo(storage, prefix, distribution, context.ArchitecturesList(), components, sources, context.CollectionFactory()) if err != nil { return fmt.Errorf("unable to publish: %s", err) } published.Origin = context.Flags().Lookup("origin").Value.String() published.Label = context.Flags().Lookup("label").Value.String() if context.Flags().IsSet("skip-contents") { published.SkipContents = context.Flags().Lookup("skip-contents").Value.Get().(bool) } duplicate := context.CollectionFactory().PublishedRepoCollection().CheckDuplicate(published) if duplicate != nil { context.CollectionFactory().PublishedRepoCollection().LoadComplete(duplicate, context.CollectionFactory()) return fmt.Errorf("prefix/distribution already used by another published repo: %s", duplicate) } signer, err := getSigner(context.Flags()) if err != nil { return fmt.Errorf("unable to initialize GPG signer: %s", err) } forceOverwrite := context.Flags().Lookup("force-overwrite").Value.Get().(bool) if forceOverwrite { context.Progress().ColoredPrintf("@rWARNING@|: force overwrite mode enabled, aptly might corrupt other published repositories sharing " + "the same package pool.\n") } err = published.Publish(context.PackagePool(), context, context.CollectionFactory(), signer, context.Progress(), forceOverwrite) if err != nil { return fmt.Errorf("unable to publish: %s", err) } err = context.CollectionFactory().PublishedRepoCollection().Add(published) if err != nil { return fmt.Errorf("unable to save to DB: %s", err) } var repoComponents string prefix, repoComponents, distribution = published.Prefix, strings.Join(published.Components(), " "), published.Distribution if prefix == "." { prefix = "" } else if !strings.HasSuffix(prefix, "/") { prefix += "/" } context.Progress().Printf("\n%s been successfully published.\n", message) if localStorage, ok := context.GetPublishedStorage(storage).(aptly.LocalPublishedStorage); ok { context.Progress().Printf("Please setup your webserver to serve directory '%s' with autoindexing.\n", localStorage.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, repoComponents) if utils.StrSliceHasItem(published.Architectures, "source") { 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") return err }
func (a *Api) PublishRepoOrSnapshot(prefix, distribution, label, origin string, sourceKind string, sources []PublishSource, forceOverwrite bool, architectures []string, signingOptions SigningOptions) (*deb.PublishedRepo, error) { param := parseEscapedPath(prefix) storage, prefix := deb.ParsePrefix(param) signer, err := getSigner(&signingOptions) if err != nil { return nil, err } if len(sources) == 0 { return nil, fmt.Errorf("Must specify at least one source") } var components []string var debSources []interface{} if sourceKind == "snapshot" { var snapshot *deb.Snapshot snapshotCollection := a.Ctx().CollectionFactory().SnapshotCollection() snapshotCollection.RLock() defer snapshotCollection.RUnlock() for _, source := range sources { components = append(components, source.Component) snapshot, err = snapshotCollection.ByName(source.Name) if err != nil { return nil, fmt.Errorf("unable to publish: %s", err) } err = snapshotCollection.LoadComplete(snapshot) if err != nil { return nil, fmt.Errorf("unable to publish: %s", err) } debSources = append(debSources, snapshot) } } else if sourceKind == "local" { var localRepo *deb.LocalRepo localCollection := a.Ctx().CollectionFactory().LocalRepoCollection() localCollection.RLock() defer localCollection.RUnlock() for _, source := range sources { components = append(components, source.Component) localRepo, err = localCollection.ByName(source.Name) if err != nil { return nil, fmt.Errorf("unable to publish: %s", err) } err = localCollection.LoadComplete(localRepo) if err != nil { return nil, fmt.Errorf("unable to publish: %s", err) } debSources = append(debSources, localRepo) } } else { return nil, fmt.Errorf("unknown SourceKind") } collection := a.Ctx().CollectionFactory().PublishedRepoCollection() collection.Lock() defer collection.Unlock() published, err := deb.NewPublishedRepo(storage, prefix, distribution, architectures, components, debSources, a.Ctx().CollectionFactory()) if err != nil { return nil, fmt.Errorf("unable to publish: %s", err) } published.Origin = origin published.Label = label duplicate := collection.CheckDuplicate(published) if duplicate != nil { a.Ctx().CollectionFactory().PublishedRepoCollection().LoadComplete(duplicate, a.Ctx().CollectionFactory()) return nil, fmt.Errorf("prefix/distribution already used by another published repo: %s", duplicate) } err = published.Publish(a.Ctx().PackagePool(), a.Ctx(), a.Ctx().CollectionFactory(), signer, nil, forceOverwrite) if err != nil { return nil, fmt.Errorf("unable to publish: %s", err) } err = collection.Add(published) if err != nil { return nil, fmt.Errorf("unable to save to DB: %s", err) } return published, nil }
func (a *Api) PublishSwitch(prefix, distribution string, snapshots []PublishSource, forceOverwrite bool, signingOptions SigningOptions) (*deb.PublishedRepo, error) { param := parseEscapedPath(prefix) storage, prefix := deb.ParsePrefix(param) signer, err := getSigner(&signingOptions) if err != nil { return nil, fmt.Errorf("unable to initialize GPG signer: %s", err) } // published.LoadComplete would touch local repo collection localRepoCollection := a.Ctx().CollectionFactory().LocalRepoCollection() localRepoCollection.RLock() defer localRepoCollection.RUnlock() snapshotCollection := a.Ctx().CollectionFactory().SnapshotCollection() snapshotCollection.RLock() defer snapshotCollection.RUnlock() collection := a.Ctx().CollectionFactory().PublishedRepoCollection() collection.Lock() defer collection.Unlock() published, err := collection.ByStoragePrefixDistribution(storage, prefix, distribution) if err != nil { return nil, fmt.Errorf("unable to update: %s", err) } err = collection.LoadComplete(published, a.Ctx().CollectionFactory()) if err != nil { return nil, fmt.Errorf("unable to update: %s", err) } var updatedComponents []string if published.SourceKind == "local" { if len(snapshots) > 0 { return nil, fmt.Errorf("snapshots shouldn't be given when updating local repo") } updatedComponents = published.Components() for _, component := range updatedComponents { published.UpdateLocalRepo(component) } } else if published.SourceKind == "snapshot" { publishedComponents := published.Components() for _, snapshotInfo := range snapshots { if !utils.StrSliceHasItem(publishedComponents, snapshotInfo.Component) { return nil, fmt.Errorf("component %s is not in published repository", snapshotInfo.Component) } snapshot, err := snapshotCollection.ByName(snapshotInfo.Name) if err != nil { return nil, err } err = snapshotCollection.LoadComplete(snapshot) if err != nil { return nil, err } published.UpdateSnapshot(snapshotInfo.Component, snapshot) updatedComponents = append(updatedComponents, snapshotInfo.Component) } } else { return nil, fmt.Errorf("unknown published repository type") } err = published.Publish(a.Ctx().PackagePool(), a.Ctx(), a.Ctx().CollectionFactory(), signer, nil, forceOverwrite) if err != nil { return nil, fmt.Errorf("unable to update: %s", err) } err = collection.Update(published) if err != nil { return nil, fmt.Errorf("unable to save to DB: %s", err) } err = collection.CleanupPrefixComponentFiles(published.Prefix, updatedComponents, a.Ctx().GetPublishedStorage(storage), a.Ctx().CollectionFactory(), nil) if err != nil { return nil, fmt.Errorf("unable to update: %s", err) } return published, nil }
// POST /publish/:prefix func apiPublishRepoOrSnapshot(c *gin.Context) { param := parseEscapedPath(c.Params.ByName("prefix")) storage, prefix := deb.ParsePrefix(param) var b struct { SourceKind string `binding:"required"` Sources []struct { Component string Name string `binding:"required"` } `binding:"required"` Distribution string Label string Origin string ForceOverwrite bool SkipContents *bool Architectures []string Signing SigningOptions } if !c.Bind(&b) { return } signer, err := getSigner(&b.Signing) if err != nil { c.Fail(500, fmt.Errorf("unable to initialize GPG signer: %s", err)) return } if len(b.Sources) == 0 { c.Fail(400, fmt.Errorf("unable to publish: soures are empty")) return } var components []string var sources []interface{} if b.SourceKind == "snapshot" { var snapshot *deb.Snapshot snapshotCollection := context.CollectionFactory().SnapshotCollection() snapshotCollection.RLock() defer snapshotCollection.RUnlock() for _, source := range b.Sources { components = append(components, source.Component) snapshot, err = snapshotCollection.ByName(source.Name) if err != nil { c.Fail(404, fmt.Errorf("unable to publish: %s", err)) return } err = snapshotCollection.LoadComplete(snapshot) if err != nil { c.Fail(500, fmt.Errorf("unable to publish: %s", err)) return } sources = append(sources, snapshot) } } else if b.SourceKind == "local" { var localRepo *deb.LocalRepo localCollection := context.CollectionFactory().LocalRepoCollection() localCollection.RLock() defer localCollection.RUnlock() for _, source := range b.Sources { components = append(components, source.Component) localRepo, err = localCollection.ByName(source.Name) if err != nil { c.Fail(404, fmt.Errorf("unable to publish: %s", err)) return } err = localCollection.LoadComplete(localRepo) if err != nil { c.Fail(500, fmt.Errorf("unable to publish: %s", err)) } sources = append(sources, localRepo) } } else { c.Fail(400, fmt.Errorf("unknown SourceKind")) return } collection := context.CollectionFactory().PublishedRepoCollection() collection.Lock() defer collection.Unlock() published, err := deb.NewPublishedRepo(storage, prefix, b.Distribution, b.Architectures, components, sources, context.CollectionFactory()) if err != nil { c.Fail(500, fmt.Errorf("unable to publish: %s", err)) return } published.Origin = b.Origin published.Label = b.Label published.SkipContents = context.Config().SkipContentsPublishing if b.SkipContents != nil { published.SkipContents = *b.SkipContents } duplicate := collection.CheckDuplicate(published) if duplicate != nil { context.CollectionFactory().PublishedRepoCollection().LoadComplete(duplicate, context.CollectionFactory()) c.Fail(400, fmt.Errorf("prefix/distribution already used by another published repo: %s", duplicate)) return } err = published.Publish(context.PackagePool(), context, context.CollectionFactory(), signer, nil, b.ForceOverwrite) if err != nil { c.Fail(500, fmt.Errorf("unable to publish: %s", err)) return } err = collection.Add(published) if err != nil { c.Fail(500, fmt.Errorf("unable to save to DB: %s", err)) return } c.JSON(201, published) }
// PUT /publish/:prefix/:distribution func apiPublishUpdateSwitch(c *gin.Context) { param := parseEscapedPath(c.Params.ByName("prefix")) storage, prefix := deb.ParsePrefix(param) distribution := c.Params.ByName("distribution") var b struct { ForceOverwrite bool Signing SigningOptions SkipContents *bool Snapshots []struct { Component string `binding:"required"` Name string `binding:"required"` } } if !c.Bind(&b) { return } signer, err := getSigner(&b.Signing) if err != nil { c.Fail(500, fmt.Errorf("unable to initialize GPG signer: %s", err)) return } // published.LoadComplete would touch local repo collection localRepoCollection := context.CollectionFactory().LocalRepoCollection() localRepoCollection.RLock() defer localRepoCollection.RUnlock() snapshotCollection := context.CollectionFactory().SnapshotCollection() snapshotCollection.RLock() defer snapshotCollection.RUnlock() collection := context.CollectionFactory().PublishedRepoCollection() collection.Lock() defer collection.Unlock() published, err := collection.ByStoragePrefixDistribution(storage, prefix, distribution) if err != nil { c.Fail(404, fmt.Errorf("unable to update: %s", err)) return } err = collection.LoadComplete(published, context.CollectionFactory()) if err != nil { c.Fail(500, fmt.Errorf("unable to update: %s", err)) return } var updatedComponents []string if published.SourceKind == "local" { if len(b.Snapshots) > 0 { c.Fail(400, fmt.Errorf("snapshots shouldn't be given when updating local repo")) return } updatedComponents = published.Components() for _, component := range updatedComponents { published.UpdateLocalRepo(component) } } else if published.SourceKind == "snapshot" { publishedComponents := published.Components() for _, snapshotInfo := range b.Snapshots { if !utils.StrSliceHasItem(publishedComponents, snapshotInfo.Component) { c.Fail(404, fmt.Errorf("component %s is not in published repository", snapshotInfo.Component)) return } snapshot, err := snapshotCollection.ByName(snapshotInfo.Name) if err != nil { c.Fail(404, err) return } err = snapshotCollection.LoadComplete(snapshot) if err != nil { c.Fail(500, err) return } published.UpdateSnapshot(snapshotInfo.Component, snapshot) updatedComponents = append(updatedComponents, snapshotInfo.Component) } } else { c.Fail(500, fmt.Errorf("unknown published repository type")) return } if b.SkipContents != nil { published.SkipContents = *b.SkipContents } err = published.Publish(context.PackagePool(), context, context.CollectionFactory(), signer, nil, b.ForceOverwrite) if err != nil { c.Fail(500, fmt.Errorf("unable to update: %s", err)) return } err = collection.Update(published) if err != nil { c.Fail(500, fmt.Errorf("unable to save to DB: %s", err)) return } err = collection.CleanupPrefixComponentFiles(published.Prefix, updatedComponents, context.GetPublishedStorage(storage), context.CollectionFactory(), nil) if err != nil { c.Fail(500, fmt.Errorf("unable to update: %s", err)) return } c.JSON(200, published) }
func aptlyPublishSwitch(cmd *commander.Command, args []string) error { var err error 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 } distribution := args[0] param := "." var ( names []string snapshot *deb.Snapshot ) if len(args) == len(components)+2 { param = args[1] names = args[2:] } else { names = args[1:] } storage, prefix := deb.ParsePrefix(param) var published *deb.PublishedRepo published, err = context.CollectionFactory().PublishedRepoCollection().ByStoragePrefixDistribution(storage, prefix, distribution) if err != nil { return fmt.Errorf("unable to update: %s", err) } if published.SourceKind != "snapshot" { return fmt.Errorf("unable to update: not a snapshot publish") } err = context.CollectionFactory().PublishedRepoCollection().LoadComplete(published, context.CollectionFactory()) if err != nil { return fmt.Errorf("unable to update: %s", err) } publishedComponents := published.Components() if len(components) == 1 && len(publishedComponents) == 1 && components[0] == "" { components = publishedComponents } 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 { if !utils.StrSliceHasItem(publishedComponents, component) { return fmt.Errorf("unable to switch: component %s is not in published repository", component) } 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 { return fmt.Errorf("unable to initialize GPG signer: %s", err) } forceOverwrite := context.Flags().Lookup("force-overwrite").Value.Get().(bool) if forceOverwrite { context.Progress().ColoredPrintf("@rWARNING@|: force overwrite mode enabled, aptly might corrupt other published repositories sharing " + "the same package pool.\n") } if context.Flags().IsSet("skip-contents") { published.SkipContents = context.Flags().Lookup("skip-contents").Value.Get().(bool) } err = published.Publish(context.PackagePool(), context, context.CollectionFactory(), signer, context.Progress(), forceOverwrite) if err != nil { return fmt.Errorf("unable to publish: %s", err) } err = context.CollectionFactory().PublishedRepoCollection().Update(published) if err != nil { return fmt.Errorf("unable to save to DB: %s", err) } err = context.CollectionFactory().PublishedRepoCollection().CleanupPrefixComponentFiles(published.Prefix, components, context.GetPublishedStorage(storage), context.CollectionFactory(), context.Progress()) if err != nil { return fmt.Errorf("unable to update: %s", err) } context.Progress().Printf("\nPublish for snapshot %s has been successfully switched to new snapshot.\n", published.String()) return err }
func aptlyPublishUpdate(cmd *commander.Command, args []string) error { var err error if len(args) < 1 || len(args) > 2 { cmd.Usage() return commander.ErrCommandError } distribution := args[0] param := "." if len(args) == 2 { param = args[1] } storage, prefix := deb.ParsePrefix(param) var published *deb.PublishedRepo published, err = context.CollectionFactory().PublishedRepoCollection().ByStoragePrefixDistribution(storage, prefix, distribution) if err != nil { return fmt.Errorf("unable to update: %s", err) } if published.SourceKind != "local" { return fmt.Errorf("unable to update: not a local repository publish") } err = context.CollectionFactory().PublishedRepoCollection().LoadComplete(published, context.CollectionFactory()) if err != nil { return fmt.Errorf("unable to update: %s", err) } components := published.Components() for _, component := range components { published.UpdateLocalRepo(component) } signer, err := getSigner(context.Flags()) if err != nil { return fmt.Errorf("unable to initialize GPG signer: %s", err) } forceOverwrite := context.Flags().Lookup("force-overwrite").Value.Get().(bool) if forceOverwrite { context.Progress().ColoredPrintf("@rWARNING@|: force overwrite mode enabled, aptly might corrupt other published repositories sharing " + "the same package pool.\n") } if context.Flags().IsSet("skip-contents") { published.SkipContents = context.Flags().Lookup("skip-contents").Value.Get().(bool) } err = published.Publish(context.PackagePool(), context, context.CollectionFactory(), signer, context.Progress(), forceOverwrite) if err != nil { return fmt.Errorf("unable to publish: %s", err) } err = context.CollectionFactory().PublishedRepoCollection().Update(published) if err != nil { return fmt.Errorf("unable to save to DB: %s", err) } err = context.CollectionFactory().PublishedRepoCollection().CleanupPrefixComponentFiles(published.Prefix, components, context.GetPublishedStorage(storage), context.CollectionFactory(), context.Progress()) if err != nil { return fmt.Errorf("unable to update: %s", err) } context.Progress().Printf("\nPublish for local repo %s has been successfully updated.\n", published.String()) return err }