github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/provider/local/config.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package local
     5  
     6  import (
     7  	"fmt"
     8  	"os"
     9  	"path/filepath"
    10  
    11  	"github.com/juju/schema"
    12  	"gopkg.in/juju/environschema.v1"
    13  
    14  	"github.com/juju/juju/agent"
    15  	"github.com/juju/juju/container/kvm"
    16  	"github.com/juju/juju/container/lxc"
    17  	"github.com/juju/juju/environs/config"
    18  	"github.com/juju/juju/instance"
    19  )
    20  
    21  var checkIfRoot = func() bool {
    22  	return os.Getuid() == 0
    23  }
    24  
    25  // Attribute keys
    26  const (
    27  	BootstrapIpKey   = "bootstrap-ip"
    28  	ContainerKey     = "container"
    29  	NamespaceKey     = "namespace"
    30  	NetworkBridgeKey = "network-bridge"
    31  	RootDirKey       = "root-dir"
    32  	StoragePortKey   = "storage-port"
    33  )
    34  
    35  // configSchema defines the schema for the configuration attributes
    36  // defined by the local provider.
    37  var configSchema = environschema.Fields{
    38  	RootDirKey: {
    39  		Description: `The directory that is used for the storage files and database. The default location is $JUJU_HOME/<env-name>. $JUJU_HOME defaults to ~/.juju. Override if needed.`,
    40  		Type:        environschema.Tstring,
    41  		Example:     "~/.juju/local",
    42  	},
    43  	BootstrapIpKey: {
    44  		Description: `The IP address of the bootstrap machine`,
    45  		Type:        environschema.Tstring,
    46  		Group:       environschema.JujuGroup,
    47  	},
    48  	NetworkBridgeKey: {
    49  		Description: `The name of the LXC network bridge to use. Override if the default LXC network bridge is different.`,
    50  		Type:        environschema.Tstring,
    51  	},
    52  	ContainerKey: {
    53  		Description: `The kind of container to use for machines`,
    54  		Type:        environschema.Tstring,
    55  		Values: []interface{}{
    56  			string(instance.LXC),
    57  			string(instance.KVM),
    58  		},
    59  	},
    60  	StoragePortKey: {
    61  		Description: `The port where the local provider starts the HTTP file server. Override the value if you have multiple local providers, or if the default port is used by another program.`,
    62  		Type:        environschema.Tint,
    63  	},
    64  	NamespaceKey: {
    65  		Description: `The name space to use for local provider resources. Override if you have multiple local providers`,
    66  		Type:        environschema.Tstring,
    67  	},
    68  }
    69  
    70  var (
    71  	configFields = func() schema.Fields {
    72  		fs, _, err := configSchema.ValidationSchema()
    73  		if err != nil {
    74  			panic(err)
    75  		}
    76  		return fs
    77  	}()
    78  	// The port defaults below are not entirely arbitrary.  Local user web
    79  	// frameworks often use 8000 or 8080, so I didn't want to use either of
    80  	// these, but did want the familiarity of using something in the 8000
    81  	// range.
    82  	configDefaults = schema.Defaults{
    83  		RootDirKey:       "",
    84  		NetworkBridgeKey: "",
    85  		ContainerKey:     string(instance.LXC),
    86  		BootstrapIpKey:   schema.Omit,
    87  		StoragePortKey:   8040,
    88  		NamespaceKey:     "",
    89  	}
    90  )
    91  
    92  type environConfig struct {
    93  	*config.Config
    94  	attrs map[string]interface{}
    95  }
    96  
    97  func newEnvironConfig(config *config.Config, attrs map[string]interface{}) *environConfig {
    98  	return &environConfig{
    99  		Config: config,
   100  		attrs:  attrs,
   101  	}
   102  }
   103  
   104  // Since it is technically possible for two different users on one machine to
   105  // have the same local provider name, we need to have a simple way to
   106  // namespace the file locations, but more importantly the containers.
   107  func (c *environConfig) namespace() string {
   108  	return c.attrs[NamespaceKey].(string)
   109  }
   110  
   111  func (c *environConfig) rootDir() string {
   112  	return c.attrs[RootDirKey].(string)
   113  }
   114  
   115  func (c *environConfig) container() instance.ContainerType {
   116  	return instance.ContainerType(c.attrs[ContainerKey].(string))
   117  }
   118  
   119  // setDefaultNetworkBridge sets default network bridge if none is
   120  // provided. Default network bridge varies based on container type.
   121  func (c *environConfig) setDefaultNetworkBridge() {
   122  	name := c.networkBridge()
   123  	switch c.container() {
   124  	case instance.LXC:
   125  		if name == "" {
   126  			name = lxc.DefaultLxcBridge
   127  		}
   128  	case instance.KVM:
   129  		if name == "" {
   130  			name = kvm.DefaultKvmBridge
   131  		}
   132  	}
   133  	c.attrs[NetworkBridgeKey] = name
   134  }
   135  
   136  func (c *environConfig) networkBridge() string {
   137  	// We don't care if it's not a string, because Validate takes care
   138  	// of that.
   139  	return c.attrs[NetworkBridgeKey].(string)
   140  }
   141  
   142  func (c *environConfig) storageDir() string {
   143  	return filepath.Join(c.rootDir(), "storage")
   144  }
   145  
   146  func (c *environConfig) mongoDir() string {
   147  	return filepath.Join(c.rootDir(), "db")
   148  }
   149  
   150  func (c *environConfig) logDir() string {
   151  	return fmt.Sprintf("%s-%s", agent.DefaultPaths.LogDir, c.namespace())
   152  }
   153  
   154  // bootstrapIPAddress returns the IP address of the bootstrap machine.
   155  // As of 1.18 this is only set inside the environment, and not in the
   156  // .jenv file.
   157  func (c *environConfig) bootstrapIPAddress() string {
   158  	addr, _ := c.attrs[BootstrapIpKey].(string)
   159  	return addr
   160  }
   161  
   162  func (c *environConfig) stateServerAddr() string {
   163  	return fmt.Sprintf("localhost:%d", c.Config.APIPort())
   164  }
   165  
   166  func (c *environConfig) storagePort() int {
   167  	return c.attrs[StoragePortKey].(int)
   168  }
   169  
   170  func (c *environConfig) storageAddr() string {
   171  	return fmt.Sprintf("%s:%d", c.bootstrapIPAddress(), c.storagePort())
   172  }
   173  
   174  func (c *environConfig) configFile(filename string) string {
   175  	return filepath.Join(c.rootDir(), filename)
   176  }
   177  
   178  func (c *environConfig) createDirs() error {
   179  	for _, dirname := range []string{
   180  		c.storageDir(),
   181  		c.mongoDir(),
   182  	} {
   183  		logger.Tracef("creating directory %s", dirname)
   184  		if err := os.MkdirAll(dirname, 0755); err != nil {
   185  			return err
   186  		}
   187  	}
   188  	return nil
   189  }