|
|
@@ -8,9 +8,12 @@ import (
|
|
|
"goseg/structs"
|
|
|
"log/slog"
|
|
|
"os"
|
|
|
+ "strings"
|
|
|
|
|
|
"github.com/docker/docker/api/types"
|
|
|
"github.com/docker/docker/client"
|
|
|
+ "github.com/docker/docker/api/types/container"
|
|
|
+
|
|
|
)
|
|
|
|
|
|
var (
|
|
|
@@ -106,28 +109,42 @@ func GetContainerStats(containerName string) (structs.ContainerStats, error) {
|
|
|
|
|
|
// start a container by name + tag
|
|
|
// not for booting new ships
|
|
|
-func StartContainer(containerName, containerType string) error {
|
|
|
+func StartContainer(containerName string, containerType string) error {
|
|
|
ctx := context.Background()
|
|
|
cli, err := client.NewClientWithOpts(client.FromEnv)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
- // Placeholder: Get the desired tag and hash from your config
|
|
|
- containerInfo, err := getCurrentContainerInfo()
|
|
|
+ // get the desired tag and hash from config
|
|
|
+ containerInfo, err := getCurrentContainerInfo(containerType)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ // check if container exists
|
|
|
+ containers, err := cli.ContainerList(ctx, types.ContainerListOptions{All: true})
|
|
|
if err != nil {
|
|
|
- errMsg := fmt.Errorf("Couldn't get %s container info: %v", containerName, err)
|
|
|
- logger.Error(errMsg)
|
|
|
return err
|
|
|
}
|
|
|
+ var existingContainer *types.Container = nil
|
|
|
+ for _, container := range containers {
|
|
|
+ for _, name := range container.Names {
|
|
|
+ if name == "/"+containerName {
|
|
|
+ existingContainer = &container
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if existingContainer != nil {
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
desiredTag := containerInfo["tag"]
|
|
|
desiredHash := containerInfo["hash"]
|
|
|
desiredRepo := containerInfo["repo"]
|
|
|
if desiredTag == "" || desiredHash == "" {
|
|
|
err = fmt.Errorf("Version info has not been retrieved!")
|
|
|
- logger.Error(err)
|
|
|
return err
|
|
|
}
|
|
|
- // Check if the desired image is available locally
|
|
|
+ // check if the desired image is available locally
|
|
|
images, err := cli.ImageList(ctx, types.ImageListOptions{})
|
|
|
if err != nil {
|
|
|
return err
|
|
|
@@ -155,7 +172,7 @@ func StartContainer(containerName, containerType string) error {
|
|
|
case existingContainer == nil:
|
|
|
// if the container does not exist, create and start it
|
|
|
_, err := cli.ContainerCreate(ctx, &container.Config{
|
|
|
- Image: containerType + ":" + containerTag,
|
|
|
+ Image: containerType + ":" + desiredTag,
|
|
|
}, nil, nil, nil, containerName)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
@@ -164,7 +181,7 @@ func StartContainer(containerName, containerType string) error {
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
- msg := fmt.Sprintf("%s started with image %s:%s", containerName, containerType, containerTag)
|
|
|
+ msg := fmt.Sprintf("%s started with image %s:%s", containerName, containerType, desiredTag)
|
|
|
logger.Info(msg)
|
|
|
case existingContainer.State == "exited":
|
|
|
// if the container exists but is stopped, start it
|
|
|
@@ -178,14 +195,14 @@ func StartContainer(containerName, containerType string) error {
|
|
|
// if container is running, check the image tag
|
|
|
currentImage := existingContainer.Image
|
|
|
currentTag := strings.Split(currentImage, ":")[1]
|
|
|
- if currentTag != containerTag {
|
|
|
+ if currentTag != desiredTag {
|
|
|
// 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
|
|
|
}
|
|
|
_, err = cli.ContainerCreate(ctx, &container.Config{
|
|
|
- Image: containerType + ":" + containerTag,
|
|
|
+ Image: containerType + ":" + desiredTag,
|
|
|
}, nil, nil, nil, containerName)
|
|
|
if err != nil {
|
|
|
return err
|
|
|
@@ -194,10 +211,10 @@ func StartContainer(containerName, containerType string) error {
|
|
|
if err != nil {
|
|
|
return err
|
|
|
}
|
|
|
- msg := fmt.Sprintf("Restarted %s with image %s:%s", containerName, containerType, containerTag)
|
|
|
+ msg := fmt.Sprintf("Restarted %s with image %s:%s", containerName, containerType, desiredTag)
|
|
|
logger.Info(msg)
|
|
|
} else {
|
|
|
- msg := fmt.Sprintf("%s is already running with the correct tag: %s", containerName, containerTag)
|
|
|
+ msg := fmt.Sprintf("%s is already running with the correct tag: %s", containerName, desiredTag)
|
|
|
logger.Info(msg)
|
|
|
}
|
|
|
}
|
|
|
@@ -213,7 +230,7 @@ func getCurrentContainerInfo(containerType string) (map[string]string, error) {
|
|
|
arch := config.Architecture
|
|
|
hashLabel := arch + "_sha256"
|
|
|
versionInfo := config.VersionInfo
|
|
|
- jsonData, err := json.Marshal(VersionInfo)
|
|
|
+ jsonData, err := json.Marshal(versionInfo)
|
|
|
if err != nil {
|
|
|
return res, err
|
|
|
}
|
|
|
@@ -223,8 +240,21 @@ func getCurrentContainerInfo(containerType string) (map[string]string, error) {
|
|
|
if err != nil {
|
|
|
return res, err
|
|
|
}
|
|
|
- res["tag"] = m["groundseg"][releaseChannel][containerType]["tag"]
|
|
|
- res["hash"] = m["groundseg"][releaseChannel][containerType][hashLabel]
|
|
|
- res["repo"] = m["groundseg"][releaseChannel][containerType]["repo"]
|
|
|
+ groundseg, ok := m["groundseg"].(map[string]interface{})
|
|
|
+ if !ok {
|
|
|
+ return nil, fmt.Errorf("groundseg is not a map")
|
|
|
+ }
|
|
|
+ channel, ok := groundseg[releaseChannel].(map[string]interface{})
|
|
|
+ if !ok {
|
|
|
+ return nil, fmt.Errorf("%s is not a map", releaseChannel)
|
|
|
+ }
|
|
|
+ containerData, ok := channel[containerType].(map[string]interface{})
|
|
|
+ if !ok {
|
|
|
+ return nil, fmt.Errorf("%s data is not a map", containerType)
|
|
|
+ }
|
|
|
+ res = make(map[string]string)
|
|
|
+ res["tag"] = containerData["tag"].(string)
|
|
|
+ res["hash"] = containerData[hashLabel].(string)
|
|
|
+ res["repo"] = containerData["repo"].(string)
|
|
|
return res, nil
|
|
|
}
|