1
// Copyright 2015 Canonical Ltd.
2
// Licensed under the AGPLv3, see LICENCE file for details.
10
"github.com/juju/errors"
12
"github.com/juju/juju/storage"
15
type storageFlag struct {
16
stores *map[string]storage.Constraints
17
bundleStores *map[string]map[string]storage.Constraints
20
// Set implements gnuflag.Value.Set.
21
func (f storageFlag) Set(s string) error {
22
fields := strings.SplitN(s, "=", 2)
24
return errors.New("expected [<application>:]<store>=<constraints>")
26
var serviceName, storageName string
27
if colon := strings.IndexRune(fields[0], ':'); colon >= 0 {
28
serviceName = fields[0][:colon]
29
storageName = fields[0][colon+1:]
31
storageName = fields[0]
33
cons, err := storage.ParseConstraints(fields[1])
35
return errors.Annotate(err, "cannot parse disk constraints")
37
var stores map[string]storage.Constraints
38
if serviceName != "" {
39
if *f.bundleStores == nil {
40
*f.bundleStores = make(map[string]map[string]storage.Constraints)
42
stores = (*f.bundleStores)[serviceName]
44
stores = make(map[string]storage.Constraints)
45
(*f.bundleStores)[serviceName] = stores
49
*f.stores = make(map[string]storage.Constraints)
53
stores[storageName] = cons
57
// String implements gnuflag.Value.String.
58
func (f storageFlag) String() string {
59
strs := make([]string, 0, len(*f.stores)+len(*f.bundleStores))
60
for store, cons := range *f.stores {
61
strs = append(strs, fmt.Sprintf("%s=%v", store, cons))
63
for application, stores := range *f.bundleStores {
64
for store, cons := range stores {
65
strs = append(strs, fmt.Sprintf("%s:%s=%v", application, store, cons))
68
return strings.Join(strs, " ")
71
// stringMap is a type that deserializes a CLI string using gnuflag's Value
72
// semantics. It expects a name=value pair, and supports multiple copies of the
73
// flag adding more pairs, though the names must be unique.
74
type stringMap struct {
75
mapping *map[string]string
78
// Set implements gnuflag.Value's Set method.
79
func (m stringMap) Set(s string) error {
80
if *m.mapping == nil {
81
*m.mapping = map[string]string{}
83
// make a copy so the following code is less ugly with dereferencing.
86
vals := strings.SplitN(s, "=", 2)
88
return errors.NewNotValid(nil, "badly formatted name value pair: "+s)
90
name, value := vals[0], vals[1]
91
if _, ok := mapping[name]; ok {
92
return errors.Errorf("duplicate name specified: %q", name)
98
// String implements gnuflag.Value's String method
99
func (m stringMap) String() string {
100
pairs := make([]string, 0, len(*m.mapping))
101
for name, value := range *m.mapping {
102
pairs = append(pairs, name+"="+value)
104
return strings.Join(pairs, ";")