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

Side by Side Diff: environs/manual/bootstrap.go

Issue 13635044: Implement manual bootstrapping
Patch Set: Implement manual bootstrapping Created 11 years, 6 months ago
Left:
Right:
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 unified diff | Download patch
« no previous file with comments | « environs/manual/agent.go ('k') | environs/manual/bootstrap_test.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2013 Canonical Ltd.
2 // Licensed under the AGPLv3, see LICENCE file for details.
3
4 package manual
5
6 import (
7 "errors"
8 "fmt"
9
10 "launchpad.net/juju-core/agent"
11 "launchpad.net/juju-core/environs"
12 envtools "launchpad.net/juju-core/environs/tools"
13 "launchpad.net/juju-core/instance"
14 "launchpad.net/juju-core/names"
15 "launchpad.net/juju-core/provider"
16 "launchpad.net/juju-core/state"
17 "launchpad.net/juju-core/tools"
18 "launchpad.net/juju-core/worker/localstorage"
19 )
20
21 const BootstrapInstanceId = instance.Id(manualInstancePrefix)
22
23 // LocalStorageEnviron is an Environ where the bootstrap node
24 // manages its own local storage.
25 type LocalStorageEnviron interface {
26 environs.Environ
27 environs.BootstrapStorager
28 localstorage.LocalStorageConfig
29 }
30
31 type BootstrapArgs struct {
32 Host string
33 Environ LocalStorageEnviron
34 MachineId string
35 PossibleTools tools.List
36 }
37
38 // TODO(axw) make this configurable?
39 const dataDir = "/var/lib/juju"
40
41 func errMachineIdInvalid(machineId string) error {
42 return fmt.Errorf("%q is not a valid machine ID", machineId)
43 }
44
45 // NewManualBootstrapEnviron wraps a LocalStorageEnviron with another which
46 // overrides the Bootstrap method; when Bootstrap is invoked, the specified
47 // host will be manually bootstrapped.
48 func Bootstrap(args BootstrapArgs) (err error) {
49 if args.Host == "" {
50 return errors.New("host argument is empty")
51 }
52 if args.Environ == nil {
53 return errors.New("environ argument is nil")
54 }
55 if !names.IsMachine(args.MachineId) {
56 return errMachineIdInvalid(args.MachineId)
57 }
58
59 provisioned, err := checkProvisioned(args.Host)
60 if err != nil {
61 return fmt.Errorf("failed to check provisioned status: %v", err)
62 }
63 if provisioned {
64 return ErrProvisioned
65 }
66
67 bootstrapStorage, err := args.Environ.BootstrapStorage()
68 if err != nil {
69 return err
70 }
71
72 hc, series, err := detectSeriesAndHardwareCharacteristics(args.Host)
73 if err != nil {
74 return fmt.Errorf("error detecting hardware characteristics: %v" , err)
75 }
76
77 // Filter tools based on detected series/arch.
78 logger.Infof("Filtering possible tools: %v", args.PossibleTools)
79 possibleTools, err := args.PossibleTools.Match(tools.Filter{
80 Arch: *hc.Arch,
81 Series: series,
82 })
83 if err != nil {
84 return err
85 }
86
87 // Store the state file. If provisioning fails, we'll remove the file.
88 logger.Infof("Saving bootstrap state file to bootstrap storage")
89 err = provider.SaveState(
90 bootstrapStorage,
91 &provider.BootstrapState{
92 StateInstances: []instance.Id{BootstrapInstanceId},
93 Characteristics: []instance.HardwareCharacteristics{hc},
94 },
95 )
96 if err != nil {
97 return err
98 }
99 defer func() {
100 if err != nil {
101 logger.Errorf("bootstrapping failed, removing state file : %v", err)
102 bootstrapStorage.Remove(provider.StateFile)
103 }
104 }()
105
106 // Get a file:// scheme tools URL for the tools, which will have been
107 // copied to the remote machine's storage directory.
108 tools := *possibleTools[0]
109 storageDir := args.Environ.StorageDir()
110 toolsStorageName := envtools.StorageName(tools.Version)
111 tools.URL = fmt.Sprintf("file://%s/%s", storageDir, toolsStorageName)
112
113 // Add the local storage configuration.
114 agentEnv := map[string]string{
115 agent.StorageAddr: args.Environ.StorageAddr(),
116 agent.StorageDir: storageDir,
117 agent.SharedStorageAddr: args.Environ.SharedStorageAddr(),
118 agent.SharedStorageDir: args.Environ.SharedStorageDir(),
119 }
120
121 // Finally, provision the machine agent.
122 stateFileURL := fmt.Sprintf("file://%s/%s", storageDir, provider.StateFi le)
123 err = provisionMachineAgent(provisionMachineAgentArgs{
124 host: args.Host,
125 dataDir: dataDir,
126 environConfig: args.Environ.Config(),
127 stateFileURL: stateFileURL,
128 machineId: args.MachineId,
129 bootstrap: true,
130 nonce: state.BootstrapNonce,
131 tools: &tools,
132 agentEnv: agentEnv,
133 })
134 return err
135 }
OLDNEW
« no previous file with comments | « environs/manual/agent.go ('k') | environs/manual/bootstrap_test.go » ('j') | no next file with comments »

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