Merge pull request #115 from cyphar/toml-config

cmd: server: use TOML configuration file
This commit is contained in:
Mrunal Patel 2016-10-11 16:07:25 -07:00 committed by GitHub
commit e999610fd6
33 changed files with 3702 additions and 73 deletions

135
server/config.go Normal file
View file

@ -0,0 +1,135 @@
package server
import (
"bytes"
"io/ioutil"
"github.com/BurntSushi/toml"
)
// Config represents the entire set of configuration values that can be set for
// the server. This is intended to be loaded from a toml-encoded config file.
type Config struct {
RootConfig
APIConfig
RuntimeConfig
ImageConfig
}
// This structure is necessary to fake the TOML tables when parsing,
// while also not requiring a bunch of layered structs for no good
// reason.
// RootConfig represents the root of the "ocid" TOML config table.
type RootConfig struct {
// Root is a path to the "root directory" where all information not
// explicitly handled by other options will be stored.
Root string `toml:"root"`
// SandboxDir is the directory where ocid will store all of its sandbox
// state and other information.
SandboxDir string `toml:"sandbox_dir"`
// ContainerDir is the directory where ocid will store all of its container
// state and other information.
ContainerDir string `toml:"container_dir"`
}
// APIConfig represents the "ocid.api" TOML config table.
type APIConfig struct {
// Listen is the path to the AF_LOCAL socket on which cri-o will listen.
// This may support proto://addr formats later, but currently this is just
// a path.
Listen string `toml:"listen"`
}
// RuntimeConfig represents the "ocid.runtime" TOML config table.
type RuntimeConfig struct {
// Runtime is a path to the OCI runtime which ocid will be using. Currently
// the only known working choice is runC, simply because the OCI has not
// yet merged a CLI API (so we assume runC's API here).
Runtime string `toml:"runtime"`
// Conmon is the path to conmon binary, used for managing the runtime.
Conmon string `toml:"conmon"`
// SELinux determines whether or not SELinux is used for pod separation.
SELinux bool `toml:"selinux"`
}
// ImageConfig represents the "ocid.image" TOML config table.
type ImageConfig struct {
// Pause is the path to the statically linked pause container binary, used
// as the entrypoint for infra containers.
//
// TODO(cyphar): This should be replaced with a path to an OCI image
// bundle, once the OCI image/storage code has been implemented.
Pause string `toml:"pause"`
// ImageStore is the directory where the ocid image store will be stored.
ImageStore string
}
// tomlConfig is another way of looking at a Config, which is
// TOML-friendly (it has all of the explicit tables). It's just used for
// conversions.
type tomlConfig struct {
Ocid struct {
RootConfig
API struct{ APIConfig } `toml:"api"`
Runtime struct{ RuntimeConfig } `toml:"runtime"`
Image struct{ ImageConfig } `toml:"image"`
} `toml:"ocid"`
}
func (t *tomlConfig) toConfig(c *Config) {
c.RootConfig = t.Ocid.RootConfig
c.APIConfig = t.Ocid.API.APIConfig
c.RuntimeConfig = t.Ocid.Runtime.RuntimeConfig
c.ImageConfig = t.Ocid.Image.ImageConfig
}
func (t *tomlConfig) fromConfig(c *Config) {
t.Ocid.RootConfig = c.RootConfig
t.Ocid.API.APIConfig = c.APIConfig
t.Ocid.Runtime.RuntimeConfig = c.RuntimeConfig
t.Ocid.Image.ImageConfig = c.ImageConfig
}
// FromFile populates the Config from the TOML-encoded file at the given path.
// Returns errors encountered when reading or parsing the files, or nil
// otherwise.
func (c *Config) FromFile(path string) error {
data, err := ioutil.ReadFile(path)
if err != nil {
return err
}
t := new(tomlConfig)
t.fromConfig(c)
_, err = toml.Decode(string(data), t)
if err != nil {
return err
}
t.toConfig(c)
return nil
}
// ToFile outputs the given Config as a TOML-encoded file at the given path.
// Returns errors encountered when generating or writing the file, or nil
// otherwise.
func (c *Config) ToFile(path string) error {
var w bytes.Buffer
e := toml.NewEncoder(&w)
t := new(tomlConfig)
t.fromConfig(c)
if err := e.Encode(*t); err != nil {
return err
}
return ioutil.WriteFile(path, w.Bytes(), 0644)
}

View file

