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 ( import (
"bufio" "bufio"
"context" "context"
"encoding/json"
"fmt" "fmt"
"github.com/apex/log" "github.com/apex/log"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
@ -19,6 +20,11 @@ import (
"time" "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 // 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* // 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 // 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 // Convert 127.0.0.1 to the pterodactyl0 network interface if the environment is Docker
// so that the server operates as expected. // so that the server operates as expected.
if v == "SERVER_IP=127.0.0.1" { 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 // TODO: local images
func (e *Environment) ensureImageExists(image string) error { 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 // 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 // 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... // 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. // is done being pulled, which is what we need.
scanner := bufio.NewScanner(out) scanner := bufio.NewScanner(out)
for scanner.Scan() { 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 { if err := scanner.Err(); err != nil {
return err return err
} }
log.WithField("image", image).Debug("completed docker image pull")
return nil return nil
} }

View File

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

View File

@ -11,6 +11,12 @@ import (
"strconv" "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 // 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. // removed by deleting the server as they should last for the duration of the process' lifetime.
func (s *Server) StartEventListeners() { func (s *Server) StartEventListeners() {
@ -45,10 +51,23 @@ func (s *Server) StartEventListeners() {
s.emitProcUsage() 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.Log().Info("registering event listeners: console, state, resources...")
s.Environment.Events().On(environment.ConsoleOutputEvent, &console) s.Environment.Events().On(environment.ConsoleOutputEvent, &console)
s.Environment.Events().On(environment.StateChangeEvent, &state) s.Environment.Events().On(environment.StateChangeEvent, &state)
s.Environment.Events().On(environment.ResourceEvent, &stats) 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=><~]))") var stripAnsiRegex = regexp.MustCompile("[\u001B\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[a-zA-Z\\d]*)*)?\u0007)|(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PRZcf-ntqry=><~]))")