func (a *Api) RepoDeletePackage(repoName, packageRef string) error { collection := a.Ctx().CollectionFactory().LocalRepoCollection() collection.Lock() defer collection.Unlock() repo, err := collection.ByName(repoName) if err != nil { return err } err = collection.LoadComplete(repo) if err != nil { return err } list, err := deb.NewPackageListFromRefList(repo.RefList(), a.Ctx().CollectionFactory().PackageCollection(), nil) if err != nil { return err } pkg, err := a.Ctx().CollectionFactory().PackageCollection().ByKey([]byte(packageRef)) if err != nil { return err } list.Remove(pkg) repo.UpdateRefList(deb.NewPackageRefListFromPackageList(list)) return collection.Update(repo) }
func (a *Api) RepoShowPackagesDetail(repoName string) ([]*deb.Package, error) { collection := a.Ctx().CollectionFactory().LocalRepoCollection() collection.RLock() defer collection.RUnlock() repo, err := collection.ByName(repoName) if err != nil { return nil, err } err = collection.LoadComplete(repo) if err != nil { return nil, err } list, err := deb.NewPackageListFromRefList(repo.RefList(), a.Ctx().CollectionFactory().PackageCollection(), nil) if err != nil { return nil, err } result := []*deb.Package{} list.ForEach(func(p *deb.Package) error { result = append(result, p) return nil }) return result, nil }
func aptlyRepoRemove(cmd *commander.Command, args []string) error { var err error if len(args) < 2 { cmd.Usage() return commander.ErrCommandError } name := args[0] repo, err := context.CollectionFactory().LocalRepoCollection().ByName(name) if err != nil { return fmt.Errorf("unable to remove: %s", err) } err = context.CollectionFactory().LocalRepoCollection().LoadComplete(repo) if err != nil { return fmt.Errorf("unable to remove: %s", err) } context.Progress().Printf("Loading packages...\n") list, err := deb.NewPackageListFromRefList(repo.RefList(), context.CollectionFactory().PackageCollection(), context.Progress()) if err != nil { return fmt.Errorf("unable to load packages: %s", err) } queries := make([]deb.PackageQuery, len(args)-1) for i := 0; i < len(args)-1; i++ { queries[i], err = query.Parse(args[i+1]) if err != nil { return fmt.Errorf("unable to remove: %s", err) } } list.PrepareIndex() toRemove, err := list.Filter(queries, false, nil, 0, nil) if err != nil { return fmt.Errorf("unable to remove: %s", err) } toRemove.ForEach(func(p *deb.Package) error { list.Remove(p) context.Progress().ColoredPrintf("@r[-]@| %s removed", p) return nil }) if context.Flags().Lookup("dry-run").Value.Get().(bool) { context.Progress().Printf("\nChanges not saved, as dry run has been requested.\n") } else { repo.UpdateRefList(deb.NewPackageRefListFromPackageList(list)) err = context.CollectionFactory().LocalRepoCollection().Update(repo) if err != nil { return fmt.Errorf("unable to save: %s", err) } } return err }
// Common piece of code to show list of packages, // with searching & details if requested func showPackages(c *gin.Context, reflist *deb.PackageRefList) { result := []*deb.Package{} list, err := deb.NewPackageListFromRefList(reflist, context.CollectionFactory().PackageCollection(), nil) if err != nil { c.Fail(404, err) return } queryS := c.Request.URL.Query().Get("q") if queryS != "" { q, err := query.Parse(c.Request.URL.Query().Get("q")) if err != nil { c.Fail(400, err) return } withDeps := c.Request.URL.Query().Get("withDeps") == "1" architecturesList := []string{} if withDeps { if len(context.ArchitecturesList()) > 0 { architecturesList = context.ArchitecturesList() } else { architecturesList = list.Architectures(false) } sort.Strings(architecturesList) if len(architecturesList) == 0 { c.Fail(400, fmt.Errorf("unable to determine list of architectures, please specify explicitly")) return } } list.PrepareIndex() list, err = list.Filter([]deb.PackageQuery{q}, withDeps, nil, context.DependencyOptions(), architecturesList) if err != nil { c.Fail(500, fmt.Errorf("unable to search: %s", err)) return } } if c.Request.URL.Query().Get("format") == "details" { list.ForEach(func(p *deb.Package) error { result = append(result, p) return nil }) c.JSON(200, result) } else { c.JSON(200, list.Strings()) } }
func (a *Api) RepoAddFile(repoName, fileName string, removeAfter, forceReplace bool) (*aptly.RecordingResultReporter, []string, error) { verifier := &utils.GpgVerifier{} collection := a.Ctx().CollectionFactory().LocalRepoCollection() collection.Lock() defer collection.Unlock() repo, err := collection.ByName(repoName) if err != nil { return nil, []string{}, err } err = collection.LoadComplete(repo) if err != nil { return nil, []string{}, err } var reporter = &aptly.RecordingResultReporter{ Warnings: []string{}, AddedLines: []string{}, RemovedLines: []string{}, } var packageFiles, failedFiles []string packageFiles, failedFiles = deb.CollectPackageFiles([]string{fileName}, reporter) list, err := deb.NewPackageListFromRefList(repo.RefList(), a.Ctx().CollectionFactory().PackageCollection(), nil) if err != nil { return nil, []string{}, err } var processedFiles, failedFiles2 []string processedFiles, failedFiles2, err = deb.ImportPackageFiles(list, packageFiles, forceReplace, verifier, a.Ctx().PackagePool(), a.Ctx().CollectionFactory().PackageCollection(), reporter, nil) failedFiles = append(failedFiles, failedFiles2...) if err != nil { return nil, []string{}, err } repo.UpdateRefList(deb.NewPackageRefListFromPackageList(list)) err = collection.Update(repo) if err != nil { return nil, []string{}, err } processedFiles = utils.StrSliceDeduplicate(processedFiles) if removeAfter { for _, file := range processedFiles { os.Remove(file) } } if failedFiles == nil { failedFiles = []string{} } return reporter, failedFiles, nil }
func (a *Api) RepoShowPackages(repoName string) ([]string, error) { collection := a.Ctx().CollectionFactory().LocalRepoCollection() collection.RLock() defer collection.RUnlock() repo, err := collection.ByName(repoName) if err != nil { return []string{}, err } err = collection.LoadComplete(repo) if err != nil { return []string{}, err } list, err := deb.NewPackageListFromRefList(repo.RefList(), a.Ctx().CollectionFactory().PackageCollection(), nil) if err != nil { return []string{}, err } return list.Strings(), nil }
func (a *Api) SnapshotShowPackages(snapshotName string) ([]string, error) { collection := a.Ctx().CollectionFactory().SnapshotCollection() collection.RLock() defer collection.RUnlock() snapshot, err := collection.ByName(snapshotName) if err != nil { return nil, err } err = collection.LoadComplete(snapshot) if err != nil { return nil, err } list, err := deb.NewPackageListFromRefList(snapshot.RefList(), a.Ctx().CollectionFactory().PackageCollection(), nil) if err != nil { return nil, err } return list.Strings(), nil }
func aptlySnapshotMirrorRepoSearch(cmd *commander.Command, args []string) error { var err error if len(args) != 2 { cmd.Usage() return commander.ErrCommandError } name := args[0] command := cmd.Parent.Name() var reflist *deb.PackageRefList if command == "snapshot" { snapshot, err := context.CollectionFactory().SnapshotCollection().ByName(name) if err != nil { return fmt.Errorf("unable to search: %s", err) } err = context.CollectionFactory().SnapshotCollection().LoadComplete(snapshot) if err != nil { return fmt.Errorf("unable to search: %s", err) } reflist = snapshot.RefList() } else if command == "mirror" { repo, err := context.CollectionFactory().RemoteRepoCollection().ByName(name) if err != nil { return fmt.Errorf("unable to search: %s", err) } err = context.CollectionFactory().RemoteRepoCollection().LoadComplete(repo) if err != nil { return fmt.Errorf("unable to search: %s", err) } reflist = repo.RefList() } else if command == "repo" { repo, err := context.CollectionFactory().LocalRepoCollection().ByName(name) if err != nil { return fmt.Errorf("unable to search: %s", err) } err = context.CollectionFactory().LocalRepoCollection().LoadComplete(repo) if err != nil { return fmt.Errorf("unable to search: %s", err) } reflist = repo.RefList() } else { panic("unknown command") } list, err := deb.NewPackageListFromRefList(reflist, context.CollectionFactory().PackageCollection(), context.Progress()) if err != nil { return fmt.Errorf("unable to search: %s", err) } list.PrepareIndex() q, err := query.Parse(args[1]) if err != nil { return fmt.Errorf("unable to search: %s", err) } withDeps := context.Flags().Lookup("with-deps").Value.Get().(bool) architecturesList := []string{} if withDeps { if len(context.ArchitecturesList()) > 0 { architecturesList = context.ArchitecturesList() } else { architecturesList = list.Architectures(false) } sort.Strings(architecturesList) if len(architecturesList) == 0 { return fmt.Errorf("unable to determine list of architectures, please specify explicitly") } } result, err := list.Filter([]deb.PackageQuery{q}, withDeps, nil, context.DependencyOptions(), architecturesList) if err != nil { return fmt.Errorf("unable to search: %s", err) } if result.Len() == 0 { return fmt.Errorf("no results") } result.ForEach(func(p *deb.Package) error { context.Progress().Printf("%s\n", p) return nil }) return err }
func aptlyRepoInclude(cmd *commander.Command, args []string) error { var err error if len(args) < 1 { cmd.Usage() return commander.ErrCommandError } verifier, err := getVerifier(context.Flags()) if err != nil { return fmt.Errorf("unable to initialize GPG verifier: %s", err) } if verifier == nil { verifier = &utils.GpgVerifier{} } forceReplace := context.Flags().Lookup("force-replace").Value.Get().(bool) acceptUnsigned := context.Flags().Lookup("accept-unsigned").Value.Get().(bool) ignoreSignatures := context.Flags().Lookup("ignore-signatures").Value.Get().(bool) noRemoveFiles := context.Flags().Lookup("no-remove-files").Value.Get().(bool) repoTemplate, err := template.New("repo").Parse(context.Flags().Lookup("repo").Value.Get().(string)) if err != nil { return fmt.Errorf("error parsing -repo template: %s", err) } uploaders := (*deb.Uploaders)(nil) uploadersFile := context.Flags().Lookup("uploaders-file").Value.Get().(string) if uploadersFile != "" { uploaders, err = deb.NewUploadersFromFile(uploadersFile) if err != nil { return err } for i := range uploaders.Rules { uploaders.Rules[i].CompiledCondition, err = query.Parse(uploaders.Rules[i].Condition) if err != nil { return fmt.Errorf("error parsing query %s: %s", uploaders.Rules[i].Condition, err) } } } reporter := &aptly.ConsoleResultReporter{Progress: context.Progress()} var changesFiles, failedFiles, processedFiles []string changesFiles, failedFiles = deb.CollectChangesFiles(args, reporter) for _, path := range changesFiles { var changes *deb.Changes changes, err = deb.NewChanges(path) if err != nil { failedFiles = append(failedFiles, path) reporter.Warning("unable to process file %s: %s", path, err) continue } err = changes.VerifyAndParse(acceptUnsigned, ignoreSignatures, verifier) if err != nil { failedFiles = append(failedFiles, path) reporter.Warning("unable to process file %s: %s", changes.ChangesName, err) changes.Cleanup() continue } err = changes.Prepare() if err != nil { failedFiles = append(failedFiles, path) reporter.Warning("unable to process file %s: %s", changes.ChangesName, err) changes.Cleanup() continue } repoName := &bytes.Buffer{} err = repoTemplate.Execute(repoName, changes.Stanza) if err != nil { return fmt.Errorf("error applying template to repo: %s", err) } context.Progress().Printf("Loading repository %s for changes file %s...\n", repoName.String(), changes.ChangesName) repo, err := context.CollectionFactory().LocalRepoCollection().ByName(repoName.String()) if err != nil { failedFiles = append(failedFiles, path) reporter.Warning("unable to process file %s: %s", changes.ChangesName, err) changes.Cleanup() continue } currentUploaders := uploaders if repo.Uploaders != nil { currentUploaders = repo.Uploaders for i := range currentUploaders.Rules { currentUploaders.Rules[i].CompiledCondition, err = query.Parse(currentUploaders.Rules[i].Condition) if err != nil { return fmt.Errorf("error parsing query %s: %s", currentUploaders.Rules[i].Condition, err) } } } if currentUploaders != nil { if err = currentUploaders.IsAllowed(changes); err != nil { failedFiles = append(failedFiles, path) reporter.Warning("changes file skipped due to uploaders config: %s, keys %#v: %s", changes.ChangesName, changes.SignatureKeys, err) changes.Cleanup() continue } } err = context.CollectionFactory().LocalRepoCollection().LoadComplete(repo) if err != nil { return fmt.Errorf("unable to load repo: %s", err) } list, err := deb.NewPackageListFromRefList(repo.RefList(), context.CollectionFactory().PackageCollection(), context.Progress()) if err != nil { return fmt.Errorf("unable to load packages: %s", err) } packageFiles, _ := deb.CollectPackageFiles([]string{changes.TempDir}, reporter) var restriction deb.PackageQuery restriction, err = changes.PackageQuery() if err != nil { failedFiles = append(failedFiles, path) reporter.Warning("unable to process file %s: %s", changes.ChangesName, err) changes.Cleanup() continue } var processedFiles2, failedFiles2 []string processedFiles2, failedFiles2, err = deb.ImportPackageFiles(list, packageFiles, forceReplace, verifier, context.PackagePool(), context.CollectionFactory().PackageCollection(), reporter, restriction) if err != nil { return fmt.Errorf("unable to import package files: %s", err) } repo.UpdateRefList(deb.NewPackageRefListFromPackageList(list)) err = context.CollectionFactory().LocalRepoCollection().Update(repo) if err != nil { return fmt.Errorf("unable to save: %s", err) } err = changes.Cleanup() if err != nil { return err } for _, file := range failedFiles2 { failedFiles = append(failedFiles, filepath.Join(changes.BasePath, filepath.Base(file))) } for _, file := range processedFiles2 { processedFiles = append(processedFiles, filepath.Join(changes.BasePath, filepath.Base(file))) } processedFiles = append(processedFiles, path) } if !noRemoveFiles { processedFiles = utils.StrSliceDeduplicate(processedFiles) for _, file := range processedFiles { err := os.Remove(file) if err != nil { return fmt.Errorf("unable to remove file: %s", err) } } } if len(failedFiles) > 0 { context.Progress().ColoredPrintf("@y[!]@| @!Some files were skipped due to errors:@|") for _, file := range failedFiles { context.Progress().ColoredPrintf(" %s", file) } return fmt.Errorf("some files failed to be added") } return err }
func aptlySnapshotPull(cmd *commander.Command, args []string) error { var err error if len(args) < 4 { cmd.Usage() return commander.ErrCommandError } noDeps := context.Flags().Lookup("no-deps").Value.Get().(bool) noRemove := context.Flags().Lookup("no-remove").Value.Get().(bool) allMatches := context.Flags().Lookup("all-matches").Value.Get().(bool) // Load <name> snapshot snapshot, err := context.CollectionFactory().SnapshotCollection().ByName(args[0]) if err != nil { return fmt.Errorf("unable to pull: %s", err) } err = context.CollectionFactory().SnapshotCollection().LoadComplete(snapshot) if err != nil { return fmt.Errorf("unable to pull: %s", err) } // Load <source> snapshot source, err := context.CollectionFactory().SnapshotCollection().ByName(args[1]) if err != nil { return fmt.Errorf("unable to pull: %s", err) } err = context.CollectionFactory().SnapshotCollection().LoadComplete(source) if err != nil { return fmt.Errorf("unable to pull: %s", err) } context.Progress().Printf("Dependencies would be pulled into snapshot:\n %s\nfrom snapshot:\n %s\nand result would be saved as new snapshot %s.\n", snapshot, source, args[2]) // Convert snapshot to package list context.Progress().Printf("Loading packages (%d)...\n", snapshot.RefList().Len()+source.RefList().Len()) packageList, err := deb.NewPackageListFromRefList(snapshot.RefList(), context.CollectionFactory().PackageCollection(), context.Progress()) if err != nil { return fmt.Errorf("unable to load packages: %s", err) } sourcePackageList, err := deb.NewPackageListFromRefList(source.RefList(), context.CollectionFactory().PackageCollection(), context.Progress()) if err != nil { return fmt.Errorf("unable to load packages: %s", err) } context.Progress().Printf("Building indexes...\n") packageList.PrepareIndex() sourcePackageList.PrepareIndex() // Calculate architectures var architecturesList []string if len(context.ArchitecturesList()) > 0 { architecturesList = context.ArchitecturesList() } else { architecturesList = packageList.Architectures(false) } sort.Strings(architecturesList) if len(architecturesList) == 0 { return fmt.Errorf("unable to determine list of architectures, please specify explicitly") } // Build architecture query: (arch == "i386" | arch == "amd64" | ...) var archQuery deb.PackageQuery = &deb.FieldQuery{Field: "$Architecture", Relation: deb.VersionEqual, Value: ""} for _, arch := range architecturesList { archQuery = &deb.OrQuery{L: &deb.FieldQuery{Field: "$Architecture", Relation: deb.VersionEqual, Value: arch}, R: archQuery} } // Initial queries out of arguments queries := make([]deb.PackageQuery, len(args)-3) for i, arg := range args[3:] { queries[i], err = query.Parse(arg) if err != nil { return fmt.Errorf("unable to parse query: %s", err) } // Add architecture filter queries[i] = &deb.AndQuery{L: queries[i], R: archQuery} } // Filter with dependencies as requested result, err := sourcePackageList.Filter(queries, !noDeps, packageList, context.DependencyOptions(), architecturesList) if err != nil { return fmt.Errorf("unable to pull: %s", err) } result.PrepareIndex() alreadySeen := map[string]bool{} result.ForEachIndexed(func(pkg *deb.Package) error { key := pkg.Architecture + "_" + pkg.Name _, seen := alreadySeen[key] // If we haven't seen such name-architecture pair and were instructed to remove, remove it if !noRemove && !seen { // Remove all packages with the same name and architecture pS := packageList.Search(deb.Dependency{Architecture: pkg.Architecture, Pkg: pkg.Name}, true) for _, p := range pS { packageList.Remove(p) context.Progress().ColoredPrintf("@r[-]@| %s removed", p) } } // If !allMatches, add only first matching name-arch package if !seen || allMatches { packageList.Add(pkg) context.Progress().ColoredPrintf("@g[+]@| %s added", pkg) } alreadySeen[key] = true return nil }) alreadySeen = nil if context.Flags().Lookup("dry-run").Value.Get().(bool) { context.Progress().Printf("\nNot creating snapshot, as dry run was requested.\n") } else { // Create <destination> snapshot destination := deb.NewSnapshotFromPackageList(args[2], []*deb.Snapshot{snapshot, source}, packageList, fmt.Sprintf("Pulled into '%s' with '%s' as source, pull request was: '%s'", snapshot.Name, source.Name, strings.Join(args[3:], " "))) err = context.CollectionFactory().SnapshotCollection().Add(destination) if err != nil { return fmt.Errorf("unable to create snapshot: %s", err) } context.Progress().Printf("\nSnapshot %s successfully created.\nYou can run 'aptly publish snapshot %s' to publish snapshot as Debian repository.\n", destination.Name, destination.Name) } return err }
func aptlySnapshotVerify(cmd *commander.Command, args []string) error { var err error if len(args) < 1 { cmd.Usage() return err } snapshots := make([]*deb.Snapshot, len(args)) for i := range snapshots { snapshots[i], err = context.CollectionFactory().SnapshotCollection().ByName(args[i]) if err != nil { return fmt.Errorf("unable to verify: %s", err) } err = context.CollectionFactory().SnapshotCollection().LoadComplete(snapshots[i]) if err != nil { return fmt.Errorf("unable to verify: %s", err) } } context.Progress().Printf("Loading packages...\n") packageList, err := deb.NewPackageListFromRefList(snapshots[0].RefList(), context.CollectionFactory().PackageCollection(), context.Progress()) if err != nil { fmt.Errorf("unable to load packages: %s", err) } sourcePackageList := deb.NewPackageList() err = sourcePackageList.Append(packageList) if err != nil { fmt.Errorf("unable to merge sources: %s", err) } var pL *deb.PackageList for i := 1; i < len(snapshots); i++ { pL, err = deb.NewPackageListFromRefList(snapshots[i].RefList(), context.CollectionFactory().PackageCollection(), context.Progress()) if err != nil { fmt.Errorf("unable to load packages: %s", err) } err = sourcePackageList.Append(pL) if err != nil { fmt.Errorf("unable to merge sources: %s", err) } } sourcePackageList.PrepareIndex() var architecturesList []string if len(context.ArchitecturesList()) > 0 { architecturesList = context.ArchitecturesList() } else { architecturesList = packageList.Architectures(true) } if len(architecturesList) == 0 { return fmt.Errorf("unable to determine list of architectures, please specify explicitly") } context.Progress().Printf("Verifying...\n") missing, err := packageList.VerifyDependencies(context.DependencyOptions(), architecturesList, sourcePackageList, context.Progress()) if err != nil { return fmt.Errorf("unable to verify dependencies: %s", err) } if len(missing) == 0 { context.Progress().Printf("All dependencies are satisfied.\n") } else { context.Progress().Printf("Missing dependencies (%d):\n", len(missing)) deps := make([]string, len(missing)) i := 0 for _, dep := range missing { deps[i] = dep.String() i++ } sort.Strings(deps) for _, dep := range deps { context.Progress().Printf(" %s\n", dep) } } return err }
func aptlyRepoMoveCopyImport(cmd *commander.Command, args []string) error { var err error if len(args) < 3 { cmd.Usage() return commander.ErrCommandError } command := cmd.Name() dstRepo, err := context.CollectionFactory().LocalRepoCollection().ByName(args[1]) if err != nil { return fmt.Errorf("unable to %s: %s", command, err) } err = context.CollectionFactory().LocalRepoCollection().LoadComplete(dstRepo) if err != nil { return fmt.Errorf("unable to %s: %s", command, err) } var ( srcRefList *deb.PackageRefList srcRepo *deb.LocalRepo ) if command == "copy" || command == "move" { srcRepo, err = context.CollectionFactory().LocalRepoCollection().ByName(args[0]) if err != nil { return fmt.Errorf("unable to %s: %s", command, err) } if srcRepo.UUID == dstRepo.UUID { return fmt.Errorf("unable to %s: source and destination are the same", command) } err = context.CollectionFactory().LocalRepoCollection().LoadComplete(srcRepo) if err != nil { return fmt.Errorf("unable to %s: %s", command, err) } srcRefList = srcRepo.RefList() } else if command == "import" { var srcRemoteRepo *deb.RemoteRepo srcRemoteRepo, err = context.CollectionFactory().RemoteRepoCollection().ByName(args[0]) if err != nil { return fmt.Errorf("unable to %s: %s", command, err) } err = context.CollectionFactory().RemoteRepoCollection().LoadComplete(srcRemoteRepo) if err != nil { return fmt.Errorf("unable to %s: %s", command, err) } if srcRemoteRepo.RefList() == nil { return fmt.Errorf("unable to %s: mirror not updated", command) } srcRefList = srcRemoteRepo.RefList() } else { panic("unexpected command") } context.Progress().Printf("Loading packages...\n") dstList, err := deb.NewPackageListFromRefList(dstRepo.RefList(), context.CollectionFactory().PackageCollection(), context.Progress()) if err != nil { return fmt.Errorf("unable to load packages: %s", err) } srcList, err := deb.NewPackageListFromRefList(srcRefList, context.CollectionFactory().PackageCollection(), context.Progress()) if err != nil { return fmt.Errorf("unable to load packages: %s", err) } srcList.PrepareIndex() var architecturesList []string withDeps := context.flags.Lookup("with-deps").Value.Get().(bool) if withDeps { dstList.PrepareIndex() // Calculate architectures if len(context.ArchitecturesList()) > 0 { architecturesList = context.ArchitecturesList() } else { architecturesList = dstList.Architectures(false) } sort.Strings(architecturesList) if len(architecturesList) == 0 { return fmt.Errorf("unable to determine list of architectures, please specify explicitly") } } toProcess, err := srcList.Filter(args[2:], withDeps, dstList, context.DependencyOptions(), architecturesList) if err != nil { return fmt.Errorf("unable to %s: %s", command, err) } var verb string if command == "move" { verb = "moved" } else if command == "copy" { verb = "copied" } else if command == "import" { verb = "imported" } err = toProcess.ForEach(func(p *deb.Package) error { err = dstList.Add(p) if err != nil { return err } if command == "move" { srcList.Remove(p) } context.Progress().ColoredPrintf("@g[o]@| %s %s", p, verb) return nil }) if err != nil { return fmt.Errorf("unable to %s: %s", command, err) } if context.flags.Lookup("dry-run").Value.Get().(bool) { context.Progress().Printf("\nChanges not saved, as dry run has been requested.\n") } else { dstRepo.UpdateRefList(deb.NewPackageRefListFromPackageList(dstList)) err = context.CollectionFactory().LocalRepoCollection().Update(dstRepo) if err != nil { return fmt.Errorf("unable to save: %s", err) } if command == "move" { srcRepo.UpdateRefList(deb.NewPackageRefListFromPackageList(srcList)) err = context.CollectionFactory().LocalRepoCollection().Update(srcRepo) if err != nil { return fmt.Errorf("unable to save: %s", err) } } } return err }
func aptlyRepoAdd(cmd *commander.Command, args []string) error { var err error if len(args) < 2 { cmd.Usage() return err } name := args[0] verifier := &utils.GpgVerifier{} repo, err := context.CollectionFactory().LocalRepoCollection().ByName(name) if err != nil { return fmt.Errorf("unable to add: %s", err) } err = context.CollectionFactory().LocalRepoCollection().LoadComplete(repo) if err != nil { return fmt.Errorf("unable to add: %s", err) } context.Progress().Printf("Loading packages...\n") list, err := deb.NewPackageListFromRefList(repo.RefList(), context.CollectionFactory().PackageCollection(), context.Progress()) if err != nil { return fmt.Errorf("unable to load packages: %s", err) } packageFiles := []string{} for _, location := range args[1:] { info, err2 := os.Stat(location) if err2 != nil { context.Progress().ColoredPrintf("@y[!]@| @!Unable to process %s: %s@|", location, err2) continue } if info.IsDir() { err2 = filepath.Walk(location, func(path string, info os.FileInfo, err3 error) error { if err3 != nil { return err3 } if info.IsDir() { return nil } if strings.HasSuffix(info.Name(), ".deb") || strings.HasSuffix(info.Name(), ".dsc") { packageFiles = append(packageFiles, path) } return nil }) } else { if strings.HasSuffix(info.Name(), ".deb") || strings.HasSuffix(info.Name(), ".dsc") { packageFiles = append(packageFiles, location) } else { context.Progress().ColoredPrintf("@y[!]@| @!Unknwon file extenstion: %s@|", location) continue } } } processedFiles := []string{} sort.Strings(packageFiles) for _, file := range packageFiles { var ( stanza deb.Stanza p *deb.Package ) candidateProcessedFiles := []string{} isSourcePackage := strings.HasSuffix(file, ".dsc") if isSourcePackage { stanza, err = deb.GetControlFileFromDsc(file, verifier) if err == nil { stanza["Package"] = stanza["Source"] delete(stanza, "Source") p, err = deb.NewSourcePackageFromControlFile(stanza) } } else { stanza, err = deb.GetControlFileFromDeb(file) p = deb.NewPackageFromControlFile(stanza) } if err != nil { context.Progress().ColoredPrintf("@y[!]@| @!Unable to read file %s: %s@|", file, err) continue } var checksums utils.ChecksumInfo checksums, err = utils.ChecksumsForFile(file) if err != nil { return err } if isSourcePackage { p.UpdateFiles(append(p.Files(), deb.PackageFile{Filename: filepath.Base(file), Checksums: checksums})) } else { p.UpdateFiles([]deb.PackageFile{deb.PackageFile{Filename: filepath.Base(file), Checksums: checksums}}) } err = context.PackagePool().Import(file, checksums.MD5) if err != nil { context.Progress().ColoredPrintf("@y[!]@| @!Unable to import file %s into pool: %s@|", file, err) continue } candidateProcessedFiles = append(candidateProcessedFiles, file) // go over all files, except for the last one (.dsc/.deb itself) for _, f := range p.Files() { if filepath.Base(f.Filename) == filepath.Base(file) { continue } sourceFile := filepath.Join(filepath.Dir(file), filepath.Base(f.Filename)) err = context.PackagePool().Import(sourceFile, f.Checksums.MD5) if err != nil { context.Progress().ColoredPrintf("@y[!]@| @!Unable to import file %s into pool: %s@|", sourceFile, err) break } candidateProcessedFiles = append(candidateProcessedFiles, sourceFile) } if err != nil { // some files haven't been imported continue } err = context.CollectionFactory().PackageCollection().Update(p) if err != nil { context.Progress().ColoredPrintf("@y[!]@| @!Unable to save package %s: %s@|", p, err) continue } err = list.Add(p) if err != nil { context.Progress().ColoredPrintf("@y[!]@| @!Unable to add package to repo %s: %s@|", p, err) continue } context.Progress().ColoredPrintf("@g[+]@| %s added@|", p) processedFiles = append(processedFiles, candidateProcessedFiles...) } repo.UpdateRefList(deb.NewPackageRefListFromPackageList(list)) err = context.CollectionFactory().LocalRepoCollection().Update(repo) if err != nil { return fmt.Errorf("unable to save: %s", err) } if context.flags.Lookup("remove-files").Value.Get().(bool) { processedFiles = utils.StrSliceDeduplicate(processedFiles) for _, file := range processedFiles { err := os.Remove(file) if err != nil { return fmt.Errorf("unable to remove file: %s", err) } } } return err }
func aptlyRepoAdd(cmd *commander.Command, args []string) error { var err error if len(args) < 2 { cmd.Usage() return commander.ErrCommandError } name := args[0] verifier := &utils.GpgVerifier{} repo, err := context.CollectionFactory().LocalRepoCollection().ByName(name) if err != nil { return fmt.Errorf("unable to add: %s", err) } err = context.CollectionFactory().LocalRepoCollection().LoadComplete(repo) if err != nil { return fmt.Errorf("unable to add: %s", err) } context.Progress().Printf("Loading packages...\n") list, err := deb.NewPackageListFromRefList(repo.RefList(), context.CollectionFactory().PackageCollection(), context.Progress()) if err != nil { return fmt.Errorf("unable to load packages: %s", err) } forceReplace := context.Flags().Lookup("force-replace").Value.Get().(bool) var packageFiles, failedFiles []string packageFiles, failedFiles = deb.CollectPackageFiles(args[1:], &aptly.ConsoleResultReporter{Progress: context.Progress()}) var processedFiles, failedFiles2 []string processedFiles, failedFiles2, err = deb.ImportPackageFiles(list, packageFiles, forceReplace, verifier, context.PackagePool(), context.CollectionFactory().PackageCollection(), &aptly.ConsoleResultReporter{Progress: context.Progress()}, nil) failedFiles = append(failedFiles, failedFiles2...) if err != nil { return fmt.Errorf("unable to import package files: %s", err) } repo.UpdateRefList(deb.NewPackageRefListFromPackageList(list)) err = context.CollectionFactory().LocalRepoCollection().Update(repo) if err != nil { return fmt.Errorf("unable to save: %s", err) } if context.Flags().Lookup("remove-files").Value.Get().(bool) { processedFiles = utils.StrSliceDeduplicate(processedFiles) for _, file := range processedFiles { err := os.Remove(file) if err != nil { return fmt.Errorf("unable to remove file: %s", err) } } } if len(failedFiles) > 0 { context.Progress().ColoredPrintf("@y[!]@| @!Some files were skipped due to errors:@|") for _, file := range failedFiles { context.Progress().ColoredPrintf(" %s", file) } return fmt.Errorf("some files failed to be added") } return err }
func aptlySnapshotFilter(cmd *commander.Command, args []string) error { var err error if len(args) < 3 { cmd.Usage() return commander.ErrCommandError } withDeps := context.Flags().Lookup("with-deps").Value.Get().(bool) // Load <source> snapshot source, err := context.CollectionFactory().SnapshotCollection().ByName(args[0]) if err != nil { return fmt.Errorf("unable to filter: %s", err) } err = context.CollectionFactory().SnapshotCollection().LoadComplete(source) if err != nil { return fmt.Errorf("unable to filter: %s", err) } // Convert snapshot to package list context.Progress().Printf("Loading packages (%d)...\n", source.RefList().Len()) packageList, err := deb.NewPackageListFromRefList(source.RefList(), context.CollectionFactory().PackageCollection(), context.Progress()) if err != nil { return fmt.Errorf("unable to load packages: %s", err) } context.Progress().Printf("Building indexes...\n") packageList.PrepareIndex() // Calculate architectures var architecturesList []string if len(context.ArchitecturesList()) > 0 { architecturesList = context.ArchitecturesList() } else { architecturesList = packageList.Architectures(false) } sort.Strings(architecturesList) if len(architecturesList) == 0 && withDeps { return fmt.Errorf("unable to determine list of architectures, please specify explicitly") } // Initial queries out of arguments queries := make([]deb.PackageQuery, len(args)-2) for i, arg := range args[2:] { queries[i], err = query.Parse(arg) if err != nil { return fmt.Errorf("unable to parse query: %s", err) } } // Filter with dependencies as requested result, err := packageList.Filter(queries, withDeps, nil, context.DependencyOptions(), architecturesList) if err != nil { return fmt.Errorf("unable to filter: %s", err) } // Create <destination> snapshot destination := deb.NewSnapshotFromPackageList(args[1], []*deb.Snapshot{source}, result, fmt.Sprintf("Filtered '%s', query was: '%s'", source.Name, strings.Join(args[2:], " "))) err = context.CollectionFactory().SnapshotCollection().Add(destination) if err != nil { return fmt.Errorf("unable to create snapshot: %s", err) } context.Progress().Printf("\nSnapshot %s successfully filtered.\nYou can run 'aptly publish snapshot %s' to publish snapshot as Debian repository.\n", destination.Name, destination.Name) return err }
// Handler for both add and delete func apiReposPackagesAddDelete(c *gin.Context, cb func(list *deb.PackageList, p *deb.Package) error) { var b struct { PackageRefs []string } if !c.Bind(&b) { return } collection := context.CollectionFactory().LocalRepoCollection() collection.Lock() defer collection.Unlock() repo, err := collection.ByName(c.Params.ByName("name")) if err != nil { c.Fail(404, err) return } err = collection.LoadComplete(repo) if err != nil { c.Fail(500, err) return } list, err := deb.NewPackageListFromRefList(repo.RefList(), context.CollectionFactory().PackageCollection(), nil) if err != nil { c.Fail(500, err) return } // verify package refs and build package list for _, ref := range b.PackageRefs { var p *deb.Package p, err = context.CollectionFactory().PackageCollection().ByKey([]byte(ref)) if err != nil { if err == database.ErrNotFound { c.Fail(404, fmt.Errorf("package %s: %s", ref, err)) } else { c.Fail(500, err) } return } err = cb(list, p) if err != nil { c.Fail(400, err) return } } repo.UpdateRefList(deb.NewPackageRefListFromPackageList(list)) err = context.CollectionFactory().LocalRepoCollection().Update(repo) if err != nil { c.Fail(500, fmt.Errorf("unable to save: %s", err)) return } c.JSON(200, repo) }
// POST /repos/:name/file/:dir func apiReposPackageFromDir(c *gin.Context) { forceReplace := c.Request.URL.Query().Get("forceReplace") == "1" noRemove := c.Request.URL.Query().Get("noRemove") == "1" if !verifyDir(c) { return } fileParam := c.Params.ByName("file") if fileParam != "" && !verifyPath(fileParam) { c.Fail(400, fmt.Errorf("wrong file")) return } collection := context.CollectionFactory().LocalRepoCollection() collection.Lock() defer collection.Unlock() repo, err := collection.ByName(c.Params.ByName("name")) if err != nil { c.Fail(404, err) return } err = collection.LoadComplete(repo) if err != nil { c.Fail(500, err) return } verifier := &utils.GpgVerifier{} var ( sources []string packageFiles, failedFiles []string processedFiles, failedFiles2 []string reporter = &aptly.RecordingResultReporter{ Warnings: []string{}, AddedLines: []string{}, RemovedLines: []string{}, } list *deb.PackageList ) if fileParam == "" { sources = []string{filepath.Join(context.UploadPath(), c.Params.ByName("dir"))} } else { sources = []string{filepath.Join(context.UploadPath(), c.Params.ByName("dir"), c.Params.ByName("file"))} } packageFiles, failedFiles = deb.CollectPackageFiles(sources, reporter) list, err = deb.NewPackageListFromRefList(repo.RefList(), context.CollectionFactory().PackageCollection(), nil) if err != nil { c.Fail(500, fmt.Errorf("unable to load packages: %s", err)) return } processedFiles, failedFiles2, err = deb.ImportPackageFiles(list, packageFiles, forceReplace, verifier, context.PackagePool(), context.CollectionFactory().PackageCollection(), reporter, nil) failedFiles = append(failedFiles, failedFiles2...) if err != nil { c.Fail(500, fmt.Errorf("unable to import package files: %s", err)) return } repo.UpdateRefList(deb.NewPackageRefListFromPackageList(list)) err = context.CollectionFactory().LocalRepoCollection().Update(repo) if err != nil { c.Fail(500, fmt.Errorf("unable to save: %s", err)) return } if !noRemove { processedFiles = utils.StrSliceDeduplicate(processedFiles) for _, file := range processedFiles { err := os.Remove(file) if err != nil { reporter.Warning("unable to remove file %s: %s", file, err) } } // atempt to remove dir, if it fails, that's fine: probably it's not empty os.Remove(filepath.Join(context.UploadPath(), c.Params.ByName("dir"))) } if failedFiles == nil { failedFiles = []string{} } c.JSON(200, gin.H{ "Report": reporter, "FailedFiles": failedFiles, }) }
func aptlySnapshotPull(cmd *commander.Command, args []string) error { var err error if len(args) < 4 { cmd.Usage() return commander.ErrCommandError } noDeps := context.flags.Lookup("no-deps").Value.Get().(bool) noRemove := context.flags.Lookup("no-remove").Value.Get().(bool) // Load <name> snapshot snapshot, err := context.CollectionFactory().SnapshotCollection().ByName(args[0]) if err != nil { return fmt.Errorf("unable to pull: %s", err) } err = context.CollectionFactory().SnapshotCollection().LoadComplete(snapshot) if err != nil { return fmt.Errorf("unable to pull: %s", err) } // Load <source> snapshot source, err := context.CollectionFactory().SnapshotCollection().ByName(args[1]) if err != nil { return fmt.Errorf("unable to pull: %s", err) } err = context.CollectionFactory().SnapshotCollection().LoadComplete(source) if err != nil { return fmt.Errorf("unable to pull: %s", err) } context.Progress().Printf("Dependencies would be pulled into snapshot:\n %s\nfrom snapshot:\n %s\nand result would be saved as new snapshot %s.\n", snapshot, source, args[2]) // Convert snapshot to package list context.Progress().Printf("Loading packages (%d)...\n", snapshot.RefList().Len()+source.RefList().Len()) packageList, err := deb.NewPackageListFromRefList(snapshot.RefList(), context.CollectionFactory().PackageCollection(), context.Progress()) if err != nil { return fmt.Errorf("unable to load packages: %s", err) } sourcePackageList, err := deb.NewPackageListFromRefList(source.RefList(), context.CollectionFactory().PackageCollection(), context.Progress()) if err != nil { return fmt.Errorf("unable to load packages: %s", err) } context.Progress().Printf("Building indexes...\n") packageList.PrepareIndex() sourcePackageList.PrepareIndex() // Calculate architectures var architecturesList []string if len(context.ArchitecturesList()) > 0 { architecturesList = context.ArchitecturesList() } else { architecturesList = packageList.Architectures(false) } sort.Strings(architecturesList) if len(architecturesList) == 0 { return fmt.Errorf("unable to determine list of architectures, please specify explicitly") } // Initial dependencies out of arguments initialDependencies := make([]deb.Dependency, len(args)-3) for i, arg := range args[3:] { initialDependencies[i], err = deb.ParseDependency(arg) if err != nil { return fmt.Errorf("unable to parse argument: %s", err) } } // Perform pull for _, arch := range architecturesList { dependencies := make([]deb.Dependency, len(initialDependencies), 2*len(initialDependencies)) for i := range dependencies { dependencies[i] = initialDependencies[i] dependencies[i].Architecture = arch } // Go over list of initial dependencies + list of dependencies found for i := 0; i < len(dependencies); i++ { dep := dependencies[i] // Search for package that can satisfy dependencies pkg := sourcePackageList.Search(dep) if pkg == nil { context.Progress().ColoredPrintf("@y[!]@| @!Dependency %s can't be satisfied with source %s@|", &dep, source) continue } if !noRemove { // Remove all packages with the same name and architecture for p := packageList.Search(deb.Dependency{Architecture: pkg.Architecture, Pkg: pkg.Name}); p != nil; { packageList.Remove(p) context.Progress().ColoredPrintf("@r[-]@| %s removed", p) p = packageList.Search(deb.Dependency{Architecture: pkg.Architecture, Pkg: pkg.Name}) } } // Add new discovered package packageList.Add(pkg) context.Progress().ColoredPrintf("@g[+]@| %s added", pkg) if noDeps { continue } // Find missing dependencies for single added package pL := deb.NewPackageList() pL.Add(pkg) var missing []deb.Dependency missing, err = pL.VerifyDependencies(context.DependencyOptions(), []string{arch}, packageList, nil) if err != nil { context.Progress().ColoredPrintf("@y[!]@| @!Error while verifying dependencies for pkg %s: %s@|", pkg, err) } // Append missing dependencies to the list of dependencies to satisfy for _, misDep := range missing { found := false for _, d := range dependencies { if d == misDep { found = true break } } if !found { dependencies = append(dependencies, misDep) } } } } if context.flags.Lookup("dry-run").Value.Get().(bool) { context.Progress().Printf("\nNot creating snapshot, as dry run was requested.\n") } else { // Create <destination> snapshot destination := deb.NewSnapshotFromPackageList(args[2], []*deb.Snapshot{snapshot, source}, packageList, fmt.Sprintf("Pulled into '%s' with '%s' as source, pull request was: '%s'", snapshot.Name, source.Name, strings.Join(args[3:], " "))) err = context.CollectionFactory().SnapshotCollection().Add(destination) if err != nil { return fmt.Errorf("unable to create snapshot: %s", err) } context.Progress().Printf("\nSnapshot %s successfully created.\nYou can run 'aptly publish snapshot %s' to publish snapshot as Debian repository.\n", destination.Name, destination.Name) } return err }