Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

handle already in use container name #6906

Merged
merged 6 commits into from
Mar 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions pkg/drivers/kic/kic.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,25 @@ func (d *Driver) Create() error {
ContainerPort: constants.DockerDaemonPort,
},
)

exists, err := oci.ContainerExists(d.OCIBinary, params.Name)
if err != nil {
glog.Warningf("failed to check if container already exists: %v", err)
}
if exists {
// if container was created by minikube it is safe to delete and recreate it.
if oci.IsCreatedByMinikube(d.OCIBinary, params.Name) {
glog.Info("Found already existing abandoned minikube container, will try to delete.")
if err := oci.DeleteContainer(d.OCIBinary, params.Name); err != nil {
glog.Errorf("Failed to delete a conflicting minikube container %s. You might need to restart your %s daemon and delete it manually and try again: %v", params.Name, params.OCIBinary, err)
}
} else {
// The conflicting container name was not created by minikube
// user has a container that conflicts with minikube profile name, will not delete users container.
return errors.Wrapf(err, "user has a conflicting container name %q with minikube container. Needs to be deleted by user's consent.", params.Name)
}
}

if err := oci.CreateContainerNode(params); err != nil {
return errors.Wrap(err, "create kic node")
}
Expand Down
71 changes: 67 additions & 4 deletions pkg/drivers/kic/oci/oci.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func DeleteContainersByLabel(ociBin string, label string) []error {
// if it doesn't it means docker daemon is stuck and needs restart
if err != nil {
deleteErrs = append(deleteErrs, errors.Wrapf(err, "delete container %s: %s daemon is stuck. please try again!", c, ociBin))
glog.Errorf("%s daemon seems to be stuck. Please try restarting your %s.", ociBin, ociBin)
glog.Errorf("%s daemon seems to be stuck. Please try restarting your %s. :%v", ociBin, ociBin, err)
continue
}
cmd := exec.Command(ociBin, "rm", "-f", "-v", c)
Expand All @@ -69,6 +69,23 @@ func DeleteContainersByLabel(ociBin string, label string) []error {
return deleteErrs
}

// DeleteContainer deletes a container by ID or Name
func DeleteContainer(ociBin string, name string) error {
if err := PointToHostDockerDaemon(); err != nil {
return errors.Wrap(err, "point host docker daemon")
}
_, err := ContainerStatus(ociBin, name)
if err != nil {
glog.Errorf("%s daemon seems to be stuck. Please try restarting your %s. Will try to delete anyways: %v", ociBin, ociBin, err)
}
// try to delete anyways
cmd := exec.Command(ociBin, "rm", "-f", "-v", name)
if out, err := cmd.CombinedOutput(); err != nil {
return errors.Wrapf(err, "delete container %s: output %s", name, out)
}
return nil
}

// CreateContainerNode creates a new container node
func CreateContainerNode(p CreateParams) error {
if err := PointToHostDockerDaemon(); err != nil {
Expand Down Expand Up @@ -217,11 +234,57 @@ func ContainerID(ociBinary string, nameOrID string) (string, error) {
return "", errors.Wrap(err, "point host docker daemon")
}
cmd := exec.Command(ociBinary, "inspect", "-f", "{{.Id}}", nameOrID)
id, err := cmd.CombinedOutput()
out, err := cmd.CombinedOutput()
if err != nil { // don't return error if not found, only return empty string
if strings.Contains(string(out), "Error: No such object:") || strings.Contains(string(out), "unable to find") {
err = nil
}
out = []byte{}
}
return string(out), err
}

// ContainerExists checks if container name exists (either running or exited)
func ContainerExists(ociBin string, name string) (bool, error) {
if err := PointToHostDockerDaemon(); err != nil {
return false, errors.Wrap(err, "point host docker daemon")
}
// allow no more than 3 seconds for this.
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
cmd := exec.CommandContext(ctx, ociBin, "ps", "-a", "--format", "{{.Names}}")
out, err := cmd.CombinedOutput()
if ctx.Err() == context.DeadlineExceeded {
return false, fmt.Errorf("time out running %s ps -a", ociBin)
}
if err != nil {
return false, errors.Wrapf(err, string(out))
}
containers := strings.Split(string(out), "\n")
for _, c := range containers {
if strings.TrimSpace(c) == name {
return true, nil
}
}
return false, nil
}

// IsCreatedByMinikube returns true if the container was created by minikube
// with default assumption that it is not created by minikube when we don't know for sure
func IsCreatedByMinikube(ociBinary string, nameOrID string) bool {
if err := PointToHostDockerDaemon(); err != nil {
glog.Warningf("Failed to point to host docker daemon")
return false
}
cmd := exec.Command(ociBinary, "inspect", nameOrID, "--format", "{{.Config.Labels}}")
out, err := cmd.CombinedOutput()
if err != nil {
id = []byte{}
return false
}
if strings.Contains(string(out), fmt.Sprintf("%s:true", CreatedByLabelKey)) {
return true
}
return string(id), err
return false
}

// ListOwnedContainers lists all the containres that kic driver created on user's machine using a label
Expand Down