blob: 0723ebe3f77d93a2bed4dbec758d6f5d44a8dfdb [file] [log] [blame]
Cosmos Nicolaou486d3492014-09-30 22:21:20 -07001package exec
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -07002
3import (
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -07004 "sync"
5
Jiri Simsa764efb72014-12-25 20:57:03 -08006 "v.io/core/veyron2/verror2"
Todd Wang3425a902015-01-21 18:43:59 -08007 "v.io/core/veyron2/vom"
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -07008)
9
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -070010// Config defines a simple key-value configuration. Keys and values are
11// strings, and a key can have exactly one value. The client is responsible for
12// encoding structured values, or multiple values, in the provided string.
13//
14// Config data can come from several sources:
15// - passed from parent process to child process through pipe;
16// - using environment variables or flags;
17// - via the neighborhood-based config service;
18// - by RPCs using the Config idl;
19// - manually, by calling the Set method.
20//
21// This interface makes no assumptions about the source of the configuration,
22// but provides a unified API for accessing it.
23type Config interface {
24 // Set sets the value for the key. If the key already exists in the
25 // config, its value is overwritten.
26 Set(key, value string)
Jiri Simsa37893392014-11-07 10:55:45 -080027 // Get returns the value for the key. If the key doesn't exist
28 // in the config, Get returns an error.
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -070029 Get(key string) (string, error)
Jiri Simsa37893392014-11-07 10:55:45 -080030 // Clear removes the specified key from the config.
31 Clear(key string)
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -070032 // Serialize serializes the config to a string.
33 Serialize() (string, error)
34 // MergeFrom deserializes config information from a string created using
35 // Serialize(), and merges this information into the config, updating
36 // values for keys that already exist and creating new key-value pairs
37 // for keys that don't.
38 MergeFrom(string) error
Bogdan Capritabf356d72015-01-08 17:28:48 -080039 // Dump returns the config information as a map from ket to value.
40 Dump() map[string]string
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -070041}
42
43type cfg struct {
44 sync.RWMutex
45 m map[string]string
46}
47
48// New creates a new empty config.
Cosmos Nicolaou486d3492014-09-30 22:21:20 -070049func NewConfig() Config {
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -070050 return &cfg{m: make(map[string]string)}
51}
52
Todd Wangf519f8f2015-01-21 10:07:41 -080053func (c *cfg) Set(key, value string) {
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -070054 c.Lock()
55 defer c.Unlock()
56 c.m[key] = value
57}
58
Todd Wangf519f8f2015-01-21 10:07:41 -080059func (c *cfg) Get(key string) (string, error) {
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -070060 c.RLock()
61 defer c.RUnlock()
62 v, ok := c.m[key]
63 if !ok {
Mike Burrowscd7f8d22014-10-08 11:35:50 -070064 return "", verror2.Make(verror2.NoExist, nil, "config.Get", key)
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -070065 }
66 return v, nil
67}
68
Todd Wangf519f8f2015-01-21 10:07:41 -080069func (c *cfg) Dump() (res map[string]string) {
Bogdan Capritabf356d72015-01-08 17:28:48 -080070 res = make(map[string]string)
71 c.RLock()
72 defer c.RUnlock()
73 for k, v := range c.m {
74 res[k] = v
75 }
76 return
77}
78
Todd Wangf519f8f2015-01-21 10:07:41 -080079func (c *cfg) Clear(key string) {
Jiri Simsa37893392014-11-07 10:55:45 -080080 c.Lock()
81 defer c.Unlock()
82 delete(c.m, key)
83}
84
Todd Wangf519f8f2015-01-21 10:07:41 -080085func (c *cfg) Serialize() (string, error) {
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -070086 c.RLock()
Todd Wang3425a902015-01-21 18:43:59 -080087 data, err := vom.Encode(c.m)
Todd Wangf519f8f2015-01-21 10:07:41 -080088 c.RUnlock()
89 if err != nil {
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -070090 return "", err
91 }
Todd Wangf519f8f2015-01-21 10:07:41 -080092 return string(data), nil
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -070093}
94
Todd Wangf519f8f2015-01-21 10:07:41 -080095func (c *cfg) MergeFrom(serialized string) error {
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -070096 var newM map[string]string
Todd Wang3425a902015-01-21 18:43:59 -080097 if err := vom.Decode([]byte(serialized), &newM); err != nil {
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -070098 return err
99 }
100 c.Lock()
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -0700101 for k, v := range newM {
102 c.m[k] = v
103 }
Todd Wangf519f8f2015-01-21 10:07:41 -0800104 c.Unlock()
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -0700105 return nil
106}