1
0
mirror of https://github.com/rancher/os.git synced 2025-08-31 22:32:14 +00:00

Merge pull request #1326 from joshwget/rewrite-scripts-in-go

Rewrite a few scripts in Go and remove unneeded services
This commit is contained in:
Josh Curl
2016-10-19 17:30:44 -07:00
committed by GitHub
22 changed files with 321 additions and 226 deletions

View File

@@ -105,10 +105,10 @@ func Main() {
cloudinitexecute.ApplyConsole(cfg)
if err := runScript(config.CloudConfigScriptFile); err != nil {
if err := util.RunScript(config.CloudConfigScriptFile); err != nil {
log.Error(err)
}
if err := runScript(startScript); err != nil {
if err := util.RunScript(startScript); err != nil {
log.Error(err)
}
@@ -116,7 +116,7 @@ func Main() {
log.Error(err)
}
if err := runScript("/etc/rc.local"); err != nil {
if err := util.RunScript("/etc/rc.local"); err != nil {
log.Error(err)
}
@@ -282,29 +282,3 @@ func setupSSH(cfg *config.CloudConfig) error {
return os.MkdirAll("/var/run/sshd", 0644)
}
func runScript(path string) error {
if !util.ExistsAndExecutable(path) {
return nil
}
script, err := os.Open(path)
if err != nil {
return err
}
magic := make([]byte, 2)
if _, err = script.Read(magic); err != nil {
return err
}
cmd := exec.Command("/bin/sh", path)
if string(magic) == "#!" {
cmd = exec.Command(path)
}
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
return cmd.Run()
}

107
cmd/control/bootstrap.go Normal file
View File

@@ -0,0 +1,107 @@
package control
import (
"io/ioutil"
"os"
"os/exec"
"strings"
"time"
"github.com/codegangsta/cli"
log "github.com/Sirupsen/logrus"
"github.com/rancher/os/config"
"github.com/rancher/os/util"
)
func bootstrapAction(c *cli.Context) error {
if err := UdevSettle(); err != nil {
log.Errorf("Failed to run udev settle: %v", err)
}
cfg := config.LoadConfig()
if cfg.Rancher.State.MdadmScan {
if err := mdadmScan(); err != nil {
log.Errorf("Failed to run mdadm scan: %v", err)
}
}
stateScript := cfg.Rancher.State.Script
if stateScript != "" {
if err := runStateScript(stateScript); err != nil {
log.Errorf("Failed to run state script: %v", err)
}
}
if cfg.Rancher.State.Dev != "" && cfg.Rancher.State.Wait {
waitForRoot(cfg)
}
autoformatDevices := cfg.Rancher.State.Autoformat
if len(autoformatDevices) > 0 {
if err := autoformat(autoformatDevices); err != nil {
log.Errorf("Failed to run autoformat: %v", err)
}
}
if err := UdevSettle(); err != nil {
log.Errorf("Failed to run udev settle: %v", err)
}
return nil
}
func mdadmScan() error {
cmd := exec.Command("mdadm", "--assemble", "--scan")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
return cmd.Run()
}
func runStateScript(script string) error {
f, err := ioutil.TempFile("", "")
if err != nil {
return err
}
if _, err := f.WriteString(script); err != nil {
return err
}
if err := f.Chmod(os.ModePerm); err != nil {
return err
}
if err := f.Close(); err != nil {
return err
}
return util.RunScript(f.Name())
}
func waitForRoot(cfg *config.CloudConfig) {
var dev string
for i := 0; i < 30; i++ {
dev = util.ResolveDevice(cfg.Rancher.State.Dev)
if dev != "" {
break
}
time.Sleep(time.Millisecond * 1000)
}
if dev == "" {
return
}
for i := 0; i < 30; i++ {
if _, err := os.Stat(dev); err == nil {
break
}
time.Sleep(time.Millisecond * 1000)
}
}
func autoformat(autoformatDevices []string) error {
cmd := exec.Command("/usr/sbin/auto-format.sh")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Env = []string{
"AUTOFORMAT=" + strings.Join(autoformatDevices, " "),
}
return cmd.Run()
}

View File

@@ -24,6 +24,12 @@ func Main() {
}
app.Commands = []cli.Command{
{
Name: "bootstrap",
HideHelp: true,
SkipFlagParsing: true,
Action: bootstrapAction,
},
{
Name: "config",
ShortName: "c",
@@ -72,12 +78,24 @@ func Main() {
HideHelp: true,
Subcommands: osSubcommands(),
},
{
Name: "preload-images",
HideHelp: true,
SkipFlagParsing: true,
Action: preloadImagesAction,
},
{
Name: "tls",
Usage: "setup tls configuration",
HideHelp: true,
Subcommands: tlsConfCommands(),
},
{
Name: "udev-settle",
HideHelp: true,
SkipFlagParsing: true,
Action: udevSettleAction,
},
installCommand,
selinuxCommand(),
}

View File

@@ -85,9 +85,6 @@ func imagesFromConfig(cfg *config.CloudConfig) []string {
for _, service := range cfg.Rancher.BootstrapContainers {
imagesMap[service.Image] = 1
}
for _, service := range cfg.Rancher.Autoformat {
imagesMap[service.Image] = 1
}
for _, service := range cfg.Rancher.Services {
imagesMap[service.Image] = 1
}

106
cmd/control/preload.go Normal file
View File

@@ -0,0 +1,106 @@
package control
import (
"compress/gzip"
"context"
"fmt"
"io"
"io/ioutil"
"os"
"path"
"regexp"
"strings"
"github.com/codegangsta/cli"
log "github.com/Sirupsen/logrus"
dockerClient "github.com/docker/engine-api/client"
"github.com/rancher/os/docker"
)
const (
userImagesPreloadDirectory = "/var/lib/rancher/preload/docker"
)
func preloadImagesAction(c *cli.Context) error {
return PreloadImages(docker.NewDefaultClient, userImagesPreloadDirectory)
}
func shouldLoad(file string) bool {
if strings.HasSuffix(file, ".done") {
return false
}
if _, err := os.Stat(fmt.Sprintf("%s.done", file)); err == nil {
return false
}
return true
}
func PreloadImages(clientFactory func() (dockerClient.APIClient, error), imagesDir string) error {
var client dockerClient.APIClient
clientInitialized := false
if _, err := os.Stat(imagesDir); os.IsNotExist(err) {
if err = os.MkdirAll(imagesDir, 0755); err != nil {
return err
}
} else if err != nil {
return err
}
files, err := ioutil.ReadDir(imagesDir)
if err != nil {
return err
}
for _, file := range files {
filename := path.Join(imagesDir, file.Name())
if !shouldLoad(filename) {
continue
}
image, err := os.Open(filename)
if err != nil {
return err
}
var imageReader io.Reader
imageReader = image
match, err := regexp.MatchString(".t?gz$", file.Name())
if err != nil {
return err
}
if match {
imageReader, err = gzip.NewReader(image)
if err != nil {
return err
}
}
if !clientInitialized {
client, err = clientFactory()
if err != nil {
return err
}
clientInitialized = true
}
log.Infof("Loading image %s", filename)
if _, err = client.ImageLoad(context.Background(), imageReader, false); err != nil {
return err
}
if err = image.Close(); err != nil {
return err
}
doneStamp, err := os.Create(fmt.Sprintf("%s.done", filename))
if err != nil {
return err
}
if err = doneStamp.Close(); err != nil {
return err
}
}
return nil
}

36
cmd/control/udevsettle.go Normal file
View File

@@ -0,0 +1,36 @@
package control
import (
"os"
"os/exec"
log "github.com/Sirupsen/logrus"
"github.com/codegangsta/cli"
)
func udevSettleAction(c *cli.Context) {
if err := UdevSettle(); err != nil {
log.Fatal(err)
}
}
func UdevSettle() error {
cmd := exec.Command("udevd", "--daemon")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
return err
}
cmd = exec.Command("udevadm", "trigger", "--action=add")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
return err
}
cmd = exec.Command("udevadm", "settle")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
return cmd.Run()
}

View File

@@ -176,9 +176,6 @@ func amendNils(c *CloudConfig) *CloudConfig {
if t.Rancher.Environment == nil {
t.Rancher.Environment = map[string]string{}
}
if t.Rancher.Autoformat == nil {
t.Rancher.Autoformat = map[string]*composeConfig.ServiceConfigV1{}
}
if t.Rancher.BootstrapContainers == nil {
t.Rancher.BootstrapContainers = map[string]*composeConfig.ServiceConfigV1{}
}
@@ -199,7 +196,6 @@ func amendNils(c *CloudConfig) *CloudConfig {
func amendContainerNames(c *CloudConfig) *CloudConfig {
for _, scm := range []map[string]*composeConfig.ServiceConfigV1{
c.Rancher.Autoformat,
c.Rancher.BootstrapContainers,
c.Rancher.Services,
} {

View File

@@ -102,7 +102,6 @@ type RancherConfig struct {
Environment map[string]string `yaml:"environment,omitempty"`
Services map[string]*composeConfig.ServiceConfigV1 `yaml:"services,omitempty"`
BootstrapContainers map[string]*composeConfig.ServiceConfigV1 `yaml:"bootstrap,omitempty"`
Autoformat map[string]*composeConfig.ServiceConfigV1 `yaml:"autoformat,omitempty"`
BootstrapDocker DockerConfig `yaml:"bootstrap_docker,omitempty"`
CloudInit CloudInit `yaml:"cloud_init,omitempty"`
Debug bool `yaml:"debug,omitempty"`

View File

@@ -1,4 +1,3 @@
FROM rancher/os-base
COPY auto-format.sh /usr/sbin/
COPY od-1m0 /
ENTRYPOINT ["/usr/sbin/auto-format.sh"]

View File

@@ -1,4 +0,0 @@
FROM rancher/os-base
RUN ln -sf /var/lib/rancher/engine/docker /usr/bin/docker
COPY preload.sh /
CMD ["/preload.sh"]

View File

@@ -1,46 +0,0 @@
#!/bin/bash
set -e
BASE=${1:-${PRELOAD_DIR}}
BASE=${BASE:-/mnt/preload}
if [ "${SYSTEM_IMAGES}" = "true" ]; then
docker_bin=system-docker
else
docker_bin=docker
fi
should_load() {
file=${1}
if [[ ${file} =~ \.done$ ]]; then echo false
elif [ -f ${file} ]; then
if [[ ${file} -nt ${file}.done ]]; then echo true
else echo false
fi
else echo false
fi
}
if [ -d ${BASE} ]; then
echo Preloading docker images from ${BASE}...
for file in $(ls ${BASE}); do
path=${BASE}/${file}
loading=$(should_load ${path})
if [ ${loading} == "true" ]; then
CAT="cat ${path}"
if [[ ${file} =~ \.t?gz$ ]]; then CAT="${CAT} | gunzip"; fi
if [[ ${file} =~ \.t?xz$ ]]; then CAT="${CAT} | unxz"; fi
wait-for-docker
CAT="${CAT} | ${docker_bin} load"
echo loading from ${path}
eval ${CAT} || :
touch ${path}.done || :
fi
done
echo Done.
else
echo Can not preload images from ${BASE}: not a dir or does not exist.
fi

View File

@@ -1,3 +0,0 @@
FROM rancher/os-base
COPY state.sh /usr/sbin/
CMD ["/usr/sbin/state.sh"]

View File

@@ -1,12 +0,0 @@
#!/bin/bash
set -x
if [ "$(ros config get rancher.state.mdadm_scan)" = "true" ]; then
mdadm --assemble --scan
fi
ros config get rancher.state.script > config.sh
if [ -s config.sh ]; then
chmod +x config.sh
exec ./config.sh
fi

View File

@@ -1,3 +0,0 @@
FROM rancher/os-base
COPY udev.sh /
CMD ["/udev.sh"]

View File

@@ -1,33 +0,0 @@
#!/bin/bash
if [ "$DAEMON" = true ]; then
exec udevd
fi
udevd --daemon
udevadm trigger --action=add
udevadm settle
dev=$(ros config get rancher.state.dev)
wait=$(ros config get rancher.state.wait)
if [ "$BOOTSTRAP" != true ] || [ "$dev" == "" ] || [ "$wait" != "true" ]; then
exit
fi
for i in `seq 1 30`; do
drive=$(ros dev $dev)
if [ "$drive" != "" ]; then
break
fi
sleep 1
done
drive=$(ros dev $dev)
if [ "$drive" = "" ]; then
exit
fi
for i in `seq 1 30`; do
if [ -e $drive ]; then
break
fi
sleep 1
done

View File

@@ -3,8 +3,6 @@ package init
import (
"syscall"
"strings"
log "github.com/Sirupsen/logrus"
"github.com/rancher/docker-from-scratch"
"github.com/rancher/os/compose"
@@ -12,20 +10,11 @@ import (
"github.com/rancher/os/util"
)
func autoformat(cfg *config.CloudConfig) (*config.CloudConfig, error) {
func bootstrapServices(cfg *config.CloudConfig) (*config.CloudConfig, error) {
if len(cfg.Rancher.State.Autoformat) == 0 || util.ResolveDevice(cfg.Rancher.State.Dev) != "" {
return cfg, nil
}
AUTOFORMAT := "AUTOFORMAT=" + strings.Join(cfg.Rancher.State.Autoformat, " ")
t := *cfg
t.Rancher.Autoformat["autoformat"].Environment = []string{AUTOFORMAT}
log.Info("Running Autoformat services")
_, err := compose.RunServiceSet("autoformat", &t, t.Rancher.Autoformat)
return &t, err
}
func runBootstrapContainers(cfg *config.CloudConfig) (*config.CloudConfig, error) {
log.Info("Running Bootstrap services")
log.Info("Running Bootstrap")
_, err := compose.RunServiceSet("bootstrap", cfg, cfg.Rancher.BootstrapContainers)
return cfg, err
}
@@ -70,7 +59,6 @@ func bootstrap(cfg *config.CloudConfig) error {
_, err = config.ChainCfgFuncs(cfg,
loadImages,
runBootstrapContainers,
autoformat)
bootstrapServices)
return err
}

View File

@@ -9,11 +9,16 @@ import (
log "github.com/Sirupsen/logrus"
"github.com/docker/libcompose/project/options"
"github.com/rancher/os/cmd/control"
"github.com/rancher/os/compose"
"github.com/rancher/os/config"
"github.com/rancher/os/docker"
)
const (
systemImagesPreloadDirectory = "/var/lib/rancher/preload/system-docker"
)
func hasImage(name string) bool {
stamp := path.Join(STATE, name)
if _, err := os.Stat(stamp); os.IsNotExist(err) {
@@ -91,6 +96,10 @@ func loadImages(cfg *config.CloudConfig) (*config.CloudConfig, error) {
func SysInit() error {
cfg := config.LoadConfig()
if err := control.PreloadImages(docker.NewSystemClient, systemImagesPreloadDirectory); err != nil {
log.Errorf("Failed to preload System Docker images: %v", err)
}
_, err := config.ChainCfgFuncs(cfg,
loadImages,
func(cfg *config.CloudConfig) (*config.CloudConfig, error) {

View File

@@ -15,15 +15,14 @@ rancher:
dns:
nameservers: [8.8.8.8, 8.8.4.4]
bootstrap:
state-script:
image: {{.OS_REPO}}/os-statescript:{{.VERSION}}{{.SUFFIX}}
bootstrap:
image: {{.OS_REPO}}/os-bootstrap:{{.VERSION}}{{.SUFFIX}}
command: ros bootstrap
labels:
io.rancher.os.detach: "false"
io.rancher.os.scope: system
io.rancher.os.after: udev-bootstrap
log_driver: json-file
net: host
uts: host
net: none
privileged: true
volumes:
- /dev:/host/dev
@@ -31,46 +30,6 @@ rancher:
- /lib/firmware:/lib/firmware
- /usr/bin/ros:/usr/bin/ros:ro
- /usr/share/ros:/usr/share/ros:ro
udev-bootstrap:
image: {{.OS_REPO}}/os-udev:{{.VERSION}}{{.SUFFIX}}
environment:
- BOOTSTRAP=true
labels:
io.rancher.os.detach: "false"
io.rancher.os.scope: system
log_driver: json-file
net: host
uts: host
privileged: true
volumes:
- /dev:/host/dev
- /lib/modules:/lib/modules
- /lib/firmware:/lib/firmware
- /usr/bin/ros:/usr/bin/ros:ro
autoformat:
autoformat:
image: {{.OS_REPO}}/os-autoformat:{{.VERSION}}{{.SUFFIX}}
labels:
io.rancher.os.detach: "false"
io.rancher.os.scope: system
log_driver: json-file
net: none
privileged: true
udev-autoformat:
image: {{.OS_REPO}}/os-udev:{{.VERSION}}{{.SUFFIX}}
labels:
io.rancher.os.detach: "false"
io.rancher.os.scope: system
io.rancher.os.after: autoformat
log_driver: json-file
net: host
uts: host
privileged: true
volumes:
- /dev:/host/dev
- /lib/modules:/lib/modules
- /lib/firmware:/lib/firmware
- /usr/bin/ros:/usr/bin/ros:ro
bootstrap_docker:
bridge: none
storage_driver: overlay
@@ -157,7 +116,7 @@ rancher:
io.rancher.os.detach: "false"
io.rancher.os.reloadconfig: "true"
io.rancher.os.scope: system
io.rancher.os.after: udev,preload-system-images
io.rancher.os.after: udev
net: host
uts: host
privileged: true
@@ -263,34 +222,14 @@ rancher:
volumes_from:
- command-volumes
- system-volumes
preload-system-images:
image: {{.OS_REPO}}/os-preload:{{.VERSION}}{{.SUFFIX}}
environment:
- SYSTEM_IMAGES=true
labels:
io.rancher.os.detach: "false"
io.rancher.os.scope: system
net: host
privileged: true
volumes:
- /var/run/system-docker.sock:/var/run/docker.sock
- /var/lib/rancher/preload/system-docker:/mnt/preload
- /usr/bin/ros:/usr/sbin/wait-for-docker:ro
volumes_from:
- command-volumes
- system-volumes
preload-user-images:
image: {{.OS_REPO}}/os-preload:{{.VERSION}}{{.SUFFIX}}
image: {{.OS_REPO}}/os-base:{{.VERSION}}{{.SUFFIX}}
command: ros preload-images
labels:
io.rancher.os.detach: "false"
io.rancher.os.scope: system
io.rancher.os.after: console
net: host
privileged: true
volumes:
- /var/run/:/var/run/
- /var/lib/rancher/preload/docker:/mnt/preload
- /usr/bin/ros:/usr/sbin/wait-for-docker:ro
volumes_from:
- command-volumes
- system-volumes
@@ -333,7 +272,8 @@ rancher:
- /var/log:/var/log
- /var/run:/var/run
udev-cold:
image: {{.OS_REPO}}/os-udev:{{.VERSION}}{{.SUFFIX}}
image: {{.OS_REPO}}/os-base:{{.VERSION}}{{.SUFFIX}}
command: ros udev-settle
labels:
io.rancher.os.detach: "false"
io.rancher.os.scope: system
@@ -344,9 +284,8 @@ rancher:
- command-volumes
- system-volumes
udev:
image: {{.OS_REPO}}/os-udev:{{.VERSION}}{{.SUFFIX}}
environment:
- DAEMON=true
image: {{.OS_REPO}}/os-base:{{.VERSION}}{{.SUFFIX}}
command: udevd
labels:
io.rancher.os.detach: "true"
io.rancher.os.scope: system

View File

@@ -11,6 +11,7 @@ func (s *QemuSuite) TestPreload(c *C) {
s.CheckCall(c, `
docker pull busybox
sudo docker save -o /var/lib/rancher/preload/system-docker/busybox.tar busybox
sudo gzip /var/lib/rancher/preload/system-docker/busybox.tar
sudo system-docker pull alpine
sudo system-docker save -o /var/lib/rancher/preload/docker/alpine.tar alpine`)

View File

@@ -7,6 +7,7 @@ import (
"fmt"
"io/ioutil"
"os"
"os/exec"
"path"
"strings"
@@ -241,3 +242,29 @@ func ExistsAndExecutable(path string) bool {
mode := info.Mode().Perm()
return mode&os.ModePerm != 0
}
func RunScript(path string) error {
if !ExistsAndExecutable(path) {
return nil
}
script, err := os.Open(path)
if err != nil {
return err
}
magic := make([]byte, 2)
if _, err = script.Read(magic); err != nil {
return err
}
cmd := exec.Command("/bin/sh", path)
if string(magic) == "#!" {
cmd = exec.Command(path)
}
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
return cmd.Run()
}