mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-05 10:19:50 +00:00
Merge pull request #8228 from yifan-gu/rkt_image_cat
kubelet/rkt: Add getImageManifest()
This commit is contained in:
commit
353f304433
@ -38,7 +38,7 @@ type image struct {
|
|||||||
// sha512-91e98d7f1679a097c878203c9659f2a26ae394656b3147963324c61fa3832f15 coreos.com/etcd:v2.0.9
|
// sha512-91e98d7f1679a097c878203c9659f2a26ae394656b3147963324c61fa3832f15 coreos.com/etcd:v2.0.9
|
||||||
//
|
//
|
||||||
func (im *image) parseString(input string) error {
|
func (im *image) parseString(input string) error {
|
||||||
idName := strings.Split(input, "\t")
|
idName := strings.Split(strings.TrimSpace(input), "\t")
|
||||||
if len(idName) != 2 {
|
if len(idName) != 2 {
|
||||||
return fmt.Errorf("invalid image information from 'rkt images': %q", input)
|
return fmt.Errorf("invalid image information from 'rkt images': %q", input)
|
||||||
}
|
}
|
||||||
|
@ -148,6 +148,7 @@ func New(config *Config,
|
|||||||
generator: generator,
|
generator: generator,
|
||||||
recorder: recorder,
|
recorder: recorder,
|
||||||
readinessManager: readinessManager,
|
readinessManager: readinessManager,
|
||||||
|
volumeGetter: volumeGetter,
|
||||||
}
|
}
|
||||||
rkt.prober = prober.New(rkt, readinessManager, containerRefManager, recorder)
|
rkt.prober = prober.New(rkt, readinessManager, containerRefManager, recorder)
|
||||||
|
|
||||||
@ -174,7 +175,7 @@ func (r *runtime) buildCommand(args ...string) *exec.Cmd {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// runCommand invokes rkt binary with arguments and returns the result
|
// runCommand invokes rkt binary with arguments and returns the result
|
||||||
// from stdout in a list of strings.
|
// from stdout in a list of strings. Each string in the list is a line.
|
||||||
func (r *runtime) runCommand(args ...string) ([]string, error) {
|
func (r *runtime) runCommand(args ...string) ([]string, error) {
|
||||||
glog.V(4).Info("rkt: Run command:", args)
|
glog.V(4).Info("rkt: Run command:", args)
|
||||||
|
|
||||||
@ -285,7 +286,7 @@ func setIsolators(app *appctypes.App, c *api.Container) error {
|
|||||||
|
|
||||||
// setApp overrides the app's fields if any of them are specified in the
|
// setApp overrides the app's fields if any of them are specified in the
|
||||||
// container's spec.
|
// container's spec.
|
||||||
func setApp(app *appctypes.App, c *api.Container) error {
|
func setApp(app *appctypes.App, c *api.Container, opts *kubecontainer.RunContainerOptions) error {
|
||||||
// Override the exec.
|
// Override the exec.
|
||||||
// TOOD(yifan): Revisit this for the overriding rule.
|
// TOOD(yifan): Revisit this for the overriding rule.
|
||||||
if len(c.Command) > 0 || len(c.Args) > 0 {
|
if len(c.Command) > 0 || len(c.Args) > 0 {
|
||||||
@ -302,8 +303,7 @@ func setApp(app *appctypes.App, c *api.Container) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Override the environment.
|
// Override the environment.
|
||||||
// TODO(yifan): Use RunContainerOptions.
|
if len(opts.Envs) > 0 {
|
||||||
if len(c.Env) > 0 {
|
|
||||||
app.Environment = []appctypes.EnvironmentVariable{}
|
app.Environment = []appctypes.EnvironmentVariable{}
|
||||||
}
|
}
|
||||||
for _, env := range c.Env {
|
for _, env := range c.Env {
|
||||||
@ -314,30 +314,31 @@ func setApp(app *appctypes.App, c *api.Container) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Override the mount points.
|
// Override the mount points.
|
||||||
if len(c.VolumeMounts) > 0 {
|
if len(opts.Mounts) > 0 {
|
||||||
app.MountPoints = []appctypes.MountPoint{}
|
app.MountPoints = []appctypes.MountPoint{}
|
||||||
}
|
}
|
||||||
for _, m := range c.VolumeMounts {
|
for _, m := range opts.Mounts {
|
||||||
mountPointName, err := appctypes.NewACName(m.Name)
|
mountPointName, err := appctypes.NewACName(m.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
app.MountPoints = append(app.MountPoints, appctypes.MountPoint{
|
app.MountPoints = append(app.MountPoints, appctypes.MountPoint{
|
||||||
Name: *mountPointName,
|
Name: *mountPointName,
|
||||||
Path: m.MountPath,
|
Path: m.ContainerPath,
|
||||||
ReadOnly: m.ReadOnly,
|
ReadOnly: m.ReadOnly,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Override the ports.
|
// Override the ports.
|
||||||
if len(c.Ports) > 0 {
|
if len(opts.PortMappings) > 0 {
|
||||||
app.Ports = []appctypes.Port{}
|
app.Ports = []appctypes.Port{}
|
||||||
}
|
}
|
||||||
for _, p := range c.Ports {
|
for _, p := range opts.PortMappings {
|
||||||
portName, err := appctypes.NewACName(p.Name)
|
name, err := appctypes.SanitizeACName(p.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
portName := appctypes.MustACName(name)
|
||||||
app.Ports = append(app.Ports, appctypes.Port{
|
app.Ports = append(app.Ports, appctypes.Port{
|
||||||
Name: *portName,
|
Name: *portName,
|
||||||
Protocol: string(p.Protocol),
|
Protocol: string(p.Protocol),
|
||||||
@ -349,12 +350,38 @@ func setApp(app *appctypes.App, c *api.Container) error {
|
|||||||
return setIsolators(app, c)
|
return setIsolators(app, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getImageManifest invokes 'rkt image cat-manifest' to retrive the image manifest
|
||||||
|
// for the image.
|
||||||
|
func (r *runtime) getImageManifest(image string) (*appcschema.ImageManifest, error) {
|
||||||
|
var manifest appcschema.ImageManifest
|
||||||
|
|
||||||
|
// TODO(yifan): Assume docker images for now.
|
||||||
|
output, err := r.runCommand("image", "cat-manifest", "--quiet", dockerPrefix+image)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(output) != 1 {
|
||||||
|
return nil, fmt.Errorf("invalid output: %v", output)
|
||||||
|
}
|
||||||
|
return &manifest, json.Unmarshal([]byte(output[0]), &manifest)
|
||||||
|
}
|
||||||
|
|
||||||
// makePodManifest transforms a kubelet pod spec to the rkt pod manifest.
|
// makePodManifest transforms a kubelet pod spec to the rkt pod manifest.
|
||||||
// TODO(yifan): Use the RunContainerOptions generated by GenerateRunContainerOptions().
|
// TODO(yifan): Use the RunContainerOptions generated by GenerateRunContainerOptions().
|
||||||
func (r *runtime) makePodManifest(pod *api.Pod) (*appcschema.PodManifest, error) {
|
func (r *runtime) makePodManifest(pod *api.Pod) (*appcschema.PodManifest, error) {
|
||||||
|
var globalPortMappings []kubecontainer.PortMapping
|
||||||
manifest := appcschema.BlankPodManifest()
|
manifest := appcschema.BlankPodManifest()
|
||||||
|
|
||||||
for _, c := range pod.Spec.Containers {
|
for _, c := range pod.Spec.Containers {
|
||||||
|
imgManifest, err := r.getImageManifest(c.Image)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if imgManifest.App == nil {
|
||||||
|
return nil, fmt.Errorf("no app section in image manifest for image: %q", c.Image)
|
||||||
|
}
|
||||||
|
|
||||||
img, err := r.getImageByName(c.Image)
|
img, err := r.getImageByName(c.Image)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -364,22 +391,23 @@ func (r *runtime) makePodManifest(pod *api.Pod) (*appcschema.PodManifest, error)
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(yifan): Override the image manifest's app and store it in the pod manifest.
|
opts, err := r.generator.GenerateRunContainerOptions(pod, &c)
|
||||||
// We need to get the image manifest. https://github.com/coreos/rkt/issues/850
|
|
||||||
app := &appctypes.App{}
|
|
||||||
if err := setApp(app, &c); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
imageName, err := appctypes.NewACName(img.name)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
globalPortMappings = append(globalPortMappings, opts.PortMappings...)
|
||||||
|
|
||||||
|
if err := setApp(imgManifest.App, &c, opts); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
manifest.Apps = append(manifest.Apps, appcschema.RuntimeApp{
|
manifest.Apps = append(manifest.Apps, appcschema.RuntimeApp{
|
||||||
// TODO(yifan): We should allow app name to be different with
|
// TODO(yifan): We should allow app name to be different with
|
||||||
// image name. See https://github.com/coreos/rkt/pull/640.
|
// image name. See https://github.com/coreos/rkt/pull/640.
|
||||||
Name: *imageName,
|
Name: imgManifest.Name,
|
||||||
Image: appcschema.RuntimeImage{ID: *hash},
|
Image: appcschema.RuntimeImage{ID: *hash},
|
||||||
App: app,
|
App: imgManifest.App,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -402,17 +430,16 @@ func (r *runtime) makePodManifest(pod *api.Pod) (*appcschema.PodManifest, error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set global ports.
|
// Set global ports.
|
||||||
for _, c := range pod.Spec.Containers {
|
for _, port := range globalPortMappings {
|
||||||
for _, port := range c.Ports {
|
name, err := appctypes.SanitizeACName(port.Name)
|
||||||
portName, err := appctypes.NewACName(port.Name)
|
if err != nil {
|
||||||
if err != nil {
|
return nil, fmt.Errorf("cannot use the port's name %q as ACName: %v", port.Name, err)
|
||||||
return nil, fmt.Errorf("cannot use the port's name %q as ACName: %v", port.Name, err)
|
|
||||||
}
|
|
||||||
manifest.Ports = append(manifest.Ports, appctypes.ExposedPort{
|
|
||||||
Name: *portName,
|
|
||||||
HostPort: uint(port.HostPort),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
portName := appctypes.MustACName(name)
|
||||||
|
manifest.Ports = append(manifest.Ports, appctypes.ExposedPort{
|
||||||
|
Name: *portName,
|
||||||
|
HostPort: uint(port.HostPort),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
// TODO(yifan): Set pod-level isolators once it's supported in kubernetes.
|
// TODO(yifan): Set pod-level isolators once it's supported in kubernetes.
|
||||||
return manifest, nil
|
return manifest, nil
|
||||||
@ -793,7 +820,6 @@ func (r *runtime) SyncPod(pod *api.Pod, runningPod kubecontainer.Pod, podStatus
|
|||||||
podFullName := kubecontainer.GetPodFullName(pod)
|
podFullName := kubecontainer.GetPodFullName(pod)
|
||||||
if len(runningPod.Containers) == 0 {
|
if len(runningPod.Containers) == 0 {
|
||||||
glog.V(4).Infof("Pod %q is not running, will start it", podFullName)
|
glog.V(4).Infof("Pod %q is not running, will start it", podFullName)
|
||||||
// TODO(yifan): Use RunContainerOptionsGeneratior to get volumeMaps, etc.
|
|
||||||
return r.RunPod(pod)
|
return r.RunPod(pod)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1118,18 +1144,33 @@ func (r *runtime) listImages() ([]image, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// getImageByName tries to find the image info with the given image name.
|
// getImageByName tries to find the image info with the given image name.
|
||||||
func (r *runtime) getImageByName(name string) (image, error) {
|
func (r *runtime) getImageByName(imageName string) (image, error) {
|
||||||
// TODO(yifan): Use rkt image cat-file when that is ready:
|
// TODO(yifan): Print hash in rkt image?
|
||||||
// https://github.com/coreos/rkt/pull/649
|
|
||||||
images, err := r.listImages()
|
images, err := r.listImages()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return image{}, err
|
return image{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var name, version string
|
||||||
|
nameVersion := strings.Split(imageName, ":")
|
||||||
|
|
||||||
|
// TODO(yifan): Currently the name cannot include "_", it is replaced
|
||||||
|
// by "-". See the issue in appc/spec: https://github.com/appc/spec/issues/406.
|
||||||
|
name, err = appctypes.SanitizeACName(nameVersion[0])
|
||||||
|
if err != nil {
|
||||||
|
return image{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(nameVersion) == 2 {
|
||||||
|
version = nameVersion[1]
|
||||||
|
}
|
||||||
|
|
||||||
for _, img := range images {
|
for _, img := range images {
|
||||||
if img.name == name {
|
if img.name == name {
|
||||||
return img, nil
|
if version == "" || img.version == version {
|
||||||
|
return img, nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return image{}, fmt.Errorf("cannot find the image %q", name)
|
return image{}, fmt.Errorf("cannot find the image %q", imageName)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user