|
|
@@ -12,13 +12,12 @@ import (
|
|
|
"time"
|
|
|
|
|
|
"github.com/docker/docker/api/types"
|
|
|
- "github.com/docker/docker/client"
|
|
|
"github.com/docker/docker/api/types/container"
|
|
|
-
|
|
|
+ "github.com/docker/docker/client"
|
|
|
)
|
|
|
|
|
|
var (
|
|
|
- logger = slog.New(slog.NewJSONHandler(os.Stdout, nil))
|
|
|
+ logger = slog.New(slog.NewJSONHandler(os.Stdout, nil))
|
|
|
EventBus = make(chan structs.Event, 100)
|
|
|
)
|
|
|
|
|
|
@@ -111,21 +110,22 @@ func GetContainerStats(containerName string) (structs.ContainerStats, error) {
|
|
|
|
|
|
// start a container by name + tag
|
|
|
// not for booting new ships
|
|
|
-func StartContainer(containerName string, containerType string) error {
|
|
|
+func StartContainer(containerName string, containerType string) (structs.ContainerState, error) {
|
|
|
+ var containerState ContainerState
|
|
|
ctx := context.Background()
|
|
|
cli, err := client.NewClientWithOpts(client.FromEnv)
|
|
|
if err != nil {
|
|
|
- return err
|
|
|
+ return containerState, err
|
|
|
}
|
|
|
// get the desired tag and hash from config
|
|
|
- containerInfo, err := getLatestContainerInfo(containerType)
|
|
|
+ containerInfo, err := GetLatestContainerInfo(containerType)
|
|
|
if err != nil {
|
|
|
- return err
|
|
|
+ return containerState, err
|
|
|
}
|
|
|
// check if container exists
|
|
|
containers, err := cli.ContainerList(ctx, types.ContainerListOptions{All: true})
|
|
|
if err != nil {
|
|
|
- return err
|
|
|
+ return containerState, err
|
|
|
}
|
|
|
var existingContainer *types.Container = nil
|
|
|
for _, container := range containers {
|
|
|
@@ -144,12 +144,12 @@ func StartContainer(containerName string, containerType string) error {
|
|
|
desiredRepo := containerInfo["repo"]
|
|
|
if desiredTag == "" || desiredHash == "" {
|
|
|
err = fmt.Errorf("Version info has not been retrieved!")
|
|
|
- return err
|
|
|
+ return containerState, err
|
|
|
}
|
|
|
// check if the desired image is available locally
|
|
|
images, err := cli.ImageList(ctx, types.ImageListOptions{})
|
|
|
if err != nil {
|
|
|
- return err
|
|
|
+ return containerState, err
|
|
|
}
|
|
|
imageExistsLocally := false
|
|
|
for _, img := range images {
|
|
|
@@ -167,7 +167,7 @@ func StartContainer(containerName string, containerType string) error {
|
|
|
// pull the image if it doesn't exist locally
|
|
|
_, err = cli.ImagePull(ctx, desiredRepo+":"+desiredTag, types.ImagePullOptions{})
|
|
|
if err != nil {
|
|
|
- return err
|
|
|
+ return containerState, err
|
|
|
}
|
|
|
}
|
|
|
switch {
|
|
|
@@ -177,11 +177,11 @@ func StartContainer(containerName string, containerType string) error {
|
|
|
Image: containerType + ":" + desiredTag,
|
|
|
}, nil, nil, nil, containerName)
|
|
|
if err != nil {
|
|
|
- return err
|
|
|
+ return containerState, err
|
|
|
}
|
|
|
err = cli.ContainerStart(ctx, containerName, types.ContainerStartOptions{})
|
|
|
if err != nil {
|
|
|
- return err
|
|
|
+ return containerState, err
|
|
|
}
|
|
|
msg := fmt.Sprintf("%s started with image %s:%s", containerName, containerType, desiredTag)
|
|
|
logger.Info(msg)
|
|
|
@@ -189,7 +189,7 @@ func StartContainer(containerName string, containerType string) error {
|
|
|
// if the container exists but is stopped, start it
|
|
|
err := cli.ContainerStart(ctx, containerName, types.ContainerStartOptions{})
|
|
|
if err != nil {
|
|
|
- return err
|
|
|
+ return containerState, err
|
|
|
}
|
|
|
msg := fmt.Sprintf("Started stopped container %s", containerName)
|
|
|
logger.Info(msg)
|
|
|
@@ -201,17 +201,17 @@ func StartContainer(containerName string, containerType string) error {
|
|
|
// if the tags don't match, recreate the container with the new tag
|
|
|
err := cli.ContainerRemove(ctx, containerName, types.ContainerRemoveOptions{Force: true})
|
|
|
if err != nil {
|
|
|
- return err
|
|
|
+ return containerState, err
|
|
|
}
|
|
|
_, err = cli.ContainerCreate(ctx, &container.Config{
|
|
|
Image: containerType + ":" + desiredTag,
|
|
|
}, nil, nil, nil, containerName)
|
|
|
if err != nil {
|
|
|
- return err
|
|
|
+ return containerState, err
|
|
|
}
|
|
|
err = cli.ContainerStart(ctx, containerName, types.ContainerStartOptions{})
|
|
|
if err != nil {
|
|
|
- return err
|
|
|
+ return containerState, err
|
|
|
}
|
|
|
msg := fmt.Sprintf("Restarted %s with image %s:%s", containerName, containerType, desiredTag)
|
|
|
logger.Info(msg)
|
|
|
@@ -220,12 +220,23 @@ func StartContainer(containerName string, containerType string) error {
|
|
|
logger.Info(msg)
|
|
|
}
|
|
|
}
|
|
|
- return nil
|
|
|
+ containerDetails, err := cli.ContainerInspect(ctx, containerName)
|
|
|
+ if err != nil {
|
|
|
+ return containerState, fmt.Errorf("failed to inspect container %s: %v", containerName, err)
|
|
|
+ }
|
|
|
+ containerState = ContainerState{
|
|
|
+ ID: containerDetails.ID,
|
|
|
+ Name: containerName,
|
|
|
+ Image: fmt.Sprintf("%s:%s@sha256:%s", containerDetails.Config.Image, desiredTag, desiredHash),
|
|
|
+ Status: containerDetails.State.Status,
|
|
|
+ CreatedAt: containerDetails.Created,
|
|
|
+ }
|
|
|
+ return containerState, err
|
|
|
}
|
|
|
|
|
|
// convert the version info back into json then a map lol
|
|
|
// so we can easily get the correct repo/release channel/tag/hash
|
|
|
-func getLatestContainerInfo(containerType string) (map[string]string, error) {
|
|
|
+func GetLatestContainerInfo(containerType string) (map[string]string, error) {
|
|
|
var res map[string]string
|
|
|
conf := config.Conf()
|
|
|
releaseChannel := conf.UpdateBranch
|
|
|
@@ -331,4 +342,4 @@ func DockerPoller() {
|
|
|
return
|
|
|
}
|
|
|
}
|
|
|
-}
|
|
|
+}
|