Refactor a bit. (#84)

Move all logic out of cmd/root.go into a package.
This commit is contained in:
dlorenc
2018-04-14 07:59:37 -07:00
committed by GitHub
parent da1eab7251
commit 167920c405
7 changed files with 125 additions and 272 deletions
Generated
+2 -22
View File
@@ -32,22 +32,6 @@
revision = "859166bbd7810e3c3fc072f1c33ad57b9f4acbd0"
source = "github.com/GoogleCloudPlatform/container-diff"
[[projects]]
branch = "master"
name = "github.com/GoogleCloudPlatform/kaniko"
packages = [
"executor/cmd",
"kaniko/cmd",
"pkg/commands",
"pkg/constants",
"pkg/dockerfile",
"pkg/image",
"pkg/snapshot",
"pkg/util",
"testutil"
]
revision = "eb891c1ab9b051260b34f0d2f1a13438fabbd6f5"
[[projects]]
name = "github.com/Microsoft/go-winio"
packages = [
@@ -245,11 +229,7 @@
[[projects]]
name = "github.com/genuinetools/amicontained"
packages = [
".",
"container",
"version"
]
packages = ["container"]
revision = "fcae88544f0212fbb1e20699c41566655b68679b"
version = "v0.4.0"
@@ -659,6 +639,6 @@
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
inputs-digest = "94d3267001478b2c4cff40adbfb2219ebbca52d2ce8957b178b7ed38ba4ab91a"
inputs-digest = "73e91b49fe7ddd3b2189053fca5e81f748ace00c33c3c66dc63a68dd0c067dca"
solver-name = "gps-cdcl"
solver-version = 1
+1 -1
View File
@@ -35,7 +35,7 @@ GO_LDFLAGS += '
GO_BUILD_TAGS := "containers_image_ostree_stub containers_image_openpgp exclude_graphdriver_devicemapper exclude_graphdriver_btrfs exclude_graphdriver_overlay"
EXECUTOR_PACKAGE = $(REPOPATH)/executor
EXECUTOR_PACKAGE = $(REPOPATH)/cmd/executor
KANIKO_PROJECT = $(REPOPATH)/kaniko
out/executor: $(GO_FILES)
+117
View File
@@ -0,0 +1,117 @@
/*
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 cmd
import (
"errors"
"os"
"path/filepath"
"github.com/genuinetools/amicontained/container"
"github.com/GoogleCloudPlatform/kaniko/pkg/executor"
"github.com/GoogleCloudPlatform/kaniko/pkg/constants"
"github.com/GoogleCloudPlatform/kaniko/pkg/util"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
var (
dockerfilePath string
destination string
srcContext string
snapshotMode string
bucket string
logLevel string
force bool
)
func init() {
RootCmd.PersistentFlags().StringVarP(&dockerfilePath, "dockerfile", "f", "Dockerfile", "Path to the dockerfile to be built.")
RootCmd.PersistentFlags().StringVarP(&srcContext, "context", "c", "", "Path to the dockerfile build context.")
RootCmd.PersistentFlags().StringVarP(&bucket, "bucket", "b", "", "Name of the GCS bucket from which to access build context as tarball.")
RootCmd.PersistentFlags().StringVarP(&destination, "destination", "d", "", "Registry the final image should be pushed to (ex: gcr.io/test/example:latest)")
RootCmd.PersistentFlags().StringVarP(&snapshotMode, "snapshotMode", "", "full", "Set this flag to change the file attributes inspected during snapshotting")
RootCmd.PersistentFlags().StringVarP(&logLevel, "verbosity", "v", constants.DefaultLogLevel, "Log level (debug, info, warn, error, fatal, panic")
RootCmd.PersistentFlags().BoolVarP(&force, "force", "", false, "Force building outside of a container")
}
var RootCmd = &cobra.Command{
Use: "executor",
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
if err := util.SetLogLevel(logLevel); err != nil {
return err
}
if err := resolveSourceContext(); err != nil {
return err
}
return checkDockerfilePath()
},
Run: func(cmd *cobra.Command, args []string) {
if !checkContained() {
if !force {
logrus.Error("kaniko should only be run inside of a container, run with the --force flag if you are sure you want to continue.")
os.Exit(1)
}
logrus.Warn("kaniko is being run outside of a container. This can have dangerous effects on your system")
}
if err := executor.DoBuild(dockerfilePath, srcContext, destination, snapshotMode); err != nil {
logrus.Error(err)
os.Exit(1)
}
},
}
func checkContained() bool {
_, err := container.DetectRuntime()
return err == nil
}
func checkDockerfilePath() error {
if util.FilepathExists(dockerfilePath) {
return nil
}
// Otherwise, check if the path relative to the build context exists
if util.FilepathExists(filepath.Join(srcContext, dockerfilePath)) {
dockerfilePath = filepath.Join(srcContext, dockerfilePath)
return nil
}
return errors.New("please provide a valid path to a Dockerfile within the build context")
}
// resolveSourceContext unpacks the source context if it is a tar in a GCS bucket
// it resets srcContext to be the path to the unpacked build context within the image
func resolveSourceContext() error {
if srcContext == "" && bucket == "" {
return errors.New("please specify a path to the build context with the --context flag or a GCS bucket with the --bucket flag")
}
if srcContext != "" && bucket != "" {
return errors.New("please specify either --bucket or --context as the desired build context")
}
if srcContext != "" {
return nil
}
logrus.Infof("Using GCS bucket %s as source context", bucket)
buildContextPath := constants.BuildContextDir
if err := util.UnpackTarFromGCSBucket(bucket, buildContextPath); err != nil {
return err
}
logrus.Debugf("Unpacked tar from %s to path %s", bucket, buildContextPath)
srcContext = buildContextPath
return nil
}
+1 -1
View File
@@ -20,7 +20,7 @@ import (
"fmt"
"os"
"github.com/GoogleCloudPlatform/kaniko/executor/cmd"
"github.com/GoogleCloudPlatform/kaniko/cmd/executor/cmd"
)
func main() {
@@ -14,15 +14,12 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd
package executor
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"github.com/genuinetools/amicontained/container"
"github.com/GoogleCloudPlatform/kaniko/pkg/commands"
"github.com/GoogleCloudPlatform/kaniko/pkg/constants"
@@ -32,99 +29,10 @@ import (
"github.com/GoogleCloudPlatform/kaniko/pkg/util"
"github.com/containers/image/manifest"
"github.com/docker/docker/builder/dockerfile/instructions"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
var (
dockerfilePath string
destination string
srcContext string
snapshotMode string
bucket string
logLevel string
force bool
)
func init() {
RootCmd.PersistentFlags().StringVarP(&dockerfilePath, "dockerfile", "f", "Dockerfile", "Path to the dockerfile to be built.")
RootCmd.PersistentFlags().StringVarP(&srcContext, "context", "c", "", "Path to the dockerfile build context.")
RootCmd.PersistentFlags().StringVarP(&bucket, "bucket", "b", "", "Name of the GCS bucket from which to access build context as tarball.")
RootCmd.PersistentFlags().StringVarP(&destination, "destination", "d", "", "Registry the final image should be pushed to (ex: gcr.io/test/example:latest)")
RootCmd.PersistentFlags().StringVarP(&snapshotMode, "snapshotMode", "", "full", "Set this flag to change the file attributes inspected during snapshotting")
RootCmd.PersistentFlags().StringVarP(&logLevel, "verbosity", "v", constants.DefaultLogLevel, "Log level (debug, info, warn, error, fatal, panic")
RootCmd.PersistentFlags().BoolVarP(&force, "force", "", false, "Force running outside of a container.")
}
var RootCmd = &cobra.Command{
Use: "executor",
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
if err := util.SetLogLevel(logLevel); err != nil {
return err
}
if err := resolveSourceContext(); err != nil {
return err
}
return checkDockerfilePath()
},
Run: func(cmd *cobra.Command, args []string) {
if err := execute(); err != nil {
logrus.Error(err)
os.Exit(1)
}
},
}
func checkDockerfilePath() error {
if util.FilepathExists(dockerfilePath) {
return nil
}
// Otherwise, check if the path relative to the build context exists
if util.FilepathExists(filepath.Join(srcContext, dockerfilePath)) {
dockerfilePath = filepath.Join(srcContext, dockerfilePath)
return nil
}
return errors.New("please provide a valid path to a Dockerfile within the build context")
}
// resolveSourceContext unpacks the source context if it is a tar in a GCS bucket
// it resets srcContext to be the path to the unpacked build context within the image
func resolveSourceContext() error {
if srcContext == "" && bucket == "" {
return errors.New("please specify a path to the build context with the --context flag or a GCS bucket with the --bucket flag")
}
if srcContext != "" && bucket != "" {
return errors.New("please specify either --bucket or --context as the desired build context")
}
if srcContext != "" {
return nil
}
logrus.Infof("Using GCS bucket %s as source context", bucket)
buildContextPath := constants.BuildContextDir
if err := util.UnpackTarFromGCSBucket(bucket, buildContextPath); err != nil {
return err
}
logrus.Debugf("Unpacked tar from %s to path %s", bucket, buildContextPath)
srcContext = buildContextPath
return nil
}
func checkContained() bool {
_, err := container.DetectRuntime()
return err == nil
}
func execute() error {
if !checkContained() {
if !force {
logrus.Error("kaniko should only be run inside of a container, run with the --force flag if you are sure you want to continue.")
return errors.New("kaniko should only be run inside of a container")
}
logrus.Warn("kaniko is being run outside of a container. This can have dangerous effects on your system")
}
func DoBuild(dockerfilePath, srcContext, destination, snapshotMode string) error {
// Parse dockerfile and unpack base image to root
d, err := ioutil.ReadFile(dockerfilePath)
if err != nil {
@@ -143,7 +51,7 @@ func execute() error {
return err
}
hasher, err := getHasher()
hasher, err := getHasher(snapshotMode)
if err != nil {
return err
}
@@ -205,7 +113,7 @@ func execute() error {
return image.PushImage(sourceImage, destination)
}
func getHasher() (func(string) (string, error), error) {
func getHasher(snapshotMode string) (func(string) (string, error), error) {
if snapshotMode == constants.SnapshotModeTime {
logrus.Info("Only file modification time will be considered when snapshotting")
return util.MtimeHasher(), nil
-145
View File
@@ -1,145 +0,0 @@
package main
import (
"flag"
"fmt"
"log"
"os"
"strings"
"github.com/genuinetools/amicontained/container"
"github.com/genuinetools/amicontained/version"
"github.com/sirupsen/logrus"
)
const (
// BANNER is what is printed for help/info output
BANNER = ` _ _ _ _
__ _ _ __ ___ (_) ___ ___ _ __ | |_ __ _(_)_ __ ___ __| |
/ _` + "`" + ` | '_ ` + "`" + ` _ \| |/ __/ _ \| '_ \| __/ _` + "`" + ` | | '_ \ / _ \/ _` + "`" + ` |
| (_| | | | | | | | (_| (_) | | | | || (_| | | | | | __/ (_| |
\__,_|_| |_| |_|_|\___\___/|_| |_|\__\__,_|_|_| |_|\___|\__,_|
Container introspection tool.
Version: %s
`
)
var (
debug bool
vrsn bool
)
func init() {
// parse flags
flag.BoolVar(&vrsn, "version", false, "print version and exit")
flag.BoolVar(&vrsn, "v", false, "print version and exit (shorthand)")
flag.BoolVar(&debug, "d", false, "run in debug mode")
flag.Usage = func() {
fmt.Fprint(os.Stderr, fmt.Sprintf(BANNER, version.VERSION))
flag.PrintDefaults()
}
flag.Parse()
// set log level
if debug {
logrus.SetLevel(logrus.DebugLevel)
}
if vrsn {
fmt.Printf("amicontained version %s, build %s\n", version.VERSION, version.GITCOMMIT)
os.Exit(0)
}
if flag.NArg() < 1 {
return
}
// parse the arg
arg := flag.Args()[0]
if arg == "help" {
usageAndExit("", 0)
}
if arg == "version" {
fmt.Printf("amicontained version %s, build %s\n", version.VERSION, version.GITCOMMIT)
os.Exit(0)
}
}
func main() {
// Container Runtime
runtime, err := container.DetectRuntime()
if err != nil && err != container.ErrContainerRuntimeNotFound {
log.Fatal(err)
return
}
fmt.Printf("Container Runtime: %s\n", runtime)
// Namespaces
namespaces := []string{"pid"}
fmt.Println("Has Namespaces:")
for _, namespace := range namespaces {
ns, err := container.HasNamespace(namespace)
if err != nil {
fmt.Printf("\t%s: error -> %v\n", namespace, err)
continue
}
fmt.Printf("\t%s: %t\n", namespace, ns)
}
// User Namespaces
userNS, userMappings := container.UserNamespace()
fmt.Printf("\tuser: %t\n", userNS)
if len(userMappings) > 0 {
fmt.Println("User Namespace Mappings:")
for _, userMapping := range userMappings {
fmt.Printf("\tContainer -> %d\tHost -> %d\tRange -> %d\n", userMapping.ContainerID, userMapping.HostID, userMapping.Range)
}
}
// AppArmor Profile
aaprof := container.AppArmorProfile()
fmt.Printf("AppArmor Profile: %s\n", aaprof)
// Capabilities
caps, err := container.Capabilities()
if err != nil {
logrus.Warnf("getting capabilities failed: %v", err)
}
if len(caps) > 0 {
fmt.Println("Capabilities:")
for k, v := range caps {
if len(v) > 0 {
fmt.Printf("\t%s -> %s\n", k, strings.Join(v, " "))
}
}
}
// Chroot
chroot, err := container.Chroot()
if err != nil {
logrus.Debugf("chroot check error: %v", err)
}
fmt.Printf("Chroot (not pivot_root): %t\n", chroot)
// Seccomp
seccompMode, err := container.SeccompEnforcingMode()
if err != nil {
logrus.Debugf("error: %v", err)
}
fmt.Printf("Seccomp: %s\n", seccompMode)
}
func usageAndExit(message string, exitCode int) {
if message != "" {
fmt.Fprintf(os.Stderr, message)
fmt.Fprintf(os.Stderr, "\n\n")
}
flag.Usage()
fmt.Fprintf(os.Stderr, "\n")
os.Exit(exitCode)
}
-7
View File
@@ -1,7 +0,0 @@
package version
// VERSION indicates which version of the binary is running.
var VERSION string
// GITCOMMIT indicates which git hash the binary was built off of
var GITCOMMIT string