@ -55,10 +55,10 @@ func (s *Server) PullImage(ctx context.Context, req *pb.PullImageRequest) (*pb.P
return nil, err
}
if err = os.Mkdir(filepath.Join(imageStore, tr.StringWithinTransport()), 0755); err != nil {
if err = os.Mkdir(filepath.Join(s.config.ImageStore, tr.StringWithinTransport()), 0755); err != nil {
return nil, err
}
dir, err := directory.NewReference(filepath.Join(imageStore, tr.StringWithinTransport()))
dir, err := directory.NewReference(filepath.Join(s.config.ImageStore, tr.StringWithinTransport()))
if err != nil {
return nil, err
}

View file

@ -99,7 +99,7 @@ func (s *Server) RunPodSandbox(ctx context.Context, req *pb.RunPodSandboxRequest
if err != nil {
return nil, err
}
podSandboxDir := filepath.Join(s.sandboxDir, id)
podSandboxDir := filepath.Join(s.config.SandboxDir, id)
if _, err = os.Stat(podSandboxDir); err == nil {
return nil, fmt.Errorf("pod sandbox (%s) already exists", podSandboxDir)
}
@ -120,7 +120,7 @@ func (s *Server) RunPodSandbox(ctx context.Context, req *pb.RunPodSandboxRequest
// creates a spec Generator with the default spec.
g := generate.New()
podInfraRootfs := filepath.Join(s.root, "graph/vfs/pause")
podInfraRootfs := filepath.Join(s.config.Root, "graph/vfs/pause")
// setup defaults for the pod sandbox
g.SetRootPath(filepath.Join(podInfraRootfs, "rootfs"))
g.SetRootReadonly(true)
@ -236,7 +236,7 @@ func (s *Server) RunPodSandbox(ctx context.Context, req *pb.RunPodSandboxRequest
if _, err = os.Stat(podInfraRootfs); err != nil {
if os.IsNotExist(err) {
// TODO: Replace by rootfs creation API when it is ready
if err = utils.CreateInfraRootfs(podInfraRootfs, s.pausePath); err != nil {
if err = utils.CreateInfraRootfs(podInfraRootfs, s.config.Pause); err != nil {
return nil, err
}
} else {
@ -362,7 +362,7 @@ func (s *Server) RemovePodSandbox(ctx context.Context, req *pb.RemovePodSandboxR
}
// Remove the files related to the sandbox
podSandboxDir := filepath.Join(s.sandboxDir, sb.id)
podSandboxDir := filepath.Join(s.config.SandboxDir, sb.id)
if err := os.RemoveAll(podSandboxDir); err != nil {
return nil, fmt.Errorf("failed to remove sandbox %s directory: %v", sb.id, err)
}

View file

@ -20,15 +20,12 @@ import (
const (
runtimeAPIVersion = "v1alpha1"
imageStore = "/var/lib/ocid/images"
)
// Server implements the RuntimeService and ImageService
type Server struct {
root string
config Config
runtime *oci.Runtime
sandboxDir string
pausePath string
stateLock sync.Mutex
state *serverState
netPlugin ocicni.CNIPlugin
@ -83,7 +80,7 @@ func (s *Server) loadContainer(id string) error {
}
func (s *Server) loadSandbox(id string) error {
config, err := ioutil.ReadFile(filepath.Join(s.sandboxDir, id, "config.json"))
config, err := ioutil.ReadFile(filepath.Join(s.config.SandboxDir, id, "config.json"))
if err != nil {
return err
}
@ -114,7 +111,7 @@ func (s *Server) loadSandbox(id string) error {
processLabel: processLabel,
mountLabel: mountLabel,
})
sandboxPath := filepath.Join(s.sandboxDir, id)
sandboxPath := filepath.Join(s.config.SandboxDir, id)
if err := label.ReserveLabel(processLabel); err != nil {
return err
@ -142,7 +139,7 @@ func (s *Server) loadSandbox(id string) error {
}
func (s *Server) restore() {
sandboxDir, err := ioutil.ReadDir(s.sandboxDir)
sandboxDir, err := ioutil.ReadDir(s.config.SandboxDir)
if err != nil && !os.IsNotExist(err) {
logrus.Warnf("could not read sandbox directory %s: %v", sandboxDir, err)
}
@ -208,7 +205,7 @@ func (s *Server) releaseContainerName(name string) {
}
// New creates a new Server with options provided
func New(runtimePath, root, sandboxDir, containerDir, conmonPath, pausePath string) (*Server, error) {
func New(config *Config) (*Server, error) {
// TODO: This will go away later when we have wrapper process or systemd acting as
// subreaper.
if err := utils.SetSubreaper(1); err != nil {
@ -217,15 +214,15 @@ func New(runtimePath, root, sandboxDir, containerDir, conmonPath, pausePath stri
utils.StartReaper()
if err := os.MkdirAll(imageStore, 0755); err != nil {
if err := os.MkdirAll(config.ImageStore, 0755); err != nil {
return nil, err
}
if err := os.MkdirAll(sandboxDir, 0755); err != nil {
if err := os.MkdirAll(config.SandboxDir, 0755); err != nil {
return nil, err
}
r, err := oci.New(runtimePath, containerDir, conmonPath)
r, err := oci.New(config.Runtime, config.ContainerDir, config.Conmon)
if err != nil {
return nil, err
}
@ -236,11 +233,9 @@ func New(runtimePath, root, sandboxDir, containerDir, conmonPath, pausePath stri
return nil, err
}
s := &Server{
root: root,
runtime: r,
netPlugin: netPlugin,
sandboxDir: sandboxDir,
pausePath: pausePath,
runtime: r,
netPlugin: netPlugin,
config: *config,
state: &serverState{
sandboxes: sandboxes,
containers: containers,