Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(59)

Unified Diff: upgrade/upgrade.go

Issue 6307061: upgrader: new command and upgrade package
Patch Set: upgrader: new command and upgrade package Created 13 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « upgrade/msg.go ('k') | upgrade/upgrade_test.go » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: upgrade/upgrade.go
=== added file 'upgrade/upgrade.go'
--- upgrade/upgrade.go 1970-01-01 00:00:00 +0000
+++ upgrade/upgrade.go 2012-06-11 17:52:25 +0000
@@ -0,0 +1,89 @@
+package upgrade
+
+import (
+ "errors"
+ "fmt"
+ "launchpad.net/gnuflag"
+ "os"
+ "sync"
+)
+
+var upgradedFlag = gnuflag.Bool("upgraded", false, "process is started by the upgrader process")
+
+var (
+ mutex sync.Mutex
+ started bool
+ startError error
+)
+
+// Start signals to the upgrader that the command has started. If it
+// returns with an error, the command should abort and exit; otherwise
+// it should assume normal operation.
+func Start() error {
+ if !*upgradedFlag {
+ return nil
+ }
+ mutex.Lock()
+ defer mutex.Unlock()
+ if !started {
+ WriteMsg(os.Stdout, "started")
+ _, startError = ReadMsg(os.Stdin, "run")
+ started = true
+ }
+ return startError
+}
+
+// StartError signals to the upgrader that the command
+// has failed to start correctly. The caller should arrange
+// to exit the program after calling this function.
+// Any subsequent calls to Start will fail with the given
+// error.
+func StartError(err error) {
+ if !*upgradedFlag {
+ return
+ }
+ mutex.Lock()
+ defer mutex.Unlock()
+ if !started {
+ WriteMsg(os.Stdout, "error", err.Error())
+ startError = err
+ started = true
+ }
+}
+
+// Upgrade requests to the upgrader that the current command be upgraded
+// by running the given executable command. If the command succeeds in
+// starting, the shutdown function will be called to shut down all
+// operations. If it succeeds, Upgrade will return no error, and the
+// caller should exit the program to allow the new command to take over
+// operations.
+func Upgrade(shutdown func() error, cmd string, args ...string) error {
+ if !*upgradedFlag {
+ return errors.New("cannot upgrade when not started from the upgrader")
+ }
+ mutex.Lock()
+ defer mutex.Unlock()
+ if !started {
+ return errors.New("upgrade called before start")
+ }
+ if startError != nil {
+ return fmt.Errorf("start encountered an error so cannot upgrade: %v", startError)
+ }
+ m := make([]string, 2+len(args))
+ m[0] = "upgrade"
+ m[1] = cmd
+ copy(m[2:], args)
+ WriteMsg(os.Stdout, m...)
+ _, err := ReadMsg(os.Stdin, "upgraded")
+ if err != nil {
+ return err
+ }
+ err = shutdown()
+ if err != nil {
+ WriteMsg(os.Stdout, "error", err.Error())
+ return fmt.Errorf("shutdown failed: %v", err)
+ }
+ WriteMsg(os.Stdout, "shutdown")
+ // TODO os.Exit(0) ?
+ return nil
+}
« no previous file with comments | « upgrade/msg.go ('k') | upgrade/upgrade_test.go » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b