mirror of
https://github.com/rancher/os.git
synced 2025-09-02 07:15:41 +00:00
Extend write_files to run in all system services
This commit is contained in:
@@ -12,8 +12,10 @@ import (
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/coreos/coreos-cloudinit/system"
|
||||
"github.com/docker/docker/pkg/mount"
|
||||
"github.com/rancher/os/config"
|
||||
rancherConfig "github.com/rancher/os/config"
|
||||
"github.com/rancher/os/docker"
|
||||
"github.com/rancher/os/util"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -38,7 +40,7 @@ func Main() {
|
||||
|
||||
log.Infof("Running cloud-init-execute: pre-console=%v, console=%v", preConsole, console)
|
||||
|
||||
cfg := config.LoadConfig()
|
||||
cfg := rancherConfig.LoadConfig()
|
||||
|
||||
if !console && !preConsole {
|
||||
console = true
|
||||
@@ -53,21 +55,13 @@ func Main() {
|
||||
}
|
||||
}
|
||||
|
||||
func ApplyConsole(cfg *config.CloudConfig) {
|
||||
func ApplyConsole(cfg *rancherConfig.CloudConfig) {
|
||||
if len(cfg.SSHAuthorizedKeys) > 0 {
|
||||
authorizeSSHKeys("rancher", cfg.SSHAuthorizedKeys, sshKeyName)
|
||||
authorizeSSHKeys("docker", cfg.SSHAuthorizedKeys, sshKeyName)
|
||||
}
|
||||
|
||||
for _, file := range cfg.WriteFiles {
|
||||
f := system.File{File: file}
|
||||
fullPath, err := system.WriteFile(&f, "/")
|
||||
if err != nil {
|
||||
log.WithFields(log.Fields{"err": err, "path": fullPath}).Error("Error writing file")
|
||||
continue
|
||||
}
|
||||
log.Printf("Wrote file %s to filesystem", fullPath)
|
||||
}
|
||||
WriteFiles(cfg, "console")
|
||||
|
||||
for _, configMount := range cfg.Mounts {
|
||||
if len(configMount) != 4 {
|
||||
@@ -88,7 +82,29 @@ func ApplyConsole(cfg *config.CloudConfig) {
|
||||
}
|
||||
}
|
||||
|
||||
func applyPreConsole(cfg *config.CloudConfig) {
|
||||
func WriteFiles(cfg *rancherConfig.CloudConfig, container string) {
|
||||
for _, file := range cfg.WriteFiles {
|
||||
fileContainer := file.Container
|
||||
if fileContainer == "" {
|
||||
fileContainer = "console"
|
||||
}
|
||||
if fileContainer != container {
|
||||
continue
|
||||
}
|
||||
|
||||
f := system.File{
|
||||
File: file.File,
|
||||
}
|
||||
fullPath, err := system.WriteFile(&f, "/")
|
||||
if err != nil {
|
||||
log.WithFields(log.Fields{"err": err, "path": fullPath}).Error("Error writing file")
|
||||
continue
|
||||
}
|
||||
log.Printf("Wrote file %s to filesystem", fullPath)
|
||||
}
|
||||
}
|
||||
|
||||
func applyPreConsole(cfg *rancherConfig.CloudConfig) {
|
||||
if _, err := os.Stat(resizeStamp); os.IsNotExist(err) && cfg.Rancher.ResizeDevice != "" {
|
||||
if err := resizeDevice(cfg); err == nil {
|
||||
os.Create(resizeStamp)
|
||||
@@ -105,9 +121,20 @@ func applyPreConsole(cfg *config.CloudConfig) {
|
||||
log.Errorf("Failed to set sysctl key %s: %s", k, err)
|
||||
}
|
||||
}
|
||||
|
||||
client, err := docker.NewSystemClient()
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
|
||||
for _, restart := range cfg.Rancher.RestartServices {
|
||||
if err = client.ContainerRestart(context.Background(), restart, 10); err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func resizeDevice(cfg *config.CloudConfig) error {
|
||||
func resizeDevice(cfg *rancherConfig.CloudConfig) error {
|
||||
cmd := exec.Command("growpart", cfg.Rancher.ResizeDevice, "1")
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
|
@@ -70,9 +70,6 @@ func Main() {
|
||||
|
||||
func saveFiles(cloudConfigBytes, scriptBytes []byte, metadata datasource.Metadata) error {
|
||||
os.MkdirAll(rancherConfig.CloudConfigDir, os.ModeDir|0600)
|
||||
os.Remove(rancherConfig.CloudConfigScriptFile)
|
||||
os.Remove(rancherConfig.CloudConfigBootFile)
|
||||
os.Remove(rancherConfig.MetaDataFile)
|
||||
|
||||
if len(scriptBytes) > 0 {
|
||||
log.Infof("Writing to %s", rancherConfig.CloudConfigScriptFile)
|
||||
@@ -82,10 +79,12 @@ func saveFiles(cloudConfigBytes, scriptBytes []byte, metadata datasource.Metadat
|
||||
}
|
||||
}
|
||||
|
||||
if err := util.WriteFileAtomic(rancherConfig.CloudConfigBootFile, cloudConfigBytes, 400); err != nil {
|
||||
return err
|
||||
if len(cloudConfigBytes) > 0 {
|
||||
if err := util.WriteFileAtomic(rancherConfig.CloudConfigBootFile, cloudConfigBytes, 400); err != nil {
|
||||
return err
|
||||
}
|
||||
log.Infof("Written to %s:\n%s", rancherConfig.CloudConfigBootFile, string(cloudConfigBytes))
|
||||
}
|
||||
log.Infof("Written to %s:\n%s", rancherConfig.CloudConfigBootFile, string(cloudConfigBytes))
|
||||
|
||||
metaDataBytes, err := yaml.Marshal(metadata)
|
||||
if err != nil {
|
||||
|
@@ -45,6 +45,12 @@ func Main() {
|
||||
SkipFlagParsing: true,
|
||||
Action: devAction,
|
||||
},
|
||||
{
|
||||
Name: "entrypoint",
|
||||
HideHelp: true,
|
||||
SkipFlagParsing: true,
|
||||
Action: entrypointAction,
|
||||
},
|
||||
{
|
||||
Name: "env",
|
||||
ShortName: "e",
|
||||
|
74
cmd/control/entrypoint.go
Normal file
74
cmd/control/entrypoint.go
Normal file
@@ -0,0 +1,74 @@
|
||||
package control
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"syscall"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/codegangsta/cli"
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/docker/docker/pkg/mount"
|
||||
"github.com/rancher/os/cmd/cloudinitexecute"
|
||||
"github.com/rancher/os/config"
|
||||
"github.com/rancher/os/docker"
|
||||
"github.com/rancher/os/util"
|
||||
)
|
||||
|
||||
const (
|
||||
ca = "/etc/ssl/certs/ca-certificates.crt"
|
||||
caBase = "/etc/ssl/certs/ca-certificates.crt.rancher"
|
||||
)
|
||||
|
||||
func entrypointAction(c *cli.Context) error {
|
||||
if err := mount.Mount("/host/dev", "/dev", "", "rbind"); err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
|
||||
if err := util.FileCopy(caBase, ca); err != nil && !os.IsNotExist(err) {
|
||||
log.Error(err)
|
||||
}
|
||||
|
||||
cfg := config.LoadConfig()
|
||||
|
||||
shouldWriteFiles := false
|
||||
for _, file := range cfg.WriteFiles {
|
||||
if file.Container != "" {
|
||||
shouldWriteFiles = true
|
||||
}
|
||||
}
|
||||
|
||||
if shouldWriteFiles {
|
||||
writeFiles(cfg)
|
||||
}
|
||||
|
||||
if len(os.Args) < 3 {
|
||||
return nil
|
||||
}
|
||||
|
||||
binary, err := exec.LookPath(os.Args[2])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return syscall.Exec(binary, os.Args[2:], os.Environ())
|
||||
}
|
||||
|
||||
func writeFiles(cfg *config.CloudConfig) error {
|
||||
id, err := util.GetCurrentContainerId()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
client, err := docker.NewSystemClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
info, err := client.ContainerInspect(context.Background(), id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cloudinitexecute.WriteFiles(cfg, info.Name[1:])
|
||||
return nil
|
||||
}
|
@@ -85,12 +85,17 @@ type Repositories map[string]Repository
|
||||
|
||||
type CloudConfig struct {
|
||||
SSHAuthorizedKeys []string `yaml:"ssh_authorized_keys"`
|
||||
WriteFiles []config.File `yaml:"write_files"`
|
||||
WriteFiles []File `yaml:"write_files"`
|
||||
Hostname string `yaml:"hostname"`
|
||||
Mounts [][]string `yaml:"mounts,omitempty"`
|
||||
Rancher RancherConfig `yaml:"rancher,omitempty"`
|
||||
}
|
||||
|
||||
type File struct {
|
||||
config.File
|
||||
Container string `yaml:"container,omitempty"`
|
||||
}
|
||||
|
||||
type RancherConfig struct {
|
||||
Console string `yaml:"console,omitempty"`
|
||||
Environment map[string]string `yaml:"environment,omitempty"`
|
||||
@@ -119,6 +124,7 @@ type RancherConfig struct {
|
||||
Defaults Defaults `yaml:"defaults,omitempty"`
|
||||
ResizeDevice string `yaml:"resize_device,omitempty"`
|
||||
Sysctl map[string]string `yaml:"sysctl,omitempty"`
|
||||
RestartServices []string `yaml:"restart_services,omitempty"`
|
||||
}
|
||||
|
||||
type UpgradeConfig struct {
|
||||
|
@@ -32,8 +32,7 @@ RUN rm /sbin/poweroff /sbin/reboot /sbin/halt && \
|
||||
adduser docker sudo && \
|
||||
echo '%sudo ALL=(ALL) ALL' >> /etc/sudoers
|
||||
COPY inputrc /etc/inputrc
|
||||
COPY entry.sh /usr/sbin/entry.sh
|
||||
COPY growpart /usr/bin/growpart
|
||||
RUN sed -i -e 's/duid/clientid/g' /etc/dhcpcd.conf
|
||||
|
||||
ENTRYPOINT ["/usr/sbin/entry.sh"]
|
||||
ENTRYPOINT ["/usr/bin/ros", "entrypoint"]
|
||||
|
@@ -250,6 +250,9 @@ rancher:
|
||||
uts: host
|
||||
privileged: true
|
||||
restart: always
|
||||
volumes_from:
|
||||
- command-volumes
|
||||
- system-volumes
|
||||
preload-system-images:
|
||||
image: {{.OS_REPO}}/os-preload:{{.VERSION}}{{.SUFFIX}}
|
||||
labels:
|
||||
@@ -289,6 +292,7 @@ rancher:
|
||||
privileged: true
|
||||
restart: always
|
||||
volumes_from:
|
||||
- command-volumes
|
||||
- system-volumes
|
||||
system-volumes:
|
||||
image: {{.OS_REPO}}/os-base:{{.VERSION}}{{.SUFFIX}}
|
||||
@@ -325,9 +329,8 @@ rancher:
|
||||
uts: host
|
||||
privileged: true
|
||||
volumes_from:
|
||||
- command-volumes
|
||||
- system-volumes
|
||||
volumes:
|
||||
- /usr/bin/ros:/usr/bin/ros:ro
|
||||
udev:
|
||||
image: {{.OS_REPO}}/os-udev:{{.VERSION}}{{.SUFFIX}}
|
||||
environment:
|
||||
@@ -340,6 +343,7 @@ rancher:
|
||||
privileged: true
|
||||
restart: always
|
||||
volumes_from:
|
||||
- command-volumes
|
||||
- system-volumes
|
||||
user-volumes:
|
||||
image: {{.OS_REPO}}/os-base:{{.VERSION}}{{.SUFFIX}}
|
||||
|
@@ -15,19 +15,19 @@ INITRD=${ARTIFACTS}/initrd
|
||||
|
||||
mkdir -p ${ARTIFACTS} ${PREPOP_DIR}
|
||||
|
||||
if [ "$(docker info | grep 'Storage Driver: ' | sed 's/Storage Driver: //')" != "overlay" ]; then
|
||||
echo Overlay storage driver is require to prepackage exploded images
|
||||
echo packaging images.tar instead
|
||||
tar czf ${ARTIFACTS}/rootfs.tar.gz --exclude lib/modules --exclude lib/firmware -C ${INITRD_DIR} .
|
||||
exit 0
|
||||
fi
|
||||
#if [ "$(docker info | grep 'Storage Driver: ' | sed 's/Storage Driver: //')" != "overlay" ]; then
|
||||
echo Overlay storage driver is require to prepackage exploded images
|
||||
echo packaging images.tar instead
|
||||
tar czf ${ARTIFACTS}/rootfs.tar.gz --exclude lib/modules --exclude lib/firmware -C ${INITRD_DIR} .
|
||||
exit 0
|
||||
#fi
|
||||
|
||||
DFS=$(docker run -d --privileged -v /lib/modules/$(uname -r):/lib/modules/$(uname -r) ${DFS_IMAGE}${SUFFIX} ${DFS_ARGS})
|
||||
trap "docker rm -fv ${DFS_ARCH} ${DFS}" EXIT
|
||||
docker exec -i ${DFS} docker load < ${INITRD_DIR}/usr/share/ros/images.tar
|
||||
docker stop ${DFS}
|
||||
docker run --rm --volumes-from=${DFS} rancher/os-base tar -c -C /var/lib/docker ./image | tar -x -C ${PREPOP_DIR}
|
||||
docker run --rm --volumes-from=${DFS} rancher/os-base tar -c -C /var/lib/docker ./overlay | tar -x -C ${PREPOP_DIR}
|
||||
docker run --rm --volumes-from=${DFS} busybox tar -c -C /var/lib/docker ./image | tar -x -C ${PREPOP_DIR}
|
||||
docker run --rm --volumes-from=${DFS} busybox tar -c -C /var/lib/docker ./overlay | tar -x -C ${PREPOP_DIR}
|
||||
|
||||
tar -cf ${ARTIFACTS}/rootfs.tar --exclude usr/share/ros/images.tar --exclude lib/modules --exclude lib/firmware -C ${INITRD_DIR} .
|
||||
tar -rf ${ARTIFACTS}/rootfs.tar -C ${IMAGE_CACHE} .
|
||||
|
29
tests/assets/test_23/cloud-config.yml
Normal file
29
tests/assets/test_23/cloud-config.yml
Normal file
@@ -0,0 +1,29 @@
|
||||
#cloud-config
|
||||
write_files:
|
||||
- path: "/test"
|
||||
permissions: "0644"
|
||||
owner: "root"
|
||||
content: |
|
||||
console content
|
||||
- path: "/test2"
|
||||
container: console
|
||||
permissions: "0644"
|
||||
owner: "root"
|
||||
content: |
|
||||
console content
|
||||
- path: "/test"
|
||||
container: ntp
|
||||
permissions: "0644"
|
||||
owner: "root"
|
||||
content: |
|
||||
ntp content
|
||||
- path: "/test"
|
||||
container: syslog
|
||||
permissions: "0644"
|
||||
owner: "root"
|
||||
content: |
|
||||
syslog content
|
||||
rancher:
|
||||
restart_services: [syslog]
|
||||
ssh_authorized_keys:
|
||||
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC85w9stZyiLQp/DkVO6fqwiShYcj1ClKdtCqgHtf+PLpJkFReSFu8y21y+ev09gsSMRRrjF7yt0pUHV6zncQhVeqsZtgc5WbELY2DOYUGmRn/CCvPbXovoBrQjSorqlBmpuPwsStYLr92Xn+VVsMNSUIegHY22DphGbDKG85vrKB8HxUxGIDxFBds/uE8FhSy+xsoyT/jUZDK6pgq2HnGl6D81ViIlKecpOpWlW3B+fea99ADNyZNVvDzbHE5pcI3VRw8u59WmpWOUgT6qacNVACl8GqpBvQk8sw7O/X9DSZHCKafeD9G5k+GYbAUz92fKWrx/lOXfUXPS3+c8dRIF
|
@@ -7,6 +7,6 @@ func (s *QemuSuite) TestKernelHeaders(c *C) {
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
s.CheckCall(c, `
|
||||
sleep 10
|
||||
sleep 15
|
||||
docker inspect kernel-headers`)
|
||||
}
|
||||
|
13
tests/write_files_test.go
Normal file
13
tests/write_files_test.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package integration
|
||||
|
||||
import . "gopkg.in/check.v1"
|
||||
|
||||
func (s *QemuSuite) TestWriteFiles(c *C) {
|
||||
err := s.RunQemu("--cloud-config", "./tests/assets/test_23/cloud-config.yml")
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
s.CheckCall(c, "sudo cat /test | grep 'console content'")
|
||||
s.CheckCall(c, "sudo cat /test2 | grep 'console content'")
|
||||
s.CheckCall(c, "sudo system-docker exec ntp cat /test | grep 'ntp content'")
|
||||
s.CheckCall(c, "sudo system-docker exec syslog cat /test | grep 'syslog content'")
|
||||
}
|
Reference in New Issue
Block a user