2020-11-16 18:37:13 +01:00
package main
import (
"encoding/base64"
"fmt"
"io/ioutil"
"os"
"github.com/joho/godotenv"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/urfave/cli"
2021-04-21 02:14:05 +02:00
kaniko "git.dotya.ml/wanderer/drone-kaniko"
"git.dotya.ml/wanderer/drone-kaniko/cmd/artifact"
2020-11-16 18:37:13 +01:00
)
const (
2020-11-21 11:43:01 +01:00
// Docker file path
dockerPath string = "/kaniko/.docker"
2020-11-16 18:37:13 +01:00
dockerConfigPath string = "/kaniko/.docker/config.json"
2020-11-26 11:59:05 +01:00
v1Registry string = "https://index.docker.io/v1/" // Default registry
v2Registry string = "https://index.docker.io/v2/" // v2 registry is not supported
2021-04-29 12:05:57 +02:00
defaultDigestFile string = "/kaniko/digest-file"
2020-11-16 18:37:13 +01:00
)
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 docker plugin"
app . Usage = "kaniko docker 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 : "docker repository" ,
EnvVar : "PLUGIN_REPO" ,
} ,
cli . StringSliceFlag {
Name : "custom-labels" ,
Usage : "additional k=v labels" ,
EnvVar : "PLUGIN_CUSTOM_LABELS" ,
} ,
cli . StringFlag {
Name : "registry" ,
Usage : "docker registry" ,
2020-11-26 11:59:05 +01:00
Value : v1Registry ,
2020-11-16 18:37:13 +01:00
EnvVar : "PLUGIN_REGISTRY" ,
} ,
cli . StringFlag {
Name : "username" ,
Usage : "docker username" ,
EnvVar : "PLUGIN_USERNAME" ,
} ,
cli . StringFlag {
Name : "password" ,
Usage : "docker password" ,
EnvVar : "PLUGIN_PASSWORD" ,
} ,
2021-03-02 16:45:44 +01:00
cli . BoolFlag {
Name : "skip-tls-verify" ,
Usage : "Skip registry tls verify" ,
2021-02-18 09:19:21 +01:00
EnvVar : "PLUGIN_SKIP_TLS_VERIFY" ,
} ,
2021-03-02 16:45:44 +01:00
cli . StringFlag {
Name : "snapshot-mode" ,
Usage : "Specify one of full, redo or time as snapshot mode" ,
EnvVar : "PLUGIN_SNAPSHOT_MODE" ,
} ,
2021-04-07 20:35:53 +02:00
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. 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" ,
} ,
2021-04-29 12:05:57 +02:00
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" ,
} ,
2021-04-29 17:23:43 +02:00
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" ,
} ,
2021-08-20 13:08:35 +02:00
cli . StringFlag {
Name : "verbosity" ,
Usage : "Set this flag with value as oneof <panic|fatal|error|warn|info|debug|trace> to set the logging level for kaniko. Defaults to info." ,
EnvVar : "PLUGIN_VERBOSITY" ,
} ,
2020-11-16 18:37:13 +01:00
}
if err := app . Run ( os . Args ) ; err != nil {
logrus . Fatal ( err )
}
}
func run ( c * cli . Context ) error {
err := createDockerCfgFile ( c . String ( "username" ) , c . String ( "password" ) , c . String ( "registry" ) )
if err != nil {
return err
}
2020-11-16 19:11:59 +01:00
plugin := kaniko . Plugin {
Build : kaniko . Build {
2021-03-02 16:45:44 +01:00
Dockerfile : c . String ( "dockerfile" ) ,
Context : c . String ( "context" ) ,
Tags : c . StringSlice ( "tags" ) ,
Args : c . StringSlice ( "args" ) ,
Target : c . String ( "target" ) ,
Repo : c . String ( "repo" ) ,
Labels : c . StringSlice ( "custom-labels" ) ,
2021-02-18 09:19:21 +01:00
SkipTlsVerify : c . Bool ( "skip-tls-verify" ) ,
2021-03-02 16:45:44 +01:00
SnapshotMode : c . String ( "snapshot-mode" ) ,
2021-04-07 20:35:53 +02:00
EnableCache : c . Bool ( "enable-cache" ) ,
CacheRepo : c . String ( "cache-repo" ) ,
CacheTTL : c . Int ( "cache-ttl" ) ,
2021-04-29 12:05:57 +02:00
DigestFile : defaultDigestFile ,
2021-04-29 17:23:43 +02:00
NoPush : c . Bool ( "no-push" ) ,
2021-08-20 13:08:35 +02:00
Verbosity : c . String ( "verbosity" ) ,
2021-04-29 12:05:57 +02:00
} ,
Artifact : kaniko . Artifact {
Tags : c . StringSlice ( "tags" ) ,
Repo : c . String ( "repo" ) ,
Registry : c . String ( "registry" ) ,
ArtifactFile : c . String ( "artifact-file" ) ,
RegistryType : artifact . Docker ,
2020-11-16 18:37:13 +01:00
} ,
}
return plugin . Exec ( )
}
// Create the docker config file for authentication
func createDockerCfgFile ( username , password , registry string ) error {
if username == "" {
2021-04-21 02:36:25 +02:00
fmt . Println ( "no username provided, using empty string" )
2020-11-16 18:37:13 +01:00
}
if password == "" {
2021-04-21 02:36:25 +02:00
fmt . Println ( "no password provided, using empty string" )
2020-11-16 18:37:13 +01:00
}
if registry == "" {
2021-04-21 02:36:25 +02:00
fmt . Println ( "no registry string provided, using the default value" )
registry = v1Registry
2020-11-16 18:37:13 +01:00
}
2020-11-26 11:59:05 +01:00
if registry == v2Registry {
fmt . Println ( "Docker v2 registry is not supported in kaniko. Refer issue: https://github.com/GoogleContainerTools/kaniko/issues/1209" )
fmt . Printf ( "Using v1 registry instead: %s\n" , v1Registry )
registry = v1Registry
}
2020-11-21 11:43:01 +01:00
err := os . MkdirAll ( dockerPath , 0600 )
if err != nil {
return errors . Wrap ( err , fmt . Sprintf ( "failed to create %s directory" , dockerPath ) )
}
2020-11-16 18:37:13 +01:00
authBytes := [ ] byte ( fmt . Sprintf ( "%s:%s" , username , password ) )
encodedString := base64 . StdEncoding . EncodeToString ( authBytes )
jsonBytes := [ ] byte ( fmt . Sprintf ( ` { "auths": { "%s": { "auth": "%s"}}} ` , registry , encodedString ) )
2020-11-21 11:43:01 +01:00
err = ioutil . WriteFile ( dockerConfigPath , jsonBytes , 0644 )
2020-11-16 18:37:13 +01:00
if err != nil {
return errors . Wrap ( err , "failed to create docker config file" )
}
return nil
}