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

Side by Side Diff: state/state.go

Issue 6551044: state: check unit/service name validity
Patch Set: check unit/service name validity Created 12 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 | « state/service_test.go ('k') | state/state_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
1 // The state package enables reading, observing, and changing 1 // The state package enables reading, observing, and changing
2 // the state stored in MongoDB of a whole environment 2 // the state stored in MongoDB of a whole environment
3 // managed by juju. 3 // managed by juju.
4 package state 4 package state
5 5
6 import ( 6 import (
7 "fmt" 7 "fmt"
8 "labix.org/v2/mgo" 8 "labix.org/v2/mgo"
9 "labix.org/v2/mgo/bson" 9 "labix.org/v2/mgo/bson"
10 "labix.org/v2/mgo/txn" 10 "labix.org/v2/mgo/txn"
11 "launchpad.net/juju-core/charm" 11 "launchpad.net/juju-core/charm"
12 "launchpad.net/juju-core/environs/config" 12 "launchpad.net/juju-core/environs/config"
13 "launchpad.net/juju-core/state/presence" 13 "launchpad.net/juju-core/state/presence"
14 "launchpad.net/juju-core/state/watcher" 14 "launchpad.net/juju-core/state/watcher"
15 "launchpad.net/juju-core/trivial" 15 "launchpad.net/juju-core/trivial"
16 "launchpad.net/juju-core/version" 16 "launchpad.net/juju-core/version"
17 "net/url" 17 "net/url"
18 "regexp"
18 ) 19 )
19 20
20 type D []bson.DocElem 21 type D []bson.DocElem
21 22
22 // Tools describes a particular set of juju tools and where to find them. 23 // Tools describes a particular set of juju tools and where to find them.
23 type Tools struct { 24 type Tools struct {
24 version.Binary 25 version.Binary
25 URL string 26 URL string
26 } 27 }
27 28
29 var (
30 validService = regexp.MustCompile("^[a-z][a-z0-9]*(-[a-z0-9]*[a-z][a-z0- 9]*)*$")
31 validUnit = regexp.MustCompile("^[a-z][a-z0-9]*(-[a-z0-9]*[a-z][a-z0- 9]*)*/[0-9]+$")
32 )
33
34 // IsServiceName returns true if name is a valid service name.
niemeyer 2012/09/20 10:35:34 s/true if/whether/ (both are of course right.. it'
fwereade 2012/09/20 10:41:32 Done.
35 func IsServiceName(name string) bool {
36 return validService.MatchString(name)
37 }
38
39 // IsUnitName returns true if name is a valid service name.
niemeyer 2012/09/20 10:35:34 s/true if/whether/ s/service/unit/
fwereade 2012/09/20 10:41:32 Done.
40 func IsUnitName(name string) bool {
41 return validUnit.MatchString(name)
42 }
43
28 // State represents the state of an environment 44 // State represents the state of an environment
29 // managed by juju. 45 // managed by juju.
30 type State struct { 46 type State struct {
31 db *mgo.Database 47 db *mgo.Database
32 charms *mgo.Collection 48 charms *mgo.Collection
33 machines *mgo.Collection 49 machines *mgo.Collection
34 relations *mgo.Collection 50 relations *mgo.Collection
35 services *mgo.Collection 51 services *mgo.Collection
36 settings *mgo.Collection 52 settings *mgo.Collection
37 units *mgo.Collection 53 units *mgo.Collection
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 if err != nil { 185 if err != nil {
170 return nil, fmt.Errorf("cannot get charm %q: %v", curl, err) 186 return nil, fmt.Errorf("cannot get charm %q: %v", curl, err)
171 } 187 }
172 188
173 return newCharm(s, cdoc) 189 return newCharm(s, cdoc)
174 } 190 }
175 191
176 // AddService creates a new service state with the given unique name 192 // AddService creates a new service state with the given unique name
177 // and the charm state. 193 // and the charm state.
178 func (s *State) AddService(name string, ch *Charm) (service *Service, err error) { 194 func (s *State) AddService(name string, ch *Charm) (service *Service, err error) {
195 if !IsServiceName(name) {
196 return nil, fmt.Errorf("%q is not a valid service name", name)
197 }
179 sdoc := &serviceDoc{ 198 sdoc := &serviceDoc{
180 Name: name, 199 Name: name,
181 CharmURL: ch.URL(), 200 CharmURL: ch.URL(),
182 Life: Alive, 201 Life: Alive,
183 } 202 }
184 ops := []txn.Op{{ 203 ops := []txn.Op{{
185 C: s.services.Name, 204 C: s.services.Name,
186 Id: name, 205 Id: name,
187 Assert: txn.DocMissing, 206 Assert: txn.DocMissing,
188 Insert: sdoc, 207 Insert: sdoc,
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 }} 259 }}
241 if err := s.runner.Run(ops, "", nil); err != nil { 260 if err := s.runner.Run(ops, "", nil); err != nil {
242 // If aborted, the service is either dead or recreated. 261 // If aborted, the service is either dead or recreated.
243 return onAbort(err, nil) 262 return onAbort(err, nil)
244 } 263 }
245 return nil 264 return nil
246 } 265 }
247 266
248 // Service returns a service state by name. 267 // Service returns a service state by name.
249 func (s *State) Service(name string) (service *Service, err error) { 268 func (s *State) Service(name string) (service *Service, err error) {
269 if !IsServiceName(name) {
270 return nil, fmt.Errorf("%q is not a valid service name", name)
271 }
250 sdoc := &serviceDoc{} 272 sdoc := &serviceDoc{}
251 sel := D{{"_id", name}} 273 sel := D{{"_id", name}}
252 err = s.services.Find(sel).One(sdoc) 274 err = s.services.Find(sel).One(sdoc)
253 if err != nil { 275 if err != nil {
254 return nil, fmt.Errorf("cannot get service %q: %v", name, err) 276 return nil, fmt.Errorf("cannot get service %q: %v", name, err)
255 } 277 }
256 return newService(s, sdoc), nil 278 return newService(s, sdoc), nil
257 } 279 }
258 280
259 // AllServices returns all deployed services in the environment. 281 // AllServices returns all deployed services in the environment.
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
352 }} 374 }}
353 if err := s.runner.Run(ops, "", nil); err != nil { 375 if err := s.runner.Run(ops, "", nil); err != nil {
354 // If aborted, the relation is either dead or recreated. 376 // If aborted, the relation is either dead or recreated.
355 return onAbort(err, nil) 377 return onAbort(err, nil)
356 } 378 }
357 return nil 379 return nil
358 } 380 }
359 381
360 // Unit returns a unit by name. 382 // Unit returns a unit by name.
361 func (s *State) Unit(name string) (*Unit, error) { 383 func (s *State) Unit(name string) (*Unit, error) {
384 if !IsUnitName(name) {
385 return nil, fmt.Errorf("%q is not a valid unit name", name)
386 }
362 doc := unitDoc{} 387 doc := unitDoc{}
363 err := s.units.FindId(name).One(&doc) 388 err := s.units.FindId(name).One(&doc)
364 if err != nil { 389 if err != nil {
365 return nil, fmt.Errorf("cannot get unit %q: %v", name, err) 390 return nil, fmt.Errorf("cannot get unit %q: %v", name, err)
366 } 391 }
367 return newUnit(s, &doc), nil 392 return newUnit(s, &doc), nil
368 } 393 }
369 394
370 // StartSync forces watchers to resynchronize their state with the 395 // StartSync forces watchers to resynchronize their state with the
371 // database immediately. This will happen periodically automatically. 396 // database immediately. This will happen periodically automatically.
372 func (s *State) StartSync() { 397 func (s *State) StartSync() {
373 s.watcher.StartSync() 398 s.watcher.StartSync()
374 s.pwatcher.StartSync() 399 s.pwatcher.StartSync()
375 } 400 }
376 401
377 // Sync forces watchers to resynchronize their state with the 402 // Sync forces watchers to resynchronize their state with the
378 // database immediately, and waits until all events are known. 403 // database immediately, and waits until all events are known.
379 func (s *State) Sync() { 404 func (s *State) Sync() {
380 s.watcher.Sync() 405 s.watcher.Sync()
381 s.pwatcher.Sync() 406 s.pwatcher.Sync()
382 } 407 }
OLDNEW
« no previous file with comments | « state/service_test.go ('k') | state/state_test.go » ('j') | no next file with comments »

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