1
0
mirror of https://github.com/rancher/os.git synced 2025-07-13 06:34:04 +00:00

Merge pull request #521 from imikushin/ros-install

ros install
This commit is contained in:
Ivan Mikushin 2015-08-25 17:41:06 +05:00
commit ab6cba20ff
6 changed files with 152 additions and 2 deletions

View File

@ -59,6 +59,7 @@ func Main() {
HideHelp: true,
Subcommands: tlsConfCommands(),
},
installCommand,
}
app.Run(os.Args)

126
cmd/control/install.go Normal file
View File

@ -0,0 +1,126 @@
package control
import (
"bufio"
"fmt"
"os"
"os/exec"
log "github.com/Sirupsen/logrus"
"github.com/codegangsta/cli"
"github.com/rancherio/os/cmd/power"
"github.com/rancherio/os/config"
"github.com/rancherio/os/util"
)
var installCommand = cli.Command{
Name: "install",
Usage: "install RancherOS to disk",
HideHelp: true,
Action: installAction,
Flags: []cli.Flag{
cli.StringFlag{
Name: "image, i",
Usage: "install from a certain image",
},
cli.StringFlag{
Name: "install-type, t",
Usage: `generic: (Default) Creates 1 ext4 partition and installs RancherOS
amazon-ebs: Installs RancherOS and sets up PV-GRUB`,
},
cli.StringFlag{
Name: "cloud-config, c",
Usage: "cloud-config yml file - needed for SSH authorized keys",
},
cli.StringFlag{
Name: "device, d",
Usage: "storage device",
},
cli.BoolFlag{
Name: "force, f",
Usage: "[ DANGEROUS! Data loss can happen ] partition/format without prompting",
},
cli.BoolFlag{
Name: "no-reboot",
Usage: "do not reboot after install",
},
},
}
func installAction(c *cli.Context) {
if c.Args().Present() {
log.Fatalf("invalid arguments %v", c.Args())
}
device := c.String("device")
if device == "" {
log.Fatal("Can not proceed without -d <dev> specified")
}
image := c.String("image")
cfg, err := config.LoadConfig()
if err != nil {
log.WithFields(log.Fields{"err": err}).Fatal("ros install: failed to load config")
}
if image == "" {
image = cfg.Rancher.Upgrade.Image + ":" + config.VERSION
}
installType := c.String("install-type")
if installType == "" {
log.Info("No install type specified...defaulting to generic")
installType = "generic"
}
cloudConfig := c.String("cloud-config")
if cloudConfig == "" {
log.Warn("Cloud-config not provided: you might need to provide cloud-config on boot with ssh_authorized_keys")
} else {
uc := "/opt/user_config.yml"
if err := util.FileCopy(cloudConfig, uc); err != nil {
log.WithFields(log.Fields{"cloudConfig": cloudConfig}).Fatal("Failed to copy cloud-config")
}
cloudConfig = uc
}
force := c.Bool("force")
reboot := !c.Bool("no-reboot")
if err := runInstall(cfg, image, installType, cloudConfig, device, force, reboot); err != nil {
log.WithFields(log.Fields{"err": err}).Fatal("Failed to run install")
}
}
func runInstall(cfg *config.CloudConfig, image, installType, cloudConfig, device string, force, reboot bool) error {
in := bufio.NewReader(os.Stdin)
fmt.Printf("Installing from %s\n", image)
if !force {
if !yes(in, "Continue") {
os.Exit(1)
}
}
if installType == "generic" {
cmd := exec.Command("system-docker", "run", "--net=host", "--privileged", "--volumes-from=all-volumes",
"--entrypoint=/scripts/set-disk-partitions", image, device)
cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
if err := cmd.Run(); err != nil {
return err
}
}
cmd := exec.Command("system-docker", "run", "--net=host", "--privileged", "--volumes-from=user-volumes", image,
"-d", device, "-t", installType, "-c", cloudConfig)
cmd.Stdout, cmd.Stderr = os.Stdout, os.Stderr
if err := cmd.Run(); err != nil {
return err
}
if reboot && yes(in, "Continue with reboot") {
log.Info("Rebooting")
power.Reboot()
}
return nil
}

View File

@ -0,0 +1,2 @@
#cloud-config
{}

View File

@ -19,6 +19,7 @@ do
done
DIST=${DIST:-/dist}
CLOUD_CONFIG=${CLOUD_CONFIG:-/scripts/conf/empty.yml}
BASE_DIR="/mnt/new_img"
# TODO: Change this to a number so that users can specify.
# Will need to make it so that our builds and packer APIs remain consistent.

View File

@ -12,8 +12,9 @@ if [ -z ${BASE_DIR} ]; then
fi
mkdir -p ${BASE_DIR}/var/lib/rancher/conf/cloud-config.d
cp ${CLOUD_DATA} ${BASE_DIR}/var/lib/rancher/conf/cloud-config.d/
if [ "$CLOUD_DATA" != "/scripts/conf/empty.yml" ]; then
cp ${CLOUD_DATA} ${BASE_DIR}/var/lib/rancher/conf/cloud-config.d/
fi
for f in ${FILES[@]}; do
IFS=":" read s d <<< "${f}"

View File

@ -152,6 +152,25 @@ func RandSeq(n int) string {
return string(b)
}
func FileCopy(src, dest string) (err error) {
in, err := os.Open(src)
if err != nil {
return err
}
defer func() { err = in.Close() }()
out, err := os.Create(dest)
if err != nil {
return err
}
defer func() { err = out.Close() }()
if _, err := io.Copy(out, in); err != nil {
return err
}
return
}
func Convert(from, to interface{}) error {
bytes, err := yaml.Marshal(from)
if err != nil {