Compare commits
7 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
d823f99f7d | ||
|
282e4637cd | ||
|
840b1dfb6e | ||
|
7474a85fec | ||
|
95a00070c3 | ||
|
8b5049cf40 | ||
|
743b2dd939 |
@@ -15,6 +15,9 @@ Only a subset of [cloud-config functionality][cloud-config] is implemented. A se
|
|||||||
|
|
||||||
Provided public SSH keys will be authorized for the `core` user.
|
Provided public SSH keys will be authorized for the `core` user.
|
||||||
|
|
||||||
|
The keys will be named "coreos-cloudinit" by default.
|
||||||
|
Override this with the `--ssh-key-name` flag when calling `coreos-cloudinit`.
|
||||||
|
|
||||||
### Custom cloud-config Parameters
|
### Custom cloud-config Parameters
|
||||||
|
|
||||||
#### coreos.etcd.discovery_url
|
#### coreos.etcd.discovery_url
|
||||||
|
@@ -6,6 +6,8 @@ import (
|
|||||||
"launchpad.net/goyaml"
|
"launchpad.net/goyaml"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const DefaultSSHKeyName = "coreos-cloudinit"
|
||||||
|
|
||||||
type CloudConfig struct {
|
type CloudConfig struct {
|
||||||
SSH_Authorized_Keys []string
|
SSH_Authorized_Keys []string
|
||||||
Coreos struct{Etcd struct{ Discovery_URL string }; Fleet struct{ Autostart bool } }
|
Coreos struct{Etcd struct{ Discovery_URL string }; Fleet struct{ Autostart bool } }
|
||||||
@@ -26,9 +28,9 @@ func (cc CloudConfig) String() string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ResolveCloudConfig(cfg CloudConfig) error {
|
func ApplyCloudConfig(cfg CloudConfig, sshKeyName string) error {
|
||||||
if len(cfg.SSH_Authorized_Keys) > 0 {
|
if len(cfg.SSH_Authorized_Keys) > 0 {
|
||||||
err := AuthorizeSSHKeys(cfg.SSH_Authorized_Keys)
|
err := AuthorizeSSHKeys(sshKeyName, cfg.SSH_Authorized_Keys)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
log.Printf("Authorized SSH keys for core user")
|
log.Printf("Authorized SSH keys for core user")
|
||||||
} else {
|
} else {
|
||||||
|
@@ -10,7 +10,7 @@ import (
|
|||||||
|
|
||||||
// Add the provide SSH public key to the core user's list of
|
// Add the provide SSH public key to the core user's list of
|
||||||
// authorized keys
|
// authorized keys
|
||||||
func AuthorizeSSHKeys(keys []string) error {
|
func AuthorizeSSHKeys(name string, keys []string) error {
|
||||||
for i, key := range keys {
|
for i, key := range keys {
|
||||||
keys[i] = strings.TrimSpace(key)
|
keys[i] = strings.TrimSpace(key)
|
||||||
}
|
}
|
||||||
@@ -19,7 +19,7 @@ func AuthorizeSSHKeys(keys []string) error {
|
|||||||
// also ends with a newline
|
// also ends with a newline
|
||||||
joined := fmt.Sprintf("%s\n", strings.Join(keys, "\n"))
|
joined := fmt.Sprintf("%s\n", strings.Join(keys, "\n"))
|
||||||
|
|
||||||
cmd := exec.Command("update-ssh-keys", "-u", "core", "-a", "coreos-cloudinit")
|
cmd := exec.Command("update-ssh-keys", "-u", "core", "-a", name)
|
||||||
stdin, err := cmd.StdinPipe()
|
stdin, err := cmd.StdinPipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@@ -10,7 +10,7 @@ import (
|
|||||||
"github.com/coreos/coreos-cloudinit/cloudinit"
|
"github.com/coreos/coreos-cloudinit/cloudinit"
|
||||||
)
|
)
|
||||||
|
|
||||||
const version = "0.1.0"
|
const version = "0.1.1"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var userdata []byte
|
var userdata []byte
|
||||||
@@ -28,6 +28,9 @@ func main() {
|
|||||||
var workspace string
|
var workspace string
|
||||||
flag.StringVar(&workspace, "workspace", "/var/lib/coreos-cloudinit", "Base directory coreos-cloudinit should use to store data")
|
flag.StringVar(&workspace, "workspace", "/var/lib/coreos-cloudinit", "Base directory coreos-cloudinit should use to store data")
|
||||||
|
|
||||||
|
var sshKeyName string
|
||||||
|
flag.StringVar(&sshKeyName, "ssh-key-name", cloudinit.DefaultSSHKeyName, "Add SSH keys to the system with the given name")
|
||||||
|
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
if printVersion == true {
|
if printVersion == true {
|
||||||
@@ -70,7 +73,7 @@ func main() {
|
|||||||
|
|
||||||
switch t := parsed.(type) {
|
switch t := parsed.(type) {
|
||||||
case cloudinit.CloudConfig:
|
case cloudinit.CloudConfig:
|
||||||
err = cloudinit.ResolveCloudConfig(t)
|
err = cloudinit.ApplyCloudConfig(t, sshKeyName)
|
||||||
case cloudinit.Script:
|
case cloudinit.Script:
|
||||||
var path string
|
var path string
|
||||||
path, err = cloudinit.PersistScriptInWorkspace(t, workspace)
|
path, err = cloudinit.PersistScriptInWorkspace(t, workspace)
|
||||||
|
@@ -128,10 +128,7 @@ func (c *Conn) ReloadOrTryRestartUnit(name string, mode string) (string, error)
|
|||||||
// unique. mode is the same as in StartUnit(), properties contains properties
|
// unique. mode is the same as in StartUnit(), properties contains properties
|
||||||
// of the unit.
|
// of the unit.
|
||||||
func (c *Conn) StartTransientUnit(name string, mode string, properties ...Property) (string, error) {
|
func (c *Conn) StartTransientUnit(name string, mode string, properties ...Property) (string, error) {
|
||||||
// the dbus interface for this method does not use the last argument and
|
return c.runJob("org.freedesktop.systemd1.Manager.StartTransientUnit", name, mode, properties, make([]PropertyCollection, 0))
|
||||||
// should simply be given an empty list. We use a concrete type here
|
|
||||||
// (instead of the more appropriate interface{}) to satisfy the dbus library.
|
|
||||||
return c.runJob("org.freedesktop.systemd1.Manager.StartTransientUnit", name, mode, properties, make([]string, 0))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// KillUnit takes the unit name and a UNIX signal number to send. All of the unit's
|
// KillUnit takes the unit name and a UNIX signal number to send. All of the unit's
|
||||||
|
@@ -17,6 +17,8 @@ limitations under the License.
|
|||||||
package dbus
|
package dbus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
@@ -153,3 +155,59 @@ func TestGetUnitPropertiesRejectsInvalidName(t *testing.T) {
|
|||||||
t.Fatal("Expected an error, got nil")
|
t.Fatal("Expected an error, got nil")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure that basic transient unit starting and stopping works.
|
||||||
|
func TestStartStopTransientUnit(t *testing.T) {
|
||||||
|
conn := setupConn(t)
|
||||||
|
|
||||||
|
props := []Property{
|
||||||
|
PropExecStart([]string{"/bin/sleep", "400"}, false),
|
||||||
|
}
|
||||||
|
target := fmt.Sprintf("testing-transient-%d.service", rand.Int())
|
||||||
|
|
||||||
|
// Start the unit
|
||||||
|
job, err := conn.StartTransientUnit(target, "replace", props...)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if job != "done" {
|
||||||
|
t.Fatal("Job is not done, %v", job)
|
||||||
|
}
|
||||||
|
|
||||||
|
units, err := conn.ListUnits()
|
||||||
|
|
||||||
|
var unit *UnitStatus
|
||||||
|
for _, u := range units {
|
||||||
|
if u.Name == target {
|
||||||
|
unit = &u
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if unit == nil {
|
||||||
|
t.Fatalf("Test unit not found in list")
|
||||||
|
}
|
||||||
|
|
||||||
|
if unit.ActiveState != "active" {
|
||||||
|
t.Fatalf("Test unit not active")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Stop the unit
|
||||||
|
job, err = conn.StopUnit(target, "replace")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
units, err = conn.ListUnits()
|
||||||
|
|
||||||
|
unit = nil
|
||||||
|
for _, u := range units {
|
||||||
|
if u.Name == target {
|
||||||
|
unit = &u
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if unit != nil {
|
||||||
|
t.Fatalf("Test unit found in list, should be stopped")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -41,6 +41,11 @@ type Property struct {
|
|||||||
Value dbus.Variant
|
Value dbus.Variant
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PropertyCollection struct {
|
||||||
|
Name string
|
||||||
|
Properties []Property
|
||||||
|
}
|
||||||
|
|
||||||
type execStart struct {
|
type execStart struct {
|
||||||
Path string // the binary path to execute
|
Path string // the binary path to execute
|
||||||
Args []string // an array with all arguments to pass to the executed command, starting with argument 0
|
Args []string // an array with all arguments to pass to the executed command, starting with argument 0
|
||||||
|
Reference in New Issue
Block a user