mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 03:41:45 +00:00
Merge pull request #466 from smarterclayton/move_docker_function_out
Move Docker specific function out of the Kubelet
This commit is contained in:
commit
8ef60138e5
138
pkg/kubelet/docker.go
Normal file
138
pkg/kubelet/docker.go
Normal file
@ -0,0 +1,138 @@
|
||||
/*
|
||||
Copyright 2014 Google Inc. All rights reserved.
|
||||
|
||||
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 kubelet
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"strings"
|
||||
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
|
||||
"github.com/fsouza/go-dockerclient"
|
||||
)
|
||||
|
||||
// DockerContainerData is the structured representation of the JSON object returned by Docker inspect
|
||||
type DockerContainerData struct {
|
||||
state struct {
|
||||
Running bool
|
||||
}
|
||||
}
|
||||
|
||||
// DockerInterface is an abstract interface for testability. It abstracts the interface of docker.Client.
|
||||
type DockerInterface interface {
|
||||
ListContainers(options docker.ListContainersOptions) ([]docker.APIContainers, error)
|
||||
InspectContainer(id string) (*docker.Container, error)
|
||||
CreateContainer(docker.CreateContainerOptions) (*docker.Container, error)
|
||||
StartContainer(id string, hostConfig *docker.HostConfig) error
|
||||
StopContainer(id string, timeout uint) error
|
||||
PullImage(opts docker.PullImageOptions, auth docker.AuthConfiguration) error
|
||||
}
|
||||
|
||||
// DockerID is an ID of docker container. It is a type to make it clear when we're working with docker container Ids
|
||||
type DockerID string
|
||||
|
||||
// DockerPuller is an abstract interface for testability. It abstracts image pull operations.
|
||||
type DockerPuller interface {
|
||||
Pull(image string) error
|
||||
}
|
||||
|
||||
// dockerPuller is the default implementation of DockerPuller.
|
||||
type dockerPuller struct {
|
||||
client DockerInterface
|
||||
}
|
||||
|
||||
// NewDockerPuller creates a new instance of the default implementation of DockerPuller.
|
||||
func NewDockerPuller(client DockerInterface) DockerPuller {
|
||||
return dockerPuller{
|
||||
client: client,
|
||||
}
|
||||
}
|
||||
|
||||
func (p dockerPuller) Pull(image string) error {
|
||||
image, tag := parseImageName(image)
|
||||
opts := docker.PullImageOptions{
|
||||
Repository: image,
|
||||
Tag: tag,
|
||||
}
|
||||
return p.client.PullImage(opts, docker.AuthConfiguration{})
|
||||
}
|
||||
|
||||
// Converts "-" to "_-_" and "_" to "___" so that we can use "--" to meaningfully separate parts of a docker name.
|
||||
func escapeDash(in string) (out string) {
|
||||
out = strings.Replace(in, "_", "___", -1)
|
||||
out = strings.Replace(out, "-", "_-_", -1)
|
||||
return
|
||||
}
|
||||
|
||||
// Reverses the transformation of escapeDash.
|
||||
func unescapeDash(in string) (out string) {
|
||||
out = strings.Replace(in, "_-_", "-", -1)
|
||||
out = strings.Replace(out, "___", "_", -1)
|
||||
return
|
||||
}
|
||||
|
||||
const containerNamePrefix = "k8s"
|
||||
|
||||
// Creates a name which can be reversed to identify both manifest id and container name.
|
||||
func buildDockerName(manifest *api.ContainerManifest, container *api.Container) string {
|
||||
// Note, manifest.ID could be blank.
|
||||
return fmt.Sprintf("%s--%s--%s--%08x", containerNamePrefix, escapeDash(container.Name), escapeDash(manifest.ID), rand.Uint32())
|
||||
}
|
||||
|
||||
// Upacks a container name, returning the manifest id and container name we would have used to
|
||||
// construct the docker name. If the docker name isn't one we created, we may return empty strings.
|
||||
func parseDockerName(name string) (manifestID, containerName string) {
|
||||
// For some reason docker appears to be appending '/' to names.
|
||||
// If its there, strip it.
|
||||
if name[0] == '/' {
|
||||
name = name[1:]
|
||||
}
|
||||
parts := strings.Split(name, "--")
|
||||
if len(parts) == 0 || parts[0] != containerNamePrefix {
|
||||
return
|
||||
}
|
||||
if len(parts) > 1 {
|
||||
containerName = unescapeDash(parts[1])
|
||||
}
|
||||
if len(parts) > 2 {
|
||||
manifestID = unescapeDash(parts[2])
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Parses image name including an tag and returns image name and tag
|
||||
// TODO: Future Docker versions can parse the tag on daemon side, see:
|
||||
// https://github.com/dotcloud/docker/issues/6876
|
||||
// So this can be deprecated at some point.
|
||||
func parseImageName(image string) (string, string) {
|
||||
tag := ""
|
||||
parts := strings.SplitN(image, "/", 2)
|
||||
repo := ""
|
||||
if len(parts) == 2 {
|
||||
repo = parts[0]
|
||||
image = parts[1]
|
||||
}
|
||||
parts = strings.SplitN(image, ":", 2)
|
||||
if len(parts) == 2 {
|
||||
image = parts[0]
|
||||
tag = parts[1]
|
||||
}
|
||||
if repo != "" {
|
||||
image = fmt.Sprintf("%s/%s", repo, image)
|
||||
}
|
||||
return image, tag
|
||||
}
|
@ -21,7 +21,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
@ -47,31 +46,6 @@ import (
|
||||
|
||||
const defaultChanSize = 1024
|
||||
|
||||
// DockerContainerData is the structured representation of the JSON object returned by Docker inspect
|
||||
type DockerContainerData struct {
|
||||
state struct {
|
||||
Running bool
|
||||
}
|
||||
}
|
||||
|
||||
// DockerInterface is an abstract interface for testability. It abstracts the interface of docker.Client.
|
||||
type DockerInterface interface {
|
||||
ListContainers(options docker.ListContainersOptions) ([]docker.APIContainers, error)
|
||||
InspectContainer(id string) (*docker.Container, error)
|
||||
CreateContainer(docker.CreateContainerOptions) (*docker.Container, error)
|
||||
StartContainer(id string, hostConfig *docker.HostConfig) error
|
||||
StopContainer(id string, timeout uint) error
|
||||
PullImage(opts docker.PullImageOptions, auth docker.AuthConfiguration) error
|
||||
}
|
||||
|
||||
// DockerID is an ID of docker container. It is a type to make it clear when we're working with docker container Ids
|
||||
type DockerID string
|
||||
|
||||
// DockerPuller is an abstract interface for testability. It abstracts image pull operations.
|
||||
type DockerPuller interface {
|
||||
Pull(image string) error
|
||||
}
|
||||
|
||||
// CadvisorInterface is an abstract interface for testability. It abstracts the interface of "github.com/google/cadvisor/client".Client.
|
||||
type CadvisorInterface interface {
|
||||
ContainerInfo(name string) (*info.ContainerInfo, error)
|
||||
@ -120,7 +94,7 @@ func (kl *Kubelet) RunKubelet(dockerEndpoint, configPath, manifestURL, etcdServe
|
||||
}
|
||||
}
|
||||
if kl.DockerPuller == nil {
|
||||
kl.DockerPuller = kl.MakeDockerPuller()
|
||||
kl.DockerPuller = NewDockerPuller(kl.DockerClient)
|
||||
}
|
||||
updateChannel := make(chan manifestUpdate)
|
||||
if configPath != "" {
|
||||
@ -237,70 +211,6 @@ func (kl *Kubelet) getContainer(ID DockerID) (*docker.APIContainers, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// MakeDockerPuller creates a new instance of the default implementation of DockerPuller.
|
||||
func (kl *Kubelet) MakeDockerPuller() DockerPuller {
|
||||
return dockerPuller{
|
||||
client: kl.DockerClient,
|
||||
}
|
||||
}
|
||||
|
||||
// dockerPuller is the default implementation of DockerPuller.
|
||||
type dockerPuller struct {
|
||||
client DockerInterface
|
||||
}
|
||||
|
||||
func (p dockerPuller) Pull(image string) error {
|
||||
image, tag := parseImageName(image)
|
||||
opts := docker.PullImageOptions{
|
||||
Repository: image,
|
||||
Tag: tag,
|
||||
}
|
||||
return p.client.PullImage(opts, docker.AuthConfiguration{})
|
||||
}
|
||||
|
||||
// Converts "-" to "_-_" and "_" to "___" so that we can use "--" to meaningfully separate parts of a docker name.
|
||||
func escapeDash(in string) (out string) {
|
||||
out = strings.Replace(in, "_", "___", -1)
|
||||
out = strings.Replace(out, "-", "_-_", -1)
|
||||
return
|
||||
}
|
||||
|
||||
// Reverses the transformation of escapeDash.
|
||||
func unescapeDash(in string) (out string) {
|
||||
out = strings.Replace(in, "_-_", "-", -1)
|
||||
out = strings.Replace(out, "___", "_", -1)
|
||||
return
|
||||
}
|
||||
|
||||
const containerNamePrefix = "k8s"
|
||||
|
||||
// Creates a name which can be reversed to identify both manifest id and container name.
|
||||
func buildDockerName(manifest *api.ContainerManifest, container *api.Container) string {
|
||||
// Note, manifest.ID could be blank.
|
||||
return fmt.Sprintf("%s--%s--%s--%08x", containerNamePrefix, escapeDash(container.Name), escapeDash(manifest.ID), rand.Uint32())
|
||||
}
|
||||
|
||||
// Upacks a container name, returning the manifest id and container name we would have used to
|
||||
// construct the docker name. If the docker name isn't one we created, we may return empty strings.
|
||||
func parseDockerName(name string) (manifestID, containerName string) {
|
||||
// For some reason docker appears to be appending '/' to names.
|
||||
// If its there, strip it.
|
||||
if name[0] == '/' {
|
||||
name = name[1:]
|
||||
}
|
||||
parts := strings.Split(name, "--")
|
||||
if len(parts) == 0 || parts[0] != containerNamePrefix {
|
||||
return
|
||||
}
|
||||
if len(parts) > 1 {
|
||||
containerName = unescapeDash(parts[1])
|
||||
}
|
||||
if len(parts) > 2 {
|
||||
manifestID = unescapeDash(parts[2])
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func makeEnvironmentVariables(container *api.Container) []string {
|
||||
var result []string
|
||||
for _, value := range container.Env {
|
||||
@ -359,29 +269,6 @@ func makePortsAndBindings(container *api.Container) (map[docker.Port]struct{}, m
|
||||
return exposedPorts, portBindings
|
||||
}
|
||||
|
||||
// Parses image name including an tag and returns image name and tag
|
||||
// TODO: Future Docker versions can parse the tag on daemon side, see:
|
||||
// https://github.com/dotcloud/docker/issues/6876
|
||||
// So this can be deprecated at some point.
|
||||
func parseImageName(image string) (string, string) {
|
||||
tag := ""
|
||||
parts := strings.SplitN(image, "/", 2)
|
||||
repo := ""
|
||||
if len(parts) == 2 {
|
||||
repo = parts[0]
|
||||
image = parts[1]
|
||||
}
|
||||
parts = strings.SplitN(image, ":", 2)
|
||||
if len(parts) == 2 {
|
||||
image = parts[0]
|
||||
tag = parts[1]
|
||||
}
|
||||
if repo != "" {
|
||||
image = fmt.Sprintf("%s/%s", repo, image)
|
||||
}
|
||||
return image, tag
|
||||
}
|
||||
|
||||
// Run a single container from a manifest. Returns the docker container ID
|
||||
func (kl *Kubelet) runContainer(manifest *api.ContainerManifest, container *api.Container, netMode string) (id DockerID, err error) {
|
||||
envVariables := makeEnvironmentVariables(container)
|
||||
|
Loading…
Reference in New Issue
Block a user