unit: refactor config
- Seperate the config from Destination() - Add YAML tags for the fields
This commit is contained in:
parent
667dbd8fb7
commit
1fbbaaec19
34
config/unit.go
Normal file
34
config/unit.go
Normal file
@ -0,0 +1,34 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Unit struct {
|
||||
Name string `yaml:"name"`
|
||||
Mask bool `yaml:"mask"`
|
||||
Enable bool `yaml:"enable"`
|
||||
Runtime bool `yaml:"runtime"`
|
||||
Content string `yaml:"content"`
|
||||
Command string `yaml:"command"`
|
||||
|
||||
// For drop-in units, a cloudinit.conf is generated.
|
||||
// This is currently unbound in YAML (and hence unsettable in cloud-config files)
|
||||
// until the correct behaviour for multiple drop-in units is determined.
|
||||
DropIn bool `yaml:"-"`
|
||||
}
|
||||
|
||||
func (u *Unit) Type() string {
|
||||
ext := filepath.Ext(u.Name)
|
||||
return strings.TrimLeft(ext, ".")
|
||||
}
|
||||
|
||||
func (u *Unit) Group() string {
|
||||
switch u.Type() {
|
||||
case "network", "netdev", "link":
|
||||
return "network"
|
||||
default:
|
||||
return "system"
|
||||
}
|
||||
}
|
@ -35,7 +35,7 @@ type CloudConfig struct {
|
||||
Fleet config.Fleet
|
||||
OEM config.OEM
|
||||
Update config.Update
|
||||
Units []system.Unit
|
||||
Units []config.Unit
|
||||
}
|
||||
WriteFiles []system.File `yaml:"write_files"`
|
||||
Hostname string
|
||||
@ -231,6 +231,11 @@ func Apply(cfg CloudConfig, env *Environment) error {
|
||||
}
|
||||
}
|
||||
|
||||
var units []system.Unit
|
||||
for _, u := range cfg.Coreos.Units {
|
||||
units = append(units, system.Unit{u})
|
||||
}
|
||||
|
||||
for _, ccu := range []CloudConfigUnit{
|
||||
system.Etcd{cfg.Coreos.Etcd},
|
||||
system.Fleet{cfg.Coreos.Fleet},
|
||||
@ -240,7 +245,7 @@ func Apply(cfg CloudConfig, env *Environment) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cfg.Coreos.Units = append(cfg.Coreos.Units, u...)
|
||||
units = append(units, u...)
|
||||
}
|
||||
|
||||
wroteEnvironment := false
|
||||
@ -291,7 +296,7 @@ func Apply(cfg CloudConfig, env *Environment) error {
|
||||
}
|
||||
|
||||
um := system.NewUnitManager(env.Root())
|
||||
return processUnits(cfg.Coreos.Units, env.Root(), um)
|
||||
return processUnits(units, env.Root(), um)
|
||||
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/coreos/coreos-cloudinit/config"
|
||||
"github.com/coreos/coreos-cloudinit/system"
|
||||
)
|
||||
|
||||
@ -401,10 +402,10 @@ func (tum *TestUnitManager) UnmaskUnit(unit *system.Unit) error {
|
||||
func TestProcessUnits(t *testing.T) {
|
||||
tum := &TestUnitManager{}
|
||||
units := []system.Unit{
|
||||
system.Unit{
|
||||
system.Unit{config.Unit{
|
||||
Name: "foo",
|
||||
Mask: true,
|
||||
},
|
||||
}},
|
||||
}
|
||||
if err := processUnits(units, "", tum); err != nil {
|
||||
t.Fatalf("unexpected error calling processUnits: %v", err)
|
||||
@ -415,9 +416,9 @@ func TestProcessUnits(t *testing.T) {
|
||||
|
||||
tum = &TestUnitManager{}
|
||||
units = []system.Unit{
|
||||
system.Unit{
|
||||
system.Unit{config.Unit{
|
||||
Name: "bar.network",
|
||||
},
|
||||
}},
|
||||
}
|
||||
if err := processUnits(units, "", tum); err != nil {
|
||||
t.Fatalf("unexpected error calling processUnits: %v", err)
|
||||
@ -428,10 +429,10 @@ func TestProcessUnits(t *testing.T) {
|
||||
|
||||
tum = &TestUnitManager{}
|
||||
units = []system.Unit{
|
||||
system.Unit{
|
||||
system.Unit{config.Unit{
|
||||
Name: "baz.service",
|
||||
Content: "[Service]\nExecStart=/bin/true",
|
||||
},
|
||||
}},
|
||||
}
|
||||
if err := processUnits(units, "", tum); err != nil {
|
||||
t.Fatalf("unexpected error calling processUnits: %v", err)
|
||||
@ -442,10 +443,10 @@ func TestProcessUnits(t *testing.T) {
|
||||
|
||||
tum = &TestUnitManager{}
|
||||
units = []system.Unit{
|
||||
system.Unit{
|
||||
system.Unit{config.Unit{
|
||||
Name: "locksmithd.service",
|
||||
Runtime: true,
|
||||
},
|
||||
}},
|
||||
}
|
||||
if err := processUnits(units, "", tum); err != nil {
|
||||
t.Fatalf("unexpected error calling processUnits: %v", err)
|
||||
@ -456,10 +457,10 @@ func TestProcessUnits(t *testing.T) {
|
||||
|
||||
tum = &TestUnitManager{}
|
||||
units = []system.Unit{
|
||||
system.Unit{
|
||||
system.Unit{config.Unit{
|
||||
Name: "woof",
|
||||
Enable: true,
|
||||
},
|
||||
}},
|
||||
}
|
||||
if err := processUnits(units, "", tum); err != nil {
|
||||
t.Fatalf("unexpected error calling processUnits: %v", err)
|
||||
|
@ -16,10 +16,10 @@ func (ee Etcd) Units() ([]Unit, error) {
|
||||
if content == "" {
|
||||
return nil, nil
|
||||
}
|
||||
return []Unit{{
|
||||
return []Unit{{config.Unit{
|
||||
Name: "etcd.service",
|
||||
Runtime: true,
|
||||
DropIn: true,
|
||||
Content: content,
|
||||
}}, nil
|
||||
}}}, nil
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ func TestEtcdUnits(t *testing.T) {
|
||||
Discovery: "http://disco.example.com/foobar",
|
||||
PeerBindAddr: "127.0.0.1:7002",
|
||||
},
|
||||
[]Unit{{
|
||||
[]Unit{{config.Unit{
|
||||
Name: "etcd.service",
|
||||
Runtime: true,
|
||||
DropIn: true,
|
||||
@ -29,7 +29,7 @@ func TestEtcdUnits(t *testing.T) {
|
||||
Environment="ETCD_DISCOVERY=http://disco.example.com/foobar"
|
||||
Environment="ETCD_PEER_BIND_ADDR=127.0.0.1:7002"
|
||||
`,
|
||||
}},
|
||||
}}},
|
||||
},
|
||||
{
|
||||
config.Etcd{
|
||||
@ -37,7 +37,7 @@ Environment="ETCD_PEER_BIND_ADDR=127.0.0.1:7002"
|
||||
Discovery: "http://disco.example.com/foobar",
|
||||
PeerBindAddr: "127.0.0.1:7002",
|
||||
},
|
||||
[]Unit{{
|
||||
[]Unit{{config.Unit{
|
||||
Name: "etcd.service",
|
||||
Runtime: true,
|
||||
DropIn: true,
|
||||
@ -46,7 +46,7 @@ Environment="ETCD_DISCOVERY=http://disco.example.com/foobar"
|
||||
Environment="ETCD_NAME=node001"
|
||||
Environment="ETCD_PEER_BIND_ADDR=127.0.0.1:7002"
|
||||
`,
|
||||
}},
|
||||
}}},
|
||||
},
|
||||
} {
|
||||
units, err := Etcd{tt.config}.Units()
|
||||
|
@ -17,10 +17,10 @@ func (fe Fleet) Units() ([]Unit, error) {
|
||||
if content == "" {
|
||||
return nil, nil
|
||||
}
|
||||
return []Unit{{
|
||||
return []Unit{{config.Unit{
|
||||
Name: "fleet.service",
|
||||
Runtime: true,
|
||||
DropIn: true,
|
||||
Content: content,
|
||||
}}, nil
|
||||
}}}, nil
|
||||
}
|
||||
|
@ -20,14 +20,14 @@ func TestFleetUnits(t *testing.T) {
|
||||
config.Fleet{
|
||||
PublicIP: "12.34.56.78",
|
||||
},
|
||||
[]Unit{{
|
||||
[]Unit{{config.Unit{
|
||||
Name: "fleet.service",
|
||||
Content: `[Service]
|
||||
Environment="FLEET_PUBLIC_IP=12.34.56.78"
|
||||
`,
|
||||
Runtime: true,
|
||||
DropIn: true,
|
||||
}},
|
||||
}}},
|
||||
},
|
||||
} {
|
||||
units, err := Fleet{tt.config}.Units()
|
||||
|
@ -5,10 +5,12 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
"github.com/coreos/coreos-cloudinit/config"
|
||||
)
|
||||
|
||||
func TestPlaceNetworkUnit(t *testing.T) {
|
||||
u := Unit{
|
||||
u := Unit{config.Unit{
|
||||
Name: "50-eth0.network",
|
||||
Runtime: true,
|
||||
Content: `[Match]
|
||||
@ -17,7 +19,7 @@ Name=eth47
|
||||
[Network]
|
||||
Address=10.209.171.177/19
|
||||
`,
|
||||
}
|
||||
}}
|
||||
|
||||
dir, err := ioutil.TempDir(os.TempDir(), "coreos-cloudinit-")
|
||||
if err != nil {
|
||||
@ -66,10 +68,10 @@ func TestUnitDestination(t *testing.T) {
|
||||
dir := "/some/dir"
|
||||
name := "foobar.service"
|
||||
|
||||
u := Unit{
|
||||
u := Unit{config.Unit{
|
||||
Name: name,
|
||||
DropIn: false,
|
||||
}
|
||||
}}
|
||||
|
||||
dst := u.Destination(dir)
|
||||
expectDst := path.Join(dir, "etc", "systemd", "system", "foobar.service")
|
||||
@ -87,14 +89,14 @@ func TestUnitDestination(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestPlaceMountUnit(t *testing.T) {
|
||||
u := Unit{
|
||||
u := Unit{config.Unit{
|
||||
Name: "media-state.mount",
|
||||
Runtime: false,
|
||||
Content: `[Mount]
|
||||
What=/dev/sdb1
|
||||
Where=/media/state
|
||||
`,
|
||||
}
|
||||
}}
|
||||
|
||||
dir, err := ioutil.TempDir(os.TempDir(), "coreos-cloudinit-")
|
||||
if err != nil {
|
||||
@ -162,7 +164,7 @@ func TestMaskUnit(t *testing.T) {
|
||||
sd := &systemd{dir}
|
||||
|
||||
// Ensure mask works with units that do not currently exist
|
||||
uf := &Unit{Name: "foo.service"}
|
||||
uf := &Unit{config.Unit{Name: "foo.service"}}
|
||||
if err := sd.MaskUnit(uf); err != nil {
|
||||
t.Fatalf("Unable to mask new unit: %v", err)
|
||||
}
|
||||
@ -176,7 +178,7 @@ func TestMaskUnit(t *testing.T) {
|
||||
}
|
||||
|
||||
// Ensure mask works with unit files that already exist
|
||||
ub := &Unit{Name: "bar.service"}
|
||||
ub := &Unit{config.Unit{Name: "bar.service"}}
|
||||
barPath := path.Join(dir, "etc", "systemd", "system", "bar.service")
|
||||
if _, err := os.Create(barPath); err != nil {
|
||||
t.Fatalf("Error creating new unit file: %v", err)
|
||||
@ -202,12 +204,12 @@ func TestUnmaskUnit(t *testing.T) {
|
||||
|
||||
sd := &systemd{dir}
|
||||
|
||||
nilUnit := &Unit{Name: "null.service"}
|
||||
nilUnit := &Unit{config.Unit{Name: "null.service"}}
|
||||
if err := sd.UnmaskUnit(nilUnit); err != nil {
|
||||
t.Errorf("unexpected error from unmasking nonexistent unit: %v", err)
|
||||
}
|
||||
|
||||
uf := &Unit{Name: "foo.service", Content: "[Service]\nExecStart=/bin/true"}
|
||||
uf := &Unit{config.Unit{Name: "foo.service", Content: "[Service]\nExecStart=/bin/true"}}
|
||||
dst := uf.Destination(dir)
|
||||
if err := os.MkdirAll(path.Dir(dst), os.FileMode(0755)); err != nil {
|
||||
t.Fatalf("Unable to create unit directory: %v", err)
|
||||
@ -227,7 +229,7 @@ func TestUnmaskUnit(t *testing.T) {
|
||||
t.Errorf("unmask of non-empty unit mutated unit contents unexpectedly")
|
||||
}
|
||||
|
||||
ub := &Unit{Name: "bar.service"}
|
||||
ub := &Unit{config.Unit{Name: "bar.service"}}
|
||||
dst = ub.Destination(dir)
|
||||
if err := os.Symlink("/dev/null", dst); err != nil {
|
||||
t.Fatalf("Unable to create masked unit: %v", err)
|
||||
|
@ -3,8 +3,8 @@ package system
|
||||
import (
|
||||
"fmt"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/coreos/coreos-cloudinit/config"
|
||||
)
|
||||
|
||||
// Name for drop-in service configuration files created by cloudconfig
|
||||
@ -19,33 +19,10 @@ type UnitManager interface {
|
||||
UnmaskUnit(unit *Unit) error
|
||||
}
|
||||
|
||||
// Unit is a top-level structure which embeds its underlying configuration,
|
||||
// config.Unit, and provides the system-specific Destination().
|
||||
type Unit struct {
|
||||
Name string
|
||||
Mask bool
|
||||
Enable bool
|
||||
Runtime bool
|
||||
Content string
|
||||
Command string
|
||||
|
||||
// For drop-in units, a cloudinit.conf is generated.
|
||||
// This is currently unbound in YAML (and hence unsettable in cloud-config files)
|
||||
// until the correct behaviour for multiple drop-in units is determined.
|
||||
DropIn bool `yaml:"-"`
|
||||
}
|
||||
|
||||
func (u *Unit) Type() string {
|
||||
ext := filepath.Ext(u.Name)
|
||||
return strings.TrimLeft(ext, ".")
|
||||
}
|
||||
|
||||
func (u *Unit) Group() (group string) {
|
||||
t := u.Type()
|
||||
if t == "network" || t == "netdev" || t == "link" {
|
||||
group = "network"
|
||||
} else {
|
||||
group = "system"
|
||||
}
|
||||
return
|
||||
config.Unit
|
||||
}
|
||||
|
||||
type Script []byte
|
||||
|
@ -103,12 +103,12 @@ func (uc Update) File() (*File, error) {
|
||||
func (uc Update) Units() ([]Unit, error) {
|
||||
var units []Unit
|
||||
if uc.Config.RebootStrategy != "" {
|
||||
ls := &Unit{
|
||||
ls := &Unit{config.Unit{
|
||||
Name: locksmithUnit,
|
||||
Command: "restart",
|
||||
Mask: false,
|
||||
Runtime: true,
|
||||
}
|
||||
}}
|
||||
|
||||
if uc.Config.RebootStrategy == "off" {
|
||||
ls.Command = "stop"
|
||||
@ -118,10 +118,10 @@ func (uc Update) Units() ([]Unit, error) {
|
||||
}
|
||||
|
||||
if uc.Config.Group != "" || uc.Config.Server != "" {
|
||||
ue := Unit{
|
||||
ue := Unit{config.Unit{
|
||||
Name: updateEngineUnit,
|
||||
Command: "restart",
|
||||
}
|
||||
}}
|
||||
units = append(units, ue)
|
||||
}
|
||||
|
||||
|
@ -27,43 +27,43 @@ func TestUpdateUnits(t *testing.T) {
|
||||
},
|
||||
{
|
||||
config: config.Update{Group: "master", Server: "http://foo.com"},
|
||||
units: []Unit{{
|
||||
units: []Unit{{config.Unit{
|
||||
Name: "update-engine.service",
|
||||
Command: "restart",
|
||||
}},
|
||||
}}},
|
||||
},
|
||||
{
|
||||
config: config.Update{RebootStrategy: "best-effort"},
|
||||
units: []Unit{{
|
||||
units: []Unit{{config.Unit{
|
||||
Name: "locksmithd.service",
|
||||
Command: "restart",
|
||||
Runtime: true,
|
||||
}},
|
||||
}}},
|
||||
},
|
||||
{
|
||||
config: config.Update{RebootStrategy: "etcd-lock"},
|
||||
units: []Unit{{
|
||||
units: []Unit{{config.Unit{
|
||||
Name: "locksmithd.service",
|
||||
Command: "restart",
|
||||
Runtime: true,
|
||||
}},
|
||||
}}},
|
||||
},
|
||||
{
|
||||
config: config.Update{RebootStrategy: "reboot"},
|
||||
units: []Unit{{
|
||||
units: []Unit{{config.Unit{
|
||||
Name: "locksmithd.service",
|
||||
Command: "restart",
|
||||
Runtime: true,
|
||||
}},
|
||||
}}},
|
||||
},
|
||||
{
|
||||
config: config.Update{RebootStrategy: "off"},
|
||||
units: []Unit{{
|
||||
units: []Unit{{config.Unit{
|
||||
Name: "locksmithd.service",
|
||||
Command: "stop",
|
||||
Runtime: true,
|
||||
Mask: true,
|
||||
}},
|
||||
}}},
|
||||
},
|
||||
} {
|
||||
units, err := Update{tt.config, testReadConfig("")}.Units()
|
||||
|
Loading…
Reference in New Issue
Block a user