mirror of
https://github.com/rancher/os.git
synced 2025-09-03 07:44:21 +00:00
Godep changes
This commit is contained in:
13
Godeps/Godeps.json
generated
13
Godeps/Godeps.json
generated
@@ -22,11 +22,6 @@
|
|||||||
"Comment": "v1.3.2-6-g405c260",
|
"Comment": "v1.3.2-6-g405c260",
|
||||||
"Rev": "405c2600b19ae77516c967f8ee8ebde5624d3663"
|
"Rev": "405c2600b19ae77516c967f8ee8ebde5624d3663"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"ImportPath": "github.com/coreos/coreos-cloudinit/initialize",
|
|
||||||
"Comment": "v1.3.2-6-g405c260",
|
|
||||||
"Rev": "405c2600b19ae77516c967f8ee8ebde5624d3663"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/coreos/coreos-cloudinit/network",
|
"ImportPath": "github.com/coreos/coreos-cloudinit/network",
|
||||||
"Comment": "v1.3.2-6-g405c260",
|
"Comment": "v1.3.2-6-g405c260",
|
||||||
@@ -226,13 +221,13 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/rancherio/rancher-compose/docker",
|
"ImportPath": "github.com/rancherio/rancher-compose/docker",
|
||||||
"Comment": "0.1.0-8-g45c7de3",
|
"Comment": "0.1.0-9-g7343438",
|
||||||
"Rev": "45c7de3d9b5b106475cf1461df7550bdaab0a9aa"
|
"Rev": "734343806223cab5de0532ea7add0beeb2cbea92"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/rancherio/rancher-compose/project",
|
"ImportPath": "github.com/rancherio/rancher-compose/project",
|
||||||
"Comment": "0.1.0-8-g45c7de3",
|
"Comment": "0.1.0-9-g7343438",
|
||||||
"Rev": "45c7de3d9b5b106475cf1461df7550bdaab0a9aa"
|
"Rev": "734343806223cab5de0532ea7add0beeb2cbea92"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/ryanuber/go-glob",
|
"ImportPath": "github.com/ryanuber/go-glob",
|
||||||
|
293
Godeps/_workspace/src/github.com/coreos/coreos-cloudinit/initialize/config.go
generated
vendored
293
Godeps/_workspace/src/github.com/coreos/coreos-cloudinit/initialize/config.go
generated
vendored
@@ -1,293 +0,0 @@
|
|||||||
// Copyright 2015 CoreOS, Inc.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package initialize
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"path"
|
|
||||||
|
|
||||||
"github.com/coreos/coreos-cloudinit/config"
|
|
||||||
"github.com/coreos/coreos-cloudinit/network"
|
|
||||||
"github.com/coreos/coreos-cloudinit/system"
|
|
||||||
)
|
|
||||||
|
|
||||||
// CloudConfigFile represents a CoreOS specific configuration option that can generate
|
|
||||||
// an associated system.File to be written to disk
|
|
||||||
type CloudConfigFile interface {
|
|
||||||
// File should either return (*system.File, error), or (nil, nil) if nothing
|
|
||||||
// needs to be done for this configuration option.
|
|
||||||
File() (*system.File, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CloudConfigUnit represents a CoreOS specific configuration option that can generate
|
|
||||||
// associated system.Units to be created/enabled appropriately
|
|
||||||
type CloudConfigUnit interface {
|
|
||||||
Units() []system.Unit
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply renders a CloudConfig to an Environment. This can involve things like
|
|
||||||
// configuring the hostname, adding new users, writing various configuration
|
|
||||||
// files to disk, and manipulating systemd services.
|
|
||||||
func Apply(cfg config.CloudConfig, ifaces []network.InterfaceGenerator, env *Environment) error {
|
|
||||||
if cfg.Hostname != "" {
|
|
||||||
if err := system.SetHostname(cfg.Hostname); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
log.Printf("Set hostname to %s", cfg.Hostname)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, user := range cfg.Users {
|
|
||||||
if user.Name == "" {
|
|
||||||
log.Printf("User object has no 'name' field, skipping")
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if system.UserExists(&user) {
|
|
||||||
log.Printf("User '%s' exists, ignoring creation-time fields", user.Name)
|
|
||||||
if user.PasswordHash != "" {
|
|
||||||
log.Printf("Setting '%s' user's password", user.Name)
|
|
||||||
if err := system.SetUserPassword(user.Name, user.PasswordHash); err != nil {
|
|
||||||
log.Printf("Failed setting '%s' user's password: %v", user.Name, err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.Printf("Creating user '%s'", user.Name)
|
|
||||||
if err := system.CreateUser(&user); err != nil {
|
|
||||||
log.Printf("Failed creating user '%s': %v", user.Name, err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(user.SSHAuthorizedKeys) > 0 {
|
|
||||||
log.Printf("Authorizing %d SSH keys for user '%s'", len(user.SSHAuthorizedKeys), user.Name)
|
|
||||||
if err := system.AuthorizeSSHKeys(user.Name, env.SSHKeyName(), user.SSHAuthorizedKeys); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if user.SSHImportGithubUser != "" {
|
|
||||||
log.Printf("Authorizing github user %s SSH keys for CoreOS user '%s'", user.SSHImportGithubUser, user.Name)
|
|
||||||
if err := SSHImportGithubUser(user.Name, user.SSHImportGithubUser); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, u := range user.SSHImportGithubUsers {
|
|
||||||
log.Printf("Authorizing github user %s SSH keys for CoreOS user '%s'", u, user.Name)
|
|
||||||
if err := SSHImportGithubUser(user.Name, u); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if user.SSHImportURL != "" {
|
|
||||||
log.Printf("Authorizing SSH keys for CoreOS user '%s' from '%s'", user.Name, user.SSHImportURL)
|
|
||||||
if err := SSHImportKeysFromURL(user.Name, user.SSHImportURL); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(cfg.SSHAuthorizedKeys) > 0 {
|
|
||||||
err := system.AuthorizeSSHKeys("core", env.SSHKeyName(), cfg.SSHAuthorizedKeys)
|
|
||||||
if err == nil {
|
|
||||||
log.Printf("Authorized SSH keys for core user")
|
|
||||||
} else {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var writeFiles []system.File
|
|
||||||
for _, file := range cfg.WriteFiles {
|
|
||||||
writeFiles = append(writeFiles, system.File{File: file})
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, ccf := range []CloudConfigFile{
|
|
||||||
system.OEM{OEM: cfg.CoreOS.OEM},
|
|
||||||
system.Update{Update: cfg.CoreOS.Update, ReadConfig: system.DefaultReadConfig},
|
|
||||||
system.EtcHosts{EtcHosts: cfg.ManageEtcHosts},
|
|
||||||
system.Flannel{Flannel: cfg.CoreOS.Flannel},
|
|
||||||
} {
|
|
||||||
f, err := ccf.File()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if f != nil {
|
|
||||||
writeFiles = append(writeFiles, *f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var units []system.Unit
|
|
||||||
for _, u := range cfg.CoreOS.Units {
|
|
||||||
units = append(units, system.Unit{Unit: u})
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, ccu := range []CloudConfigUnit{
|
|
||||||
system.Etcd{Etcd: cfg.CoreOS.Etcd},
|
|
||||||
system.Fleet{Fleet: cfg.CoreOS.Fleet},
|
|
||||||
system.Locksmith{Locksmith: cfg.CoreOS.Locksmith},
|
|
||||||
system.Update{Update: cfg.CoreOS.Update, ReadConfig: system.DefaultReadConfig},
|
|
||||||
} {
|
|
||||||
units = append(units, ccu.Units()...)
|
|
||||||
}
|
|
||||||
|
|
||||||
wroteEnvironment := false
|
|
||||||
for _, file := range writeFiles {
|
|
||||||
fullPath, err := system.WriteFile(&file, env.Root())
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if path.Clean(file.Path) == "/etc/environment" {
|
|
||||||
wroteEnvironment = true
|
|
||||||
}
|
|
||||||
log.Printf("Wrote file %s to filesystem", fullPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !wroteEnvironment {
|
|
||||||
ef := env.DefaultEnvironmentFile()
|
|
||||||
if ef != nil {
|
|
||||||
err := system.WriteEnvFile(ef, env.Root())
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
log.Printf("Updated /etc/environment")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(ifaces) > 0 {
|
|
||||||
units = append(units, createNetworkingUnits(ifaces)...)
|
|
||||||
if err := system.RestartNetwork(ifaces); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
um := system.NewUnitManager(env.Root())
|
|
||||||
return processUnits(units, env.Root(), um)
|
|
||||||
}
|
|
||||||
|
|
||||||
func createNetworkingUnits(interfaces []network.InterfaceGenerator) (units []system.Unit) {
|
|
||||||
appendNewUnit := func(units []system.Unit, name, content string) []system.Unit {
|
|
||||||
if content == "" {
|
|
||||||
return units
|
|
||||||
}
|
|
||||||
return append(units, system.Unit{Unit: config.Unit{
|
|
||||||
Name: name,
|
|
||||||
Runtime: true,
|
|
||||||
Content: content,
|
|
||||||
}})
|
|
||||||
}
|
|
||||||
for _, i := range interfaces {
|
|
||||||
units = appendNewUnit(units, fmt.Sprintf("%s.netdev", i.Filename()), i.Netdev())
|
|
||||||
units = appendNewUnit(units, fmt.Sprintf("%s.link", i.Filename()), i.Link())
|
|
||||||
units = appendNewUnit(units, fmt.Sprintf("%s.network", i.Filename()), i.Network())
|
|
||||||
}
|
|
||||||
return units
|
|
||||||
}
|
|
||||||
|
|
||||||
// processUnits takes a set of Units and applies them to the given root using
|
|
||||||
// the given UnitManager. This can involve things like writing unit files to
|
|
||||||
// disk, masking/unmasking units, or invoking systemd
|
|
||||||
// commands against units. It returns any error encountered.
|
|
||||||
func processUnits(units []system.Unit, root string, um system.UnitManager) error {
|
|
||||||
type action struct {
|
|
||||||
unit system.Unit
|
|
||||||
command string
|
|
||||||
}
|
|
||||||
actions := make([]action, 0, len(units))
|
|
||||||
reload := false
|
|
||||||
restartNetworkd := false
|
|
||||||
for _, unit := range units {
|
|
||||||
if unit.Name == "" {
|
|
||||||
log.Printf("Skipping unit without name")
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if unit.Content != "" {
|
|
||||||
log.Printf("Writing unit %q to filesystem", unit.Name)
|
|
||||||
if err := um.PlaceUnit(unit); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
log.Printf("Wrote unit %q", unit.Name)
|
|
||||||
reload = true
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, dropin := range unit.DropIns {
|
|
||||||
if dropin.Name != "" && dropin.Content != "" {
|
|
||||||
log.Printf("Writing drop-in unit %q to filesystem", dropin.Name)
|
|
||||||
if err := um.PlaceUnitDropIn(unit, dropin); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
log.Printf("Wrote drop-in unit %q", dropin.Name)
|
|
||||||
reload = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if unit.Mask {
|
|
||||||
log.Printf("Masking unit file %q", unit.Name)
|
|
||||||
if err := um.MaskUnit(unit); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else if unit.Runtime {
|
|
||||||
log.Printf("Ensuring runtime unit file %q is unmasked", unit.Name)
|
|
||||||
if err := um.UnmaskUnit(unit); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if unit.Enable {
|
|
||||||
if unit.Group() != "network" {
|
|
||||||
log.Printf("Enabling unit file %q", unit.Name)
|
|
||||||
if err := um.EnableUnitFile(unit); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
log.Printf("Enabled unit %q", unit.Name)
|
|
||||||
} else {
|
|
||||||
log.Printf("Skipping enable for network-like unit %q", unit.Name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if unit.Group() == "network" {
|
|
||||||
restartNetworkd = true
|
|
||||||
} else if unit.Command != "" {
|
|
||||||
actions = append(actions, action{unit, unit.Command})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if reload {
|
|
||||||
if err := um.DaemonReload(); err != nil {
|
|
||||||
return errors.New(fmt.Sprintf("failed systemd daemon-reload: %s", err))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if restartNetworkd {
|
|
||||||
log.Printf("Restarting systemd-networkd")
|
|
||||||
networkd := system.Unit{Unit: config.Unit{Name: "systemd-networkd.service"}}
|
|
||||||
res, err := um.RunUnitCommand(networkd, "restart")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
log.Printf("Restarted systemd-networkd (%s)", res)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, action := range actions {
|
|
||||||
log.Printf("Calling unit command %q on %q'", action.command, action.unit.Name)
|
|
||||||
res, err := um.RunUnitCommand(action.unit, action.command)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
log.Printf("Result of %q on %q: %s", action.command, action.unit.Name, res)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
299
Godeps/_workspace/src/github.com/coreos/coreos-cloudinit/initialize/config_test.go
generated
vendored
299
Godeps/_workspace/src/github.com/coreos/coreos-cloudinit/initialize/config_test.go
generated
vendored
@@ -1,299 +0,0 @@
|
|||||||
// Copyright 2015 CoreOS, Inc.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package initialize
|
|
||||||
|
|
||||||
import (
|
|
||||||
"reflect"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/coreos/coreos-cloudinit/config"
|
|
||||||
"github.com/coreos/coreos-cloudinit/network"
|
|
||||||
"github.com/coreos/coreos-cloudinit/system"
|
|
||||||
)
|
|
||||||
|
|
||||||
type TestUnitManager struct {
|
|
||||||
placed []string
|
|
||||||
enabled []string
|
|
||||||
masked []string
|
|
||||||
unmasked []string
|
|
||||||
commands []UnitAction
|
|
||||||
reload bool
|
|
||||||
}
|
|
||||||
|
|
||||||
type UnitAction struct {
|
|
||||||
unit string
|
|
||||||
command string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tum *TestUnitManager) PlaceUnit(u system.Unit) error {
|
|
||||||
tum.placed = append(tum.placed, u.Name)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
func (tum *TestUnitManager) PlaceUnitDropIn(u system.Unit, d config.UnitDropIn) error {
|
|
||||||
tum.placed = append(tum.placed, u.Name+".d/"+d.Name)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
func (tum *TestUnitManager) EnableUnitFile(u system.Unit) error {
|
|
||||||
tum.enabled = append(tum.enabled, u.Name)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
func (tum *TestUnitManager) RunUnitCommand(u system.Unit, c string) (string, error) {
|
|
||||||
tum.commands = append(tum.commands, UnitAction{u.Name, c})
|
|
||||||
return "", nil
|
|
||||||
}
|
|
||||||
func (tum *TestUnitManager) DaemonReload() error {
|
|
||||||
tum.reload = true
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
func (tum *TestUnitManager) MaskUnit(u system.Unit) error {
|
|
||||||
tum.masked = append(tum.masked, u.Name)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
func (tum *TestUnitManager) UnmaskUnit(u system.Unit) error {
|
|
||||||
tum.unmasked = append(tum.unmasked, u.Name)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type mockInterface struct {
|
|
||||||
name string
|
|
||||||
filename string
|
|
||||||
netdev string
|
|
||||||
link string
|
|
||||||
network string
|
|
||||||
kind string
|
|
||||||
modprobeParams string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i mockInterface) Name() string {
|
|
||||||
return i.name
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i mockInterface) Filename() string {
|
|
||||||
return i.filename
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i mockInterface) Netdev() string {
|
|
||||||
return i.netdev
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i mockInterface) Link() string {
|
|
||||||
return i.link
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i mockInterface) Network() string {
|
|
||||||
return i.network
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i mockInterface) Type() string {
|
|
||||||
return i.kind
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i mockInterface) ModprobeParams() string {
|
|
||||||
return i.modprobeParams
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCreateNetworkingUnits(t *testing.T) {
|
|
||||||
for _, tt := range []struct {
|
|
||||||
interfaces []network.InterfaceGenerator
|
|
||||||
expect []system.Unit
|
|
||||||
}{
|
|
||||||
{nil, nil},
|
|
||||||
{
|
|
||||||
[]network.InterfaceGenerator{
|
|
||||||
network.InterfaceGenerator(mockInterface{filename: "test"}),
|
|
||||||
},
|
|
||||||
nil,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
[]network.InterfaceGenerator{
|
|
||||||
network.InterfaceGenerator(mockInterface{filename: "test1", netdev: "test netdev"}),
|
|
||||||
network.InterfaceGenerator(mockInterface{filename: "test2", link: "test link"}),
|
|
||||||
network.InterfaceGenerator(mockInterface{filename: "test3", network: "test network"}),
|
|
||||||
},
|
|
||||||
[]system.Unit{
|
|
||||||
system.Unit{Unit: config.Unit{Name: "test1.netdev", Runtime: true, Content: "test netdev"}},
|
|
||||||
system.Unit{Unit: config.Unit{Name: "test2.link", Runtime: true, Content: "test link"}},
|
|
||||||
system.Unit{Unit: config.Unit{Name: "test3.network", Runtime: true, Content: "test network"}},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
[]network.InterfaceGenerator{
|
|
||||||
network.InterfaceGenerator(mockInterface{filename: "test", netdev: "test netdev", link: "test link", network: "test network"}),
|
|
||||||
},
|
|
||||||
[]system.Unit{
|
|
||||||
system.Unit{Unit: config.Unit{Name: "test.netdev", Runtime: true, Content: "test netdev"}},
|
|
||||||
system.Unit{Unit: config.Unit{Name: "test.link", Runtime: true, Content: "test link"}},
|
|
||||||
system.Unit{Unit: config.Unit{Name: "test.network", Runtime: true, Content: "test network"}},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
} {
|
|
||||||
units := createNetworkingUnits(tt.interfaces)
|
|
||||||
if !reflect.DeepEqual(tt.expect, units) {
|
|
||||||
t.Errorf("bad units (%+v): want %#v, got %#v", tt.interfaces, tt.expect, units)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestProcessUnits(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
units []system.Unit
|
|
||||||
|
|
||||||
result TestUnitManager
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
units: []system.Unit{
|
|
||||||
system.Unit{Unit: config.Unit{
|
|
||||||
Name: "foo",
|
|
||||||
Mask: true,
|
|
||||||
}},
|
|
||||||
},
|
|
||||||
result: TestUnitManager{
|
|
||||||
masked: []string{"foo"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
units: []system.Unit{
|
|
||||||
system.Unit{Unit: config.Unit{
|
|
||||||
Name: "baz.service",
|
|
||||||
Content: "[Service]\nExecStart=/bin/baz",
|
|
||||||
Command: "start",
|
|
||||||
}},
|
|
||||||
system.Unit{Unit: config.Unit{
|
|
||||||
Name: "foo.network",
|
|
||||||
Content: "[Network]\nFoo=true",
|
|
||||||
}},
|
|
||||||
system.Unit{Unit: config.Unit{
|
|
||||||
Name: "bar.network",
|
|
||||||
Content: "[Network]\nBar=true",
|
|
||||||
}},
|
|
||||||
},
|
|
||||||
result: TestUnitManager{
|
|
||||||
placed: []string{"baz.service", "foo.network", "bar.network"},
|
|
||||||
commands: []UnitAction{
|
|
||||||
UnitAction{"systemd-networkd.service", "restart"},
|
|
||||||
UnitAction{"baz.service", "start"},
|
|
||||||
},
|
|
||||||
reload: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
units: []system.Unit{
|
|
||||||
system.Unit{Unit: config.Unit{
|
|
||||||
Name: "baz.service",
|
|
||||||
Content: "[Service]\nExecStart=/bin/true",
|
|
||||||
}},
|
|
||||||
},
|
|
||||||
result: TestUnitManager{
|
|
||||||
placed: []string{"baz.service"},
|
|
||||||
reload: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
units: []system.Unit{
|
|
||||||
system.Unit{Unit: config.Unit{
|
|
||||||
Name: "locksmithd.service",
|
|
||||||
Runtime: true,
|
|
||||||
}},
|
|
||||||
},
|
|
||||||
result: TestUnitManager{
|
|
||||||
unmasked: []string{"locksmithd.service"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
units: []system.Unit{
|
|
||||||
system.Unit{Unit: config.Unit{
|
|
||||||
Name: "woof",
|
|
||||||
Enable: true,
|
|
||||||
}},
|
|
||||||
},
|
|
||||||
result: TestUnitManager{
|
|
||||||
enabled: []string{"woof"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
units: []system.Unit{
|
|
||||||
system.Unit{Unit: config.Unit{
|
|
||||||
Name: "hi.service",
|
|
||||||
Runtime: true,
|
|
||||||
Content: "[Service]\nExecStart=/bin/echo hi",
|
|
||||||
DropIns: []config.UnitDropIn{
|
|
||||||
{
|
|
||||||
Name: "lo.conf",
|
|
||||||
Content: "[Service]\nExecStart=/bin/echo lo",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "bye.conf",
|
|
||||||
Content: "[Service]\nExecStart=/bin/echo bye",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}},
|
|
||||||
},
|
|
||||||
result: TestUnitManager{
|
|
||||||
placed: []string{"hi.service", "hi.service.d/lo.conf", "hi.service.d/bye.conf"},
|
|
||||||
unmasked: []string{"hi.service"},
|
|
||||||
reload: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
units: []system.Unit{
|
|
||||||
system.Unit{Unit: config.Unit{
|
|
||||||
DropIns: []config.UnitDropIn{
|
|
||||||
{
|
|
||||||
Name: "lo.conf",
|
|
||||||
Content: "[Service]\nExecStart=/bin/echo lo",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}},
|
|
||||||
},
|
|
||||||
result: TestUnitManager{},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
units: []system.Unit{
|
|
||||||
system.Unit{Unit: config.Unit{
|
|
||||||
Name: "hi.service",
|
|
||||||
DropIns: []config.UnitDropIn{
|
|
||||||
{
|
|
||||||
Content: "[Service]\nExecStart=/bin/echo lo",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}},
|
|
||||||
},
|
|
||||||
result: TestUnitManager{},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
units: []system.Unit{
|
|
||||||
system.Unit{Unit: config.Unit{
|
|
||||||
Name: "hi.service",
|
|
||||||
DropIns: []config.UnitDropIn{
|
|
||||||
{
|
|
||||||
Name: "lo.conf",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}},
|
|
||||||
},
|
|
||||||
result: TestUnitManager{},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tt := range tests {
|
|
||||||
tum := &TestUnitManager{}
|
|
||||||
if err := processUnits(tt.units, "", tum); err != nil {
|
|
||||||
t.Errorf("bad error (%+v): want nil, got %s", tt.units, err)
|
|
||||||
}
|
|
||||||
if !reflect.DeepEqual(tt.result, *tum) {
|
|
||||||
t.Errorf("bad result (%+v): want %+v, got %+v", tt.units, tt.result, tum)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
116
Godeps/_workspace/src/github.com/coreos/coreos-cloudinit/initialize/env.go
generated
vendored
116
Godeps/_workspace/src/github.com/coreos/coreos-cloudinit/initialize/env.go
generated
vendored
@@ -1,116 +0,0 @@
|
|||||||
// Copyright 2015 CoreOS, Inc.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package initialize
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
"regexp"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/coreos/coreos-cloudinit/config"
|
|
||||||
"github.com/coreos/coreos-cloudinit/datasource"
|
|
||||||
"github.com/coreos/coreos-cloudinit/system"
|
|
||||||
)
|
|
||||||
|
|
||||||
const DefaultSSHKeyName = "coreos-cloudinit"
|
|
||||||
|
|
||||||
type Environment struct {
|
|
||||||
root string
|
|
||||||
configRoot string
|
|
||||||
workspace string
|
|
||||||
sshKeyName string
|
|
||||||
substitutions map[string]string
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(jonboulle): this is getting unwieldy, should be able to simplify the interface somehow
|
|
||||||
func NewEnvironment(root, configRoot, workspace, sshKeyName string, metadata datasource.Metadata) *Environment {
|
|
||||||
firstNonNull := func(ip net.IP, env string) string {
|
|
||||||
if ip == nil {
|
|
||||||
return env
|
|
||||||
}
|
|
||||||
return ip.String()
|
|
||||||
}
|
|
||||||
substitutions := map[string]string{
|
|
||||||
"$public_ipv4": firstNonNull(metadata.PublicIPv4, os.Getenv("COREOS_PUBLIC_IPV4")),
|
|
||||||
"$private_ipv4": firstNonNull(metadata.PrivateIPv4, os.Getenv("COREOS_PRIVATE_IPV4")),
|
|
||||||
"$public_ipv6": firstNonNull(metadata.PublicIPv6, os.Getenv("COREOS_PUBLIC_IPV6")),
|
|
||||||
"$private_ipv6": firstNonNull(metadata.PrivateIPv6, os.Getenv("COREOS_PRIVATE_IPV6")),
|
|
||||||
}
|
|
||||||
return &Environment{root, configRoot, workspace, sshKeyName, substitutions}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Environment) Workspace() string {
|
|
||||||
return path.Join(e.root, e.workspace)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Environment) Root() string {
|
|
||||||
return e.root
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Environment) ConfigRoot() string {
|
|
||||||
return e.configRoot
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Environment) SSHKeyName() string {
|
|
||||||
return e.sshKeyName
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Environment) SetSSHKeyName(name string) {
|
|
||||||
e.sshKeyName = name
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply goes through the map of substitutions and replaces all instances of
|
|
||||||
// the keys with their respective values. It supports escaping substitutions
|
|
||||||
// with a leading '\'.
|
|
||||||
func (e *Environment) Apply(data string) string {
|
|
||||||
for key, val := range e.substitutions {
|
|
||||||
matchKey := strings.Replace(key, `$`, `\$`, -1)
|
|
||||||
replKey := strings.Replace(key, `$`, `$$`, -1)
|
|
||||||
|
|
||||||
// "key" -> "val"
|
|
||||||
data = regexp.MustCompile(`([^\\]|^)`+matchKey).ReplaceAllString(data, `${1}`+val)
|
|
||||||
// "\key" -> "key"
|
|
||||||
data = regexp.MustCompile(`\\`+matchKey).ReplaceAllString(data, replKey)
|
|
||||||
}
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Environment) DefaultEnvironmentFile() *system.EnvFile {
|
|
||||||
ef := system.EnvFile{
|
|
||||||
File: &system.File{File: config.File{
|
|
||||||
Path: "/etc/environment",
|
|
||||||
}},
|
|
||||||
Vars: map[string]string{},
|
|
||||||
}
|
|
||||||
if ip, ok := e.substitutions["$public_ipv4"]; ok && len(ip) > 0 {
|
|
||||||
ef.Vars["COREOS_PUBLIC_IPV4"] = ip
|
|
||||||
}
|
|
||||||
if ip, ok := e.substitutions["$private_ipv4"]; ok && len(ip) > 0 {
|
|
||||||
ef.Vars["COREOS_PRIVATE_IPV4"] = ip
|
|
||||||
}
|
|
||||||
if ip, ok := e.substitutions["$public_ipv6"]; ok && len(ip) > 0 {
|
|
||||||
ef.Vars["COREOS_PUBLIC_IPV6"] = ip
|
|
||||||
}
|
|
||||||
if ip, ok := e.substitutions["$private_ipv6"]; ok && len(ip) > 0 {
|
|
||||||
ef.Vars["COREOS_PRIVATE_IPV6"] = ip
|
|
||||||
}
|
|
||||||
if len(ef.Vars) == 0 {
|
|
||||||
return nil
|
|
||||||
} else {
|
|
||||||
return &ef
|
|
||||||
}
|
|
||||||
}
|
|
148
Godeps/_workspace/src/github.com/coreos/coreos-cloudinit/initialize/env_test.go
generated
vendored
148
Godeps/_workspace/src/github.com/coreos/coreos-cloudinit/initialize/env_test.go
generated
vendored
@@ -1,148 +0,0 @@
|
|||||||
// Copyright 2015 CoreOS, Inc.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package initialize
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io/ioutil"
|
|
||||||
"net"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/coreos/coreos-cloudinit/datasource"
|
|
||||||
"github.com/coreos/coreos-cloudinit/system"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestEnvironmentApply(t *testing.T) {
|
|
||||||
os.Setenv("COREOS_PUBLIC_IPV4", "1.2.3.4")
|
|
||||||
os.Setenv("COREOS_PRIVATE_IPV4", "5.6.7.8")
|
|
||||||
os.Setenv("COREOS_PUBLIC_IPV6", "1234::")
|
|
||||||
os.Setenv("COREOS_PRIVATE_IPV6", "5678::")
|
|
||||||
for _, tt := range []struct {
|
|
||||||
metadata datasource.Metadata
|
|
||||||
input string
|
|
||||||
out string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
// Substituting both values directly should always take precedence
|
|
||||||
// over environment variables
|
|
||||||
datasource.Metadata{
|
|
||||||
PublicIPv4: net.ParseIP("192.0.2.3"),
|
|
||||||
PrivateIPv4: net.ParseIP("192.0.2.203"),
|
|
||||||
PublicIPv6: net.ParseIP("fe00:1234::"),
|
|
||||||
PrivateIPv6: net.ParseIP("fe00:5678::"),
|
|
||||||
},
|
|
||||||
`[Service]
|
|
||||||
ExecStart=/usr/bin/echo "$public_ipv4 $public_ipv6"
|
|
||||||
ExecStop=/usr/bin/echo $private_ipv4 $private_ipv6
|
|
||||||
ExecStop=/usr/bin/echo $unknown`,
|
|
||||||
`[Service]
|
|
||||||
ExecStart=/usr/bin/echo "192.0.2.3 fe00:1234::"
|
|
||||||
ExecStop=/usr/bin/echo 192.0.2.203 fe00:5678::
|
|
||||||
ExecStop=/usr/bin/echo $unknown`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// Substituting one value directly while falling back with the other
|
|
||||||
datasource.Metadata{
|
|
||||||
PrivateIPv4: net.ParseIP("127.0.0.1"),
|
|
||||||
},
|
|
||||||
"$private_ipv4\n$public_ipv4",
|
|
||||||
"127.0.0.1\n1.2.3.4",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// Falling back to environment variables for both values
|
|
||||||
datasource.Metadata{},
|
|
||||||
"$private_ipv4\n$public_ipv4",
|
|
||||||
"5.6.7.8\n1.2.3.4",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// No substitutions
|
|
||||||
datasource.Metadata{},
|
|
||||||
"$private_ipv4\nfoobar",
|
|
||||||
"5.6.7.8\nfoobar",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// Escaping substitutions
|
|
||||||
datasource.Metadata{
|
|
||||||
PrivateIPv4: net.ParseIP("127.0.0.1"),
|
|
||||||
},
|
|
||||||
`\$private_ipv4
|
|
||||||
$private_ipv4
|
|
||||||
addr: \$private_ipv4
|
|
||||||
\\$private_ipv4`,
|
|
||||||
`$private_ipv4
|
|
||||||
127.0.0.1
|
|
||||||
addr: $private_ipv4
|
|
||||||
\$private_ipv4`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// No substitutions with escaping
|
|
||||||
datasource.Metadata{},
|
|
||||||
"\\$test\n$test",
|
|
||||||
"\\$test\n$test",
|
|
||||||
},
|
|
||||||
} {
|
|
||||||
|
|
||||||
env := NewEnvironment("./", "./", "./", "", tt.metadata)
|
|
||||||
got := env.Apply(tt.input)
|
|
||||||
if got != tt.out {
|
|
||||||
t.Fatalf("Environment incorrectly applied.\ngot:\n%s\nwant:\n%s", got, tt.out)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestEnvironmentFile(t *testing.T) {
|
|
||||||
metadata := datasource.Metadata{
|
|
||||||
PublicIPv4: net.ParseIP("1.2.3.4"),
|
|
||||||
PrivateIPv4: net.ParseIP("5.6.7.8"),
|
|
||||||
PublicIPv6: net.ParseIP("1234::"),
|
|
||||||
PrivateIPv6: net.ParseIP("5678::"),
|
|
||||||
}
|
|
||||||
expect := "COREOS_PRIVATE_IPV4=5.6.7.8\nCOREOS_PRIVATE_IPV6=5678::\nCOREOS_PUBLIC_IPV4=1.2.3.4\nCOREOS_PUBLIC_IPV6=1234::\n"
|
|
||||||
|
|
||||||
dir, err := ioutil.TempDir(os.TempDir(), "coreos-cloudinit-")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Unable to create tempdir: %v", err)
|
|
||||||
}
|
|
||||||
defer os.RemoveAll(dir)
|
|
||||||
|
|
||||||
env := NewEnvironment("./", "./", "./", "", metadata)
|
|
||||||
ef := env.DefaultEnvironmentFile()
|
|
||||||
err = system.WriteEnvFile(ef, dir)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("WriteEnvFile failed: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fullPath := path.Join(dir, "etc", "environment")
|
|
||||||
contents, err := ioutil.ReadFile(fullPath)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Unable to read expected file: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if string(contents) != expect {
|
|
||||||
t.Fatalf("File has incorrect contents: %q", contents)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestEnvironmentFileNil(t *testing.T) {
|
|
||||||
os.Clearenv()
|
|
||||||
metadata := datasource.Metadata{}
|
|
||||||
|
|
||||||
env := NewEnvironment("./", "./", "./", "", metadata)
|
|
||||||
ef := env.DefaultEnvironmentFile()
|
|
||||||
if ef != nil {
|
|
||||||
t.Fatalf("Environment file not nil: %v", ef)
|
|
||||||
}
|
|
||||||
}
|
|
32
Godeps/_workspace/src/github.com/coreos/coreos-cloudinit/initialize/github.go
generated
vendored
32
Godeps/_workspace/src/github.com/coreos/coreos-cloudinit/initialize/github.go
generated
vendored
@@ -1,32 +0,0 @@
|
|||||||
// Copyright 2015 CoreOS, Inc.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package initialize
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/coreos/coreos-cloudinit/system"
|
|
||||||
)
|
|
||||||
|
|
||||||
func SSHImportGithubUser(system_user string, github_user string) error {
|
|
||||||
url := fmt.Sprintf("https://api.github.com/users/%s/keys", github_user)
|
|
||||||
keys, err := fetchUserKeys(url)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
key_name := fmt.Sprintf("github-%s", github_user)
|
|
||||||
return system.AuthorizeSSHKeys(system_user, key_name, keys)
|
|
||||||
}
|
|
57
Godeps/_workspace/src/github.com/coreos/coreos-cloudinit/initialize/ssh_keys.go
generated
vendored
57
Godeps/_workspace/src/github.com/coreos/coreos-cloudinit/initialize/ssh_keys.go
generated
vendored
@@ -1,57 +0,0 @@
|
|||||||
// Copyright 2015 CoreOS, Inc.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package initialize
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/coreos/coreos-cloudinit/pkg"
|
|
||||||
"github.com/coreos/coreos-cloudinit/system"
|
|
||||||
)
|
|
||||||
|
|
||||||
type UserKey struct {
|
|
||||||
ID int `json:"id,omitempty"`
|
|
||||||
Key string `json:"key"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func SSHImportKeysFromURL(system_user string, url string) error {
|
|
||||||
keys, err := fetchUserKeys(url)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
key_name := fmt.Sprintf("coreos-cloudinit-%s", system_user)
|
|
||||||
return system.AuthorizeSSHKeys(system_user, key_name, keys)
|
|
||||||
}
|
|
||||||
|
|
||||||
func fetchUserKeys(url string) ([]string, error) {
|
|
||||||
client := pkg.NewHttpClient()
|
|
||||||
data, err := client.GetRetry(url)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var userKeys []UserKey
|
|
||||||
err = json.Unmarshal(data, &userKeys)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
keys := make([]string, 0)
|
|
||||||
for _, key := range userKeys {
|
|
||||||
keys = append(keys, key.Key)
|
|
||||||
}
|
|
||||||
return keys, err
|
|
||||||
}
|
|
56
Godeps/_workspace/src/github.com/coreos/coreos-cloudinit/initialize/ssh_keys_test.go
generated
vendored
56
Godeps/_workspace/src/github.com/coreos/coreos-cloudinit/initialize/ssh_keys_test.go
generated
vendored
@@ -1,56 +0,0 @@
|
|||||||
// Copyright 2015 CoreOS, Inc.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package initialize
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
"net/http/httptest"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestCloudConfigUsersUrlMarshal(t *testing.T) {
|
|
||||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
gh_res := `
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"key": "ssh-dss AAAAB3NzaC1kc3MAAACBAIHAu822ggSkIHrJYvhmBceOSVjuflfQm8RbMMDNVe9relQfuPbN+nxGGTCKzPLebeOcX+Wwi77TPXWwK3BZMglfXxhABlFPsuMb63Tqp94pBYsJdx/iFj9iGo6pKoM1k8ubOcqsUnq+BR9895zRbE7MjdwkGo67+QhCEwvkwAnNAAAAFQCuddVqXLCubzqnWmeHLQE+2GFfHwAAAIBnlXW5h15ndVuwi0htF4oodVSB1KwnTWcuBK+aE1zRs76yvRb0Ws+oifumThDwB/Tec6FQuAfRKfy6piChZqsu5KvL98I+2t5yyi1td+kMvdTnVL2lW44etDKseOcozmknCOmh4Dqvhl/2MwrDAhlPaN08EEq9h3w3mXtNLWH64QAAAIBAzDOKr17llngaKIdDXh+LtXKh87+zfjlTA36/9r2uF2kYE5uApDtu9sPCkt7+YBQt7R8prADPckwAiXwVdk0xijIOpLDBmoydQJJRQ+zTMxvpQmUr/1kUOv0zb+lB657CgvN0vVTmP2swPeMvgntt3C4vw7Ab+O+MS9peOAJbbQ=="
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "ssh-dss AAAAB3NzaC1kc3MAAACBANxpzIbTzKTeBRaOIdUxwwGwvDasTfU/PonhbNIuhYjc+xFGvBRTumox2F+luVAKKs4WdvA4nJXaY1OFi6DZftk5Bp4E2JaSzp8ulAzHsMexDdv6LGHGEJj/qdHAL1vHk2K89PpwRFSRZI8XRBLjvkr4ZgBKLG5ZILXPJEPP2j3lAAAAFQCtxoTnV8wy0c4grcGrQ+1sCsD7WQAAAIAqZsW2GviMe1RQrbZT0xAZmI64XRPrnLsoLxycHWlS7r6uUln2c6Ae2MB/YF0d4Kd1XZii9GHj7rrypqEo7MW8uSabhu70nmu1J8m2O3Dsr+4oJLeat9vwPsJV92IKO0jQwjKnAOHOiB9JKGeCw+NfXfogbti9/q38Q6XcS+SI5wAAAIEA1803Y2h+tOOpZXAsNIwl9mRfExWzLQ3L7knwJdznQu/6SW1H/1oyoYLebuk187Qj2UFI5qQ6AZNc49DvohWx0Cg6ABcyubNyoaCjZKWIdxVnItHWNbLe//+tyTu0I2eQwJOORsEPK5gMpf599C7wXQ//DzZOWbTWiHEX52gCTmk="
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": 5224438,
|
|
||||||
"key": "ssh-dss AAAAB3NzaC1kc3MAAACBAPKRWdKhzGZuLAJL6M1eM51hWViMqNBC2C6lm2OqGRYLuIf1GJ391widUuSf4wQqnkR22Q9PCmAZ19XCf11wBRMnuw9I/Z3Bt5bXfc+dzFBCmHYGJ6wNSv++H9jxyMb+usmsenWOFZGNO2jN0wrJ4ay8Yt0bwtRU+VCXpuRLszMzAAAAFQDZUIuPjcfK5HLgnwZ/J3lvtvlUjQAAAIEApIkAwLuCQV5j3U6DmI/Y6oELqSUR2purFm8jo8jePFfe1t+ghikgD254/JXlhDCVgY0NLXcak+coJfGCTT23quJ7I5xdpTn/OZO2Q6Woum/bijFC/UWwQbLz0R2nU3DoHv5v6XHQZxuIG4Fsxa91S+vWjZFtI7RuYlBCZA//ANMAAACBAJO0FojzkX6IeaWLqrgu9GTkFwGFazZ+LPH5JOWPoPn1hQKuR32Uf6qNcBZcIjY7SF0P7HF5rLQd6zKZzHqqQQ92MV555NEwjsnJglYU8CaaZsfYooaGPgA1YN7RhTSAuDmUW5Hyfj5BH4NTtrzrvJxIhDoQLf31Fasjw00r4R0O"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
`
|
|
||||||
fmt.Fprintln(w, gh_res)
|
|
||||||
}))
|
|
||||||
defer ts.Close()
|
|
||||||
|
|
||||||
keys, err := fetchUserKeys(ts.URL)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Encountered unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
expected := "ssh-dss AAAAB3NzaC1kc3MAAACBAIHAu822ggSkIHrJYvhmBceOSVjuflfQm8RbMMDNVe9relQfuPbN+nxGGTCKzPLebeOcX+Wwi77TPXWwK3BZMglfXxhABlFPsuMb63Tqp94pBYsJdx/iFj9iGo6pKoM1k8ubOcqsUnq+BR9895zRbE7MjdwkGo67+QhCEwvkwAnNAAAAFQCuddVqXLCubzqnWmeHLQE+2GFfHwAAAIBnlXW5h15ndVuwi0htF4oodVSB1KwnTWcuBK+aE1zRs76yvRb0Ws+oifumThDwB/Tec6FQuAfRKfy6piChZqsu5KvL98I+2t5yyi1td+kMvdTnVL2lW44etDKseOcozmknCOmh4Dqvhl/2MwrDAhlPaN08EEq9h3w3mXtNLWH64QAAAIBAzDOKr17llngaKIdDXh+LtXKh87+zfjlTA36/9r2uF2kYE5uApDtu9sPCkt7+YBQt7R8prADPckwAiXwVdk0xijIOpLDBmoydQJJRQ+zTMxvpQmUr/1kUOv0zb+lB657CgvN0vVTmP2swPeMvgntt3C4vw7Ab+O+MS9peOAJbbQ=="
|
|
||||||
if keys[0] != expected {
|
|
||||||
t.Fatalf("expected %s, got %s", expected, keys[0])
|
|
||||||
}
|
|
||||||
expected = "ssh-dss AAAAB3NzaC1kc3MAAACBAPKRWdKhzGZuLAJL6M1eM51hWViMqNBC2C6lm2OqGRYLuIf1GJ391widUuSf4wQqnkR22Q9PCmAZ19XCf11wBRMnuw9I/Z3Bt5bXfc+dzFBCmHYGJ6wNSv++H9jxyMb+usmsenWOFZGNO2jN0wrJ4ay8Yt0bwtRU+VCXpuRLszMzAAAAFQDZUIuPjcfK5HLgnwZ/J3lvtvlUjQAAAIEApIkAwLuCQV5j3U6DmI/Y6oELqSUR2purFm8jo8jePFfe1t+ghikgD254/JXlhDCVgY0NLXcak+coJfGCTT23quJ7I5xdpTn/OZO2Q6Woum/bijFC/UWwQbLz0R2nU3DoHv5v6XHQZxuIG4Fsxa91S+vWjZFtI7RuYlBCZA//ANMAAACBAJO0FojzkX6IeaWLqrgu9GTkFwGFazZ+LPH5JOWPoPn1hQKuR32Uf6qNcBZcIjY7SF0P7HF5rLQd6zKZzHqqQQ92MV555NEwjsnJglYU8CaaZsfYooaGPgA1YN7RhTSAuDmUW5Hyfj5BH4NTtrzrvJxIhDoQLf31Fasjw00r4R0O"
|
|
||||||
if keys[2] != expected {
|
|
||||||
t.Fatalf("expected %s, got %s", expected, keys[2])
|
|
||||||
}
|
|
||||||
}
|
|
39
Godeps/_workspace/src/github.com/coreos/coreos-cloudinit/initialize/user_data.go
generated
vendored
39
Godeps/_workspace/src/github.com/coreos/coreos-cloudinit/initialize/user_data.go
generated
vendored
@@ -1,39 +0,0 @@
|
|||||||
// Copyright 2015 CoreOS, Inc.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package initialize
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"log"
|
|
||||||
|
|
||||||
"github.com/coreos/coreos-cloudinit/config"
|
|
||||||
)
|
|
||||||
|
|
||||||
func ParseUserData(contents string) (interface{}, error) {
|
|
||||||
if len(contents) == 0 {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
switch {
|
|
||||||
case config.IsScript(contents):
|
|
||||||
log.Printf("Parsing user-data as script")
|
|
||||||
return config.NewScript(contents)
|
|
||||||
case config.IsCloudConfig(contents):
|
|
||||||
log.Printf("Parsing user-data as cloud-config")
|
|
||||||
return config.NewCloudConfig(contents)
|
|
||||||
default:
|
|
||||||
return nil, errors.New("Unrecognized user-data format")
|
|
||||||
}
|
|
||||||
}
|
|
74
Godeps/_workspace/src/github.com/coreos/coreos-cloudinit/initialize/user_data_test.go
generated
vendored
74
Godeps/_workspace/src/github.com/coreos/coreos-cloudinit/initialize/user_data_test.go
generated
vendored
@@ -1,74 +0,0 @@
|
|||||||
// Copyright 2015 CoreOS, Inc.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package initialize
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/coreos/coreos-cloudinit/config"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestParseHeaderCRLF(t *testing.T) {
|
|
||||||
configs := []string{
|
|
||||||
"#cloud-config\nfoo: bar",
|
|
||||||
"#cloud-config\r\nfoo: bar",
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, config := range configs {
|
|
||||||
_, err := ParseUserData(config)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("Failed parsing config %d: %v", i, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
scripts := []string{
|
|
||||||
"#!bin/bash\necho foo",
|
|
||||||
"#!bin/bash\r\necho foo",
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, script := range scripts {
|
|
||||||
_, err := ParseUserData(script)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("Failed parsing script %d: %v", i, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestParseConfigCRLF(t *testing.T) {
|
|
||||||
contents := "#cloud-config\r\nhostname: foo\r\nssh_authorized_keys:\r\n - foobar\r\n"
|
|
||||||
ud, err := ParseUserData(contents)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Failed parsing config: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cfg := ud.(*config.CloudConfig)
|
|
||||||
|
|
||||||
if cfg.Hostname != "foo" {
|
|
||||||
t.Error("Failed parsing hostname from config")
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(cfg.SSHAuthorizedKeys) != 1 {
|
|
||||||
t.Error("Parsed incorrect number of SSH keys")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestParseConfigEmpty(t *testing.T) {
|
|
||||||
i, e := ParseUserData(``)
|
|
||||||
if i != nil {
|
|
||||||
t.Error("ParseUserData of empty string returned non-nil unexpectedly")
|
|
||||||
} else if e != nil {
|
|
||||||
t.Error("ParseUserData of empty string returned error unexpectedly")
|
|
||||||
}
|
|
||||||
}
|
|
66
Godeps/_workspace/src/github.com/coreos/coreos-cloudinit/initialize/workspace.go
generated
vendored
66
Godeps/_workspace/src/github.com/coreos/coreos-cloudinit/initialize/workspace.go
generated
vendored
@@ -1,66 +0,0 @@
|
|||||||
// Copyright 2015 CoreOS, Inc.
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
package initialize
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io/ioutil"
|
|
||||||
"path"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/coreos/coreos-cloudinit/config"
|
|
||||||
"github.com/coreos/coreos-cloudinit/system"
|
|
||||||
)
|
|
||||||
|
|
||||||
func PrepWorkspace(workspace string) error {
|
|
||||||
if err := system.EnsureDirectoryExists(workspace); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
scripts := path.Join(workspace, "scripts")
|
|
||||||
if err := system.EnsureDirectoryExists(scripts); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func PersistScriptInWorkspace(script config.Script, workspace string) (string, error) {
|
|
||||||
scriptsPath := path.Join(workspace, "scripts")
|
|
||||||
tmp, err := ioutil.TempFile(scriptsPath, "")
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
tmp.Close()
|
|
||||||
|
|
||||||
relpath := strings.TrimPrefix(tmp.Name(), workspace)
|
|
||||||
|
|
||||||
file := system.File{File: config.File{
|
|
||||||
Path: relpath,
|
|
||||||
RawFilePermissions: "0744",
|
|
||||||
Content: string(script),
|
|
||||||
}}
|
|
||||||
|
|
||||||
return system.WriteFile(&file, workspace)
|
|
||||||
}
|
|
||||||
|
|
||||||
func PersistUnitNameInWorkspace(name string, workspace string) error {
|
|
||||||
file := system.File{File: config.File{
|
|
||||||
Path: path.Join("scripts", "unit-name"),
|
|
||||||
RawFilePermissions: "0644",
|
|
||||||
Content: name,
|
|
||||||
}}
|
|
||||||
_, err := system.WriteFile(&file, workspace)
|
|
||||||
return err
|
|
||||||
}
|
|
29
Godeps/_workspace/src/github.com/rancherio/rancher-compose/project/project.go
generated
vendored
29
Godeps/_workspace/src/github.com/rancherio/rancher-compose/project/project.go
generated
vendored
@@ -18,6 +18,12 @@ var (
|
|||||||
ErrRestart error = errors.New("Restart execution")
|
ErrRestart error = errors.New("Restart execution")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type ProjectEvent struct {
|
||||||
|
Event Event
|
||||||
|
Service Service
|
||||||
|
Data map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
func NewProject(name string, factory ServiceFactory) *Project {
|
func NewProject(name string, factory ServiceFactory) *Project {
|
||||||
return &Project{
|
return &Project{
|
||||||
Name: name,
|
Name: name,
|
||||||
@@ -72,6 +78,12 @@ func (p *Project) Up() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *Project) startAll(wrappers map[string]*ServiceWrapper) error {
|
func (p *Project) startAll(wrappers map[string]*ServiceWrapper) error {
|
||||||
|
for name, _ := range p.Services {
|
||||||
|
if _, ok := wrappers[name]; !ok {
|
||||||
|
wrappers[name] = NewServiceWrapper(name, p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
restart := false
|
restart := false
|
||||||
|
|
||||||
for _, wrapper := range wrappers {
|
for _, wrapper := range wrappers {
|
||||||
@@ -176,6 +188,10 @@ func (s *ServiceWrapper) Wait() error {
|
|||||||
return s.err
|
return s.err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Project) AddListener(c chan<- ProjectEvent) {
|
||||||
|
p.listeners = append(p.listeners, c)
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Project) Notify(event Event, service Service, data map[string]string) {
|
func (p *Project) Notify(event Event, service Service, data map[string]string) {
|
||||||
buffer := bytes.NewBuffer(nil)
|
buffer := bytes.NewBuffer(nil)
|
||||||
if data != nil {
|
if data != nil {
|
||||||
@@ -204,4 +220,17 @@ func (p *Project) Notify(event Event, service Service, data map[string]string) {
|
|||||||
} else {
|
} else {
|
||||||
logf("[%d/%d] [%s]: %s %s", p.upCount, len(p.Services), service.Name(), event, buffer.Bytes())
|
logf("[%d/%d] [%s]: %s %s", p.upCount, len(p.Services), service.Name(), event, buffer.Bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, l := range p.listeners {
|
||||||
|
projectEvent := ProjectEvent{
|
||||||
|
Event: event,
|
||||||
|
Service: service,
|
||||||
|
Data: data,
|
||||||
|
}
|
||||||
|
// Don't ever block
|
||||||
|
select {
|
||||||
|
case l <- projectEvent:
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
1
Godeps/_workspace/src/github.com/rancherio/rancher-compose/project/types.go
generated
vendored
1
Godeps/_workspace/src/github.com/rancherio/rancher-compose/project/types.go
generated
vendored
@@ -66,6 +66,7 @@ type Project struct {
|
|||||||
factory ServiceFactory
|
factory ServiceFactory
|
||||||
ReloadCallback func() error
|
ReloadCallback func() error
|
||||||
upCount int
|
upCount int
|
||||||
|
listeners []chan<- ProjectEvent
|
||||||
}
|
}
|
||||||
|
|
||||||
type Service interface {
|
type Service interface {
|
||||||
|
Reference in New Issue
Block a user