mirror of
				https://github.com/k3s-io/kubernetes.git
				synced 2025-10-31 05:40:42 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			183 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			183 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| /*
 | |
| Copyright 2018 The Kubernetes Authors.
 | |
| 
 | |
| Licensed under the Apache License, Version 2.0 (the "License");
 | |
| you may not use this file except in compliance with the License.
 | |
| You may obtain a copy of the License at
 | |
| 
 | |
|     http://www.apache.org/licenses/LICENSE-2.0
 | |
| 
 | |
| Unless required by applicable law or agreed to in writing, software
 | |
| distributed under the License is distributed on an "AS IS" BASIS,
 | |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
| See the License for the specific language governing permissions and
 | |
| limitations under the License.
 | |
| */
 | |
| 
 | |
| package util
 | |
| 
 | |
| import (
 | |
| 	"path/filepath"
 | |
| 	goruntime "runtime"
 | |
| 	"strings"
 | |
| 
 | |
| 	pkgerrors "github.com/pkg/errors"
 | |
| 
 | |
| 	"k8s.io/apimachinery/pkg/util/errors"
 | |
| 	kubeadmapiv1beta1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta1"
 | |
| 	utilsexec "k8s.io/utils/exec"
 | |
| )
 | |
| 
 | |
| // ContainerRuntime is an interface for working with container runtimes
 | |
| type ContainerRuntime interface {
 | |
| 	IsDocker() bool
 | |
| 	IsRunning() error
 | |
| 	ListKubeContainers() ([]string, error)
 | |
| 	RemoveContainers(containers []string) error
 | |
| 	PullImage(image string) error
 | |
| 	ImageExists(image string) (bool, error)
 | |
| }
 | |
| 
 | |
| // CRIRuntime is a struct that interfaces with the CRI
 | |
| type CRIRuntime struct {
 | |
| 	exec      utilsexec.Interface
 | |
| 	criSocket string
 | |
| }
 | |
| 
 | |
| // DockerRuntime is a struct that interfaces with the Docker daemon
 | |
| type DockerRuntime struct {
 | |
| 	exec utilsexec.Interface
 | |
| }
 | |
| 
 | |
| // NewContainerRuntime sets up and returns a ContainerRuntime struct
 | |
| func NewContainerRuntime(execer utilsexec.Interface, criSocket string) (ContainerRuntime, error) {
 | |
| 	var toolName string
 | |
| 	var runtime ContainerRuntime
 | |
| 
 | |
| 	if criSocket != kubeadmapiv1beta1.DefaultCRISocket {
 | |
| 		toolName = "crictl"
 | |
| 		// !!! temporary work around crictl warning:
 | |
| 		// Using "/var/run/crio/crio.sock" as endpoint is deprecated,
 | |
| 		// please consider using full url format "unix:///var/run/crio/crio.sock"
 | |
| 		if filepath.IsAbs(criSocket) && goruntime.GOOS != "windows" {
 | |
| 			criSocket = "unix://" + criSocket
 | |
| 		}
 | |
| 		runtime = &CRIRuntime{execer, criSocket}
 | |
| 	} else {
 | |
| 		toolName = "docker"
 | |
| 		runtime = &DockerRuntime{execer}
 | |
| 	}
 | |
| 
 | |
| 	if _, err := execer.LookPath(toolName); err != nil {
 | |
| 		return nil, pkgerrors.Wrapf(err, "%s is required for container runtime", toolName)
 | |
| 	}
 | |
| 
 | |
| 	return runtime, nil
 | |
| }
 | |
| 
 | |
| // IsDocker returns true if the runtime is docker
 | |
| func (runtime *CRIRuntime) IsDocker() bool {
 | |
| 	return false
 | |
| }
 | |
| 
 | |
| // IsDocker returns true if the runtime is docker
 | |
| func (runtime *DockerRuntime) IsDocker() bool {
 | |
| 	return true
 | |
| }
 | |
| 
 | |
| // IsRunning checks if runtime is running
 | |
