General code cleanup

This commit is contained in:
Dane Everitt 2019-12-24 16:40:51 -08:00
parent d9ceb9601d
commit 32e389db21
No known key found for this signature in database
GPG Key ID: EEA66103B3D71F53
3 changed files with 49 additions and 78 deletions

View File

@ -14,6 +14,7 @@ import (
"github.com/docker/go-connections/nat" "github.com/docker/go-connections/nat"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/pterodactyl/wings/api" "github.com/pterodactyl/wings/api"
"github.com/pterodactyl/wings/config"
"go.uber.org/zap" "go.uber.org/zap"
"io" "io"
"os" "os"
@ -26,13 +27,6 @@ import (
type DockerEnvironment struct { type DockerEnvironment struct {
Server *Server Server *Server
// The user ID that containers should be running as.
User int
// Defines the configuration for the Docker instance that will allow us to connect
// and create and modify containers.
TimezonePath string
// The Docker client being used for this instance. // The Docker client being used for this instance.
Client *client.Client Client *client.Client
@ -51,22 +45,18 @@ type DockerEnvironment struct {
} }
// Creates a new base Docker environment. A server must still be attached to it. // Creates a new base Docker environment. A server must still be attached to it.
func NewDockerEnvironment(opts ...func(*DockerEnvironment)) (*DockerEnvironment, error) { func NewDockerEnvironment(server *Server) error {
cli, err := client.NewClientWithOpts(client.FromEnv) cli, err := client.NewClientWithOpts(client.FromEnv)
if err != nil { if err != nil {
return nil, err return err
} }
env := &DockerEnvironment{ server.Environment = &DockerEnvironment{
User: 1000, Server: server,
Client: cli, Client: cli,
} }
for _, opt := range opts { return nil
opt(env)
}
return env, nil
} }
// Ensure that the Docker environment is always implementing all of the methods // Ensure that the Docker environment is always implementing all of the methods
@ -210,11 +200,8 @@ func (d *DockerEnvironment) Start() error {
// No reason to try starting a container that is already running. // No reason to try starting a container that is already running.
if c.State.Running { if c.State.Running {
d.Server.SetState(ProcessRunningState) d.Server.SetState(ProcessRunningState)
if !d.attached {
return d.Attach()
}
return nil return d.Attach()
} }
d.Server.SetState(ProcessStartingState) d.Server.SetState(ProcessStartingState)
@ -259,6 +246,8 @@ func (d *DockerEnvironment) Start() error {
// No errors, good to continue through. // No errors, good to continue through.
sawError = false sawError = false
zap.S().Debugw("right before start attach")
return d.Attach() return d.Attach()
} }
@ -354,8 +343,12 @@ func (d *DockerEnvironment) Attach() error {
Server: d.Server, Server: d.Server,
} }
d.EnableResourcePolling()
d.attached = true d.attached = true
go func() {
if err := d.EnableResourcePolling(); err != nil {
zap.S().Warnw("failed to enabled resource polling on server", zap.String("server", d.Server.Uuid), zap.Error(errors.WithStack(err)))
}
}()
go func() { go func() {
defer d.stream.Close() defer d.stream.Close()
@ -430,7 +423,10 @@ func (d *DockerEnvironment) EnableResourcePolling() error {
var v *types.StatsJSON var v *types.StatsJSON
if err := dec.Decode(&v); err != nil { if err := dec.Decode(&v); err != nil {
if err != io.EOF {
zap.S().Warnw("encountered error processing server stats; stopping collection", zap.Error(err)) zap.S().Warnw("encountered error processing server stats; stopping collection", zap.Error(err))
}
d.DisableResourcePolling() d.DisableResourcePolling()
return return
} }
@ -537,7 +533,7 @@ func (d *DockerEnvironment) Create() error {
conf := &container.Config{ conf := &container.Config{
Hostname: "container", Hostname: "container",
User: strconv.Itoa(d.User), User: strconv.Itoa(config.Get().System.User.Uid),
AttachStdin: true, AttachStdin: true,
AttachStdout: true, AttachStdout: true,
AttachStderr: true, AttachStderr: true,
@ -569,8 +565,8 @@ func (d *DockerEnvironment) Create() error {
ReadOnly: false, ReadOnly: false,
}, },
{ {
Target: d.TimezonePath, Target: config.Get().System.TimezonePath,
Source: d.TimezonePath, Source: config.Get().System.TimezonePath,
Type: mount.TypeBind, Type: mount.TypeBind,
ReadOnly: true, ReadOnly: true,
}, },

View File

@ -221,23 +221,13 @@ func FromConfiguration(data []byte, cfg *config.SystemConfiguration) (*Server, e
s.AddEventListeners() s.AddEventListeners()
withConfiguration := func(e *DockerEnvironment) {
e.User = cfg.User.Uid
e.TimezonePath = cfg.TimezonePath
e.Server = s
}
// Right now we only support a Docker based environment, so I'm going to hard code // Right now we only support a Docker based environment, so I'm going to hard code
// this logic in. When we're ready to support other environment we'll need to make // this logic in. When we're ready to support other environment we'll need to make
// some modifications here obviously. // some modifications here obviously.
var env Environment if err := NewDockerEnvironment(s); err != nil {
if t, err := NewDockerEnvironment(withConfiguration); err == nil {
env = t
} else {
return nil, err return nil, err
} }
s.Environment = env
s.Cache = cache.New(time.Minute*10, time.Minute*15) s.Cache = cache.New(time.Minute*10, time.Minute*15)
s.Filesystem = Filesystem{ s.Filesystem = Filesystem{
Configuration: cfg, Configuration: cfg,
@ -337,7 +327,7 @@ func (s *Server) SetState(state string) error {
} }
}(s) }(s)
zap.S().Debugw("saw server status change event", zap.String("server", s.Uuid), zap.String("status", state)) zap.S().Debugw("saw server status change event", zap.String("server", s.Uuid), zap.String("status", s.State))
// Emit the event to any listeners that are currently registered. // Emit the event to any listeners that are currently registered.
s.Emit(StatusEvent, s.State) s.Emit(StatusEvent, s.State)

View File

@ -106,48 +106,33 @@ func main() {
zap.S().Errorw("failed to create an environment for server", zap.String("server", s.Uuid), zap.Error(err)) zap.S().Errorw("failed to create an environment for server", zap.String("server", s.Uuid), zap.Error(err))
} }
if r, err := s.Environment.IsRunning(); err != nil { r, err := s.Environment.IsRunning()
if err != nil {
zap.S().Errorw("error checking server environment status", zap.String("server", s.Uuid), zap.Error(err)) zap.S().Errorw("error checking server environment status", zap.String("server", s.Uuid), zap.Error(err))
} else if r { }
// If the server is currently running on Docker, mark the process as being in that state. // If the server is currently running on Docker, mark the process as being in that state.
// We never want to stop an instance that is currently running external from Wings since // We never want to stop an instance that is currently running external from Wings since
// that is a good way of keeping things running even if Wings gets in a very corrupted state. // that is a good way of keeping things running even if Wings gets in a very corrupted state.
//
// This will also validate that a server process is running if the last tracked state we have
// is that it was running, but we see that the container process is not currently running.
if r || (!r && (s.State == server.ProcessRunningState || s.State == server.ProcessStartingState)) {
zap.S().Infow("detected server is running, re-attaching to process", zap.String("server", s.Uuid)) zap.S().Infow("detected server is running, re-attaching to process", zap.String("server", s.Uuid))
if err := s.Sync(); err != nil {
zap.S().Errorw("failed to sync server state, cannot mark as running", zap.String("server", s.Uuid), zap.Error(errors.WithStack(err)))
} else {
s.SetState(server.ProcessRunningState)
// If we cannot attach to the environment go ahead and mark the processs as being offline.
if err := s.Environment.Attach(); err != nil {
zap.S().Warnw("error attaching to server environment", zap.String("server", s.Uuid), zap.Error(err))
s.SetState(server.ProcessOfflineState)
}
}
} else if !r {
// If the server is not in a running state right now but according to the configuration it
// should be, we want to go ahead and restart the instance.
if s.State == server.ProcessRunningState || s.State == server.ProcessStartingState {
zap.S().Infow(
"server state does not match last recorded state in configuration, starting instance now",
zap.String("server", s.Uuid),
)
if err := s.Environment.Start(); err != nil { if err := s.Environment.Start(); err != nil {
zap.S().Warnw( zap.S().Warnw(
"failed to put server instance back in running state", "failed to properly start server detected as already running",
zap.String("server", s.Uuid), zap.String("server", s.Uuid),
zap.Error(errors.WithStack(err)), zap.Error(errors.WithStack(err)),
) )
} }
} else {
if s.State == "" { return
}
// Addresses potentially invalid data in the stored file that can cause Wings to lose // Addresses potentially invalid data in the stored file that can cause Wings to lose
// track of what the actual server state is. // track of what the actual server state is.
s.SetState(server.ProcessOfflineState) s.SetState(server.ProcessOfflineState)
}
}
}
}(serv) }(serv)
} }