1
0
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:
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"
"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 {

View File

@@ -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 {

View File

@@ -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
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 {
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 {

View File

@@ -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"]

View File

@@ -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}}

View File

@@ -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} .

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)
s.CheckCall(c, `
sleep 10
sleep 15
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'")
}