github.com/polydawn/docket@v0.5.4-0.20140630233848-90b70fb433da/conf/parse.go (about)

     1  package conf
     2  
     3  // The only file that imports toml.
     4  // Keeps our chosen file format isolated from the rest of the system.
     5  
     6  import (
     7  	"path/filepath"
     8  	"github.com/BurntSushi/toml"
     9  	. "polydawn.net/hroot/util"
    10  )
    11  
    12  type TomlConfigParser struct {
    13  	config *Configuration
    14  }
    15  
    16  func (p *TomlConfigParser) AddConfig(data, dir string) ConfigParser {
    17  	//Load default configuration if no previous data
    18  	if p.config == nil {
    19  		a := DefaultConfiguration
    20  		p.config = &a
    21  	}
    22  
    23  	//Parse toml, expand relative paths, and override settings
    24  	conf, meta := ParseString(data)
    25  	conf.Settings.Localize(dir)
    26  	LoadContainerSettings(&p.config.Settings, &conf.Settings, meta, "settings")
    27  
    28  	//Load image names
    29  	p.config.Image = conf.Image
    30  
    31  	//If image keys 'upstream' and 'index' are defined, reject.
    32  	if meta.IsDefined("image", "upstream") && meta.IsDefined("image", "index") {
    33  		//Try to report absolute directory
    34  		absDir, err := filepath.Abs(dir)
    35  		if err == nil { dir = absDir }
    36  
    37  		ExitGently("In", dir, ": Cannot define 'index' and 'upstream' in the same file. \nUse separate config files to produce different images.")
    38  	}
    39  
    40  	//Load any target settings
    41  	p.config.Targets = conf.Targets
    42  
    43  	for x := range p.config.Targets {
    44  		a := p.config.Settings
    45  		b := p.config.Targets[x]
    46  		LoadContainerSettings(&a, &b, meta, "target", x)
    47  		p.config.Targets[x] = a
    48  	}
    49  
    50  	//Chain calls
    51  	return p
    52  }
    53  
    54  func (p *TomlConfigParser) GetConfig() *Configuration {
    55  	if p.config == nil {
    56  		return &DefaultConfiguration
    57  	} else {
    58  		return p.config
    59  	}
    60  }
    61  
    62  //Parse a TOML-formatted string into a configuration struct.
    63  func ParseString(data string) (*Configuration, *toml.MetaData) {
    64  	var set Configuration
    65  
    66  	//Decode the file
    67  	md, err := toml.Decode(data, &set)
    68  	if err != nil { ExitGently("Could not decode file:", err) }
    69  
    70  	return &set, &md
    71  }
    72  
    73  //Loads a container configuration object, overriding a base
    74  //This function prevents empty TOML keys (anything you didn't specify) from overriding a preset value.
    75  func LoadContainerSettings(base *Container, inc *Container, meta *toml.MetaData, key ...string) {
    76  
    77  	if meta.IsDefined(append(key, "command")...) {
    78  		base.Command = inc.Command
    79  	}
    80  
    81  	if meta.IsDefined(append(key, "folder")...) {
    82  		base.Folder = inc.Folder
    83  	}
    84  
    85  	if meta.IsDefined(append(key, "privileged")...) {
    86  		base.Privileged = inc.Privileged
    87  	}
    88  
    89  	if meta.IsDefined(append(key, "mounts")...) {
    90  		base.Mounts = append(base.Mounts, inc.Mounts...)
    91  	}
    92  
    93  	if meta.IsDefined(append(key, "ports")...) {
    94  		base.Ports = append(base.Ports, inc.Ports...)
    95  	}
    96  
    97  	if meta.IsDefined(append(key, "dns")...) {
    98  		base.DNS = append(base.DNS, inc.DNS...)
    99  	}
   100  
   101  	if meta.IsDefined(append(key, "attach")...) {
   102  		base.Attach = inc.Attach
   103  	}
   104  
   105  	if meta.IsDefined(append(key, "purge")...) {
   106  		base.Purge = inc.Purge
   107  	}
   108  
   109  	if meta.IsDefined(append(key, "environment")...) {
   110  		base.Environment = append(base.Environment, inc.Environment...)
   111  	}
   112  }