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

Side by Side Diff: worker/provisioner/container_initialisation.go

Issue 25040043: Refactor container provisioner (Closed)
Patch Set: - Created 10 years, 4 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
OLDNEW
(Empty)
1 // Copyright 2012, 2013 Canonical Ltd.
2 // Licensed under the AGPLv3, see LICENCE file for details.
3
4 package provisioner
5
6 import (
7 "fmt"
8 "sync/atomic"
9
10 "launchpad.net/juju-core/agent"
11 "launchpad.net/juju-core/instance"
12 apiprovisioner "launchpad.net/juju-core/state/api/provisioner"
13 "launchpad.net/juju-core/state/api/watcher"
14 "launchpad.net/juju-core/worker"
15 )
16
17 // ContainerSetup is a StringsWatchHandler that is notified when containers of
18 // the specified type are created on the given machine. It will set up the
19 // machine to be able to create containers and start a provisioner.
20 type ContainerSetup struct {
21 runner worker.Runner
22 containerType instance.ContainerType
23 provisioner *apiprovisioner.State
24 machine *apiprovisioner.Machine
25 config agent.Config
26
27 // Save the workerName so the worker thread can be stopped.
28 workerName string
29 // setupDone is non zero if the container setup has been invoked.
30 setupDone int32
31 }
32
33 // NewContainerSetupHandler returns a StringsWatchHandler which is notified when
34 // containers are created on the given machine.
35 func NewContainerSetupHandler(runner worker.Runner, workerName string, container instance.ContainerType,
36 machine *apiprovisioner.Machine, provisioner *apiprovisioner.State,
37 config agent.Config) worker.StringsWatchHandler {
38
39 return &ContainerSetup{
40 runner: runner,
41 containerType: container,
42 machine: machine,
43 provisioner: provisioner,
44 config: config,
45 workerName: workerName,
46 }
47 }
48
49 // SetUp is defined on the StringsWatchHandler interface.
50 func (cs *ContainerSetup) SetUp() (watcher watcher.StringsWatcher, err error) {
51 if watcher, err = cs.machine.WatchContainers(cs.containerType); err != n il {
52 return nil, err
53 }
54 return watcher, nil
55 }
56
57 // Handle is called whenever containers change on the machine being watched.
58 // All machines start out with so containers so the first time Handle is called,
59 // it will be because a container has been added.
60 func (cs *ContainerSetup) Handle(containerIds []string) error {
61 // Consume the initial watcher event.
62 if len(containerIds) == 0 {
63 return nil
64 }
65
66 // This callback must only be invoked once. Stopping the watcher
67 // below should be sufficient but I'm paranoid.
68 if atomic.LoadInt32(&cs.setupDone) != 0 {
69 return nil
70 }
71 atomic.StoreInt32(&cs.setupDone, 1)
72
73 logger.Tracef("initial container setup with ids: %v", containerIds)
74 // We only care about the initial container creation.
75 // This worker has done its job so stop it.
76 // We do not expect there will be an error, and there's not much we can do anyway.
77 if err := cs.runner.StopWorker(cs.workerName); err != nil {
78 logger.Warningf("stopping machine agent container watcher: %v", err)
79 }
80 if err := cs.ensureContainerDependencies(); err != nil {
william.reade 2013/11/18 15:30:58 I still think this is better done lazily inside th
81 return fmt.Errorf("setting up container dependnecies on host mac hine: %v", err)
82 }
83 var provisionerType ProvisionerType
84 switch cs.containerType {
85 case instance.LXC:
86 provisionerType = LXC
87 case instance.KVM:
88 provisionerType = KVM
89 default:
90 return fmt.Errorf("invalid container type %q", cs.containerType)
91 }
92 return StartProvisioner(cs.runner, provisionerType, cs.provisioner, cs.c onfig)
93 }
94
95 // TearDown is defined on the StringsWatchHandler interface.
96 func (cs *ContainerSetup) TearDown() error {
97 // Nothing to do here.
98 return nil
99 }
100
101 func (cs *ContainerSetup) ensureContainerDependencies() error {
102 // TODO(wallyworld) - install whatever dependencies are required to supp ort starting containers
103 return nil
104 }
105
106 // Override for testing.
107 var StartProvisioner = startProvisionerWorker
108
109 // startProvisionerWorker kicks off a provisioner task responsible for creating containers
110 // of the specified type on the machine.
111 func startProvisionerWorker(runner worker.Runner, provisionerType ProvisionerTyp e,
112 provisioner *apiprovisioner.State, config agent.Config) error {
113
114 workerName := fmt.Sprintf("%s-provisioner", provisionerType)
115 // The provisioner task is created after a container record has already been added to the machine.
116 // It will see that the container does not have an instance yet and crea te one.
117 return runner.StartWorker(workerName, func() (worker.Worker, error) {
118 return NewProvisioner(provisionerType, provisioner, config), nil
william.reade 2013/11/18 15:30:58 This is all still kinda messed up (nothing to do w
119 })
120 }
OLDNEW

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