88 lines
2.5 KiB
Go
88 lines
2.5 KiB
Go
/*
|
|
Copyright 2018 Google LLC
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package util
|
|
|
|
import (
|
|
"bufio"
|
|
pkgutil "github.com/GoogleCloudPlatform/container-diff/pkg/util"
|
|
"github.com/GoogleCloudPlatform/k8s-container-builder/pkg/constants"
|
|
"github.com/containers/image/docker"
|
|
"github.com/sirupsen/logrus"
|
|
"io"
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
var whitelist = []string{"/work-dir", "/dockerfile"}
|
|
|
|
// ExtractFileSystemFromImage pulls an image and unpacks it to a file system at root
|
|
func ExtractFileSystemFromImage(img string) error {
|
|
ref, err := docker.ParseReference("//" + img)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
imgSrc, err := ref.NewImageSource(nil)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
whitelist, err := fileSystemWhitelist(constants.WhitelistPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
logrus.Infof("Whitelisted directories are %s", whitelist)
|
|
return pkgutil.GetFileSystemFromReference(ref, imgSrc, constants.RootDir, whitelist)
|
|
}
|
|
|
|
// Get whitelist from roots of mounted files
|
|
// Each line of /proc/self/mountinfo is in the form:
|
|
// 36 35 98:0 /mnt1 /mnt2 rw,noatime master:1 - ext3 /dev/root rw,errors=continue
|
|
// (1)(2)(3) (4) (5) (6) (7) (8) (9) (10) (11)
|
|
// Where (5) is the mount point relative to the process's root
|
|
// From: https://www.kernel.org/doc/Documentation/filesystems/proc.txt
|
|
func fileSystemWhitelist(path string) ([]string, error) {
|
|
f, err := os.Open(path)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer f.Close()
|
|
reader := bufio.NewReader(f)
|
|
for {
|
|
line, err := reader.ReadString('\n')
|
|
logrus.Debugf("Read the following line from %s: %s", path, line)
|
|
if err != nil && err != io.EOF {
|
|
return nil, err
|
|
}
|
|
lineArr := strings.Split(line, " ")
|
|
if len(lineArr) < 5 {
|
|
if err == io.EOF {
|
|
logrus.Debugf("Reached end of file %s", path)
|
|
break
|
|
}
|
|
continue
|
|
}
|
|
if lineArr[4] != constants.RootDir {
|
|
logrus.Debugf("Appending %s from line: %s", lineArr[4], line)
|
|
whitelist = append(whitelist, lineArr[4])
|
|
}
|
|
if err == io.EOF {
|
|
logrus.Debugf("Reached end of file %s", path)
|
|
break
|
|
}
|
|
}
|
|
return whitelist, nil
|
|
}
|