diff --git a/cloudinit.go b/cloudinit.go index b769227..8dad597 100644 --- a/cloudinit.go +++ b/cloudinit.go @@ -77,7 +77,6 @@ func init() { flag.StringVar(&flags.sources.file, "from-file", "", "Read user-data from provided file") flag.StringVar(&flags.sources.configDrive, "from-configdrive", "", "Read data from provided cloud-drive directory") flag.StringVar(&flags.sources.waagent, "from-waagent", "", "Read data from provided waagent directory") - flag.BoolVar(&flags.sources.metadataService, "from-metadata-service", false, "[DEPRECATED - Use -from-ec2-metadata] Download data from metadata service") flag.StringVar(&flags.sources.ec2MetadataService, "from-ec2-metadata", "", "Download EC2 data from the provided url") // flag.BoolVar(&flags.sources.cloudSigmaMetadataService, "from-cloudsigma-metadata", false, "Download data from CloudSigma server context") flag.StringVar(&flags.sources.digitalOceanMetadataService, "from-digitalocean-metadata", "", "Download DigitalOcean data from the provided url") @@ -86,7 +85,7 @@ func init() { flag.BoolVar(&flags.sources.procCmdLine, "from-proc-cmdline", false, fmt.Sprintf("Parse %s for '%s=', using the cloud-config served by an HTTP GET to ", proc_cmdline.ProcCmdlineLocation, proc_cmdline.ProcCmdlineCloudConfigFlag)) flag.StringVar(&flags.oem, "oem", "", "Use the settings specific to the provided OEM") flag.StringVar(&flags.convertNetconf, "convert-netconf", "", "Read the network config provided in cloud-drive and translate it from the specified format into networkd unit files") - flag.StringVar(&flags.workspace, "workspace", "/var/lib/coreos-cloudinit", "Base directory coreos-cloudinit should use to store data") + flag.StringVar(&flags.workspace, "workspace", "/var/lib/cloudinit", "Base directory where cloudinit should use to store data") flag.StringVar(&flags.sshKeyName, "ssh-key-name", initialize.DefaultSSHKeyName, "Add SSH keys to the system with the given name") flag.BoolVar(&flags.validate, "validate", false, "[EXPERIMENTAL] Validate the user-data but do not apply it to the system") flag.StringVar(&flags.timeout, "timeout", "60s", "Timeout to wait for all datasource metadata") diff --git a/system/filesystem_freebsd.go b/system/filesystem_freebsd.go index bc368b0..083235f 100644 --- a/system/filesystem_freebsd.go +++ b/system/filesystem_freebsd.go @@ -14,6 +14,65 @@ package system +import ( + "bufio" + "fmt" + "io" + "log" + "os/exec" + "strings" +) + func ResizeRootFS() error { + var err error + var stdout io.ReadCloser + var device string + var partition string + + cmd := exec.Command("mount", "-t", "ufs", "-p") + stdout, err = cmd.StdoutPipe() + if err != nil { + log.Printf("failed to get mounted file systems %s\n", err.Error()) + return err + } + r := bufio.NewReader(stdout) + + if err = cmd.Start(); err != nil { + log.Printf("failed to get mounted file systems %s\n", err.Error()) + return err + } + + for { + line, err := r.ReadString('\n') + if err != nil { + break + } + + ps := strings.Fields(line) // /dev/da0s1a / ufs rw 1 1 + if ps[1] == "/" { + var i int + if i = strings.Index(ps[0], "s"); i < 0 { + return fmt.Errorf("failed to find slice number") + } + device = ps[0][:i] + partition = strings.TrimSuffix(ps[0][i:], "a") + } + } + + if err = cmd.Wait(); err != nil || partition == "" { + return fmt.Errorf("failed to find partition on %s\n", device) + } + log.Printf("%s %s\n", device, partition) + /* + echo "sysctl kern.geom.debugflags=16" >> /etc/rc.local + echo "gpart resize -i 1 da0" >> /etc/rc.local + echo "gpart resize -i 1 da0s1" >> /etc/rc.local + echo "true > /dev/da0" >> /etc/rc.local + echo "true > /dev/da0s1" >> /etc/rc.local + echo "true > /dev/da0s1a" >> /etc/rc.local + echo "gpart resize -i 1 da0" >> /etc/rc.local + echo "gpart resize -i 1 da0s1" >> /etc/rc.local + echo "growfs -y /" >> /etc/rc.local + */ return nil } diff --git a/system/user.go b/system/user.go index 361b3ed..996faa6 100644 --- a/system/user.go +++ b/system/user.go @@ -15,8 +15,6 @@ package system import ( - "fmt" - "log" "os/exec" "strings" @@ -33,109 +31,5 @@ func UserHome(name string) (string, error) { } func UserExists(u *config.User) bool { - return exec.Command("getent", "shadow", u.Name).Run() == nil -} - -func CreateUser(u *config.User) error { - args := []string{} - - if u.PasswordHash != "" { - args = append(args, "--password", u.PasswordHash) - } else { - args = append(args, "--password", "*") - } - - if u.GECOS != "" { - args = append(args, "--comment", fmt.Sprintf("%q", u.GECOS)) - } - - if u.Homedir != "" { - args = append(args, "--home-dir", u.Homedir) - } - - if u.NoCreateHome { - args = append(args, "--no-create-home") - } else { - args = append(args, "--create-home") - } - - if u.PrimaryGroup != "" { - args = append(args, "--gid", u.PrimaryGroup) - } - - if len(u.Groups) > 0 { - args = append(args, "--groups", strings.Join(u.Groups, ",")) - } - - if u.NoUserGroup { - args = append(args, "--no-user-group") - } - - if u.System { - args = append(args, "--system") - } - - if u.NoLogInit { - args = append(args, "--no-log-init") - } - - if u.Shell != "" { - args = append(args, "--shell", u.Shell) - } - - args = append(args, u.Name) - - output, err := exec.Command("useradd", args...).CombinedOutput() - if err != nil { - log.Printf("Command 'useradd %s' failed: %v\n%s", strings.Join(args, " "), err, output) - return err - } - - return nil -} - -func LockUnlockUser(u *config.User) error { - args := []string{} - - if u.LockPasswd { - args = append(args, "--lock") - } else { - args = append(args, "--unlock") - } - - args = append(args, u.Name) - - output, err := exec.Command("passwd", args...).CombinedOutput() - if err != nil { - log.Printf("Command 'passwd %s' failed: %v\n%s", strings.Join(args, " "), err, output) - } - return err -} - -func SetUserPassword(user, hash string) error { - cmd := exec.Command("chpasswd", "-e") - - stdin, err := cmd.StdinPipe() - if err != nil { - return err - } - - err = cmd.Start() - if err != nil { - log.Fatal(err) - } - - arg := fmt.Sprintf("%s:%s", user, hash) - _, err = stdin.Write([]byte(arg)) - if err != nil { - return err - } - stdin.Close() - - err = cmd.Wait() - if err != nil { - return err - } - - return nil + return exec.Command("getent", "passwd", u.Name).Run() == nil } diff --git a/system/user_freebsd.go b/system/user_freebsd.go new file mode 100644 index 0000000..11f1df1 --- /dev/null +++ b/system/user_freebsd.go @@ -0,0 +1,129 @@ +// 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 system + +import ( + "fmt" + "log" + "os/exec" + "strings" + + "github.com/vtolstov/cloudinit/config" +) + +func CreateUser(u *config.User) error { + args := []string{} + + args = append(args, "useradd") + + if u.Name == "root" { + args = append(args, "-b", "/") + } else { + args = append(args, "-b", "/home") + } + + args = append(args, "-w", "no") + + if u.GECOS != "" { + args = append(args, "-c", fmt.Sprintf("%q", u.GECOS)) + } + + if u.Homedir != "" { + args = append(args, "-d", u.Homedir) + } + + if !u.NoCreateHome { + args = append(args, "-m") + } + + if u.PrimaryGroup != "" { + args = append(args, "-g", u.PrimaryGroup) + } + + if len(u.Groups) > 0 { + args = append(args, "-G", strings.Join(u.Groups, ",")) + } + + if u.Shell != "" { + args = append(args, "-s", u.Shell) + } + + args = append(args, "-n", u.Name) + + output, err := exec.Command("pw", args...).CombinedOutput() + if err != nil { + log.Printf("Command 'pw useradd %s' failed: %v\n%s", strings.Join(args, " "), err, output) + return err + } + + return nil +} + +func LockUnlockUser(u *config.User) error { + args := []string{} + + output, err := exec.Command("getent", "passwd", u.Name).CombinedOutput() + if err != nil { + return err + } + passwd := strings.Split(string(output), ":") + + if u.LockPasswd { + if strings.HasPrefix(passwd[1], "*LOCKED*") { + return nil + } + args = append(args, "lock") + } else { + if !strings.HasPrefix(passwd[1], "*LOCKED*") { + return nil + } + args = append(args, "unlock") + } + + args = append(args, u.Name) + + output, err = exec.Command("pw", args...).CombinedOutput() + if err != nil { + log.Printf("Command 'pw %s' failed: %v\n%s", strings.Join(args, " "), err, output) + } + return err +} + +func SetUserPassword(user, hash string) error { + cmd := exec.Command("pw", "usermod", user, "-H", "0") + + stdin, err := cmd.StdinPipe() + if err != nil { + return err + } + + err = cmd.Start() + if err != nil { + log.Fatal(err) + } + + _, err = stdin.Write([]byte(hash)) + if err != nil { + return err + } + stdin.Close() + + err = cmd.Wait() + if err != nil { + return err + } + + return nil +} diff --git a/system/user_linux.go b/system/user_linux.go new file mode 100644 index 0000000..31d7597 --- /dev/null +++ b/system/user_linux.go @@ -0,0 +1,128 @@ +// 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 system + +import ( + "fmt" + "log" + "os/exec" + "strings" + + "github.com/vtolstov/cloudinit/config" +) + +func CreateUser(u *config.User) error { + args := []string{} + + if u.PasswordHash != "" { + args = append(args, "--password", u.PasswordHash) + } else { + args = append(args, "--password", "*") + } + + if u.GECOS != "" { + args = append(args, "--comment", fmt.Sprintf("%q", u.GECOS)) + } + + if u.Homedir != "" { + args = append(args, "--home-dir", u.Homedir) + } + + if u.NoCreateHome { + args = append(args, "--no-create-home") + } else { + args = append(args, "--create-home") + } + + if u.PrimaryGroup != "" { + args = append(args, "--gid", u.PrimaryGroup) + } + + if len(u.Groups) > 0 { + args = append(args, "--groups", strings.Join(u.Groups, ",")) + } + + if u.NoUserGroup { + args = append(args, "--no-user-group") + } + + if u.System { + args = append(args, "--system") + } + + if u.NoLogInit { + args = append(args, "--no-log-init") + } + + if u.Shell != "" { + args = append(args, "--shell", u.Shell) + } + + args = append(args, u.Name) + + output, err := exec.Command("useradd", args...).CombinedOutput() + if err != nil { + log.Printf("Command 'useradd %s' failed: %v\n%s", strings.Join(args, " "), err, output) + return err + } + + return nil +} + +func LockUnlockUser(u *config.User) error { + args := []string{} + + if u.LockPasswd { + args = append(args, "--lock") + } else { + args = append(args, "--unlock") + } + + args = append(args, u.Name) + + output, err := exec.Command("passwd", args...).CombinedOutput() + if err != nil { + log.Printf("Command 'passwd %s' failed: %v\n%s", strings.Join(args, " "), err, output) + } + return err +} + +func SetUserPassword(user, hash string) error { + cmd := exec.Command("chpasswd", "-e") + + stdin, err := cmd.StdinPipe() + if err != nil { + return err + } + + err = cmd.Start() + if err != nil { + log.Fatal(err) + } + + arg := fmt.Sprintf("%s:%s", user, hash) + _, err = stdin.Write([]byte(arg)) + if err != nil { + return err + } + stdin.Close() + + err = cmd.Wait() + if err != nil { + return err + } + + return nil +}