From 06f495682cee2aa4132af14564e2e102f2b90cde Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Tue, 24 Dec 2019 16:49:08 -0800 Subject: [PATCH] When mounting timezone data, check for the path first to avoid a fatal error --- config/config.go | 2 +- server/environment_docker.go | 42 ++++++++++++++++++++++++++++-------- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/config/config.go b/config/config.go index 097908c..36c667a 100644 --- a/config/config.go +++ b/config/config.go @@ -166,7 +166,7 @@ type DockerConfiguration struct { // Defines the location of the timezone file on the host system that should // be mounted into the created containers so that they all use the same time. - TimezonePath string `yaml:"timezone_path"` + TimezonePath string `default:"/etc/localtime" yaml:"timezone_path"` } // Defines the configuration for the internal API that is exposed by the diff --git a/server/environment_docker.go b/server/environment_docker.go index b75ed41..0d4b2e3 100644 --- a/server/environment_docker.go +++ b/server/environment_docker.go @@ -554,9 +554,7 @@ func (d *DockerEnvironment) Create() error { PortBindings: d.portBindings(), // Configure the mounts for this container. First mount the server data directory - // into the container as a r/w bind. Additionally mount the host timezone data into - // the container as a readonly bind so that software running in the container uses - // the same time as the host system. + // into the container as a r/w bind. Mounts: []mount.Mount{ { Target: "/home/container", @@ -564,12 +562,6 @@ func (d *DockerEnvironment) Create() error { Type: mount.TypeBind, ReadOnly: false, }, - { - Target: config.Get().System.TimezonePath, - Source: config.Get().System.TimezonePath, - Type: mount.TypeBind, - ReadOnly: true, - }, }, // Configure the /tmp folder mapping in containers. This is necessary for some @@ -606,6 +598,14 @@ func (d *DockerEnvironment) Create() error { NetworkMode: "pterodactyl_nw", } + if err := mountTimezoneData(hostConf); err != nil { + if os.IsNotExist(err) { + zap.S().Warnw("the timezone data path configured does not exist on the system", zap.Error(errors.WithStack(err))) + } else { + zap.S().Warnw("failed to mount timezone data into container", zap.Error(errors.WithStack(err))) + } + } + if _, err := cli.ContainerCreate(ctx, conf, hostConf, nil, d.Server.Uuid); err != nil { return errors.WithStack(err) } @@ -613,6 +613,30 @@ func (d *DockerEnvironment) Create() error { return nil } +// Given a host configuration mount, also mount the timezone data into it. +func mountTimezoneData(c *container.HostConfig) error { + p := config.Get().System.TimezonePath + + // Check for the timezone file, if it exists use it assuming it isn't also a directory, + // otherwise bubble the error back up the stack. + if s, err := os.Stat(p); err != nil { + return err + } else { + if s.IsDir() { + return errors.New("attempting to mount directory as timezone file") + } + } + + c.Mounts = append(c.Mounts, mount.Mount{ + Target: p, + Source: p, + Type: mount.TypeBind, + ReadOnly: true, + }) + + return nil +} + // Sends the specified command to the stdin of the running container instance. There is no // confirmation that this data is sent successfully, only that it gets pushed into the stdin. func (d *DockerEnvironment) SendCommand(c string) error {