Ejemplo n.º 1
0
// 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{})
}
Ejemplo n.º 2
0
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
}
Ejemplo n.º 3
0
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
}
Ejemplo n.º 4
0
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
}
Ejemplo n.º 5
0
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
}
Ejemplo n.º 6
0
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
}
Ejemplo n.º 7
0
// 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)
}
Ejemplo n.º 8
0
// 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)
}
Ejemplo n.º 9
0
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
}
Ejemplo n.º 10
0
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
}