~juju-qa/ubuntu/xenial/juju/xenial-2.0-beta3

« back to all changes in this revision

Viewing changes to src/github.com/juju/juju/api/backups/restore.go

  • Committer: Martin Packman
  • Date: 2016-03-30 19:31:08 UTC
  • mfrom: (1.1.41)
  • Revision ID: martin.packman@canonical.com-20160330193108-h9iz3ak334uk0z5r
Merge new upstream source 2.0~beta3

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
 
6
6
import (
7
7
        "io"
8
 
        "strings"
 
8
        "reflect"
9
9
        "time"
10
10
 
11
11
        "github.com/juju/errors"
12
12
        "github.com/juju/utils"
13
13
 
14
 
        "github.com/juju/juju/apiserver"
15
14
        "github.com/juju/juju/apiserver/params"
16
15
        "github.com/juju/juju/rpc"
17
16
)
33
32
// the error type returned from a facade call is rpc.RequestError
34
33
// and we cannot use params.IsCodeUpgradeInProgress
35
34
func isUpgradeInProgressErr(err error) bool {
36
 
        errorMessage := err.Error()
37
 
        return strings.Contains(errorMessage, apiserver.UpgradeInProgressError.Error())
 
35
        return reflect.DeepEqual(errors.Cause(err), &rpc.RequestError{Message: params.CodeUpgradeInProgress, Code: params.CodeUpgradeInProgress})
38
36
}
39
37
 
40
38
// ClientConnection type represents a function capable of spawning a new Client connection
41
39
// it is used to pass around connection factories when necessary.
42
40
// TODO(perrito666) This is a workaround for lp:1399722 .
43
 
type ClientConnection func() (*Client, func() error, error)
 
41
type ClientConnection func() (*Client, error)
44
42
 
45
43
// closerfunc is a function that allows you to close a client connection.
46
44
type closerFunc func() error
47
45
 
48
 
func prepareAttempt(client *Client, closer closerFunc) (error, error) {
 
46
func prepareAttempt(client *Client) (error, error) {
49
47
        var remoteError error
50
 
        defer closer()
 
48
        defer client.Close()
51
49
        err := client.facade.FacadeCall("PrepareRestore", nil, &remoteError)
52
50
        return err, remoteError
53
51
}
61
59
        // by restore.
62
60
        for a := restoreStrategy.Start(); a.Next(); {
63
61
                logger.Debugf("Will attempt to call 'PrepareRestore'")
64
 
                client, clientCloser, clientErr := newClient()
 
62
                client, clientErr := newClient()
65
63
                if clientErr != nil {
66
64
                        return errors.Trace(clientErr)
67
65
                }
68
 
                err, remoteError = prepareAttempt(client, clientCloser)
 
66
                err, remoteError = prepareAttempt(client)
69
67
                if err == nil && remoteError == nil {
70
68
                        return nil
71
69
                }
102
100
        return c.restore(backupId, newClient)
103
101
}
104
102
 
105
 
func restoreAttempt(client *Client, closer closerFunc, restoreArgs params.RestoreArgs) (error, error) {
 
103
func restoreAttempt(client *Client, restoreArgs params.RestoreArgs) (error, error) {
106
104
        var remoteError error
107
 
        defer closer()
 
105
        defer client.Close()
108
106
        err := client.facade.FacadeCall("Restore", restoreArgs, &remoteError)
109
107
        return err, remoteError
110
108
}
127
125
        for a := restoreStrategy.Start(); a.Next(); {
128
126
                logger.Debugf("Attempting Restore of %q", backupId)
129
127
                var restoreClient *Client
130
 
                var restoreClientCloser func() error
131
 
                restoreClient, restoreClientCloser, err = newClient()
 
128
                restoreClient, err = newClient()
132
129
                if err != nil {
133
130
                        return errors.Trace(err)
134
131
                }
135
132
 
136
 
                err, remoteError = restoreAttempt(restoreClient, restoreClientCloser, restoreArgs)
 
133
                err, remoteError = restoreAttempt(restoreClient, restoreArgs)
137
134
 
138
135
                // A ShutdownErr signals that Restore almost certainly finished and
139
136
                // triggered Exit.
162
159
        return nil
163
160
}
164
161
 
165
 
func finishAttempt(client *Client, closer closerFunc) (error, error) {
 
162
func finishAttempt(client *Client) (error, error) {
166
163
        var remoteError error
167
 
        defer closer()
 
164
        defer client.Close()
168
165
        err := client.facade.FacadeCall("FinishRestore", nil, &remoteError)
169
166
        return err, remoteError
170
167
}
178
175
        for a := restoreStrategy.Start(); a.Next(); {
179
176
                logger.Debugf("Attempting finishRestore")
180
177
                var finishClient *Client
181
 
                var finishClientCloser func() error
182
 
                finishClient, finishClientCloser, err = newClient()
 
178
                finishClient, err = newClient()
183
179
                if err != nil {
184
180
                        return errors.Trace(err)
185
181
                }
186
182
 
187
 
                err, remoteError = finishAttempt(finishClient, finishClientCloser)
 
183
                err, remoteError = finishAttempt(finishClient)
188
184
                if err == nil && remoteError == nil {
189
185
                        return nil
190
186
                }