mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00

Some structures use int for sizes and UNIX timestamps. On some platforms, int is 32 bits, so this can lead to the year 2038 issues and overflows when dealing with large containers or layers. Consistently use int64 to store sizes and UNIX timestamps in api/types/types.go. Update related to code accordingly (i.e. strconv.FormatInt instead of strconv.Itoa). Use int64 in progressreader package to avoid integer overflow when dealing with large quantities. Update related code accordingly. Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
120 lines
3.3 KiB
Go
120 lines
3.3 KiB
Go
// +build !windows
|
|
|
|
package graph
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"syscall"
|
|
|
|
"github.com/Sirupsen/logrus"
|
|
"github.com/docker/docker/image"
|
|
"github.com/docker/docker/pkg/archive"
|
|
"github.com/docker/docker/pkg/system"
|
|
)
|
|
|
|
// SetupInitLayer populates a directory with mountpoints suitable
|
|
// for bind-mounting dockerinit into the container. The mountpoint is simply an
|
|
// empty file at /.dockerinit
|
|
// This extra layer is used by all containers as the top-most ro layer. It protects
|
|
// the container from unwanted side-effects on the rw layer.
|
|
func SetupInitLayer(initLayer string) error {
|
|
for pth, typ := range map[string]string{
|
|
"/dev/pts": "dir",
|
|
"/dev/shm": "dir",
|
|
"/proc": "dir",
|
|
"/sys": "dir",
|
|
"/.dockerinit": "file",
|
|
"/.dockerenv": "file",
|
|
"/etc/resolv.conf": "file",
|
|
"/etc/hosts": "file",
|
|
"/etc/hostname": "file",
|
|
"/dev/console": "file",
|
|
"/etc/mtab": "/proc/mounts",
|
|
} {
|
|
parts := strings.Split(pth, "/")
|
|
prev := "/"
|
|
for _, p := range parts[1:] {
|
|
prev = filepath.Join(prev, p)
|
|
syscall.Unlink(filepath.Join(initLayer, prev))
|
|
}
|
|
|
|
if _, err := os.Stat(filepath.Join(initLayer, pth)); err != nil {
|
|
if os.IsNotExist(err) {
|
|
if err := system.MkdirAll(filepath.Join(initLayer, filepath.Dir(pth)), 0755); err != nil {
|
|
return err
|
|
}
|
|
switch typ {
|
|
case "dir":
|
|
if err := system.MkdirAll(filepath.Join(initLayer, pth), 0755); err != nil {
|
|
return err
|
|
}
|
|
case "file":
|
|
f, err := os.OpenFile(filepath.Join(initLayer, pth), os.O_CREATE, 0755)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
f.Close()
|
|
default:
|
|
if err := os.Symlink(typ, filepath.Join(initLayer, pth)); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
} else {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
|
|
// Layer is ready to use, if it wasn't before.
|
|
return nil
|
|
}
|
|
|
|
func createRootFilesystemInDriver(graph *Graph, img *image.Image, layerData archive.ArchiveReader) error {
|
|
if err := graph.driver.Create(img.ID, img.Parent); err != nil {
|
|
return fmt.Errorf("Driver %s failed to create image rootfs %s: %s", graph.driver, img.ID, err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (graph *Graph) restoreBaseImages() ([]string, error) {
|
|
return nil, nil
|
|
}
|
|
|
|
// storeImage stores file system layer data for the given image to the
|
|
// graph's storage driver. Image metadata is stored in a file
|
|
// at the specified root directory.
|
|
func (graph *Graph) storeImage(img *image.Image, layerData archive.ArchiveReader, root string) (err error) {
|
|
// Store the layer. If layerData is not nil, unpack it into the new layer
|
|
if layerData != nil {
|
|
if err := graph.disassembleAndApplyTarLayer(img, layerData, root); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
if err := graph.saveSize(root, img.Size); err != nil {
|
|
return err
|
|
}
|
|
|
|
f, err := os.OpenFile(jsonPath(root), os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.FileMode(0600))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
defer f.Close()
|
|
|
|
return json.NewEncoder(f).Encode(img)
|
|
}
|
|
|
|
// TarLayer returns a tar archive of the image's filesystem layer.
|
|
func (graph *Graph) TarLayer(img *image.Image) (arch archive.Archive, err error) {
|
|
rdr, err := graph.assembleTarLayer(img)
|
|
if err != nil {
|
|
logrus.Debugf("[graph] TarLayer with traditional differ: %s", img.ID)
|
|
return graph.driver.Diff(img.ID, img.Parent)
|
|
}
|
|
return rdr, nil
|
|
}
|