Merge pull request #37 from pterodactyl/server-environment-tweaks
Tweaks to Server Environment
This commit is contained in:
commit
fe531e400d
|
@ -39,6 +39,9 @@ type DockerConfiguration struct {
|
|||
// for containers run through the daemon.
|
||||
Network DockerNetworkConfiguration `json:"network" yaml:"network"`
|
||||
|
||||
// Domainname is the Docker domainname for all containers.
|
||||
Domainname string `default:"" json:"domainname" yaml:"domainname"`
|
||||
|
||||
// If true, container images will be updated when a server starts if there
|
||||
// is an update available. If false the daemon will not attempt updates and will
|
||||
// defer to the host system to manage image updates.
|
||||
|
|
|
@ -94,9 +94,7 @@ func (d *DockerEnvironment) Exists() (bool, error) {
|
|||
//
|
||||
// @see docker/client/errors.go
|
||||
func (d *DockerEnvironment) IsRunning() (bool, error) {
|
||||
ctx := context.Background()
|
||||
|
||||
c, err := d.Client.ContainerInspect(ctx, d.Server.Uuid)
|
||||
c, err := d.Client.ContainerInspect(context.Background(), d.Server.Uuid)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
@ -122,12 +120,14 @@ func (d *DockerEnvironment) InSituUpdate() error {
|
|||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
ctx, _ := context.WithTimeout(context.Background(), time.Second * 10)
|
||||
u := container.UpdateConfig{
|
||||
Resources: d.getResourcesForServer(),
|
||||
}
|
||||
|
||||
d.Server.Log().WithField("limits", fmt.Sprintf("%+v", u.Resources)).Debug("updating server container on-the-fly with passed limits")
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
|
||||
defer cancel()
|
||||
if _, err := d.Client.ContainerUpdate(ctx, d.Server.Uuid, u); err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
@ -254,7 +254,8 @@ func (d *DockerEnvironment) Start() error {
|
|||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
ctx, _ := context.WithTimeout(context.Background(), time.Second * 10)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
|
||||
defer cancel()
|
||||
if err := d.Client.ContainerStart(ctx, d.Server.Uuid, types.ContainerStartOptions{}); err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
@ -323,9 +324,7 @@ func (d *DockerEnvironment) WaitForStop(seconds int, terminate bool) error {
|
|||
|
||||
// Forcefully terminates the container using the signal passed through.
|
||||
func (d *DockerEnvironment) Terminate(signal os.Signal) error {
|
||||
ctx := context.Background()
|
||||
|
||||
c, err := d.Client.ContainerInspect(ctx, d.Server.Uuid)
|
||||
c, err := d.Client.ContainerInspect(context.Background(), d.Server.Uuid)
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
@ -337,19 +336,17 @@ func (d *DockerEnvironment) Terminate(signal os.Signal) error {
|
|||
d.Server.SetState(ProcessStoppingState)
|
||||
|
||||
return d.Client.ContainerKill(
|
||||
ctx, d.Server.Uuid, strings.TrimSuffix(strings.TrimPrefix(signal.String(), "signal "), "ed"),
|
||||
context.Background(), d.Server.Uuid, strings.TrimSuffix(strings.TrimPrefix(signal.String(), "signal "), "ed"),
|
||||
)
|
||||
}
|
||||
|
||||
// Remove the Docker container from the machine. If the container is currently running
|
||||
// it will be forcibly stopped by Docker.
|
||||
func (d *DockerEnvironment) Destroy() error {
|
||||
ctx := context.Background()
|
||||
|
||||
// Avoid crash detection firing off.
|
||||
d.Server.SetState(ProcessStoppingState)
|
||||
|
||||
err := d.Client.ContainerRemove(ctx, d.Server.Uuid, types.ContainerRemoveOptions{
|
||||
err := d.Client.ContainerRemove(context.Background(), d.Server.Uuid, types.ContainerRemoveOptions{
|
||||
RemoveVolumes: true,
|
||||
RemoveLinks: false,
|
||||
Force: true,
|
||||
|
@ -403,10 +400,8 @@ func (d *DockerEnvironment) Attach() error {
|
|||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
var err error
|
||||
d.stream, err = d.Client.ContainerAttach(ctx, d.Server.Uuid, types.ContainerAttachOptions{
|
||||
d.stream, err = d.Client.ContainerAttach(context.Background(), d.Server.Uuid, types.ContainerAttachOptions{
|
||||
Stdin: true,
|
||||
Stdout: true,
|
||||
Stderr: true,
|
||||
|
@ -453,7 +448,6 @@ func (d *DockerEnvironment) FollowConsoleOutput() error {
|
|||
return errors.New(fmt.Sprintf("no such container: %s", d.Server.Uuid))
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
opts := types.ContainerLogsOptions{
|
||||
ShowStderr: true,
|
||||
ShowStdout: true,
|
||||
|
@ -461,7 +455,7 @@ func (d *DockerEnvironment) FollowConsoleOutput() error {
|
|||
Since: time.Now().Format(time.RFC3339),
|
||||
}
|
||||
|
||||
reader, err := d.Client.ContainerLogs(ctx, d.Server.Uuid, opts)
|
||||
reader, err := d.Client.ContainerLogs(context.Background(), d.Server.Uuid, opts)
|
||||
|
||||
go func(r io.ReadCloser) {
|
||||
defer r.Close()
|
||||
|
@ -487,9 +481,7 @@ func (d *DockerEnvironment) EnableResourcePolling() error {
|
|||
return errors.New("cannot enable resource polling on a server that is not running")
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
stats, err := d.Client.ContainerStats(ctx, d.Server.Uuid, true)
|
||||
stats, err := d.Client.ContainerStats(context.Background(), d.Server.Uuid, true)
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
@ -563,15 +555,16 @@ func (d *DockerEnvironment) DisableResourcePolling() error {
|
|||
// correctly if anything.
|
||||
//
|
||||
// @todo handle authorization & local images
|
||||
func (d *DockerEnvironment) ensureImageExists(c *client.Client) error {
|
||||
func (d *DockerEnvironment) ensureImageExists() error {
|
||||
// Give it up to 15 minutes to pull the image. I think this should cover 99.8% of cases where an
|
||||
// image pull might fail. I can't imagine it will ever take more than 15 minutes to fully pull
|
||||
// an image. Let me know when I am inevitably wrong here...
|
||||
ctx, _ := context.WithTimeout(context.Background(), time.Minute*15)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Minute*15)
|
||||
defer cancel()
|
||||
|
||||
out, err := c.ImagePull(ctx, d.Server.Container.Image, types.ImagePullOptions{All: false})
|
||||
out, err := d.Client.ImagePull(ctx, d.Server.Container.Image, types.ImagePullOptions{All: false})
|
||||
if err != nil {
|
||||
images, ierr := c.ImageList(ctx, types.ImageListOptions{})
|
||||
images, ierr := d.Client.ImageList(ctx, types.ImageListOptions{})
|
||||
if ierr != nil {
|
||||
// Well damn, something has gone really wrong here, just go ahead and abort there
|
||||
// isn't much anything we can do to try and self-recover from this.
|
||||
|
@ -580,16 +573,18 @@ func (d *DockerEnvironment) ensureImageExists(c *client.Client) error {
|
|||
|
||||
for _, img := range images {
|
||||
for _, t := range img.RepoTags {
|
||||
if t == d.Server.Container.Image {
|
||||
d.Server.Log().WithFields(log.Fields{
|
||||
"image": d.Server.Container.Image,
|
||||
"error": errors.New(err.Error()),
|
||||
}).Warn("unable to pull requested image from remote source, however the image exists locally")
|
||||
|
||||
// Okay, we found a matching container image, in that case just go ahead and return
|
||||
// from this function, since there is nothing else we need to do here.
|
||||
return nil
|
||||
if t != d.Server.Container.Image {
|
||||
continue
|
||||
}
|
||||
|
||||
d.Server.Log().WithFields(log.Fields{
|
||||
"image": d.Server.Container.Image,
|
||||
"error": errors.New(err.Error()),
|
||||
}).Warn("unable to pull requested image from remote source, however the image exists locally")
|
||||
|
||||
// Okay, we found a matching container image, in that case just go ahead and return
|
||||
// from this function, since there is nothing else we need to do here.
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -616,12 +611,6 @@ func (d *DockerEnvironment) ensureImageExists(c *client.Client) error {
|
|||
// Creates a new container for the server using all of the data that is currently
|
||||
// available for it. If the container already exists it will be returned.
|
||||
func (d *DockerEnvironment) Create() error {
|
||||
ctx := context.Background()
|
||||
cli, err := client.NewClientWithOpts(client.FromEnv)
|
||||
if err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
// Ensure the data directory exists before getting too far through this process.
|
||||
if err := d.Server.Filesystem.EnsureDataDirectory(); err != nil {
|
||||
return errors.WithStack(err)
|
||||
|
@ -630,19 +619,20 @@ func (d *DockerEnvironment) Create() error {
|
|||
// If the container already exists don't hit the user with an error, just return
|
||||
// the current information about it which is what we would do when creating the
|
||||
// container anyways.
|
||||
if _, err := cli.ContainerInspect(ctx, d.Server.Uuid); err == nil {
|
||||
if _, err := d.Client.ContainerInspect(context.Background(), d.Server.Uuid); err == nil {
|
||||
return nil
|
||||
} else if !client.IsErrNotFound(err) {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
// Try to pull the requested image before creating the container.
|
||||
if err := d.ensureImageExists(cli); err != nil {
|
||||
if err := d.ensureImageExists(); err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
conf := &container.Config{
|
||||
Hostname: "container",
|
||||
Hostname: d.Server.Uuid,
|
||||
Domainname: config.Get().Docker.Domainname,
|
||||
User: strconv.Itoa(config.Get().System.User.Uid),
|
||||
AttachStdin: true,
|
||||
AttachStdout: true,
|
||||
|
@ -708,7 +698,7 @@ func (d *DockerEnvironment) Create() error {
|
|||
NetworkMode: container.NetworkMode(config.Get().Docker.Network.Mode),
|
||||
}
|
||||
|
||||
if _, err := cli.ContainerCreate(ctx, conf, hostConf, nil, d.Server.Uuid); err != nil {
|
||||
if _, err := d.Client.ContainerCreate(context.Background(), conf, hostConf, nil, d.Server.Uuid); err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
|
@ -730,9 +720,7 @@ func (d *DockerEnvironment) SendCommand(c string) error {
|
|||
// Reads the log file for the server. This does not care if the server is running or not, it will
|
||||
// simply try to read the last X bytes of the file and return them.
|
||||
func (d *DockerEnvironment) Readlog(len int64) ([]string, error) {
|
||||
ctx := context.Background()
|
||||
|
||||
j, err := d.Client.ContainerInspect(ctx, d.Server.Uuid)
|
||||
j, err := d.Client.ContainerInspect(context.Background(), d.Server.Uuid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user