package main import ( "fmt" "io/ioutil" "os" "github.com/joho/godotenv" "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/urfave/cli" kaniko "git.dotya.ml/wanderer/drone-kaniko" "git.dotya.ml/wanderer/drone-kaniko/cmd/artifact" ) const ( // GCR JSON key file path gcrKeyPath string = "/kaniko/config.json" gcrEnvVariable string = "GOOGLE_APPLICATION_CREDENTIALS" defaultDigestFile string = "/kaniko/digest-file" ) var ( version = "unknown" ) func main() { // Load env-file if it exists first if env := os.Getenv("PLUGIN_ENV_FILE"); env != "" { godotenv.Load(env) } app := cli.NewApp() app.Name = "kaniko gcr plugin" app.Usage = "kaniko gcr plugin" app.Action = run app.Version = version app.Flags = []cli.Flag{ cli.StringFlag{ Name: "dockerfile", Usage: "build dockerfile", Value: "Dockerfile", EnvVar: "PLUGIN_DOCKERFILE", }, cli.StringFlag{ Name: "context", Usage: "build context", Value: ".", EnvVar: "PLUGIN_CONTEXT", }, cli.StringSliceFlag{ Name: "tags", Usage: "build tags", Value: &cli.StringSlice{"latest"}, EnvVar: "PLUGIN_TAGS", FilePath: ".tags", }, cli.StringSliceFlag{ Name: "args", Usage: "build args", EnvVar: "PLUGIN_BUILD_ARGS", }, cli.StringFlag{ Name: "target", Usage: "build target", EnvVar: "PLUGIN_TARGET", }, cli.StringFlag{ Name: "repo", Usage: "gcr repository", EnvVar: "PLUGIN_REPO", }, cli.StringSliceFlag{ Name: "custom-labels", Usage: "additional k=v labels", EnvVar: "PLUGIN_CUSTOM_LABELS", }, cli.StringFlag{ Name: "registry", Usage: "gcr registry", Value: "gcr.io", EnvVar: "PLUGIN_REGISTRY", }, cli.StringFlag{ Name: "json-key", Usage: "docker username", EnvVar: "PLUGIN_JSON_KEY", }, cli.StringFlag{ Name: "snapshot-mode", Usage: "Specify one of full, redo or time as snapshot mode", EnvVar: "PLUGIN_SNAPSHOT_MODE", }, cli.BoolFlag{ Name: "enable-cache", Usage: "Set this flag to opt into caching with kaniko", EnvVar: "PLUGIN_ENABLE_CACHE", }, cli.StringFlag{ Name: "cache-repo", Usage: "Remote repository that will be used to store cached layers. Cache repo should be present in specified registry. enable-cache needs to be set to use this flag", EnvVar: "PLUGIN_CACHE_REPO", }, cli.IntFlag{ Name: "cache-ttl", Usage: "Cache timeout in hours. Defaults to two weeks.", EnvVar: "PLUGIN_CACHE_TTL", }, cli.StringFlag{ Name: "artifact-file", Usage: "Artifact file location that will be generated by the plugin. This file will include information of docker images that are uploaded by the plugin.", EnvVar: "PLUGIN_ARTIFACT_FILE", }, cli.BoolFlag{ Name: "no-push", Usage: "Set this flag if you only want to build the image, without pushing to a registry", EnvVar: "PLUGIN_NO_PUSH", }, cli.StringFlag{ Name: "verbosity", Usage: "Set this flag as --verbosity= to set the logging level for kaniko. Defaults to info.", EnvVar: "PLUGIN_VERBOSITY", }, } if err := app.Run(os.Args); err != nil { logrus.Fatal(err) } } func run(c *cli.Context) error { err := setupGCRAuth(c.String("json-key")) if err != nil { return err } if c.String("repo") == "" { return fmt.Errorf("repo must be specified") } plugin := kaniko.Plugin{ Build: kaniko.Build{ Dockerfile: c.String("dockerfile"), Context: c.String("context"), Tags: c.StringSlice("tags"), Args: c.StringSlice("args"), Target: c.String("target"), Repo: fmt.Sprintf("%s/%s", c.String("registry"), c.String("repo")), Labels: c.StringSlice("custom-labels"), SnapshotMode: c.String("snapshot-mode"), EnableCache: c.Bool("enable-cache"), CacheRepo: fmt.Sprintf("%s/%s", c.String("registry"), c.String("cache-repo")), CacheTTL: c.Int("cache-ttl"), DigestFile: defaultDigestFile, NoPush: c.Bool("no-push"), Verbosity: c.String("verbosity"), }, Artifact: kaniko.Artifact{ Tags: c.StringSlice("tags"), Repo: c.String("repo"), Registry: c.String("registry"), ArtifactFile: c.String("artifact-file"), RegistryType: artifact.GCR, }, } return plugin.Exec() } func setupGCRAuth(jsonKey string) error { if jsonKey == "" { return fmt.Errorf("GCR JSON key must be specified") } err := ioutil.WriteFile(gcrKeyPath, []byte(jsonKey), 0644) if err != nil { return errors.Wrap(err, "failed to write GCR JSON key") } err = os.Setenv(gcrEnvVariable, gcrKeyPath) if err != nil { return errors.Wrap(err, fmt.Sprintf("failed to set %s environment variable", gcrEnvVariable)) } return nil }