diff --git a/core/compute/compute.go b/core/compute/compute.go index a1b38139..a93a3dc3 100644 --- a/core/compute/compute.go +++ b/core/compute/compute.go @@ -13,6 +13,7 @@ import ( "github.com/rancher/agent/core/storage" "github.com/rancher/agent/model" "github.com/rancher/agent/utilities/constants" + "github.com/rancher/agent/utilities/docker" "github.com/rancher/agent/utilities/utils" "golang.org/x/net/context" "strings" @@ -103,7 +104,7 @@ func DoInstanceActivate(instance model.Instance, host model.Host, progress *prog } containerID := container.ID created := false - if len(containerID) == 0 { + if containerID == "" { newID, err := createContainer(dockerClient, &config, &hostConfig, imageTag, instance, name, progress) if err != nil { return errors.Wrap(err, constants.DoInstanceActivateError+"failed to create container") @@ -205,15 +206,29 @@ func DoInstanceForceStop(request model.InstanceForceStop, dockerClient *client.C } func DoInstanceInspect(inspect model.InstanceInspect, dockerClient *client.Client) (types.ContainerJSON, error) { - containerID := inspect.ID - containerList, err := dockerClient.ContainerList(context.Background(), types.ContainerListOptions{All: true}) + clientWithTimeout, err := docker.NewEnvClientWithTimeout(time.Duration(2) * time.Second) if err != nil { - return types.ContainerJSON{}, errors.Wrap(err, constants.DoInstanceInspectError+"failed to list containers") + return types.ContainerJSON{}, errors.New("Can't initialize docker client") } - result, find := utils.FindFirst(containerList, func(c types.Container) bool { - return utils.IDFilter(containerID, c) - }) - if !find { + clientWithTimeout.UpdateClientVersion(constants.DefaultVersion) + containerID := inspect.ID + if containerID != "" { + // inspect by id + containerInspect, err := clientWithTimeout.ContainerInspect(context.Background(), containerID) + if err != nil && !client.IsErrContainerNotFound(err) { + return types.ContainerJSON{}, errors.Wrap(err, constants.DoInstanceInspectError+"Failed to inspect container") + } else if err == nil { + return containerInspect, nil + } + } + if inspect.Name != "" { + // inspect by name + containerList, err := clientWithTimeout.ContainerList(context.Background(), types.ContainerListOptions{All: true}) + if err != nil { + return types.ContainerJSON{}, errors.Wrap(err, constants.DoInstanceInspectError+"failed to list containers") + } + find := false + result := types.Container{} name := fmt.Sprintf("/%s", inspect.Name) if resultWithNameInspect, ok := utils.FindFirst(containerList, func(c types.Container) bool { return utils.NameFilter(name, c) @@ -221,15 +236,16 @@ func DoInstanceInspect(inspect model.InstanceInspect, dockerClient *client.Clien result = resultWithNameInspect find = true } - } - if find { - inspectResp, err := dockerClient.ContainerInspect(context.Background(), result.ID) - if err != nil { - return types.ContainerJSON{}, errors.Wrap(err, constants.DoInstanceInspectError+"failed to inspect container") + + if find { + inspectResp, err := clientWithTimeout.ContainerInspect(context.Background(), result.ID) + if err != nil && !client.IsErrContainerNotFound(err) { + return types.ContainerJSON{}, errors.Wrap(err, constants.DoInstanceInspectError+"failed to inspect container") + } + return inspectResp, nil } - return inspectResp, nil } - return types.ContainerJSON{}, fmt.Errorf("container with id [%v] not found", containerID) + return types.ContainerJSON{}, errors.Errorf("container with id [%v] not found", containerID) } func DoInstanceRemove(instance model.Instance, dockerClient *client.Client) error { diff --git a/main.go b/main.go index 5cafe31e..6898050f 100644 --- a/main.go +++ b/main.go @@ -18,6 +18,10 @@ func main() { os.Exit(0) } + if os.Getenv("CATTLE_DEBUG") != "" { + logrus.SetLevel(logrus.DebugLevel) + } + logrus.Info("Launching agent") url := os.Getenv("CATTLE_URL") diff --git a/utilities/utils/utils.go b/utilities/utils/utils.go index 22830a27..4a6a9ca8 100644 --- a/utilities/utils/utils.go +++ b/utilities/utils/utils.go @@ -13,6 +13,7 @@ import ( "github.com/rancher/agent/core/progress" "github.com/rancher/agent/model" "github.com/rancher/agent/utilities/constants" + "github.com/rancher/agent/utilities/docker" revents "github.com/rancher/event-subscriber/events" "github.com/rancher/go-rancher/v2" "golang.org/x/net/context" @@ -354,25 +355,21 @@ func ParseRepoTag(name string) model.RepoTag { } func GetContainer(client *engineCli.Client, instance model.Instance, byAgent bool) (types.Container, error) { - // First look for UUID label directly - args := filters.NewArgs() - args.Add("label", fmt.Sprintf("%s=%s", constants.UUIDLabel, instance.UUID)) - options := types.ContainerListOptions{All: true, Filter: args} - labeledContainers, err := client.ContainerList(context.Background(), options) - if err == nil && len(labeledContainers) > 0 { - return labeledContainers[0], nil - } else if err != nil { - return types.Container{}, errors.Wrap(err, constants.GetContainerError+"failed to list containers") + clientWithTimeout, err := docker.NewEnvClientWithTimeout(time.Duration(2) * time.Second) + if err != nil { + return types.Container{}, errors.Wrap(err, constants.GetContainerError+"failed to get docker client") } - - // Next look by UUID using fallback method - options = types.ContainerListOptions{All: true} - containerList, err := client.ContainerList(context.Background(), options) + clientWithTimeout.UpdateClientVersion(constants.DefaultVersion) + containers, err := clientWithTimeout.ContainerList(context.Background(), types.ContainerListOptions{All: true}) if err != nil { return types.Container{}, errors.Wrap(err, constants.GetContainerError+"failed to list containers") } - - if container, ok := FindFirst(containerList, func(c types.Container) bool { + for _, container := range containers { + if uuid, ok := container.Labels[constants.UUIDLabel]; ok && uuid == instance.UUID { + return container, nil + } + } + if container, ok := FindFirst(containers, func(c types.Container) bool { if GetUUID(c) == instance.UUID { return true } @@ -382,7 +379,7 @@ func GetContainer(client *engineCli.Client, instance model.Instance, byAgent boo } if externalID := instance.ExternalID; externalID != "" { - if container, ok := FindFirst(containerList, func(c types.Container) bool { + if container, ok := FindFirst(containers, func(c types.Container) bool { return IDFilter(externalID, c) }); ok { return container, nil @@ -391,7 +388,7 @@ func GetContainer(client *engineCli.Client, instance model.Instance, byAgent boo if byAgent { agentID := instance.AgentID - if container, ok := FindFirst(containerList, func(c types.Container) bool { + if container, ok := FindFirst(containers, func(c types.Container) bool { return AgentIDFilter(strconv.Itoa(agentID), c) }); ok { return container, nil