diff --git a/config.go b/config.go index 5fcda39..4f6e054 100644 --- a/config.go +++ b/config.go @@ -1,7 +1,7 @@ package main import ( - "github.com/pterodactyl/wings/environment" + "github.com/pterodactyl/wings/server" "gopkg.in/yaml.v2" "io/ioutil" "os" @@ -16,7 +16,7 @@ type Configuration struct { Data string Api *ApiConfiguration - Docker *environment.DockerConfiguration + Docker *server.DockerConfiguration // Determines if permissions for a server should be set automatically on // daemon boot. This can take a long time on systems with many servers, or on @@ -114,7 +114,7 @@ func (c *Configuration) SetDefaults() { c.Throttles.CheckInterval = 100 // Configure the defaults for Docker connection and networks. - c.Docker = &environment.DockerConfiguration{} + c.Docker = &server.DockerConfiguration{} c.Docker.UpdateImages = true c.Docker.Socket = "/var/run/docker.sock" c.Docker.Network.Name = "pterodactyl_nw" diff --git a/environment/docker.go b/environment/docker.go deleted file mode 100644 index d600f38..0000000 --- a/environment/docker.go +++ /dev/null @@ -1,64 +0,0 @@ -package environment - -import ( - "os" -) - -// Defines the docker configuration used by the daemon when interacting with -// containers and networks on the system. -type DockerConfiguration struct { - Container struct { - User string - } - - // Network configuration that should be used when creating a new network - // for containers run through the daemon. - Network struct { - // The interface that should be used to create the network. Must not conflict - // with any other interfaces in use by Docker or on the system. - Interface string - - // The name of the network to use. If this network already exists it will not - // be created. If it is not found, a new network will be created using the interface - // defined. - Name string - } - - // 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. - UpdateImages bool `yaml:"update_images"` - - // The location of the Docker socket. - Socket string - - // Defines the location of the timezone file on the host system that should - // be mounted into the created containers so that they all use the same time. - TimezonePath string `yaml:"timezone_path"` -} - -type Docker struct { - // Defines the configuration for the Docker instance that will allow us to connect - // and create and modify containers. - Configuration 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/go.mod b/go.mod index d7c8d03..9c6b0ef 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 // indirect github.com/davecgh/go-spew v1.1.0 // indirect github.com/docker/distribution v0.0.0-20180327202408-83389a148052 // indirect - github.com/docker/docker v0.0.0-20180221001059-e3831a62a305 + github.com/docker/docker v1.13.1 github.com/docker/go-connections v0.3.0 // indirect github.com/docker/go-units v0.3.2 // indirect github.com/fsnotify/fsnotify v1.4.7 // indirect @@ -46,7 +46,7 @@ require ( go.uber.org/multierr v1.1.0 // indirect go.uber.org/zap v1.9.1 golang.org/x/crypto v0.0.0-20180330210355-12892e8c234f // indirect - golang.org/x/net v0.0.0-20180330215511-b68f30494add // indirect + golang.org/x/net v0.0.0-20180330215511-b68f30494add golang.org/x/sys v0.0.0-20180329131831-378d26f46672 // indirect golang.org/x/text v0.3.0 // indirect gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect diff --git a/go.sum b/go.sum index d5619b2..5da01a0 100644 --- a/go.sum +++ b/go.sum @@ -1,75 +1,48 @@ -github.com/Microsoft/go-winio v0.4.7 h1:vOvDiY/F1avSWlCWiKJjdYKz2jVjTK3pWPHndeG4OAY= github.com/Microsoft/go-winio v0.4.7/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= -github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/docker/distribution v0.0.0-20180327202408-83389a148052 h1:bYklS+YB8BZreSEY+/WqaH+S8upfuYf0Hq/EmNOQMIA= github.com/docker/distribution v0.0.0-20180327202408-83389a148052/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v0.0.0-20180221001059-e3831a62a305 h1:63sMUq8raJguFF7xWXYlXaSKS4NVAHrYfwVs/fL1wTY= -github.com/docker/docker v0.0.0-20180221001059-e3831a62a305/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v1.13.1 h1:IkZjBSIc8hBjLpqeAbeE5mca5mNgeatLHBy3GO78BWo= +github.com/docker/docker v1.13.1/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.3.0 h1:3lOnM9cSzgGwx8VfK/NGOW5fLQ0GjIlCkaktF+n1M6o= github.com/docker/go-connections v0.3.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.3.2 h1:Kjm80apys7gTtfVmCvVY8gwu10uofaFSrmAKOVrtueE= github.com/docker/go-units v0.3.2/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7 h1:AzN37oI0cOS+cougNAV9szl6CVoj2RYwzS3DpUQNtlY= github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= -github.com/gin-gonic/gin v0.0.0-20170702092826-d459835d2b07 h1:cZPJWzd2oNeoS0oJM2TlN9rl0OnCgUr10gC8Q4mH+6M= github.com/gin-gonic/gin v0.0.0-20170702092826-d459835d2b07/go.mod h1:7cKuhb5qV2ggCFctp2fJQ+ErvciLZrIeoOSOm6mUr7Y= -github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E= github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= -github.com/gogo/protobuf v1.0.0 h1:2jyBKDKU/8v3v2xVR2PtiWQviFUyiaGk2rpfyFT8rTM= github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/golang/protobuf v1.0.0 h1:lsek0oXi8iFE9L+EXARyHIjU5rlWIhhTkjDz3vHhWWQ= github.com/golang/protobuf v1.0.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/google/jsonapi v0.0.0-20170708005851-46d3ced04344 h1:G5TmuUtIYeR0scfa8ZQ06cfHeAAfVeFlIG8TVOCfuAA= github.com/google/jsonapi v0.0.0-20170708005851-46d3ced04344/go.mod h1:XSx4m2SziAqk9DXY9nz659easTq4q6TyrpYd9tHSm0g= -github.com/gorilla/websocket v1.2.0 h1:VJtLvh6VQym50czpZzx07z/kw9EgAxI3x1ZB8taTMQQ= github.com/gorilla/websocket v1.2.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/hashicorp/hcl v0.0.0-20180320202055-f40e974e75af h1:g6buE1uPu/jBP1YRkIqjoqBz5CraM5TukA+MmymQQXA= github.com/hashicorp/hcl v0.0.0-20180320202055-f40e974e75af/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/lestrrat-go/file-rotatelogs v2.1.0+incompatible/go.mod h1:ZQnN8lSECaebrkQytbHj4xNgtg8CR7RYXnPok8e0EHA= github.com/lestrrat/go-strftime v0.0.0-20180220042222-ba3bf9c1d042/go.mod h1:TPpsiPUEh0zFL1Snz4crhMlBe60PYxRHr5oFF3rRYg0= -github.com/magiconair/properties v1.7.6 h1:U+1DqNen04MdEPgFiIwdOUiqZ8qPa37xgogX/sd3+54= github.com/magiconair/properties v1.7.6/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/mattn/go-isatty v0.0.3 h1:ns/ykhmWi7G9O+8a448SecJU3nSMBXJfqQkl0upE1jI= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mitchellh/mapstructure v0.0.0-20180220230111-00c29f56e238 h1:+MZW2uvHgN8kYvksEN3f7eFL2wpzk0GxmlFsMybWc7E= github.com/mitchellh/mapstructure v0.0.0-20180220230111-00c29f56e238/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2iki3E3Ii+WN7gQ= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= -github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI= github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/pelletier/go-toml v1.1.0 h1:cmiOvKzEunMsAxyhXSzpL5Q1CRKpVv0KQsnAIcSEVYM= github.com/pelletier/go-toml v1.1.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/remeh/sizedwaitgroup v0.0.0-20180822144253-5e7302b12cce h1:aP+C+YbHZfOQlutA4p4soHi7rVUqHQdWEVMSkHfDTqY= github.com/remeh/sizedwaitgroup v0.0.0-20180822144253-5e7302b12cce/go.mod h1:3j2R4OIe/SeS6YDhICBy22RWjJC5eNCJ1V+9+NVNYlo= github.com/rifflock/lfshook v0.0.0-20180227222202-bf539943797a/go.mod h1:GEXHk5HgEKCvEIIrSpFI3ozzG5xOKA2DVlEX/gGnewM= -github.com/shirou/gopsutil v0.0.0-20180227225847-5776ff9c7c5d h1:TW8oufRzBs0qROjv16ll0N780gaBcgSu1TxKjwJMebM= github.com/shirou/gopsutil v0.0.0-20180227225847-5776ff9c7c5d/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= -github.com/sirupsen/logrus v1.0.5 h1:8c8b5uO0zS4X6RPl/sd1ENwSkIc0/H2PaHxE3udaE8I= github.com/sirupsen/logrus v1.0.5/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= -github.com/spf13/afero v1.0.2 h1:5bRmqmInNmNFkI9NG9O0Xc/Lgl9wOWWUUA/O8XZqTCo= github.com/spf13/afero v1.0.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/cast v1.2.0 h1:HHl1DSRbEQN2i8tJmtS6ViPyHx35+p51amrdsiTCrkg= github.com/spf13/cast v1.2.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg= github.com/spf13/cobra v0.0.2/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/jwalterweatherman v0.0.0-20180109140146-7c0cea34c8ec h1:2ZXvIUGghLpdTVHR1UfvfrzoVlZaE/yOWC5LueIHZig= github.com/spf13/jwalterweatherman v0.0.0-20180109140146-7c0cea34c8ec/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/pflag v1.0.0 h1:oaPbdDe/x0UncahuwiPxW1GYJyilRAdsPnq3e1yaPcI= github.com/spf13/pflag v1.0.0/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/viper v1.0.2 h1:Ncr3ZIuJn322w2k1qmzXDnkLAdQMlJqBa9kfAH+irso= github.com/spf13/viper v1.0.2/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM= -github.com/stretchr/testify v1.2.1 h1:52QO5WkIUcHGIR7EnGagH88x1bUzqGXTC5/1bDTUQ7U= github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/ugorji/go v0.0.0-20180112141927-9831f2c3ac10 h1:4zp+5ElNBLy5qmaDFrbVDolQSOtPmquw+W6EMNEpi+k= github.com/ugorji/go v0.0.0-20180112141927-9831f2c3ac10/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ= go.uber.org/atomic v1.3.2 h1:2Oa65PReHzfn29GpvgsYwloV9AVFHPDk8tYxt2c2tr4= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -77,17 +50,13 @@ go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/zap v1.9.1 h1:XCJQEf3W6eZaVwhRBof6ImoYGJSITeKWsyeh3HFu/5o= go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= -golang.org/x/crypto v0.0.0-20180330210355-12892e8c234f h1:EDv9U2dOjZ9sVn985FJw58XWqRwhtTnd0RxCfIzqKI8= golang.org/x/crypto v0.0.0-20180330210355-12892e8c234f/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/net v0.0.0-20180330215511-b68f30494add h1:oGr9qHpQTQvl/BmeWw95ZrQKahW4qdIPUiGfQkJYDsA= golang.org/x/net v0.0.0-20180330215511-b68f30494add/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/sys v0.0.0-20180329131831-378d26f46672 h1:P+cuqFpXzcxn8UtAwY33SZdbHLKsmjveBNV9V+RoYgQ= golang.org/x/sys v0.0.0-20180329131831-378d26f46672/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/go-playground/validator.v8 v8.18.2 h1:lFB4DoMU6B626w8ny76MV7VX6W2VHct2GVOI3xgiMrQ= gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/environment/environment.go b/server/environment.go similarity index 80% rename from environment/environment.go rename to server/environment.go index ef58dfa..1087b1d 100644 --- a/environment/environment.go +++ b/server/environment.go @@ -1,4 +1,4 @@ -package environment +package server import ( "os" @@ -23,4 +23,9 @@ type Environment interface { // 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 -} \ No newline at end of file + + // Creates the necessary environment for running the server process. For example, + // in the Docker environment create will create a new container instance for the + // server. + Create() error +} diff --git a/server/environment_docker.go b/server/environment_docker.go new file mode 100644 index 0000000..2c83385 --- /dev/null +++ b/server/environment_docker.go @@ -0,0 +1,132 @@ +package server + +import ( + "fmt" + "github.com/docker/docker/api/types/container" + "github.com/docker/docker/client" + "golang.org/x/net/context" + "os" + "strings" +) + +// Defines the docker configuration used by the daemon when interacting with +// containers and networks on the system. +type DockerConfiguration struct { + Container struct { + User string + } + + // Network configuration that should be used when creating a new network + // for containers run through the daemon. + Network struct { + // The interface that should be used to create the network. Must not conflict + // with any other interfaces in use by Docker or on the system. + Interface string + + // The name of the network to use. If this network already exists it will not + // be created. If it is not found, a new network will be created using the interface + // defined. + Name string + } + + // 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. + UpdateImages bool `yaml:"update_images"` + + // The location of the Docker socket. + Socket string + + // Defines the location of the timezone file on the host system that should + // be mounted into the created containers so that they all use the same time. + TimezonePath string `yaml:"timezone_path"` +} + +type DockerEnvironment struct { + Server *Server + + // Defines the configuration for the Docker instance that will allow us to connect + // and create and modify containers. + Configuration DockerConfiguration +} + +// Ensure that the Docker environment is always implementing all of the methods +// from the base environment interface. +var _ Environment = (*DockerEnvironment)(nil) + +func (d *DockerEnvironment) Exists() bool { + return true +} + +func (d *DockerEnvironment) Start() error { + return nil +} + +func (d *DockerEnvironment) Stop() error { + return nil +} + +func (d *DockerEnvironment) Terminate(signal os.Signal) error { + return nil +} + +// 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.NewEnvClient() + if err != nil { + return err + } + + // 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 { + return nil + } + + conf := &container.Config{ + Hostname: "container", + User: "pterodactyl", + AttachStdin: true, + AttachStdout: true, + AttachStderr: true, + Tty: true, + + Cmd: strings.Split(d.Server.Invocation, " "), + Image: d.Server.Container.Image, + Env: d.environmentVariables(), + + Labels: map[string]string{ + "Service": "Pterodactyl", + }, + } + + hostConf := &container.HostConfig{ + Resources: container.Resources{ + Memory: d.Server.Build.MemoryLimit * 1000000, + }, + } + + if _, err := cli.ContainerCreate(ctx, conf, hostConf, nil, d.Server.Uuid); err != nil { + return err + } + + return nil +} + +// Returns the environment variables for a server in KEY="VALUE" form. +func (d *DockerEnvironment) environmentVariables() []string { + var out []string + + for k, v := range d.Server.EnvVars { + out = append(out, fmt.Sprintf("%s=\"%s\"", k, v)) + } + + return out +} + +func (d *DockerEnvironment) volumes() map[string]struct{} { + return nil +} \ No newline at end of file diff --git a/server/server.go b/server/server.go index 75c0915..450f102 100644 --- a/server/server.go +++ b/server/server.go @@ -1,7 +1,6 @@ package server import ( - "github.com/pterodactyl/wings/environment" "github.com/remeh/sizedwaitgroup" "go.uber.org/zap" "gopkg.in/yaml.v2" @@ -35,7 +34,12 @@ type Server struct { Build *BuildSettings Allocations *Allocations - environment *environment.Environment + Container struct { + // Defines the Docker image that will be used for this server + Image string + } + + environment Environment } // The build settings for a given server that impact docker container creation and @@ -43,22 +47,22 @@ type Server struct { type BuildSettings struct { // The total amount of memory in megabytes that this server is allowed to // use on the host system. - MemoryLimit int `yaml:"memory"` + MemoryLimit int64 `yaml:"memory"` // The amount of additional swap space to be provided to a container instance. - Swap int + Swap int64 // 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 `yaml:"io"` + IoWeight int64 `yaml:"io"` // 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 `yaml:"cpu"` + CpuLimit int64 `yaml:"cpu"` // The amount of disk space in megabytes that a server is allowed to use. - DiskSpace int `yaml:"disk"` + DiskSpace int64 `yaml:"disk"` } // Defines the allocations available for a given server. When using the Docker environment @@ -79,7 +83,7 @@ type Allocations struct { // Iterates over a given directory and loads all of the servers listed before returning // them to the calling function. -func LoadDirectory(dir string, cfg environment.DockerConfiguration) ([]*Server, error) { +func LoadDirectory(dir string, cfg DockerConfiguration) ([]*Server, error) { // We could theoretically use a standard wait group here, however doing // that introduces the potential to crash the program due to too many // open files. This wouldn't happen on a small setup, but once the daemon is @@ -134,7 +138,7 @@ func LoadDirectory(dir string, cfg environment.DockerConfiguration) ([]*Server, // 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 environment.DockerConfiguration) (*Server, error) { +func FromConfiguration(data []byte, cfg DockerConfiguration) (*Server, error) { s := &Server{} if err := yaml.Unmarshal(data, s); err != nil { @@ -144,12 +148,25 @@ func FromConfiguration(data []byte, cfg environment.DockerConfiguration) (*Serve // 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{ + var env Environment + env = &DockerEnvironment{ + Server: s, Configuration: cfg, } - s.environment = &env + s.environment = env return s, nil } + +// Determine if the server is bootable in it's current state or not. This will not +// indicate why a server is not bootable, only if it is. +func (s *Server) IsBootable() bool { + return s.environment.Exists() +} + +// Initalizes a server instance. This will run through and ensure that the environment +// for the server is setup, and that all of the necessary files are created. +func (s *Server) CreateEnvironment() error { + return s.environment.Create() +} diff --git a/wings.go b/wings.go index 3d10fc2..514215e 100644 --- a/wings.go +++ b/wings.go @@ -44,6 +44,11 @@ func main() { for _, s := range servers { zap.S().Infow("loaded configuration for server", zap.String("server", s.Uuid)) + zap.S().Infow("ensuring envrionment exists", zap.String("server", s.Uuid)) + + if err := s.CreateEnvironment(); err != nil { + zap.S().Errorw("failed to create an environment for server", zap.String("server", s.Uuid), zap.Error(err)) + } } }