Example #1
0
func aptlyPublishDrop(cmd *commander.Command, args []string) error {
	var err error
	if len(args) < 1 || len(args) > 2 {
		cmd.Usage()
		return err
	}

	distribution := args[0]
	prefix := "."

	if len(args) == 2 {
		prefix = args[1]
	}

	publishedCollecton := debian.NewPublishedRepoCollection(context.database)

	err = publishedCollecton.Remove(context.packageRepository, prefix, distribution)
	if err != nil {
		return fmt.Errorf("unable to remove: %s", err)
	}

	fmt.Printf("\nPublished repositroy has been removed successfully.\n")

	return err
}
Example #2
0
func aptlySnapshotDrop(cmd *commander.Command, args []string) error {
	var err error
	if len(args) != 1 {
		cmd.Usage()
		return err
	}

	name := args[0]

	snapshotCollection := debian.NewSnapshotCollection(context.database)
	snapshot, err := snapshotCollection.ByName(name)
	if err != nil {
		return fmt.Errorf("unable to drop: %s", err)
	}

	publishedRepoCollection := debian.NewPublishedRepoCollection(context.database)
	published := publishedRepoCollection.BySnapshot(snapshot)

	if len(published) > 0 {
		fmt.Printf("Snapshot `%s` is published currently:\n", snapshot.Name)
		for _, repo := range published {
			err = publishedRepoCollection.LoadComplete(repo, snapshotCollection)
			if err != nil {
				return fmt.Errorf("unable to load published: %s", err)
			}
			fmt.Printf(" * %s\n", repo)
		}

		return fmt.Errorf("unable to drop: snapshot is published")
	}

	force := cmd.Flag.Lookup("force").Value.Get().(bool)
	if !force {
		snapshots := snapshotCollection.BySnapshotSource(snapshot)
		if len(snapshots) > 0 {
			fmt.Printf("Snapshot `%s` was used as a source in following snapshots:\n", snapshot.Name)
			for _, snap := range snapshots {
				fmt.Printf(" * %s\n", snap)
			}

			return fmt.Errorf("won't delete snapshot that was used as source for other snapshots, use -force to override")
		}
	}

	err = snapshotCollection.Drop(snapshot)
	if err != nil {
		return fmt.Errorf("unable to drop: %s", err)
	}

	fmt.Printf("Snapshot `%s` has been dropped.\n", snapshot.Name)

	return err
}
Example #3
0
func aptlyPublishList(cmd *commander.Command, args []string) error {
	var err error
	if len(args) != 0 {
		cmd.Usage()
		return err
	}

	publishedCollecton := debian.NewPublishedRepoCollection(context.database)
	snapshotCollection := debian.NewSnapshotCollection(context.database)

	if publishedCollecton.Len() == 0 {
		fmt.Printf("No snapshots have been published. Publish a snapshot by running `aptly publish snapshot ...`.\n")
		return err
	}

	published := make([]string, 0, publishedCollecton.Len())

	err = publishedCollecton.ForEach(func(repo *debian.PublishedRepo) error {
		err := publishedCollecton.LoadComplete(repo, snapshotCollection)
		if err != nil {
			return err
		}

		published = append(published, repo.String())
		return nil
	})

	if err != nil {
		return fmt.Errorf("unable to load list of repos: %s", err)
	}

	sort.Strings(published)

	fmt.Printf("Published repositories:\n")

	for _, description := range published {
		fmt.Printf("  * %s\n", description)
	}

	return err
}
Example #4
0
func aptlyGraph(cmd *commander.Command, args []string) error {
	var err error

	graph := gographviz.NewGraph()
	graph.SetDir(true)
	graph.SetName("aptly")

	existingNodes := map[string]bool{}

	fmt.Printf("Loading mirrors...\n")

	repoCollection := debian.NewRemoteRepoCollection(context.database)

	err = repoCollection.ForEach(func(repo *debian.RemoteRepo) error {
		err := repoCollection.LoadComplete(repo)
		if err != nil {
			return err
		}

		graph.AddNode("aptly", graphvizEscape(repo.UUID), map[string]string{
			"shape":     "Mrecord",
			"style":     "filled",
			"fillcolor": "darkgoldenrod1",
			"label": graphvizEscape(fmt.Sprintf("{Mirror %s|url: %s|dist: %s|comp: %s|arch: %s|pkgs: %d}",
				repo.Name, repo.ArchiveRoot, repo.Distribution, strings.Join(repo.Components, ", "),
				strings.Join(repo.Architectures, ", "), repo.NumPackages())),
		})
		existingNodes[repo.UUID] = true
		return nil
	})

	if err != nil {
		return err
	}

	fmt.Printf("Loading local repos...\n")

	localRepoCollection := debian.NewLocalRepoCollection(context.database)

	err = localRepoCollection.ForEach(func(repo *debian.LocalRepo) error {
		err := localRepoCollection.LoadComplete(repo)
		if err != nil {
			return err
		}

		graph.AddNode("aptly", graphvizEscape(repo.UUID), map[string]string{
			"shape":     "Mrecord",
			"style":     "filled",
			"fillcolor": "mediumseagreen",
			"label": graphvizEscape(fmt.Sprintf("{Repo %s|comment: %s|pkgs: %d}",
				repo.Name, repo.Comment, repo.NumPackages())),
		})
		existingNodes[repo.UUID] = true
		return nil
	})

	if err != nil {
		return err
	}

	fmt.Printf("Loading snapshots...\n")

	snapshotCollection := debian.NewSnapshotCollection(context.database)

	snapshotCollection.ForEach(func(snapshot *debian.Snapshot) error {
		existingNodes[snapshot.UUID] = true
		return nil
	})

	err = snapshotCollection.ForEach(func(snapshot *debian.Snapshot) error {
		err := snapshotCollection.LoadComplete(snapshot)
		if err != nil {
			return err
		}

		description := snapshot.Description
		if snapshot.SourceKind == "repo" {
			description = "Snapshot from repo"
		}

		graph.AddNode("aptly", graphvizEscape(snapshot.UUID), map[string]string{
			"shape":     "Mrecord",
			"style":     "filled",
			"fillcolor": "cadetblue1",
			"label":     graphvizEscape(fmt.Sprintf("{Snapshot %s|%s|pkgs: %d}", snapshot.Name, description, snapshot.NumPackages())),
		})

		if snapshot.SourceKind == "repo" || snapshot.SourceKind == "local" || snapshot.SourceKind == "snapshot" {
			for _, uuid := range snapshot.SourceIDs {
				_, exists := existingNodes[uuid]
				if exists {
					graph.AddEdge(graphvizEscape(uuid), "", graphvizEscape(snapshot.UUID), "", true, nil)
				}
			}
		}
		return nil
	})

	if err != nil {
		return err
	}

	fmt.Printf("Loading published repos...\n")

	publishedCollection := debian.NewPublishedRepoCollection(context.database)

	publishedCollection.ForEach(func(repo *debian.PublishedRepo) error {
		graph.AddNode("aptly", graphvizEscape(repo.UUID), map[string]string{
			"shape":     "Mrecord",
			"style":     "filled",
			"fillcolor": "darkolivegreen1",
			"label":     graphvizEscape(fmt.Sprintf("{Published %s/%s|comp: %s|arch: %s}", repo.Prefix, repo.Distribution, repo.Component, strings.Join(repo.Architectures, ", "))),
		})

		_, exists := existingNodes[repo.SnapshotUUID]
		if exists {
			graph.AddEdge(graphvizEscape(repo.SnapshotUUID), "", graphvizEscape(repo.UUID), "", true, nil)
		}

		return nil
	})

	fmt.Printf("Generating graph...\n")

	buf := bytes.NewBufferString(graph.String())

	tempfile, err := ioutil.TempFile("", "aptly-graph")
	if err != nil {
		return err
	}
	tempfile.Close()
	os.Remove(tempfile.Name())

	tempfilename := tempfile.Name() + ".png"

	command := exec.Command("dot", "-Tpng", "-o"+tempfilename)
	command.Stderr = os.Stderr

	stdin, err := command.StdinPipe()
	if err != nil {
		return err
	}

	err = command.Start()
	if err != nil {
		return fmt.Errorf("unable to execute dot: %s (is graphviz package installed?)", err)
	}

	_, err = io.Copy(stdin, buf)
	if err != nil {
		return err
	}

	err = stdin.Close()
	if err != nil {
		return err
	}

	err = command.Wait()
	if err != nil {
		return err
	}

	err = exec.Command("open", tempfilename).Run()
	if err != nil {
		fmt.Printf("Rendered to PNG file: %s\n", tempfilename)
		err = nil
	}

	return err
}
Example #5
0
func aptlyPublishSnapshot(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 = ""
	}

	publishedCollecton := debian.NewPublishedRepoCollection(context.database)

	snapshotCollection := debian.NewSnapshotCollection(context.database)
	snapshot, err := snapshotCollection.ByName(name)
	if err != nil {
		return fmt.Errorf("unable to publish: %s", err)
	}

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

	var sourceRepo *debian.RemoteRepo

	if snapshot.SourceKind == "repo" && len(snapshot.SourceIDs) == 1 {
		repoCollection := debian.NewRemoteRepoCollection(context.database)

		sourceRepo, _ = repoCollection.ByUUID(snapshot.SourceIDs[0])
	}

	component := cmd.Flag.Lookup("component").Value.String()
	if component == "" {
		if sourceRepo != nil && len(sourceRepo.Components) == 1 {
			component = sourceRepo.Components[0]
		} else {
			component = "main"
		}
	}

	distribution := cmd.Flag.Lookup("distribution").Value.String()
	if distribution == "" {
		if sourceRepo != nil {
			distribution = sourceRepo.Distribution
		}

		if distribution == "" {
			return fmt.Errorf("unable to guess distribution name, please specify explicitly")
		}
	}

	published, err := debian.NewPublishedRepo(prefix, distribution, component, context.architecturesList, snapshot)
	if err != nil {
		return fmt.Errorf("unable to publish: %s", err)
	}

	duplicate := publishedCollecton.CheckDuplicate(published)
	if duplicate != nil {
		publishedCollecton.LoadComplete(duplicate, snapshotCollection)
		return fmt.Errorf("prefix/distribution already used by another published repo: %s", duplicate)
	}

	signer, err := getSigner(cmd)
	if err != nil {
		return fmt.Errorf("unable to initialize GPG signer: %s", err)
	}

	packageCollection := debian.NewPackageCollection(context.database)
	err = published.Publish(context.packageRepository, packageCollection, signer)
	if err != nil {
		return fmt.Errorf("unable to publish: %s", err)
	}

	err = publishedCollecton.Add(published)
	if err != nil {
		return fmt.Errorf("unable to save to DB: %s", err)
	}

	if prefix != "" && !strings.HasSuffix(prefix, "/") {
		prefix += "/"
	}

	fmt.Printf("\nSnapshot %s has been successfully published.\nPlease setup your webserver to serve directory '%s' with autoindexing.\n",
		snapshot.Name, context.packageRepository.PublicPath())
	fmt.Printf("Now you can add following line to apt sources:\n")
	fmt.Printf("  deb http://your-server/%s %s %s\n", prefix, distribution, component)
	fmt.Printf("Don't forget to add your GPG key to apt with apt-key.\n")
	fmt.Printf("\nYou can also use `aptly serve` to publish your repositories over HTTP quickly.\n")

	return err
}
Example #6
0
func aptlyServe(cmd *commander.Command, args []string) error {
	var err error

	publishedCollection := debian.NewPublishedRepoCollection(context.database)
	snapshotCollection := debian.NewSnapshotCollection(context.database)

	if publishedCollection.Len() == 0 {
		fmt.Printf("No published repositories, unable to serve.\n")
		return nil
	}

	listen := cmd.Flag.Lookup("listen").Value.String()

	listenHost, listenPort, err := net.SplitHostPort(listen)

	if err != nil {
		return fmt.Errorf("wrong -listen specification: %s", err)
	}

	if listenHost == "" {
		listenHost, err = os.Hostname()
		if err != nil {
			listenHost = "localhost"
		}
	}

	fmt.Printf("Serving published repositories, recommended apt sources list:\n\n")

	sources := make(sort.StringSlice, 0, publishedCollection.Len())
	published := make(map[string]*debian.PublishedRepo, publishedCollection.Len())

	err = publishedCollection.ForEach(func(repo *debian.PublishedRepo) error {
		err := publishedCollection.LoadComplete(repo, snapshotCollection)
		if err != nil {
			return err
		}

		sources = append(sources, repo.String())
		published[repo.String()] = repo

		return nil
	})

	if err != nil {
		return fmt.Errorf("unable to serve: %s", err)
	}

	sort.Strings(sources)

	for _, source := range sources {
		repo := published[source]

		prefix := repo.Prefix
		if prefix == "." {
			prefix = ""
		} else {
			prefix += "/"
		}

		fmt.Printf("# %s\ndeb http://%s:%s/%s %s %s\n",
			repo, listenHost, listenPort, prefix, repo.Distribution, repo.Component)

		if utils.StrSliceHasItem(repo.Architectures, "source") {
			fmt.Printf("deb-src http://%s:%s/%s %s %s\n",
				listenHost, listenPort, prefix, repo.Distribution, repo.Component)
		}
	}

	context.database.Close()

	fmt.Printf("\nStarting web server at: %s (press Ctrl+C to quit)...\n", listen)

	err = http.ListenAndServe(listen, http.FileServer(http.Dir(context.packageRepository.PublicPath())))
	if err != nil {
		return fmt.Errorf("unable to serve: %s", err)
	}
	return nil
}