| func (runtime *CRIRuntime) IsRunning() error {
 | |
| 	if out, err := runtime.exec.Command("crictl", "-r", runtime.criSocket, "info").CombinedOutput(); err != nil {
 | |
| 		return pkgerrors.Wrapf(err, "container runtime is not running: output: %s, error", string(out))
 | |
| 	}
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // IsRunning checks if runtime is running
 | |
| func (runtime *DockerRuntime) IsRunning() error {
 | |
| 	if out, err := runtime.exec.Command("docker", "info").CombinedOutput(); err != nil {
 | |
| 		return pkgerrors.Wrapf(err, "container runtime is not running: output: %s, error", string(out))
 | |
| 	}
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // ListKubeContainers lists running k8s CRI pods
 | |
| func (runtime *CRIRuntime) ListKubeContainers() ([]string, error) {
 | |
| 	out, err := runtime.exec.Command("crictl", "-r", runtime.criSocket, "pods", "-q").CombinedOutput()
 | |
| 	if err != nil {
 | |
| 		return nil, pkgerrors.Wrapf(err, "output: %s, error", string(out))
 | |
| 	}
 | |
| 	pods := []string{}
 | |
| 	for _, pod := range strings.Fields(string(out)) {
 | |
| 		pods = append(pods, pod)
 | |
| 	}
 | |
| 	return pods, nil
 | |
| }
 | |
| 
 | |
| // ListKubeContainers lists running k8s containers
 | |
| func (runtime *DockerRuntime) ListKubeContainers() ([]string, error) {
 | |
| 	output, err := runtime.exec.Command("docker", "ps", "-a", "--filter", "name=k8s_", "-q").CombinedOutput()
 | |
| 	return strings.Fields(string(output)), err
 | |
| }
 | |
| 
 | |
| // RemoveContainers removes running k8s pods
 | |
| func (runtime *CRIRuntime) RemoveContainers(containers []string) error {
 | |
| 	errs := []error{}
 | |
| 	for _, container := range containers {
 | |
| 		out, err := runtime.exec.Command("crictl", "-r", runtime.criSocket, "stopp", container).CombinedOutput()
 | |
| 		if err != nil {
 | |
| 			// don't stop on errors, try to remove as many containers as possible
 | |
| 			errs = append(errs, pkgerrors.Wrapf(err, "failed to stop running pod %s: output: %s, error", container, string(out)))
 | |
| 		} else {
 | |
| 			out, err = runtime.exec.Command("crictl", "-r", runtime.criSocket, "rmp", container).CombinedOutput()
 | |
| 			if err != nil {
 | |
| 				errs = append(errs, pkgerrors.Wrapf(err, "failed to remove running container %s: output: %s, error", container, string(out)))
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	return errors.NewAggregate(errs)
 | |
| }
 | |
| 
 | |
| // RemoveContainers removes running containers
 | |
| func (runtime *DockerRuntime) RemoveContainers(containers []string) error {
 | |
| 	errs := []error{}
 | |
| 	for _, container := range containers {
 | |
| 		out, err := runtime.exec.Command("docker", "rm", "--force", "--volumes", container).CombinedOutput()
 | |
| 		if err != nil {
 | |
| 			// don't stop on errors, try to remove as many containers as possible
 | |
| 			errs = append(errs, pkgerrors.Wrapf(err, "failed to remove running container %s: output: %s, error", container, string(out)))
 | |
| 		}
 | |
| 	}
 | |
| 	return errors.NewAggregate(errs)
 | |
| }
 | |
| 
 | |
| // PullImage pulls the image
 | |
| func (runtime *CRIRuntime) PullImage(image string) error {
 | |
| 	out, err := runtime.exec.Command("crictl", "-r", runtime.criSocket, "pull", image).CombinedOutput()
 | |
| 	if err != nil {
 | |
| 		return pkgerrors.Wrapf(err, "output: %s, error", string(out))
 | |
| 	}
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // PullImage pulls the image
 | |
| func (runtime *DockerRuntime) PullImage(image string) error {
 | |
| 	out, err := runtime.exec.Command("docker", "pull", image).CombinedOutput()
 | |
| 	if err != nil {
 | |
| 		return pkgerrors.Wrapf(err, "output: %s, error", string(out))
 | |
| 	}
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // ImageExists checks to see if the image exists on the system
 | |
| func (runtime *CRIRuntime) ImageExists(image string) (bool, error) {
 | |
| 	err := runtime.exec.Command("crictl", "-r", runtime.criSocket, "inspecti", image).Run()
 | |
| 	return err == nil, nil
 | |
| }
 | |
| 
 | |
| // ImageExists checks to see if the image exists on the system
 | |
| func (runtime *DockerRuntime) ImageExists(image string) (bool, error) {
 | |
| 	err := runtime.exec.Command("docker", "inspect", image).Run()
 | |
| 	return err == nil, nil
 | |
| }
 |