Left: | ||
Right: |
OLD | NEW |
---|---|
1 // Copyright 2013 Canonical Ltd. | 1 // Copyright 2013 Canonical Ltd. |
2 // Licensed under the AGPLv3, see LICENCE file for details. | 2 // Licensed under the AGPLv3, see LICENCE file for details. |
3 | 3 |
4 package lxc | 4 package lxc |
5 | 5 |
6 import ( | 6 import ( |
7 "fmt" | 7 "fmt" |
8 "io/ioutil" | 8 "io/ioutil" |
9 "os" | 9 "os" |
10 "path/filepath" | 10 "path/filepath" |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
113 } | 113 } |
114 | 114 |
115 func (manager *containerManager) StartContainer( | 115 func (manager *containerManager) StartContainer( |
116 machineId, series, nonce string, | 116 machineId, series, nonce string, |
117 network *NetworkConfig, | 117 network *NetworkConfig, |
118 tools *tools.Tools, | 118 tools *tools.Tools, |
119 environConfig *config.Config, | 119 environConfig *config.Config, |
120 stateInfo *state.Info, | 120 stateInfo *state.Info, |
121 apiInfo *api.Info) (instance.Instance, error) { | 121 apiInfo *api.Info) (instance.Instance, error) { |
122 | 122 |
123 var container golxc.Container | |
124 | |
123 name := names.MachineTag(machineId) | 125 name := names.MachineTag(machineId) |
124 if manager.name != "" { | 126 if manager.name != "" { |
125 name = fmt.Sprintf("%s-%s", manager.name, name) | 127 name = fmt.Sprintf("%s-%s", manager.name, name) |
126 } | 128 } |
127 » // Note here that the lxcObjectFacotry only returns a valid container | 129 » // Note here that the lxcObjectFactory only returns a valid container |
128 // object, and doesn't actually construct the underlying lxc container o n | 130 // object, and doesn't actually construct the underlying lxc container o n |
129 // disk. | 131 // disk. |
130 » container := lxcObjectFactory.New(name) | 132 » templateName := fmt.Sprintf("%s-%s-template", manager.name, series) |
133 » template := lxcObjectFactory.New(templateName) | |
wallyworld
2013/11/04 02:51:35
What if manager.name is ""? There's a few lines of
| |
134 » if !template.IsConstructed() { | |
fwereade
2013/11/06 12:28:44
Would it be reasonable to extract this block as a
| |
135 » » templateDirectory := jujuContainerDirectory(templateName) | |
136 » » logger.Debugf("create directory: %s", templateDirectory) | |
137 » » if err := os.MkdirAll(templateDirectory, 0755); err != nil { | |
138 » » » logger.Errorf("failed to create template container direc tory: %v", err) | |
139 » » » return nil, err | |
140 » » } | |
141 » » logger.Debugf("write the lxc.conf file") | |
142 » » configFile, err := writeLxcConfig(network, templateDirectory, ma nager.logdir) | |
143 » » if err != nil { | |
144 » » » logger.Errorf("failed to write config file: %v", err) | |
145 » » » return nil, err | |
146 » » } | |
147 » » templateParams := []string{ | |
148 » » » "--debug", // Debug errors in the cloud i mage | |
149 » » » "--hostid", templateName, // Use the container name as t he hostid | |
150 » » » "-r", series, | |
151 » » } | |
152 » » // Create the container. | |
153 » » logger.Debugf("create the container template") | |
154 » » if err := template.Create(configFile, defaultTemplate, templateP arams...); err != nil { | |
155 » » » logger.Errorf("lxc template container creation failed: % v", err) | |
156 » » » return nil, err | |
157 » » } | |
158 » » // Make sure that the mount dir has been created. | |
159 » » logger.Debugf("make the mount dir for the shard logs") | |
160 » » if err := os.MkdirAll(internalLogDir(templateName), 0755); err ! = nil { | |
161 » » » logger.Errorf("failed to create internal /var/log/juju m ount dir: %v", err) | |
162 » » » return nil, err | |
163 » » } | |
164 » } | |
131 | 165 |
132 // Create the cloud-init. | 166 // Create the cloud-init. |
133 directory := jujuContainerDirectory(name) | 167 directory := jujuContainerDirectory(name) |
134 » logger.Tracef("create directory: %s", directory) | 168 » logger.Debugf("create directory: %s", directory) |
135 if err := os.MkdirAll(directory, 0755); err != nil { | 169 if err := os.MkdirAll(directory, 0755); err != nil { |
136 logger.Errorf("failed to create container directory: %v", err) | 170 logger.Errorf("failed to create container directory: %v", err) |
137 return nil, err | 171 return nil, err |
138 } | 172 } |
139 » logger.Tracef("write cloud-init") | 173 » logger.Debugf("write cloud-init") |
140 userDataFilename, err := writeUserData(directory, machineId, nonce, tool s, environConfig, stateInfo, apiInfo) | 174 userDataFilename, err := writeUserData(directory, machineId, nonce, tool s, environConfig, stateInfo, apiInfo) |
141 if err != nil { | 175 if err != nil { |
142 logger.Errorf("failed to write user data: %v", err) | 176 logger.Errorf("failed to write user data: %v", err) |
143 return nil, err | 177 return nil, err |
144 } | 178 } |
145 » logger.Tracef("write the lxc.conf file") | 179 » templateParams := []string{ |
146 » configFile, err := writeLxcConfig(network, directory, manager.logdir) | 180 » » "--userdata", userDataFilename, // Our groovey cloud-init |
147 » if err != nil { | 181 » } |
148 » » logger.Errorf("failed to write config file: %v", err) | 182 » // Clone existing template into a new container. |
183 » logger.Debugf("create the container clone") | |
184 » if container, err = template.Clone(name, true, golxc.BackingStoreOverlay FS, templateParams...); err != nil { | |
185 » » logger.Errorf("lxc container clone creation failed: %v", err) | |
149 return nil, err | 186 return nil, err |
150 } | 187 } |
151 » templateParams := []string{ | 188 |
152 » » "--debug", // Debug errors in the cloud ima ge | 189 » logger.Debugf("lxc container clone created") |
153 » » "--userdata", userDataFilename, // Our groovey cloud-init | |
154 » » "--hostid", name, // Use the container name as the hostid | |
155 » » "-r", series, | |
156 » } | |
157 » // Create the container. | |
158 » logger.Tracef("create the container") | |
159 » if err := container.Create(configFile, defaultTemplate, templateParams.. .); err != nil { | |
160 » » logger.Errorf("lxc container creation failed: %v", err) | |
161 » » return nil, err | |
162 » } | |
163 » // Make sure that the mount dir has been created. | |
164 » logger.Tracef("make the mount dir for the shard logs") | |
165 » if err := os.MkdirAll(internalLogDir(name), 0755); err != nil { | |
166 » » logger.Errorf("failed to create internal /var/log/juju mount dir : %v", err) | |
167 » » return nil, err | |
168 » } | |
169 » logger.Tracef("lxc container created") | |
170 // Now symlink the config file into the restart directory. | 190 // Now symlink the config file into the restart directory. |
171 containerConfigFile := filepath.Join(lxcContainerDir, name, "config") | 191 containerConfigFile := filepath.Join(lxcContainerDir, name, "config") |
172 if err := os.Symlink(containerConfigFile, restartSymlink(name)); err != nil { | 192 if err := os.Symlink(containerConfigFile, restartSymlink(name)); err != nil { |
173 return nil, err | 193 return nil, err |
174 } | 194 } |
175 » logger.Tracef("auto-restart link created") | 195 » logger.Debugf("auto-restart link created") |
176 | 196 |
177 // Start the lxc container with the appropriate settings for grabbing th e | 197 // Start the lxc container with the appropriate settings for grabbing th e |
178 // console output and a log file. | 198 // console output and a log file. |
179 consoleFile := filepath.Join(directory, "console.log") | 199 consoleFile := filepath.Join(directory, "console.log") |
180 container.SetLogFile(filepath.Join(directory, "container.log"), golxc.Lo gDebug) | 200 container.SetLogFile(filepath.Join(directory, "container.log"), golxc.Lo gDebug) |
181 » logger.Tracef("start the container") | 201 » logger.Debugf("start the container") |
182 // We explicitly don't pass through the config file to the container.Sta rt | 202 // We explicitly don't pass through the config file to the container.Sta rt |
183 // method as we have passed it through at container creation time. This | 203 // method as we have passed it through at container creation time. This |
184 // is necessary to get the appropriate rootfs reference without explicit ly | 204 // is necessary to get the appropriate rootfs reference without explicit ly |
185 // setting it ourselves. | 205 // setting it ourselves. |
186 if err = container.Start("", consoleFile); err != nil { | 206 if err = container.Start("", consoleFile); err != nil { |
187 logger.Errorf("container failed to start: %v", err) | 207 logger.Errorf("container failed to start: %v", err) |
188 return nil, err | 208 return nil, err |
189 } | 209 } |
190 » logger.Tracef("container started") | 210 » logger.Debugf("container started") |
191 return &lxcInstance{container, name}, nil | 211 return &lxcInstance{container, name}, nil |
192 } | 212 } |
193 | 213 |
194 func (manager *containerManager) StopContainer(instance instance.Instance) error { | 214 func (manager *containerManager) StopContainer(instance instance.Instance) error { |
195 name := string(instance.Id()) | 215 name := string(instance.Id()) |
196 container := lxcObjectFactory.New(name) | 216 container := lxcObjectFactory.New(name) |
197 if err := container.Stop(); err != nil { | 217 if err := container.Stop(); err != nil { |
198 logger.Errorf("failed to stop lxc container: %v", err) | 218 logger.Errorf("failed to stop lxc container: %v", err) |
199 return err | 219 return err |
200 } | 220 } |
201 // Destroy removes the restart symlink for us. | 221 // Destroy removes the restart symlink for us. |
202 if err := container.Destroy(); err != nil { | 222 if err := container.Destroy(); err != nil { |
203 logger.Errorf("failed to destroy lxc container: %v", err) | 223 logger.Errorf("failed to destroy lxc container: %v", err) |
204 return err | 224 return err |
205 } | 225 } |
206 | 226 |
207 // Move the directory. | 227 // Move the directory. |
208 » logger.Tracef("create old container dir: %s", removedContainerDir) | 228 » logger.Debugf("create old container dir: %s", removedContainerDir) |
209 if err := os.MkdirAll(removedContainerDir, 0755); err != nil { | 229 if err := os.MkdirAll(removedContainerDir, 0755); err != nil { |
210 logger.Errorf("failed to create removed container directory: %v" , err) | 230 logger.Errorf("failed to create removed container directory: %v" , err) |
211 return err | 231 return err |
212 } | 232 } |
213 removedDir, err := uniqueDirectory(removedContainerDir, name) | 233 removedDir, err := uniqueDirectory(removedContainerDir, name) |
214 if err != nil { | 234 if err != nil { |
215 logger.Errorf("was not able to generate a unique directory: %v", err) | 235 logger.Errorf("was not able to generate a unique directory: %v", err) |
216 return err | 236 return err |
217 } | 237 } |
218 if err := os.Rename(jujuContainerDirectory(name), removedDir); err != ni l { | 238 if err := os.Rename(jujuContainerDirectory(name), removedDir); err != ni l { |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
393 for i := 1; ; i++ { | 413 for i := 1; ; i++ { |
394 dir := filepath.Join(path, fmt.Sprintf("%s.%d", name, i)) | 414 dir := filepath.Join(path, fmt.Sprintf("%s.%d", name, i)) |
395 _, err := os.Stat(dir) | 415 _, err := os.Stat(dir) |
396 if os.IsNotExist(err) { | 416 if os.IsNotExist(err) { |
397 return dir, nil | 417 return dir, nil |
398 } else if err != nil { | 418 } else if err != nil { |
399 return "", err | 419 return "", err |
400 } | 420 } |
401 } | 421 } |
402 } | 422 } |
OLD | NEW |