mirror of
https://github.com/linuxkit/linuxkit.git
synced 2025-07-21 18:11:35 +00:00
Use containerd reference.Spec in place of the Image string
Instead of passing the image name as string use the a reference to a containerd reference.Spec. This allows us, for example, to update the reference in place when verifying content trust with more specific information, such as the sha256 Signed-off-by: Rolf Neugebauer <rolf.neugebauer@docker.com>
This commit is contained in:
parent
d9b79548a5
commit
ad83cb8928
@ -134,7 +134,7 @@ func outputImage(image *Image, section string, prefix string, m Moby, idMap map[
|
|||||||
}
|
}
|
||||||
path := path.Join("containers", section, prefix+image.Name)
|
path := path.Join("containers", section, prefix+image.Name)
|
||||||
readonly := oci.Root.Readonly
|
readonly := oci.Root.Readonly
|
||||||
err = ImageBundle(path, image.Image, config, runtime, iw, useTrust, pull, readonly, dupMap)
|
err = ImageBundle(path, image.ref, config, runtime, iw, useTrust, pull, readonly, dupMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to extract root filesystem for %s: %v", image.Image, err)
|
return fmt.Errorf("Failed to extract root filesystem for %s: %v", image.Image, err)
|
||||||
}
|
}
|
||||||
@ -171,11 +171,11 @@ func Build(m Moby, w io.Writer, pull bool, tp string) error {
|
|||||||
// deduplicate containers with the same image
|
// deduplicate containers with the same image
|
||||||
dupMap := map[string]string{}
|
dupMap := map[string]string{}
|
||||||
|
|
||||||
if m.Kernel.Image != "" {
|
if m.Kernel.ref != nil {
|
||||||
// get kernel and initrd tarball from container
|
// get kernel and initrd tarball from container
|
||||||
log.Infof("Extract kernel image: %s", m.Kernel.Image)
|
log.Infof("Extract kernel image: %s", m.Kernel.ref)
|
||||||
kf := newKernelFilter(iw, m.Kernel.Cmdline, m.Kernel.Binary, m.Kernel.Tar)
|
kf := newKernelFilter(iw, m.Kernel.Cmdline, m.Kernel.Binary, m.Kernel.Tar)
|
||||||
err := ImageTar(m.Kernel.Image, "", kf, enforceContentTrust(m.Kernel.Image, &m.Trust), pull, "")
|
err := ImageTar(m.Kernel.ref, "", kf, enforceContentTrust(m.Kernel.ref.String(), &m.Trust), pull, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to extract kernel image and tarball: %v", err)
|
return fmt.Errorf("Failed to extract kernel image and tarball: %v", err)
|
||||||
}
|
}
|
||||||
@ -189,9 +189,8 @@ func Build(m Moby, w io.Writer, pull bool, tp string) error {
|
|||||||
if len(m.Init) != 0 {
|
if len(m.Init) != 0 {
|
||||||
log.Infof("Add init containers:")
|
log.Infof("Add init containers:")
|
||||||
}
|
}
|
||||||
for _, ii := range m.Init {
|
for _, ii := range m.initRefs {
|
||||||
log.Infof("Process init image: %s", ii)
|
err := ImageTar(ii, "", iw, enforceContentTrust(ii.String(), &m.Trust), pull, resolvconfSymlink)
|
||||||
err := ImageTar(ii, "", iw, enforceContentTrust(ii, &m.Trust), pull, resolvconfSymlink)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to build init tarball from %s: %v", ii, err)
|
return fmt.Errorf("Failed to build init tarball from %s: %v", ii, err)
|
||||||
}
|
}
|
||||||
|
@ -351,7 +351,7 @@ func ConfigToOCI(image *Image, trust bool, idMap map[string]uint32) (specs.Spec,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return specs.Spec{}, Runtime{}, err
|
return specs.Spec{}, Runtime{}, err
|
||||||
}
|
}
|
||||||
inspect, err := dockerInspectImage(cli, image.Image, trust)
|
inspect, err := dockerInspectImage(cli, image.ref, trust)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return specs.Spec{}, Runtime{}, err
|
return specs.Spec{}, Runtime{}, err
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
log "github.com/Sirupsen/logrus"
|
log "github.com/Sirupsen/logrus"
|
||||||
|
"github.com/containerd/containerd/reference"
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/container"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/docker/docker/api/types/filters"
|
"github.com/docker/docker/api/types/filters"
|
||||||
@ -97,18 +98,18 @@ func dockerRm(container string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func dockerPull(image string, forcePull, trustedPull bool) error {
|
func dockerPull(ref *reference.Spec, forcePull, trustedPull bool) error {
|
||||||
log.Debugf("docker pull: %s", image)
|
log.Debugf("docker pull: %s", ref)
|
||||||
cli, err := dockerClient()
|
cli, err := dockerClient()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New("could not initialize Docker API client")
|
return errors.New("could not initialize Docker API client")
|
||||||
}
|
}
|
||||||
|
|
||||||
if trustedPull {
|
if trustedPull {
|
||||||
log.Debugf("pulling %s with content trust", image)
|
log.Debugf("pulling %s with content trust", ref)
|
||||||
trustedImg, err := TrustedReference(image)
|
trustedImg, err := TrustedReference(ref.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Trusted pull for %s failed: %v", image, err)
|
return fmt.Errorf("Trusted pull for %s failed: %v", ref, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// tag the image on a best-effort basis after pulling with content trust,
|
// tag the image on a best-effort basis after pulling with content trust,
|
||||||
@ -117,10 +118,15 @@ func dockerPull(image string, forcePull, trustedPull bool) error {
|
|||||||
if err := cli.ImageTag(context.Background(), src, dst); err != nil {
|
if err := cli.ImageTag(context.Background(), src, dst); err != nil {
|
||||||
log.Debugf("could not tag trusted image %s to %s", src, dst)
|
log.Debugf("could not tag trusted image %s to %s", src, dst)
|
||||||
}
|
}
|
||||||
}(trustedImg.String(), image)
|
}(trustedImg.String(), ref.String())
|
||||||
|
|
||||||
log.Debugf("successfully verified trusted reference %s from notary", trustedImg.String())
|
log.Debugf("successfully verified trusted reference %s from notary", trustedImg.String())
|
||||||
image = trustedImg.String()
|
trustedSpec, err := reference.Parse(trustedImg.String())
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to convert trusted img %s to Spec: %v", trustedImg, err)
|
||||||
|
}
|
||||||
|
ref.Locator = trustedSpec.Locator
|
||||||
|
ref.Object = trustedSpec.Object
|
||||||
|
|
||||||
imageSearchArg := filters.NewArgs()
|
imageSearchArg := filters.NewArgs()
|
||||||
imageSearchArg.Add("reference", trustedImg.String())
|
imageSearchArg.Add("reference", trustedImg.String())
|
||||||
@ -130,8 +136,8 @@ func dockerPull(image string, forcePull, trustedPull bool) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Infof("Pull image: %s", image)
|
log.Infof("Pull image: %s", ref)
|
||||||
r, err := cli.ImagePull(context.Background(), image, types.ImagePullOptions{})
|
r, err := cli.ImagePull(context.Background(), ref.String(), types.ImagePullOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -140,7 +146,7 @@ func dockerPull(image string, forcePull, trustedPull bool) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.Debugf("docker pull: %s...Done", image)
|
log.Debugf("docker pull: %s...Done", ref)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,17 +159,17 @@ func dockerClient() (*client.Client, error) {
|
|||||||
return client.NewEnvClient()
|
return client.NewEnvClient()
|
||||||
}
|
}
|
||||||
|
|
||||||
func dockerInspectImage(cli *client.Client, image string, trustedPull bool) (types.ImageInspect, error) {
|
func dockerInspectImage(cli *client.Client, ref *reference.Spec, trustedPull bool) (types.ImageInspect, error) {
|
||||||
log.Debugf("docker inspect image: %s", image)
|
log.Debugf("docker inspect image: %s", ref)
|
||||||
|
|
||||||
inspect, _, err := cli.ImageInspectWithRaw(context.Background(), image)
|
inspect, _, err := cli.ImageInspectWithRaw(context.Background(), ref.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if client.IsErrImageNotFound(err) {
|
if client.IsErrImageNotFound(err) {
|
||||||
pullErr := dockerPull(image, true, trustedPull)
|
pullErr := dockerPull(ref, true, trustedPull)
|
||||||
if pullErr != nil {
|
if pullErr != nil {
|
||||||
return types.ImageInspect{}, pullErr
|
return types.ImageInspect{}, pullErr
|
||||||
}
|
}
|
||||||
inspect, _, err = cli.ImageInspectWithRaw(context.Background(), image)
|
inspect, _, err = cli.ImageInspectWithRaw(context.Background(), ref.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return types.ImageInspect{}, err
|
return types.ImageInspect{}, err
|
||||||
}
|
}
|
||||||
@ -172,7 +178,7 @@ func dockerInspectImage(cli *client.Client, image string, trustedPull bool) (typ
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("docker inspect image: %s...Done", image)
|
log.Debugf("docker inspect image: %s...Done", ref)
|
||||||
|
|
||||||
return inspect, nil
|
return inspect, nil
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
log "github.com/Sirupsen/logrus"
|
log "github.com/Sirupsen/logrus"
|
||||||
|
"github.com/containerd/containerd/reference"
|
||||||
"github.com/opencontainers/runtime-spec/specs-go"
|
"github.com/opencontainers/runtime-spec/specs-go"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -81,8 +82,8 @@ func tarPrefix(path string, tw tarWriter) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ImageTar takes a Docker image and outputs it to a tar stream
|
// ImageTar takes a Docker image and outputs it to a tar stream
|
||||||
func ImageTar(image, prefix string, tw tarWriter, trust bool, pull bool, resolv string) error {
|
func ImageTar(ref *reference.Spec, prefix string, tw tarWriter, trust bool, pull bool, resolv string) error {
|
||||||
log.Debugf("image tar: %s %s", image, prefix)
|
log.Debugf("image tar: %s %s", ref, prefix)
|
||||||
if prefix != "" && prefix[len(prefix)-1] != byte('/') {
|
if prefix != "" && prefix[len(prefix)-1] != byte('/') {
|
||||||
return fmt.Errorf("prefix does not end with /: %s", prefix)
|
return fmt.Errorf("prefix does not end with /: %s", prefix)
|
||||||
}
|
}
|
||||||
@ -93,25 +94,25 @@ func ImageTar(image, prefix string, tw tarWriter, trust bool, pull bool, resolv
|
|||||||
}
|
}
|
||||||
|
|
||||||
if pull || trust {
|
if pull || trust {
|
||||||
err := dockerPull(image, pull, trust)
|
err := dockerPull(ref, pull, trust)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Could not pull image %s: %v", image, err)
|
return fmt.Errorf("Could not pull image %s: %v", ref, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
container, err := dockerCreate(image)
|
container, err := dockerCreate(ref.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// if the image wasn't found, pull it down. Bail on other errors.
|
// if the image wasn't found, pull it down. Bail on other errors.
|
||||||
if strings.Contains(err.Error(), "No such image") {
|
if strings.Contains(err.Error(), "No such image") {
|
||||||
err := dockerPull(image, true, trust)
|
err := dockerPull(ref, true, trust)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Could not pull image %s: %v", image, err)
|
return fmt.Errorf("Could not pull image %s: %v", ref, err)
|
||||||
}
|
}
|
||||||
container, err = dockerCreate(image)
|
container, err = dockerCreate(ref.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to docker create image %s: %v", image, err)
|
return fmt.Errorf("Failed to docker create image %s: %v", ref, err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return fmt.Errorf("Failed to create docker image %s: %v", image, err)
|
return fmt.Errorf("Failed to create docker image %s: %v", ref, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
contents, err := dockerExport(container)
|
contents, err := dockerExport(container)
|
||||||
@ -137,7 +138,7 @@ func ImageTar(image, prefix string, tw tarWriter, trust bool, pull bool, resolv
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if exclude[hdr.Name] {
|
if exclude[hdr.Name] {
|
||||||
log.Debugf("image tar: %s %s exclude %s", image, prefix, hdr.Name)
|
log.Debugf("image tar: %s %s exclude %s", ref, prefix, hdr.Name)
|
||||||
_, err = io.Copy(ioutil.Discard, tr)
|
_, err = io.Copy(ioutil.Discard, tr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -147,7 +148,7 @@ func ImageTar(image, prefix string, tw tarWriter, trust bool, pull bool, resolv
|
|||||||
contents := replace[hdr.Name]
|
contents := replace[hdr.Name]
|
||||||
hdr.Size = int64(len(contents))
|
hdr.Size = int64(len(contents))
|
||||||
hdr.Name = prefix + hdr.Name
|
hdr.Name = prefix + hdr.Name
|
||||||
log.Debugf("image tar: %s %s add %s", image, prefix, hdr.Name)
|
log.Debugf("image tar: %s %s add %s", ref, prefix, hdr.Name)
|
||||||
if err := tw.WriteHeader(hdr); err != nil {
|
if err := tw.WriteHeader(hdr); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -162,7 +163,7 @@ func ImageTar(image, prefix string, tw tarWriter, trust bool, pull bool, resolv
|
|||||||
hdr.Size = 0
|
hdr.Size = 0
|
||||||
hdr.Typeflag = tar.TypeSymlink
|
hdr.Typeflag = tar.TypeSymlink
|
||||||
hdr.Linkname = resolv
|
hdr.Linkname = resolv
|
||||||
log.Debugf("image tar: %s %s add resolv symlink /etc/resolv.conf -> %s", image, prefix, resolv)
|
log.Debugf("image tar: %s %s add resolv symlink /etc/resolv.conf -> %s", ref, prefix, resolv)
|
||||||
if err := tw.WriteHeader(hdr); err != nil {
|
if err := tw.WriteHeader(hdr); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -172,7 +173,7 @@ func ImageTar(image, prefix string, tw tarWriter, trust bool, pull bool, resolv
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Debugf("image tar: %s %s add %s", image, prefix, hdr.Name)
|
log.Debugf("image tar: %s %s add %s", ref, prefix, hdr.Name)
|
||||||
hdr.Name = prefix + hdr.Name
|
hdr.Name = prefix + hdr.Name
|
||||||
if hdr.Typeflag == tar.TypeLink {
|
if hdr.Typeflag == tar.TypeLink {
|
||||||
// hard links are referenced by full path so need to be adjusted
|
// hard links are referenced by full path so need to be adjusted
|
||||||
@ -191,7 +192,7 @@ func ImageTar(image, prefix string, tw tarWriter, trust bool, pull bool, resolv
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ImageBundle produces an OCI bundle at the given path in a tarball, given an image and a config.json
|
// ImageBundle produces an OCI bundle at the given path in a tarball, given an image and a config.json
|
||||||
func ImageBundle(prefix string, image string, config []byte, runtime Runtime, tw tarWriter, trust bool, pull bool, readonly bool, dupMap map[string]string) error {
|
func ImageBundle(prefix string, ref *reference.Spec, config []byte, runtime Runtime, tw tarWriter, trust bool, pull bool, readonly bool, dupMap map[string]string) error {
|
||||||
// if read only, just unpack in rootfs/ but otherwise set up for overlay
|
// if read only, just unpack in rootfs/ but otherwise set up for overlay
|
||||||
rootExtract := "rootfs"
|
rootExtract := "rootfs"
|
||||||
if !readonly {
|
if !readonly {
|
||||||
@ -200,17 +201,17 @@ func ImageBundle(prefix string, image string, config []byte, runtime Runtime, tw
|
|||||||
|
|
||||||
// See if we have extracted this image previously
|
// See if we have extracted this image previously
|
||||||
root := path.Join(prefix, rootExtract)
|
root := path.Join(prefix, rootExtract)
|
||||||
var foundElsewhere = dupMap[image] != ""
|
var foundElsewhere = dupMap[ref.String()] != ""
|
||||||
if !foundElsewhere {
|
if !foundElsewhere {
|
||||||
if err := ImageTar(image, root+"/", tw, trust, pull, ""); err != nil {
|
if err := ImageTar(ref, root+"/", tw, trust, pull, ""); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
dupMap[image] = root
|
dupMap[ref.String()] = root
|
||||||
} else {
|
} else {
|
||||||
if err := tarPrefix(prefix+"/", tw); err != nil {
|
if err := tarPrefix(prefix+"/", tw); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
root = dupMap[image]
|
root = dupMap[ref.String()]
|
||||||
}
|
}
|
||||||
|
|
||||||
hdr := &tar.Header{
|
hdr := &tar.Header{
|
||||||
@ -274,7 +275,7 @@ func ImageBundle(prefix string, image string, config []byte, runtime Runtime, tw
|
|||||||
// write the runtime config
|
// write the runtime config
|
||||||
runtimeConfig, err := json.MarshalIndent(runtime, "", " ")
|
runtimeConfig, err := json.MarshalIndent(runtime, "", " ")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to create runtime config for %s: %v", image, err)
|
return fmt.Errorf("Failed to create runtime config for %s: %v", ref, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
hdr = &tar.Header{
|
hdr = &tar.Header{
|
||||||
@ -290,7 +291,7 @@ func ImageBundle(prefix string, image string, config []byte, runtime Runtime, tw
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("image bundle: %s %s cfg: %s runtime: %s", prefix, image, string(config), string(runtimeConfig))
|
log.Debugf("image bundle: %s %s cfg: %s runtime: %s", prefix, ref, string(config), string(runtimeConfig))
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user