Show note in console when image is being pulled, show pull status to admins

This commit is contained in:
Dane Everitt 2020-09-12 21:37:48 -07:00
parent 3ee76ea2bc
commit be49e08f4f
No known key found for this signature in database
GPG Key ID: EEA66103B3D71F53
3 changed files with 42 additions and 5 deletions

View File

@ -3,6 +3,7 @@ package docker
import (
"bufio"
"context"
"encoding/json"
"fmt"
"github.com/apex/log"
"github.com/docker/docker/api/types"
@ -19,6 +20,11 @@ import (
"time"
)
type imagePullStatus struct {
Status string `json:"status"`
Progress string `json:"progress"`
}
// Attaches to the docker container itself and ensures that we can pipe data in and out
// of the process stream. This should not be used for reading console data as you *will*
// miss important output at the beginning because of the time delay with attaching to the
@ -148,7 +154,7 @@ func (e *Environment) Create() error {
// Convert 127.0.0.1 to the pterodactyl0 network interface if the environment is Docker
// so that the server operates as expected.
if v == "SERVER_IP=127.0.0.1" {
evs[i] = "SERVER_IP="+config.Get().Docker.Network.Interface
evs[i] = "SERVER_IP=" + config.Get().Docker.Network.Interface
}
}
@ -307,6 +313,9 @@ func (e *Environment) followOutput() error {
//
// TODO: local images
func (e *Environment) ensureImageExists(image string) error {
e.Events().Publish(environment.DockerImagePullStarted, "")
defer e.Events().Publish(environment.DockerImagePullCompleted, "")
// 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...
@ -374,12 +383,18 @@ func (e *Environment) ensureImageExists(image string) error {
// is done being pulled, which is what we need.
scanner := bufio.NewScanner(out)
for scanner.Scan() {
continue
s := imagePullStatus{}
fmt.Println(scanner.Text())
if err := json.Unmarshal(scanner.Bytes(), &s); err == nil {
e.Events().Publish(environment.DockerImagePullStatus, s.Status+" "+s.Progress)
}
}
if err := scanner.Err(); err != nil {
return err
}
log.WithField("image", image).Debug("completed docker image pull")
return nil
}

View File

@ -6,9 +6,12 @@ import (
)
const (
ConsoleOutputEvent = "console output"
StateChangeEvent = "state change"
ResourceEvent = "resources"
ConsoleOutputEvent = "console output"
StateChangeEvent = "state change"
ResourceEvent = "resources"
DockerImagePullStarted = "docker image pull started"
DockerImagePullStatus = "docker image pull status"
DockerImagePullCompleted = "docker image pull completed"
)
const (

View File

@ -11,6 +11,12 @@ import (
"strconv"
)
var dockerEvents = []string{
environment.DockerImagePullStatus,
environment.DockerImagePullStarted,
environment.DockerImagePullCompleted,
}
// Adds all of the internal event listeners we want to use for a server. These listeners can only be
// removed by deleting the server as they should last for the duration of the process' lifetime.
func (s *Server) StartEventListeners() {
@ -45,10 +51,23 @@ func (s *Server) StartEventListeners() {
s.emitProcUsage()
}
docker := func(e events.Event) {
if e.Topic == environment.DockerImagePullStatus {
s.Events().Publish(InstallOutputEvent, e.Data)
} else if e.Topic == environment.DockerImagePullStarted {
s.PublishConsoleOutputFromDaemon("Pulling Docker container image, this could take a few minutes to complete...")
} else {
s.PublishConsoleOutputFromDaemon("Finished pulling Docker container image")
}
}
s.Log().Info("registering event listeners: console, state, resources...")
s.Environment.Events().On(environment.ConsoleOutputEvent, &console)
s.Environment.Events().On(environment.StateChangeEvent, &state)
s.Environment.Events().On(environment.ResourceEvent, &stats)
for _, evt := range dockerEvents {
s.Environment.Events().On(evt, &docker)
}
}
var stripAnsiRegex = regexp.MustCompile("[\u001B\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[a-zA-Z\\d]*)*)?\u0007)|(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PRZcf-ntqry=><~]))")