1
0
mirror of https://github.com/rancher/os.git synced 2025-09-04 00:04:25 +00:00

Extend write_files to run in all system services

This commit is contained in:
Josh Curl
2016-08-14 19:17:24 -07:00
parent 6658917591
commit 0a053c62ab
11 changed files with 191 additions and 34 deletions

View File

@@ -12,8 +12,10 @@ import (
log "github.com/Sirupsen/logrus" log "github.com/Sirupsen/logrus"
"github.com/coreos/coreos-cloudinit/system" "github.com/coreos/coreos-cloudinit/system"
"github.com/docker/docker/pkg/mount" "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" "github.com/rancher/os/util"
"golang.org/x/net/context"
) )
const ( const (
@@ -38,7 +40,7 @@ func Main() {
log.Infof("Running cloud-init-execute: pre-console=%v, console=%v", preConsole, console) log.Infof("Running cloud-init-execute: pre-console=%v, console=%v", preConsole, console)
cfg := config.LoadConfig() cfg := rancherConfig.LoadConfig()
if !console && !preConsole { if !console && !preConsole {
console = true console = true
@@ -53,21 +55,13 @@ func Main() {
} }
} }
func ApplyConsole(cfg *config.CloudConfig) { func ApplyConsole(cfg *rancherConfig.CloudConfig) {
if len(cfg.SSHAuthorizedKeys) > 0 { if len(cfg.SSHAuthorizedKeys) > 0 {
authorizeSSHKeys("rancher", cfg.SSHAuthorizedKeys, sshKeyName) authorizeSSHKeys("rancher", cfg.SSHAuthorizedKeys, sshKeyName)
authorizeSSHKeys("docker", cfg.SSHAuthorizedKeys, sshKeyName) authorizeSSHKeys("docker", cfg.SSHAuthorizedKeys, sshKeyName)
} }
for _, file := range cfg.WriteFiles { WriteFiles(cfg, "console")
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)
}
for _, configMount := range cfg.Mounts { for _, configMount := range cfg.Mounts {
if len(configMount) != 4 { 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 := os.Stat(resizeStamp); os.IsNotExist(err) && cfg.Rancher.ResizeDevice != "" {
if err := resizeDevice(cfg); err == nil { if err := resizeDevice(cfg); err == nil {
os.Create(resizeStamp) os.Create(resizeStamp)
@@ -105,9 +121,20 @@ func applyPreConsole(cfg *config.CloudConfig) {
log.Errorf("Failed to set sysctl key %s: %s", k, err) 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") cmd := exec.Command("growpart", cfg.Rancher.ResizeDevice, "1")
err := cmd.Run() err := cmd.Run()
if err != nil { if err != nil {

View File

@@ -70,9 +70,6 @@ func Main() {
func saveFiles(cloudConfigBytes, scriptBytes []byte, metadata datasource.Metadata) error { func saveFiles(cloudConfigBytes, scriptBytes []byte, metadata datasource.Metadata) error {
os.MkdirAll(rancherConfig.CloudConfigDir, os.ModeDir|0600) os.MkdirAll(rancherConfig.CloudConfigDir, os.ModeDir|0600)
os.Remove(rancherConfig.CloudConfigScriptFile)
os.Remove(rancherConfig.CloudConfigBootFile)
os.Remove(rancherConfig.MetaDataFile)
if len(scriptBytes) > 0 { if len(scriptBytes) > 0 {
log.Infof("Writing to %s", rancherConfig.CloudConfigScriptFile) 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 { if len(cloudConfigBytes) > 0 {
return err 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) metaDataBytes, err := yaml.Marshal(metadata)
if err != nil { if err != nil {

View File

@@ -45,6 +45,12 @@ func Main() {
SkipFlagParsing: true, SkipFlagParsing: true,
Action: devAction, Action: devAction,
}, },
{
Name: "entrypoint",
HideHelp: true,
SkipFlagParsing: true,
Action: entrypointAction,
},
{ {
Name: "env", Name: "env",
ShortName: "e", ShortName: "e",

74
cmd/control/entrypoint.go Normal file
View 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
}

View File

@@ -85,12 +85,17 @@ type Repositories map[string]Repository
type CloudConfig struct { type CloudConfig struct {
SSHAuthorizedKeys []string `yaml:"ssh_authorized_keys"` SSHAuthorizedKeys []string `yaml:"ssh_authorized_keys"`
WriteFiles []config.File `yaml:"write_files"` WriteFiles []File `yaml:"write_files"`
Hostname string `yaml:"hostname"` Hostname string `yaml:"hostname"`
Mounts [][]string `yaml:"mounts,omitempty"` Mounts [][]string `yaml:"mounts,omitempty"`
Rancher RancherConfig `yaml:"rancher,omitempty"` Rancher RancherConfig `yaml:"rancher,omitempty"`
} }
type File struct {
config.File
Container string `yaml:"container,omitempty"`
}
type RancherConfig struct { type RancherConfig struct {
Console string `yaml:"console,omitempty"` Console string `yaml:"console,omitempty"`
Environment map[string]string `yaml:"environment,omitempty"` Environment map[string]string `yaml:"environment,omitempty"`
@@ -119,6 +124,7 @@ type RancherConfig struct {
Defaults Defaults `yaml:"defaults,omitempty"` Defaults Defaults `yaml:"defaults,omitempty"`
ResizeDevice string `yaml:"resize_device,omitempty"` ResizeDevice string `yaml:"resize_device,omitempty"`
Sysctl map[string]string `yaml:"sysctl,omitempty"` Sysctl map[string]string `yaml:"sysctl,omitempty"`
RestartServices []string `yaml:"restart_services,omitempty"`
} }
type UpgradeConfig struct { type UpgradeConfig struct {

View File

@@ -32,8 +32,7 @@ RUN rm /sbin/poweroff /sbin/reboot /sbin/halt && \
adduser docker sudo && \ adduser docker sudo && \
echo '%sudo ALL=(ALL) ALL' >> /etc/sudoers echo '%sudo ALL=(ALL) ALL' >> /etc/sudoers
COPY inputrc /etc/inputrc COPY inputrc /etc/inputrc
COPY entry.sh /usr/sbin/entry.sh
COPY growpart /usr/bin/growpart COPY growpart /usr/bin/growpart
RUN sed -i -e 's/duid/clientid/g' /etc/dhcpcd.conf RUN sed -i -e 's/duid/clientid/g' /etc/dhcpcd.conf
ENTRYPOINT ["/usr/sbin/entry.sh"] ENTRYPOINT ["/usr/bin/ros", "entrypoint"]

View File

@@ -250,6 +250,9 @@ rancher:
uts: host uts: host
privileged: true privileged: true
restart: always restart: always
volumes_from:
- command-volumes
- system-volumes
preload-system-images: preload-system-images:
image: {{.OS_REPO}}/os-preload:{{.VERSION}}{{.SUFFIX}} image: {{.OS_REPO}}/os-preload:{{.VERSION}}{{.SUFFIX}}
labels: labels:
@@ -289,6 +292,7 @@ rancher:
privileged: true privileged: true
restart: always restart: always
volumes_from: volumes_from:
- command-volumes
- system-volumes - system-volumes
system-volumes: system-volumes:
image: {{.OS_REPO}}/os-base:{{.VERSION}}{{.SUFFIX}} image: {{.OS_REPO}}/os-base:{{.VERSION}}{{.SUFFIX}}
@@ -325,9 +329,8 @@ rancher:
uts: host uts: host
privileged: true privileged: true
volumes_from: volumes_from:
- command-volumes
- system-volumes - system-volumes
volumes:
- /usr/bin/ros:/usr/bin/ros:ro
udev: udev:
image: {{.OS_REPO}}/os-udev:{{.VERSION}}{{.SUFFIX}} image: {{.OS_REPO}}/os-udev:{{.VERSION}}{{.SUFFIX}}
environment: environment:
@@ -340,6 +343,7 @@ rancher:
privileged: true privileged: true
restart: always restart: always
volumes_from: volumes_from:
- command-volumes
- system-volumes - system-volumes
user-volumes: user-volumes:
image: {{.OS_REPO}}/os-base:{{.VERSION}}{{.SUFFIX}} image: {{.OS_REPO}}/os-base:{{.VERSION}}{{.SUFFIX}}

View File

@@ -15,19 +15,19 @@ INITRD=${ARTIFACTS}/initrd
mkdir -p ${ARTIFACTS} ${PREPOP_DIR} mkdir -p ${ARTIFACTS} ${PREPOP_DIR}
if [ "$(docker info | grep 'Storage Driver: ' | sed 's/Storage Driver: //')" != "overlay" ]; then #if [ "$(docker info | grep 'Storage Driver: ' | sed 's/Storage Driver: //')" != "overlay" ]; then
echo Overlay storage driver is require to prepackage exploded images echo Overlay storage driver is require to prepackage exploded images
echo packaging images.tar instead echo packaging images.tar instead
tar czf ${ARTIFACTS}/rootfs.tar.gz --exclude lib/modules --exclude lib/firmware -C ${INITRD_DIR} . tar czf ${ARTIFACTS}/rootfs.tar.gz --exclude lib/modules --exclude lib/firmware -C ${INITRD_DIR} .
exit 0 exit 0
fi #fi
DFS=$(docker run -d --privileged -v /lib/modules/$(uname -r):/lib/modules/$(uname -r) ${DFS_IMAGE}${SUFFIX} ${DFS_ARGS}) 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 trap "docker rm -fv ${DFS_ARCH} ${DFS}" EXIT
docker exec -i ${DFS} docker load < ${INITRD_DIR}/usr/share/ros/images.tar docker exec -i ${DFS} docker load < ${INITRD_DIR}/usr/share/ros/images.tar
docker stop ${DFS} 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} busybox 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 ./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 -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} . tar -rf ${ARTIFACTS}/rootfs.tar -C ${IMAGE_CACHE} .

View 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

View File

@@ -7,6 +7,6 @@ func (s *QemuSuite) TestKernelHeaders(c *C) {
c.Assert(err, IsNil) c.Assert(err, IsNil)
s.CheckCall(c, ` s.CheckCall(c, `
sleep 10 sleep 15
docker inspect kernel-headers`) docker inspect kernel-headers`)
} }

13
tests/write_files_test.go Normal file
View 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'")
}