diff --git a/config.go b/config.go index e35a0f4..bafbbd3 100644 --- a/config.go +++ b/config.go @@ -1,4 +1,4 @@ -package main +package wings import ( "gopkg.in/yaml.v2" diff --git a/const.go b/const.go index 4f3be8a..557014c 100644 --- a/const.go +++ b/const.go @@ -1,4 +1,4 @@ -package main +package wings import "os" diff --git a/environment/docker.go b/environment/docker.go new file mode 100644 index 0000000..3dd66e5 --- /dev/null +++ b/environment/docker.go @@ -0,0 +1,34 @@ +package environment + +import ( + "github.com/pterodactyl/wings" + "os" +) + +type Docker struct { + *Controller + + // Defines the configuration for the Docker instance that will allow us to connect + // and create and modify containers. + Configuration wings.DockerConfiguration +} + +// Ensure that the Docker environment is always implementing all of the methods +// from the base environment interface. +var _ Environment = (*Docker)(nil) + +func (d *Docker) Exists() bool { + return true +} + +func (d *Docker) Start() error { + return nil +} + +func (d *Docker) Stop() error { + return nil +} + +func (d *Docker) Terminate(signal os.Signal) error { + return nil +} diff --git a/environment/environment.go b/environment/environment.go new file mode 100644 index 0000000..fd5fb74 --- /dev/null +++ b/environment/environment.go @@ -0,0 +1,35 @@ +package environment + +import ( + "github.com/pterodactyl/wings/server" + "os" +) + +// Defines the basic interface that all environments need to implement so that +// a server can be properly controlled. +type Environment interface { + // Starts a server instance. If the server instance is not in a state where it + // can be started an error should be returned. + Start() error + + // Stops a server instance. If the server is already stopped an error should + // not be returned. + Stop() error + + // Determines if the server instance exists. For example, in a docker environment + // this should confirm that the container is created and in a bootable state. In + // a basic CLI environment this can probably just return true right away. + Exists() bool + + // Terminates a running server instance using the provided signal. If the server + // is not running no error should be returned. + Terminate(signal os.Signal) error +} + +// Defines an environment controller for a server instance. This can either be +// a docker environment where the server is running in a container, or a host +// CLI environment where it is not running in a container at all (theoretically). +type Controller struct { + // The server instance attached to this environment. + Server *server.Server +} diff --git a/server/server.go b/server/server.go new file mode 100644 index 0000000..da6cc75 --- /dev/null +++ b/server/server.go @@ -0,0 +1,94 @@ +package server + +import ( + "github.com/pterodactyl/wings" + "github.com/pterodactyl/wings/environment" + "gopkg.in/yaml.v2" +) + +// High level definition for a server instance being controlled by Wings. +type Server struct { + // The unique identifier for the server that should be used when referencing + // it aganist the Panel API (and internally). This will be used when naming + // docker containers as well as in log output. + Uuid string + + // Wether or not the server is in a suspended state. Suspended servers cannot + // be started or modified except in certain scenarios by an admin user. + Suspended bool + + // The power state of the server. + State int + + EnvVars map[string]string `yaml:"env"` + + Build *BuildSettings + Network *Allocations + + environment *environment.Environment +} + +// The build settings for a given server that impact docker container creation and +// resource limits for a server instance. +type BuildSettings struct { + // The total amount of memory in megabytes that this server is allowed to + // use on the host system. + MemoryLimit int + + // The amount of additional swap space to be provided to a container instance. + Swap int + + // The relative weight for IO operations in a container. This is relative to other + // containers on the system and should be a value between 10 and 1000. + IoWeight int + + // The percentage of CPU that this instance is allowed to consume relative to + // the host. A value of 200% represents complete utilization of two cores. This + // should be a value between 1 and THREAD_COUNT * 100. + CpuLimit int + + // The amount of disk space in megabytes that a server is allowed to use. + DiskSpace int +} + +// Defines the allocations available for a given server. When using the Docker environment +// driver these correspond to mappings for the container that allow external connections. +type Allocations struct { + // Defines the default allocation that should be used for this server. This is + // what will be used for {SERVER_IP} and {SERVER_PORT} when modifying configuration + // files or the startup arguments for a server. + DefaultMapping struct { + Ip string + Port int + } + + // Mappings contains all of the ports that should be assigned to a given server + // attached to the IP they correspond to. + Mappings map[string][]int +} + +// Initalizes a server using a data byte array. This will be marshaled into the +// given struct using a YAML marshaler. This will also configure the given environment +// for a server. +func FromConfiguration(data []byte, cfg wings.DockerConfiguration) (*Server, error) { + s := &Server{} + + if err := yaml.Unmarshal(data, s); err != nil { + return nil, err + } + + // 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 + // some modifications here obviously. + var env environment.Environment + env = &environment.Docker{ + Controller: &environment.Controller{ + Server: s, + }, + Configuration: cfg, + } + + s.environment = &env + + return s, nil +} diff --git a/utils/logger.go b/utils/logger.go deleted file mode 100644 index ade097b..0000000 --- a/utils/logger.go +++ /dev/null @@ -1,83 +0,0 @@ -package utils - -import ( - "os" - "path/filepath" - "time" - //"time" - - "github.com/pterodactyl/wings/constants" - - rotatelogs "github.com/lestrrat-go/file-rotatelogs" - "github.com/rifflock/lfshook" - log "github.com/sirupsen/logrus" - "github.com/spf13/viper" - - "github.com/pterodactyl/wings/config" -) - -// InitLogging initalizes the logging library for first use. -func InitLogging() { - log.SetFormatter(&log.TextFormatter{ - DisableTimestamp: true, - }) - - log.SetLevel(log.InfoLevel) -} - -// ConfigureLogging applies the configuration to the logging library. -func ConfigureLogging() error { - path := filepath.Clean(viper.GetString(config.LogPath)) - if err := os.MkdirAll(path, constants.DefaultFolderPerms); err != nil { - return err - } - writer, err := rotatelogs.New( - path+"/wings.%Y%m%d-%H%M.log", - rotatelogs.WithLinkName(path), - rotatelogs.WithMaxAge(time.Duration(viper.GetInt(config.LogDeleteAfterDays))*time.Hour*24), - rotatelogs.WithRotationTime(time.Hour*24), - ) - if err != nil { - return err - } - - log.AddHook(lfshook.NewHook(lfshook.WriterMap{ - log.DebugLevel: writer, - log.InfoLevel: writer, - log.WarnLevel: writer, - log.ErrorLevel: writer, - log.FatalLevel: writer, - }, &log.JSONFormatter{})) - - level := viper.GetString(config.LogLevel) - - // In debug mode the log level is always debug - if viper.GetBool(config.Debug) { - level = "debug" - } - - // Apply log level - switch level { - case "debug": - log.SetLevel(log.DebugLevel) - - case "info": - log.SetLevel(log.InfoLevel) - - case "warn": - log.SetLevel(log.WarnLevel) - - case "error": - log.SetLevel(log.ErrorLevel) - - case "fatal": - log.SetLevel(log.FatalLevel) - - case "panic": - log.SetLevel(log.PanicLevel) - } - - log.Info("Log level: " + level) - - return nil -} diff --git a/wings.go b/wings.go index 8575a60..3072d20 100644 --- a/wings.go +++ b/wings.go @@ -1,4 +1,4 @@ -package main +package wings import ( "flag"