Skip to content

Instantly share code, notes, and snippets.

@ehazlett
Last active October 8, 2019 19:31
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ehazlett/096f9166eff7e4f4248fcafe1bbca82b to your computer and use it in GitHub Desktop.
Save ehazlett/096f9166eff7e4f4248fcafe1bbca82b to your computer and use it in GitHub Desktop.
func withCheckpointMounts(c *container.Container) containerd.CheckpointOpts {
return func(ctx context.Context, client *containerd.Client, _ *containers.Container, index *imagespec.Index, _ *options.CheckpointOptions) error {
for _, m := range c.MountPoints {
// tarstream of content
// a tmpdir is created to use as the blank comparison directory for the diff
tmpdir, err := ioutil.TempDir("", "container-data-")
if err != nil {
return err
}
defer os.RemoveAll(tmpdir)
r := archive.Diff(ctx, tmpdir, m.Path())
desc, err := writeContent(ctx, client.ContentStore(), MediaTypeVolumeData1ContainerMountData, c.ID+"-mountpoint-"+m.ID, r)
if err != nil {
return err
}
desc.Platform = &imagespec.Platform{
OS: runtime.GOOS,
Architecture: runtime.GOARCH,
}
if desc.Annotations == nil {
desc.Annotations = map[string]string{}
}
desc.Annotations[annotationMountPointDest] = m.Destination
desc.Annotations[annotationMountPointDriver] = m.Driver
index.Manifests = append(index.Manifests, desc)
}
return nil
}
}
func (s *Service) applyContainerMounts(ctx context.Context, index *imagespec.Index, c *container.Container) error {
store := s.containerd.ContentStore()
mounts := map[string]string{}
for _, mountpoint := range c.MountPoints {
mounts[mountpoint.Destination] = mountpoint.Path()
}
for _, m := range index.Manifests {
if m.MediaType != MediaTypeVolumeData1ContainerMountData {
continue
}
dest, ok := m.Annotations[annotationMountPointDest]
if !ok {
logrus.WithField("container", c.ID).Error("checkpoint mount missing dest label")
continue
}
mp, ok := mounts[dest]
if !ok {
logrus.WithField("container", c.ID).Warnf("mount point %s not found in container", dest)
continue
}
data, err := content.ReadBlob(ctx, store, m)
if err != nil {
return errors.Wrap(err, "unable to read checkpoint mount data")
}
rw := bytes.NewReader(data)
if _, err := archive.Apply(ctx, mp, rw); err != nil {
return errors.Wrap(err, "error applying checkpoint mount data")
}
}
return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment