6306019d0b
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>
130 lines
3 KiB
Go
130 lines
3 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
|
|
}
|