예제 #1
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
}
예제 #2
0
파일: publish.go 프로젝트: bsundsrud/slapt
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
}
예제 #3
0
func aptlyPublishSnapshotOrRepo(cmd *commander.Command, args []string) error {
	var err error
	if len(args) < 1 || len(args) > 2 {
		cmd.Usage()
		return err
	}

	name := args[0]

	var prefix string
	if len(args) == 2 {
		prefix = args[1]
	} else {
		prefix = ""
	}

	var (
		source  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)
		}

		err = context.CollectionFactory().SnapshotCollection().LoadComplete(snapshot)
		if err != nil {
			return fmt.Errorf("unable to publish: %s", err)
		}

		source = snapshot
		message = fmt.Sprintf("Snapshot %s", snapshot.Name)
	} 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)
		}

		err = context.CollectionFactory().LocalRepoCollection().LoadComplete(localRepo)
		if err != nil {
			return fmt.Errorf("unable to publish: %s", err)
		}

		source = localRepo
		message = fmt.Sprintf("Local repo %s", localRepo.Name)
	} else {
		panic("unknown command")
	}

	component := context.flags.Lookup("component").Value.String()
	distribution := context.flags.Lookup("distribution").Value.String()

	published, err := deb.NewPublishedRepo(prefix, distribution, component, context.ArchitecturesList(), source, context.CollectionFactory())
	if err != nil {
		return fmt.Errorf("unable to publish: %s", err)
	}
	published.Origin = cmd.Flag.Lookup("origin").Value.String()
	published.Label = cmd.Flag.Lookup("label").Value.String()

	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)
	}

	err = published.Publish(context.PackagePool(), context.PublishedStorage(), context.CollectionFactory(), signer, context.Progress())
	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)
	}

	prefix, component, distribution = published.Prefix, published.Component, published.Distribution
	if prefix == "." {
		prefix = ""
	} else if !strings.HasSuffix(prefix, "/") {
		prefix += "/"
	}

	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)
	if utils.StrSliceHasItem(published.Architectures, "source") {
		context.Progress().Printf("  deb-src http://your-server/%s %s %s\n", prefix, distribution, component)
	}
	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
}
예제 #4
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)
}