Support for locking, unlocking, interruption, cleanup. #45 #114

This commit is contained in:
Andrey Smirnov
2014-10-03 01:34:22 +04:00
parent a356f3dff9
commit ad11053412
6 changed files with 81 additions and 11 deletions
+5
View File
@@ -20,6 +20,11 @@ func aptlyMirrorDrop(cmd *commander.Command, args []string) error {
return fmt.Errorf("unable to drop: %s", err) return fmt.Errorf("unable to drop: %s", err)
} }
err = repo.CheckLock()
if err != nil {
return fmt.Errorf("unable to drop: %s", err)
}
force := context.flags.Lookup("force").Value.Get().(bool) force := context.flags.Lookup("force").Value.Get().(bool)
if !force { if !force {
snapshots := context.CollectionFactory().SnapshotCollection().ByRemoteRepoSource(repo) snapshots := context.CollectionFactory().SnapshotCollection().ByRemoteRepoSource(repo)
+5
View File
@@ -19,6 +19,11 @@ func aptlyMirrorEdit(cmd *commander.Command, args []string) error {
return fmt.Errorf("unable to edit: %s", err) return fmt.Errorf("unable to edit: %s", err)
} }
err = repo.CheckLock()
if err != nil {
return fmt.Errorf("unable to edit: %s", err)
}
context.flags.Visit(func(flag *flag.Flag) { context.flags.Visit(func(flag *flag.Flag) {
switch flag.Name { switch flag.Name {
case "filter": case "filter":
+5
View File
@@ -24,6 +24,11 @@ func aptlyMirrorRename(cmd *commander.Command, args []string) error {
return fmt.Errorf("unable to rename: %s", err) return fmt.Errorf("unable to rename: %s", err)
} }
err = repo.CheckLock()
if err != nil {
return fmt.Errorf("unable to rename: %s", err)
}
_, err = context.CollectionFactory().RemoteRepoCollection().ByName(newName) _, err = context.CollectionFactory().RemoteRepoCollection().ByName(newName)
if err == nil { if err == nil {
return fmt.Errorf("unable to rename: mirror %s already exists", newName) return fmt.Errorf("unable to rename: mirror %s already exists", newName)
+4
View File
@@ -2,6 +2,7 @@ package cmd
import ( import (
"fmt" "fmt"
"github.com/smira/aptly/deb"
"github.com/smira/aptly/utils" "github.com/smira/aptly/utils"
"github.com/smira/commander" "github.com/smira/commander"
"github.com/smira/flag" "github.com/smira/flag"
@@ -28,6 +29,9 @@ func aptlyMirrorShow(cmd *commander.Command, args []string) error {
} }
fmt.Printf("Name: %s\n", repo.Name) fmt.Printf("Name: %s\n", repo.Name)
if repo.Status == deb.MirrorUpdating {
fmt.Printf("Status: In Update (PID %d)\n", repo.WorkerPID)
}
fmt.Printf("Archive Root URL: %s\n", repo.ArchiveRoot) fmt.Printf("Archive Root URL: %s\n", repo.ArchiveRoot)
fmt.Printf("Distribution: %s\n", repo.Distribution) fmt.Printf("Distribution: %s\n", repo.Distribution)
fmt.Printf("Components: %s\n", strings.Join(repo.Components, ", ")) fmt.Printf("Components: %s\n", strings.Join(repo.Components, ", "))
+57 -11
View File
@@ -7,8 +7,9 @@ import (
"github.com/smira/aptly/utils" "github.com/smira/aptly/utils"
"github.com/smira/commander" "github.com/smira/commander"
"github.com/smira/flag" "github.com/smira/flag"
"os"
"os/signal"
"strings" "strings"
"time"
) )
func aptlyMirrorUpdate(cmd *commander.Command, args []string) error { func aptlyMirrorUpdate(cmd *commander.Command, args []string) error {
@@ -30,6 +31,14 @@ func aptlyMirrorUpdate(cmd *commander.Command, args []string) error {
return fmt.Errorf("unable to update: %s", err) return fmt.Errorf("unable to update: %s", err)
} }
force := context.flags.Lookup("force").Value.Get().(bool)
if !force {
err = repo.CheckLock()
if err != nil {
return fmt.Errorf("unable to update: %s", err)
}
}
ignoreMismatch := context.flags.Lookup("ignore-checksums").Value.Get().(bool) ignoreMismatch := context.flags.Lookup("ignore-checksums").Value.Get().(bool)
verifier, err := getVerifier(context.flags) verifier, err := getVerifier(context.flags)
@@ -76,6 +85,30 @@ func aptlyMirrorUpdate(cmd *commander.Command, args []string) error {
return fmt.Errorf("unable to update: %s", err) return fmt.Errorf("unable to update: %s", err)
} }
defer func() {
// on any interreption, unlock the mirror
err := context.ReOpenDatabase()
if err == nil {
repo.MarkAsIdle()
context.CollectionFactory().RemoteRepoCollection().Update(repo)
}
}()
repo.MarkAsUpdating()
err = context.CollectionFactory().RemoteRepoCollection().Update(repo)
if err != nil {
return fmt.Errorf("unable to update: %s", err)
}
err = context.CloseDatabase()
if err != nil {
return fmt.Errorf("unable to update: %s", err)
}
// Catch ^C
sigch := make(chan os.Signal)
signal.Notify(sigch, os.Interrupt)
count := len(queue) count := len(queue)
context.Progress().Printf("Download queue: %d items (%s)\n", count, utils.HumanBytes(downloadSize)) context.Progress().Printf("Download queue: %d items (%s)\n", count, utils.HumanBytes(downloadSize))
@@ -85,32 +118,44 @@ func aptlyMirrorUpdate(cmd *commander.Command, args []string) error {
// Download all package files // Download all package files
ch := make(chan error, count) ch := make(chan error, count)
for _, task := range queue { go func() {
context.Downloader().DownloadWithChecksum(repo.PackageURL(task.RepoURI).String(), task.DestinationPath, ch, task.Checksums, ignoreMismatch) for _, task := range queue {
} context.Downloader().DownloadWithChecksum(repo.PackageURL(task.RepoURI).String(), task.DestinationPath, ch, task.Checksums, ignoreMismatch)
}
// We don't need queued after this point // We don't need queue after this point
queue = nil queue = nil
}()
// Wait for all downloads to finish // Wait for all downloads to finish
errors := make([]string, 0) errors := make([]string, 0)
for count > 0 { for count > 0 {
err = <-ch select {
if err != nil { case <-sigch:
errors = append(errors, err.Error()) signal.Stop(sigch)
return fmt.Errorf("unable to update: interrupted")
case err = <-ch:
if err != nil {
errors = append(errors, err.Error())
}
count--
} }
count--
} }
context.Progress().ShutdownBar() context.Progress().ShutdownBar()
signal.Stop(sigch)
if len(errors) > 0 { if len(errors) > 0 {
return fmt.Errorf("unable to update: download errors:\n %s\n", strings.Join(errors, "\n ")) return fmt.Errorf("unable to update: download errors:\n %s\n", strings.Join(errors, "\n "))
} }
repo.LastDownloadDate = time.Now() err = context.ReOpenDatabase()
if err != nil {
return fmt.Errorf("unable to update: %s", err)
}
repo.FinalizeDownload()
err = context.CollectionFactory().RemoteRepoCollection().Update(repo) err = context.CollectionFactory().RemoteRepoCollection().Update(repo)
if err != nil { if err != nil {
return fmt.Errorf("unable to update: %s", err) return fmt.Errorf("unable to update: %s", err)
@@ -137,6 +182,7 @@ Example:
Flag: *flag.NewFlagSet("aptly-mirror-update", flag.ExitOnError), Flag: *flag.NewFlagSet("aptly-mirror-update", flag.ExitOnError),
} }
cmd.Flag.Bool("force", false, "force update mirror even if it is locked by another process")
cmd.Flag.Bool("ignore-checksums", false, "ignore checksum mismatches while downloading package files and metadata") cmd.Flag.Bool("ignore-checksums", false, "ignore checksum mismatches while downloading package files and metadata")
cmd.Flag.Bool("ignore-signatures", false, "disable verification of Release file signatures") cmd.Flag.Bool("ignore-signatures", false, "disable verification of Release file signatures")
cmd.Flag.Int64("download-limit", 0, "limit download speed (kbytes/sec)") cmd.Flag.Int64("download-limit", 0, "limit download speed (kbytes/sec)")
+5
View File
@@ -23,6 +23,11 @@ func aptlySnapshotCreate(cmd *commander.Command, args []string) error {
return fmt.Errorf("unable to create snapshot: %s", err) return fmt.Errorf("unable to create snapshot: %s", err)
} }
err = repo.CheckLock()
if err != nil {
return fmt.Errorf("unable to create snapshot: %s", err)
}
err = context.CollectionFactory().RemoteRepoCollection().LoadComplete(repo) err = context.CollectionFactory().RemoteRepoCollection().LoadComplete(repo)
if err != nil { if err != nil {
return fmt.Errorf("unable to create snapshot: %s", err) return fmt.Errorf("unable to create snapshot: %s", err)