mirror of
https://github.com/rancher/os.git
synced 2025-07-21 18:31:31 +00:00
Use a subdirectory of the state partition
This commit is contained in:
parent
9c6b16928a
commit
808fbdbe1f
@ -17,6 +17,7 @@ RUN curl -sSL https://storage.googleapis.com/golang/go1.5.2.linux-amd64.tar.gz |
|
|||||||
RUN curl -sL https://get.docker.com/builds/Linux/x86_64/docker-1.9.1 > /usr/bin/docker
|
RUN curl -sL https://get.docker.com/builds/Linux/x86_64/docker-1.9.1 > /usr/bin/docker
|
||||||
RUN chmod +x /usr/bin/docker
|
RUN chmod +x /usr/bin/docker
|
||||||
|
|
||||||
|
ENV DAPPER_DOCKER_SOCKET true
|
||||||
ENV DAPPER_SOURCE /go/src/github.com/rancher/os
|
ENV DAPPER_SOURCE /go/src/github.com/rancher/os
|
||||||
ENV DAPPER_OUTPUT ./bin ./dist
|
ENV DAPPER_OUTPUT ./bin ./dist
|
||||||
ENV DAPPER_RUN_ARGS --privileged
|
ENV DAPPER_RUN_ARGS --privileged
|
||||||
|
@ -104,6 +104,7 @@ type DockerConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type StateConfig struct {
|
type StateConfig struct {
|
||||||
|
Directory string `yaml:"directory,omitempty"`
|
||||||
FsType string `yaml:"fstype,omitempty"`
|
FsType string `yaml:"fstype,omitempty"`
|
||||||
Dev string `yaml:"dev,omitempty"`
|
Dev string `yaml:"dev,omitempty"`
|
||||||
Required bool `yaml:"required,omitempty"`
|
Required bool `yaml:"required,omitempty"`
|
||||||
|
22
init/init.go
22
init/init.go
@ -83,18 +83,17 @@ func MainInit() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func mountState(cfg *config.CloudConfig) error {
|
func mountConfigured(display, dev, fsType, target string) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
if cfg.Rancher.State.Dev == "" {
|
if dev == "" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
dev := util.ResolveDevice(cfg.Rancher.State.Dev)
|
dev = util.ResolveDevice(dev)
|
||||||
if dev == "" {
|
if dev == "" {
|
||||||
return fmt.Errorf("Could not resolve device %q", cfg.Rancher.State.Dev)
|
return fmt.Errorf("Could not resolve device %q", dev)
|
||||||
}
|
}
|
||||||
fsType := cfg.Rancher.State.FsType
|
|
||||||
if fsType == "auto" {
|
if fsType == "auto" {
|
||||||
fsType, err = util.GetFsType(dev)
|
fsType, err = util.GetFsType(dev)
|
||||||
}
|
}
|
||||||
@ -104,8 +103,12 @@ func mountState(cfg *config.CloudConfig) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("FsType has been set to %s", fsType)
|
log.Debugf("FsType has been set to %s", fsType)
|
||||||
log.Infof("Mounting state device %s to %s", dev, STATE)
|
log.Infof("Mounting %s device %s to %s", display, dev, target)
|
||||||
return util.Mount(dev, STATE, fsType, "")
|
return util.Mount(dev, target, fsType, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
func mountState(cfg *config.CloudConfig) error {
|
||||||
|
return mountConfigured("state", cfg.Rancher.State.Dev, cfg.Rancher.State.FsType, STATE)
|
||||||
}
|
}
|
||||||
|
|
||||||
func tryMountState(cfg *config.CloudConfig) error {
|
func tryMountState(cfg *config.CloudConfig) error {
|
||||||
@ -128,8 +131,9 @@ func tryMountAndBootstrap(cfg *config.CloudConfig) (*config.CloudConfig, error)
|
|||||||
return cfg, err
|
return cfg, err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("Switching to new root at %s", STATE)
|
log.Debugf("Switching to new root at %s %s", STATE, cfg.Rancher.State.Directory)
|
||||||
return cfg, switchRoot(STATE, cfg.Rancher.RmUsr)
|
err := switchRoot(STATE, cfg.Rancher.State.Directory, cfg.Rancher.RmUsr)
|
||||||
|
return cfg, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func getLaunchConfig(cfg *config.CloudConfig, dockerCfg *config.DockerConfig) (*dockerlaunch.Config, []string) {
|
func getLaunchConfig(cfg *config.CloudConfig, dockerCfg *config.DockerConfig) (*dockerlaunch.Config, []string) {
|
||||||
|
27
init/root.go
27
init/root.go
@ -5,6 +5,7 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
log "github.com/Sirupsen/logrus"
|
log "github.com/Sirupsen/logrus"
|
||||||
@ -84,7 +85,7 @@ func copyMoveRoot(rootfs string, rmUsr bool) error {
|
|||||||
for _, file := range files {
|
for _, file := range files {
|
||||||
filename := path.Join("/", file.Name())
|
filename := path.Join("/", file.Name())
|
||||||
|
|
||||||
if filename == rootfs {
|
if filename == rootfs || strings.HasPrefix(rootfs, filename+"/") {
|
||||||
log.Debugf("Skipping Deleting %s", filename)
|
log.Debugf("Skipping Deleting %s", filename)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -98,7 +99,23 @@ func copyMoveRoot(rootfs string, rmUsr bool) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func switchRoot(rootfs string, rmUsr bool) error {
|
func switchRoot(rootfs, subdir string, rmUsr bool) error {
|
||||||
|
if subdir != "" {
|
||||||
|
fullRootfs := path.Join(rootfs, subdir)
|
||||||
|
if _, err := os.Stat(fullRootfs); os.IsNotExist(err) {
|
||||||
|
if err := os.MkdirAll(fullRootfs, 0755); err != nil {
|
||||||
|
log.Errorf("Failed to create directory %s: %v", fullRootfs, err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("Bind mounting mount %s to %s", fullRootfs, rootfs)
|
||||||
|
if err := syscall.Mount(fullRootfs, rootfs, "", syscall.MS_BIND, ""); err != nil {
|
||||||
|
log.Errorf("Failed to bind mount subdir for %s: %v", fullRootfs, err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for _, i := range []string{"/dev", "/sys", "/proc", "/run"} {
|
for _, i := range []string{"/dev", "/sys", "/proc", "/run"} {
|
||||||
log.Debugf("Moving mount %s to %s", i, path.Join(rootfs, i))
|
log.Debugf("Moving mount %s to %s", i, path.Join(rootfs, i))
|
||||||
if err := os.MkdirAll(path.Join(rootfs, i), 0755); err != nil {
|
if err := os.MkdirAll(path.Join(rootfs, i), 0755); err != nil {
|
||||||
@ -113,23 +130,27 @@ func switchRoot(rootfs string, rmUsr bool) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Debugf("chdir %s", rootfs)
|
||||||
if err := syscall.Chdir(rootfs); err != nil {
|
if err := syscall.Chdir(rootfs); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Debugf("mount MS_MOVE %s", rootfs)
|
||||||
if err := syscall.Mount(rootfs, "/", "", syscall.MS_MOVE, ""); err != nil {
|
if err := syscall.Mount(rootfs, "/", "", syscall.MS_MOVE, ""); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Debug("chroot .")
|
||||||
if err := syscall.Chroot("."); err != nil {
|
if err := syscall.Chroot("."); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Debug("chdir /")
|
||||||
if err := syscall.Chdir("/"); err != nil {
|
if err := syscall.Chdir("/"); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("Successfully moved to new root at %s", rootfs)
|
log.Debugf("Successfully moved to new root at %s", path.Join(rootfs, subdir))
|
||||||
os.Unsetenv("DOCKER_RAMDISK")
|
os.Unsetenv("DOCKER_RAMDISK")
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -2,11 +2,12 @@ import subprocess
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import pytest
|
import pytest
|
||||||
|
import rostest
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session", autouse=True)
|
@pytest.fixture(scope="session", autouse=True)
|
||||||
def chdir_to_project_root():
|
def chdir_to_project_root():
|
||||||
os.chdir('../..')
|
os.chdir(os.path.join(os.path.dirname(rostest.__file__), '../../..'))
|
||||||
print('\nChdir to project root dir: ' + subprocess.check_output('pwd'))
|
print('\nChdir to project root dir: ' + subprocess.check_output('pwd'))
|
||||||
os.chmod('./tests/integration/assets/test.key', 0o600)
|
os.chmod('./tests/integration/assets/test.key', 0o600)
|
||||||
print('Also, `chmod 600 tests/integration/assets/test.key` to make ssh happy')
|
print('Also, `chmod 600 tests/integration/assets/test.key` to make ssh happy')
|
||||||
|
19
tests/integration/rostest/test_06_subdir.py
Normal file
19
tests/integration/rostest/test_06_subdir.py
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import pytest
|
||||||
|
import rostest.util as u
|
||||||
|
from rostest.util import SSH
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="module")
|
||||||
|
def qemu(request):
|
||||||
|
q = u.run_qemu(request, run_args=['--append', 'rancher.state.directory=ros_subdir'])
|
||||||
|
u.flush_out(q.stdout)
|
||||||
|
return q
|
||||||
|
|
||||||
|
|
||||||
|
def test_system_docker_survives_custom_docker_install(qemu):
|
||||||
|
SSH(qemu).check_call('bash', '-c', '''
|
||||||
|
set -x -e
|
||||||
|
mkdir x
|
||||||
|
sudo mount $(ros dev LABEL=RANCHER_STATE) x
|
||||||
|
[ -d x/ros_subdir/home/rancher ]
|
||||||
|
'''.strip())
|
@ -85,3 +85,19 @@ def wait_for_ssh(qemu, ssh_command=['./scripts/ssh', '--qemu'], command=['docker
|
|||||||
print('\nWaiting for ssh and docker... ' + str(i))
|
print('\nWaiting for ssh and docker... ' + str(i))
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
assert qemu.returncode is None
|
assert qemu.returncode is None
|
||||||
|
|
||||||
|
|
||||||
|
class SSH:
|
||||||
|
def __init__(self, qemu, ssh_command=['./scripts/ssh', '--qemu']):
|
||||||
|
self._qemu = qemu
|
||||||
|
self._ssh_command = ssh_command
|
||||||
|
self._waited = False
|
||||||
|
|
||||||
|
def check_call(self, *args, **kw):
|
||||||
|
if not self._waited:
|
||||||
|
wait_for_ssh(self._qemu, ssh_command=self._ssh_command)
|
||||||
|
self._waited = True
|
||||||
|
|
||||||
|
kw['stderr'] = subprocess.STDOUT
|
||||||
|
kw['universal_newlines'] = True
|
||||||
|
return subprocess.check_call(self._ssh_command + list(args), **kw)
|
||||||
|
Loading…
Reference in New Issue
Block a user