mirror of
https://github.com/GoogleContainerTools/kaniko
synced 2026-10-21 21:37:08 +02:00
Merge branch 'master', add examples
This commit is contained in:
@@ -44,12 +44,16 @@ func GetCommand(cmd instructions.Command, buildcontext string) (DockerCommand, e
|
||||
return &ExposeCommand{cmd: c}, nil
|
||||
case *instructions.EnvCommand:
|
||||
return &EnvCommand{cmd: c}, nil
|
||||
case *instructions.WorkdirCommand:
|
||||
return &WorkdirCommand{cmd: c}, nil
|
||||
case *instructions.CmdCommand:
|
||||
return &CmdCommand{cmd: c}, nil
|
||||
case *instructions.EntrypointCommand:
|
||||
return &EntrypointCommand{cmd: c}, nil
|
||||
case *instructions.LabelCommand:
|
||||
return &LabelCommand{cmd: c}, nil
|
||||
case *instructions.UserCommand:
|
||||
return &UserCommand{cmd: c}, nil
|
||||
}
|
||||
return nil, errors.Errorf("%s is not a supported command", cmd.Name())
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ type ExposeCommand struct {
|
||||
}
|
||||
|
||||
func (r *ExposeCommand) ExecuteCommand(config *manifest.Schema2Config) error {
|
||||
logrus.Info("cmd: EXPOSE")
|
||||
// Grab the currently exposed ports
|
||||
existingPorts := config.ExposedPorts
|
||||
// Add any new ones in
|
||||
|
||||
@@ -29,6 +29,7 @@ type LabelCommand struct {
|
||||
}
|
||||
|
||||
func (r *LabelCommand) ExecuteCommand(config *manifest.Schema2Config) error {
|
||||
logrus.Info("cmd: LABEL")
|
||||
return updateLabels(r.cmd.Labels, config)
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,9 @@ import (
|
||||
"github.com/sirupsen/logrus"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
type RunCommand struct {
|
||||
@@ -44,7 +46,28 @@ func (r *RunCommand) ExecuteCommand(config *manifest.Schema2Config) error {
|
||||
logrus.Infof("args: %s", newCommand[1:])
|
||||
|
||||
cmd := exec.Command(newCommand[0], newCommand[1:]...)
|
||||
cmd.Dir = config.WorkingDir
|
||||
cmd.Stdout = os.Stdout
|
||||
// If specified, run the command as a specific user
|
||||
if config.User != "" {
|
||||
userAndGroup := strings.Split(config.User, ":")
|
||||
// uid and gid need to be uint32
|
||||
uid64, err := strconv.ParseUint(userAndGroup[0], 10, 32)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
uid := uint32(uid64)
|
||||
var gid uint32
|
||||
if len(userAndGroup) > 1 {
|
||||
gid64, err := strconv.ParseUint(userAndGroup[1], 10, 32)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
gid = uint32(gid64)
|
||||
}
|
||||
cmd.SysProcAttr = &syscall.SysProcAttr{}
|
||||
cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uid, Gid: gid}
|
||||
}
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
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 commands
|
||||
|
||||
import (
|
||||
"github.com/GoogleCloudPlatform/k8s-container-builder/pkg/util"
|
||||
"github.com/containers/image/manifest"
|
||||
"github.com/docker/docker/builder/dockerfile/instructions"
|
||||
"github.com/sirupsen/logrus"
|
||||
"os/user"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type UserCommand struct {
|
||||
cmd *instructions.UserCommand
|
||||
}
|
||||
|
||||
func (r *UserCommand) ExecuteCommand(config *manifest.Schema2Config) error {
|
||||
logrus.Info("cmd: USER")
|
||||
u := r.cmd.User
|
||||
userAndGroup := strings.Split(u, ":")
|
||||
userStr, err := util.ResolveEnvironmentReplacement(userAndGroup[0], config.Env, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var groupStr string
|
||||
if len(userAndGroup) > 1 {
|
||||
groupStr, err = util.ResolveEnvironmentReplacement(userAndGroup[1], config.Env, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Lookup by username
|
||||
userObj, err := user.Lookup(userStr)
|
||||
if err != nil {
|
||||
if _, ok := err.(user.UnknownUserError); ok {
|
||||
// Lookup by id
|
||||
userObj, err = user.LookupId(userStr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Same dance with groups
|
||||
var group *user.Group
|
||||
if groupStr != "" {
|
||||
group, err = user.LookupGroup(groupStr)
|
||||
if err != nil {
|
||||
if _, ok := err.(user.UnknownGroupError); ok {
|
||||
group, err = user.LookupGroupId(groupStr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uid := userObj.Uid
|
||||
if group != nil {
|
||||
uid = uid + ":" + group.Gid
|
||||
}
|
||||
|
||||
logrus.Infof("Setting user to %s", uid)
|
||||
config.User = uid
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *UserCommand) FilesToSnapshot() []string {
|
||||
return []string{}
|
||||
}
|
||||
|
||||
func (r *UserCommand) CreatedBy() string {
|
||||
s := []string{r.cmd.Name(), r.cmd.User}
|
||||
return strings.Join(s, " ")
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
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 commands
|
||||
|
||||
import (
|
||||
"github.com/GoogleCloudPlatform/k8s-container-builder/testutil"
|
||||
"github.com/containers/image/manifest"
|
||||
"github.com/docker/docker/builder/dockerfile/instructions"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var userTests = []struct {
|
||||
user string
|
||||
expectedUid string
|
||||
shouldError bool
|
||||
}{
|
||||
{
|
||||
user: "root",
|
||||
expectedUid: "0",
|
||||
shouldError: false,
|
||||
},
|
||||
{
|
||||
user: "0",
|
||||
expectedUid: "0",
|
||||
shouldError: false,
|
||||
},
|
||||
{
|
||||
user: "fakeUser",
|
||||
expectedUid: "",
|
||||
shouldError: true,
|
||||
},
|
||||
{
|
||||
user: "root:root",
|
||||
expectedUid: "0:0",
|
||||
shouldError: false,
|
||||
},
|
||||
{
|
||||
user: "0:root",
|
||||
expectedUid: "0:0",
|
||||
shouldError: false,
|
||||
},
|
||||
{
|
||||
user: "root:0",
|
||||
expectedUid: "0:0",
|
||||
shouldError: false,
|
||||
},
|
||||
{
|
||||
user: "0:0",
|
||||
expectedUid: "0:0",
|
||||
shouldError: false,
|
||||
},
|
||||
{
|
||||
user: "root:fakeGroup",
|
||||
expectedUid: "",
|
||||
shouldError: true,
|
||||
},
|
||||
{
|
||||
user: "$envuser",
|
||||
expectedUid: "0",
|
||||
shouldError: false,
|
||||
},
|
||||
{
|
||||
user: "root:$envgroup",
|
||||
expectedUid: "0:0",
|
||||
shouldError: false,
|
||||
},
|
||||
}
|
||||
|
||||
func TestUpdateUser(t *testing.T) {
|
||||
for _, test := range userTests {
|
||||
cfg := &manifest.Schema2Config{
|
||||
Env: []string{
|
||||
"envuser=root",
|
||||
"envgroup=root",
|
||||
},
|
||||
}
|
||||
cmd := UserCommand{
|
||||
&instructions.UserCommand{
|
||||
User: test.user,
|
||||
},
|
||||
}
|
||||
err := cmd.ExecuteCommand(cfg)
|
||||
testutil.CheckErrorAndDeepEqual(t, test.shouldError, err, test.expectedUid, cfg.User)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
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 commands
|
||||
|
||||
import (
|
||||
"github.com/GoogleCloudPlatform/k8s-container-builder/pkg/util"
|
||||
"github.com/containers/image/manifest"
|
||||
"github.com/docker/docker/builder/dockerfile/instructions"
|
||||
"github.com/sirupsen/logrus"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
type WorkdirCommand struct {
|
||||
cmd *instructions.WorkdirCommand
|
||||
snapshotFiles []string
|
||||
}
|
||||
|
||||
func (w *WorkdirCommand) ExecuteCommand(config *manifest.Schema2Config) error {
|
||||
logrus.Info("cmd: workdir")
|
||||
workdirPath := w.cmd.Path
|
||||
resolvedWorkingDir, err := util.ResolveEnvironmentReplacement(workdirPath, config.Env, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if filepath.IsAbs(resolvedWorkingDir) {
|
||||
config.WorkingDir = resolvedWorkingDir
|
||||
} else {
|
||||
config.WorkingDir = filepath.Join(config.WorkingDir, resolvedWorkingDir)
|
||||
}
|
||||
logrus.Infof("Changed working directory to %s", config.WorkingDir)
|
||||
w.snapshotFiles = []string{config.WorkingDir}
|
||||
return os.MkdirAll(config.WorkingDir, 0755)
|
||||
}
|
||||
|
||||
// FilesToSnapshot returns the workingdir, which should have been created if it didn't already exist
|
||||
func (w *WorkdirCommand) FilesToSnapshot() []string {
|
||||
return w.snapshotFiles
|
||||
}
|
||||
|
||||
// CreatedBy returns some information about the command for the image config history
|
||||
func (w *WorkdirCommand) CreatedBy() string {
|
||||
return w.cmd.Name() + " " + w.cmd.Path
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
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 commands
|
||||
|
||||
import (
|
||||
"github.com/GoogleCloudPlatform/k8s-container-builder/testutil"
|
||||
"github.com/containers/image/manifest"
|
||||
"github.com/docker/docker/builder/dockerfile/instructions"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// Each test here changes the same WorkingDir field in the config
|
||||
// So, some of the tests build off of each other
|
||||
// This is needed to make sure WorkingDir handles paths correctly
|
||||
// For example, if WORKDIR specifies a non-absolute path, it should be appended to the current WORKDIR
|
||||
var workdirTests = []struct {
|
||||
path string
|
||||
expectedPath string
|
||||
}{
|
||||
{
|
||||
path: "/a",
|
||||
expectedPath: "/a",
|
||||
},
|
||||
{
|
||||
path: "b",
|
||||
expectedPath: "/a/b",
|
||||
},
|
||||
{
|
||||
path: "c",
|
||||
expectedPath: "/a/b/c",
|
||||
},
|
||||
{
|
||||
path: "/d",
|
||||
expectedPath: "/d",
|
||||
},
|
||||
{
|
||||
path: "$path",
|
||||
expectedPath: "/d/usr",
|
||||
},
|
||||
{
|
||||
path: "$home",
|
||||
expectedPath: "/root",
|
||||
},
|
||||
{
|
||||
path: "$path/$home",
|
||||
expectedPath: "/root/usr/root",
|
||||
},
|
||||
}
|
||||
|
||||
func TestWorkdirCommand(t *testing.T) {
|
||||
|
||||
cfg := &manifest.Schema2Config{
|
||||
WorkingDir: "/",
|
||||
Env: []string{
|
||||
"path=usr/",
|
||||
"home=/root",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range workdirTests {
|
||||
cmd := WorkdirCommand{
|
||||
cmd: &instructions.WorkdirCommand{
|
||||
Path: test.path,
|
||||
},
|
||||
snapshotFiles: []string{},
|
||||
}
|
||||
cmd.ExecuteCommand(cfg)
|
||||
testutil.CheckErrorAndDeepEqual(t, false, nil, test.expectedPath, cfg.WorkingDir)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user