This patch fixed below 4 types of code line 1. Remove unnecessary variable assignment 2. Use variables declaration instead of explicit initial zero value 3. Change variable name to underbar when variable not used 4. Add erro check and return for ignored error Signed-off-by: Daehyeok Mun <daehyeok@gmail.com> Upstream-commit: 6306019d0bad9c4e60ee437e93f2450dfb0b68c0 Component: engine
131 lines
3.0 KiB
Go
131 lines
3.0 KiB
Go
//+build !windows
|
|
|
|
package chrootarchive
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"flag"
|
|
"fmt"
|
|
"io"
|
|
"io/ioutil"
|
|
"os"
|
|
"path/filepath"
|
|
"runtime"
|
|
|
|
"github.com/docker/docker/pkg/archive"
|
|
"github.com/docker/docker/pkg/reexec"
|
|
"github.com/docker/docker/pkg/system"
|
|
rsystem "github.com/opencontainers/runc/libcontainer/system"
|
|
)
|
|
|
|
type applyLayerResponse struct {
|
|
LayerSize int64 `json:"layerSize"`
|
|
}
|
|
|
|
// applyLayer is the entry-point for docker-applylayer on re-exec. This is not
|
|
// used on Windows as it does not support chroot, hence no point sandboxing
|
|
// through chroot and rexec.
|
|
func applyLayer() {
|
|
|
|
var (
|
|
tmpDir string
|
|
err error
|
|
options *archive.TarOptions
|
|
)
|
|
runtime.LockOSThread()
|
|
flag.Parse()
|
|
|
|
inUserns := rsystem.RunningInUserNS()
|
|
if err := chroot(flag.Arg(0)); err != nil {
|
|
fatal(err)
|
|
}
|
|
|
|
// We need to be able to set any perms
|
|
oldmask, err := system.Umask(0)
|
|
defer system.Umask(oldmask)
|
|
if err != nil {
|
|
fatal(err)
|
|
}
|
|
|
|
if err := json.Unmarshal([]byte(os.Getenv("OPT")), &options); err != nil {
|
|
fatal(err)
|
|
}
|
|
|
|
if inUserns {
|
|
options.InUserNS = true
|
|
}
|
|
|
|
if tmpDir, err = ioutil.TempDir("/", "temp-docker-extract"); err != nil {
|
|
fatal(err)
|
|
}
|
|
|
|
os.Setenv("TMPDIR", tmpDir)
|
|
size, err := archive.UnpackLayer("/", os.Stdin, options)
|
|
os.RemoveAll(tmpDir)
|
|
if err != nil {
|
|
fatal(err)
|
|
}
|
|
|
|
encoder := json.NewEncoder(os.Stdout)
|
|
if err := encoder.Encode(applyLayerResponse{size}); err != nil {
|
|
fatal(fmt.Errorf("unable to encode layerSize JSON: %s", err))
|
|
}
|
|
|
|
if _, err := flush(os.Stdin); err != nil {
|
|
fatal(err)
|
|
}
|
|
|
|
os.Exit(0)
|
|
}
|
|
|
|
// applyLayerHandler parses a diff in the standard layer format from `layer`, and
|
|
// applies it to the directory `dest`. Returns the size in bytes of the
|
|
// contents of the layer.
|
|
func applyLayerHandler(dest string, layer io.Reader, options *archive.TarOptions, decompress bool) (size int64, err error) {
|
|
dest = filepath.Clean(dest)
|
|
if decompress {
|
|
decompressed, err := archive.DecompressStream(layer)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
defer decompressed.Close()
|
|
|
|
layer = decompressed
|
|
}
|
|
if options == nil {
|
|
options = &archive.TarOptions{}
|
|
if rsystem.RunningInUserNS() {
|
|
options.InUserNS = true
|
|
}
|
|
}
|
|
if options.ExcludePatterns == nil {
|
|
options.ExcludePatterns = []string{}
|
|
}
|
|
|
|
data, err := json.Marshal(options)
|
|
if err != nil {
|
|
return 0, fmt.Errorf("ApplyLayer json encode: %v", err)
|
|
}
|
|
|
|
cmd := reexec.Command("docker-applyLayer", dest)
|
|
cmd.Stdin = layer
|
|
cmd.Env = append(cmd.Env, fmt.Sprintf("OPT=%s", data))
|
|
|
|
outBuf, errBuf := new(bytes.Buffer), new(bytes.Buffer)
|
|
cmd.Stdout, cmd.Stderr = outBuf, errBuf
|
|
|
|
if err = cmd.Run(); err != nil {
|
|
return 0, fmt.Errorf("ApplyLayer %s stdout: %s stderr: %s", err, outBuf, errBuf)
|
|
}
|
|
|
|
// Stdout should be a valid JSON struct representing an applyLayerResponse.
|
|
response := applyLayerResponse{}
|
|
decoder := json.NewDecoder(outBuf)
|
|
if err = decoder.Decode(&response); err != nil {
|
|
return 0, fmt.Errorf("unable to decode ApplyLayer JSON response: %s", err)
|
|
}
|
|
|
|
return response.LayerSize, nil
|
|
}
|