blob: 601ad35407cfab14c43ca4b61addbb7327165cdd [file] [log] [blame]
Jiri Simsad7616c92015-03-24 23:44:30 -07001// Copyright 2015 The Vanadium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
Cosmos Nicolaou486d3492014-09-30 22:21:20 -07005package exec
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -07006
7import (
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -07008 "sync"
9
Jiri Simsa6ac95222015-02-23 16:11:49 -080010 "v.io/v23/verror"
11 "v.io/v23/vom"
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -070012)
13
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -070014// Config defines a simple key-value configuration. Keys and values are
15// strings, and a key can have exactly one value. The client is responsible for
16// encoding structured values, or multiple values, in the provided string.
17//
18// Config data can come from several sources:
19// - passed from parent process to child process through pipe;
20// - using environment variables or flags;
21// - via the neighborhood-based config service;
22// - by RPCs using the Config idl;
23// - manually, by calling the Set method.
24//
25// This interface makes no assumptions about the source of the configuration,
26// but provides a unified API for accessing it.
27type Config interface {
28 // Set sets the value for the key. If the key already exists in the
29 // config, its value is overwritten.
30 Set(key, value string)
Jiri Simsa37893392014-11-07 10:55:45 -080031 // Get returns the value for the key. If the key doesn't exist
32 // in the config, Get returns an error.
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -070033 Get(key string) (string, error)
Jiri Simsa37893392014-11-07 10:55:45 -080034 // Clear removes the specified key from the config.
35 Clear(key string)
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -070036 // Serialize serializes the config to a string.
37 Serialize() (string, error)
38 // MergeFrom deserializes config information from a string created using
39 // Serialize(), and merges this information into the config, updating
40 // values for keys that already exist and creating new key-value pairs
41 // for keys that don't.
42 MergeFrom(string) error
Bogdan Capritabf356d72015-01-08 17:28:48 -080043 // Dump returns the config information as a map from ket to value.
44 Dump() map[string]string
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -070045}
46
47type cfg struct {
48 sync.RWMutex
49 m map[string]string
50}
51
52// New creates a new empty config.
Cosmos Nicolaou486d3492014-09-30 22:21:20 -070053func NewConfig() Config {
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -070054 return &cfg{m: make(map[string]string)}
55}
56
Todd Wangf519f8f2015-01-21 10:07:41 -080057func (c *cfg) Set(key, value string) {
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -070058 c.Lock()
59 defer c.Unlock()
60 c.m[key] = value
61}
62
Todd Wangf519f8f2015-01-21 10:07:41 -080063func (c *cfg) Get(key string) (string, error) {
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -070064 c.RLock()
65 defer c.RUnlock()
66 v, ok := c.m[key]
67 if !ok {
Jiri Simsa074bf362015-02-17 09:29:45 -080068 return "", verror.New(verror.ErrNoExist, nil, "config.Get", key)
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -070069 }
70 return v, nil
71}
72
Todd Wangf519f8f2015-01-21 10:07:41 -080073func (c *cfg) Dump() (res map[string]string) {
Bogdan Capritabf356d72015-01-08 17:28:48 -080074 res = make(map[string]string)
75 c.RLock()
76 defer c.RUnlock()
77 for k, v := range c.m {
78 res[k] = v
79 }
80 return
81}
82
Todd Wangf519f8f2015-01-21 10:07:41 -080083func (c *cfg) Clear(key string) {
Jiri Simsa37893392014-11-07 10:55:45 -080084 c.Lock()
85 defer c.Unlock()
86 delete(c.m, key)
87}
88
Todd Wangf519f8f2015-01-21 10:07:41 -080089func (c *cfg) Serialize() (string, error) {
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -070090 c.RLock()
Todd Wang3425a902015-01-21 18:43:59 -080091 data, err := vom.Encode(c.m)
Todd Wangf519f8f2015-01-21 10:07:41 -080092 c.RUnlock()
93 if err != nil {
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -070094 return "", err
95 }
Todd Wangf519f8f2015-01-21 10:07:41 -080096 return string(data), nil
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -070097}
98
Todd Wangf519f8f2015-01-21 10:07:41 -080099func (c *cfg) MergeFrom(serialized string) error {
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -0700100 var newM map[string]string
Todd Wang3425a902015-01-21 18:43:59 -0800101 if err := vom.Decode([]byte(serialized), &newM); err != nil {
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -0700102 return err
103 }
104 c.Lock()
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -0700105 for k, v := range newM {
106 c.m[k] = v
107 }
Todd Wangf519f8f2015-01-21 10:07:41 -0800108 c.Unlock()
Bogdan Capritaa4d9ee42014-06-20 16:42:53 -0700109 return nil
110}