| OLD | NEW |
| (Empty) | |
| 1 package upgrade |
| 2 import ( |
| 3 "launchpad.net/gnuflag" |
| 4 "sync" |
| 5 "os" |
| 6 "errors" |
| 7 "fmt" |
| 8 ) |
| 9 |
| 10 var upgradedFlag = gnuflag.Bool("upgraded", false, "process is started by the up
grader process") |
| 11 |
| 12 var ( |
| 13 mutex sync.Mutex |
| 14 started bool |
| 15 startError error |
| 16 ) |
| 17 |
| 18 // Start signals to the upgrader that the command has started. If it |
| 19 // returns with an error, the command should abort and exit; otherwise |
| 20 // it should assume normal operation. |
| 21 func Start() error { |
| 22 if !*upgradedFlag { |
| 23 return nil |
| 24 } |
| 25 mutex.Lock() |
| 26 defer mutex.Unlock() |
| 27 if !started { |
| 28 WriteMsg(os.Stdout, "started") |
| 29 _, startError = ReadMsg(os.Stdin, "run") |
| 30 started = true |
| 31 } |
| 32 return startError |
| 33 } |
| 34 |
| 35 // Upgrade requests to the upgrader that the current command be upgraded |
| 36 // by running the given executable command. If the command succeeds in |
| 37 // starting, the shutdown function will be called to shut down all |
| 38 // operations. If it succeeds, Upgrade will return no error, and the |
| 39 // caller should exit the program to allow the new command to take over |
| 40 // operations. |
| 41 func Upgrade(shutdown func() error, cmd string, args ...string) error { |
| 42 if !*upgradedFlag { |
| 43 return errors.New("cannot upgrade when not started from the upgr
ader") |
| 44 } |
| 45 mutex.Lock() |
| 46 defer mutex.Unlock() |
| 47 if !started { |
| 48 return errors.New("upgrade called before start") |
| 49 } |
| 50 if startError != nil { |
| 51 return fmt.Errorf("start encountered an error so cannot upgrade:
%v", startError) |
| 52 } |
| 53 m := make([]string, 2 + len(args)) |
| 54 m[0] = "upgrade" |
| 55 m[1] = cmd |
| 56 copy(m[2:], args) |
| 57 WriteMsg(os.Stdout, m...) |
| 58 _, err := ReadMsg(os.Stdin, "upgraded") |
| 59 if err != nil { |
| 60 return err |
| 61 } |
| 62 err = shutdown() |
| 63 if err != nil { |
| 64 WriteMsg(os.Stdout, "error", err.Error()) |
| 65 return fmt.Errorf("shutdown failed: %v", err) |
| 66 } |
| 67 WriteMsg(os.Stdout, "shutdown") |
| 68 // TODO os.Exit(0) ? |
| 69 return nil |
| 70 } |
| OLD | NEW |