mirror of
https://github.com/drone/drone-kaniko.git
synced 2026-06-14 22:11:18 +08:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a93b4bd647 | |||
| 113a61b0e1 |
@@ -0,0 +1,33 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CustomStringSliceFlag is like a regular StringSlice flag but with
|
||||||
|
// semicolon as a delimiter
|
||||||
|
type CustomStringSliceFlag struct {
|
||||||
|
Value []string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *CustomStringSliceFlag) GetValue() []string {
|
||||||
|
if f.Value == nil {
|
||||||
|
return make([]string, 0)
|
||||||
|
}
|
||||||
|
return f.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *CustomStringSliceFlag) String() string {
|
||||||
|
if f.Value == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return strings.Join(f.Value, ";")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *CustomStringSliceFlag) Set(v string) error {
|
||||||
|
for _, s := range strings.Split(v, ";") {
|
||||||
|
s = strings.TrimSpace(s)
|
||||||
|
f.Value = append(f.Value, s)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
+76
-2
@@ -7,6 +7,7 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go-v2/aws"
|
"github.com/aws/aws-sdk-go-v2/aws"
|
||||||
"github.com/aws/aws-sdk-go-v2/config"
|
"github.com/aws/aws-sdk-go-v2/config"
|
||||||
@@ -17,6 +18,7 @@ import (
|
|||||||
"github.com/aws/aws-sdk-go/aws/session"
|
"github.com/aws/aws-sdk-go/aws/session"
|
||||||
ecrv1 "github.com/aws/aws-sdk-go/service/ecr"
|
ecrv1 "github.com/aws/aws-sdk-go/service/ecr"
|
||||||
ecrpublicv1 "github.com/aws/aws-sdk-go/service/ecrpublic"
|
ecrpublicv1 "github.com/aws/aws-sdk-go/service/ecrpublic"
|
||||||
|
"github.com/aws/aws-sdk-go/service/sts"
|
||||||
"github.com/aws/smithy-go"
|
"github.com/aws/smithy-go"
|
||||||
"github.com/hashicorp/go-version"
|
"github.com/hashicorp/go-version"
|
||||||
"github.com/joho/godotenv"
|
"github.com/joho/godotenv"
|
||||||
@@ -35,6 +37,7 @@ const (
|
|||||||
secretKeyEnv string = "AWS_SECRET_ACCESS_KEY"
|
secretKeyEnv string = "AWS_SECRET_ACCESS_KEY"
|
||||||
ecrPublicDomain string = "public.ecr.aws"
|
ecrPublicDomain string = "public.ecr.aws"
|
||||||
kanikoVersionEnv string = "KANIKO_VERSION"
|
kanikoVersionEnv string = "KANIKO_VERSION"
|
||||||
|
sessionKeyEnv string = "AWS_SESSION_TOKEN"
|
||||||
|
|
||||||
oneDotEightVersion string = "1.8.0"
|
oneDotEightVersion string = "1.8.0"
|
||||||
defaultDigestFile string = "/kaniko/digest-file"
|
defaultDigestFile string = "/kaniko/digest-file"
|
||||||
@@ -122,6 +125,17 @@ func main() {
|
|||||||
Usage: "build args",
|
Usage: "build args",
|
||||||
EnvVar: "PLUGIN_BUILD_ARGS",
|
EnvVar: "PLUGIN_BUILD_ARGS",
|
||||||
},
|
},
|
||||||
|
cli.GenericFlag{
|
||||||
|
Name: "args-new",
|
||||||
|
Usage: "build args new",
|
||||||
|
EnvVar: "PLUGIN_BUILD_ARGS_NEW",
|
||||||
|
Value: new(CustomStringSliceFlag),
|
||||||
|
},
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "plugin-multiple-build-agrs",
|
||||||
|
Usage: "plugin multiple build agrs",
|
||||||
|
EnvVar: "PLUGIN_MULTIPLE_BUILD_ARGS",
|
||||||
|
},
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "target",
|
Name: "target",
|
||||||
Usage: "build target",
|
Usage: "build target",
|
||||||
@@ -384,6 +398,11 @@ func main() {
|
|||||||
Usage: "Number of retries for downloading base images.",
|
Usage: "Number of retries for downloading base images.",
|
||||||
EnvVar: "PLUGIN_IMAGE_DOWNLOAD_RETRY",
|
EnvVar: "PLUGIN_IMAGE_DOWNLOAD_RETRY",
|
||||||
},
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "oidc-token-id",
|
||||||
|
Usage: "OIDC token for assuming role via web identity",
|
||||||
|
EnvVar: "PLUGIN_OIDC_TOKEN_ID",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := app.Run(os.Args); err != nil {
|
if err := app.Run(os.Args); err != nil {
|
||||||
@@ -398,6 +417,7 @@ func run(c *cli.Context) error {
|
|||||||
noPush := c.Bool("no-push")
|
noPush := c.Bool("no-push")
|
||||||
assumeRole := c.String("assume-role")
|
assumeRole := c.String("assume-role")
|
||||||
externalId := c.String("external-id")
|
externalId := c.String("external-id")
|
||||||
|
oidcToken := c.String("oidc-token-id")
|
||||||
|
|
||||||
// setup docker config for azure registry and base image docker registry
|
// setup docker config for azure registry and base image docker registry
|
||||||
err := setDockerAuth(
|
err := setDockerAuth(
|
||||||
@@ -411,6 +431,7 @@ func run(c *cli.Context) error {
|
|||||||
externalId,
|
externalId,
|
||||||
region,
|
region,
|
||||||
noPush,
|
noPush,
|
||||||
|
oidcToken,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to create docker config")
|
return errors.Wrap(err, "failed to create docker config")
|
||||||
@@ -454,6 +475,8 @@ func run(c *cli.Context) error {
|
|||||||
AutoTagSuffix: c.String("auto-tag-suffix"),
|
AutoTagSuffix: c.String("auto-tag-suffix"),
|
||||||
ExpandTag: c.Bool("expand-tag"),
|
ExpandTag: c.Bool("expand-tag"),
|
||||||
Args: c.StringSlice("args"),
|
Args: c.StringSlice("args"),
|
||||||
|
ArgsNew: c.Generic("args-new").(*CustomStringSliceFlag).GetValue(),
|
||||||
|
IsMultipleBuildArgs: c.Bool("plugin-multiple-build-agrs"),
|
||||||
Target: c.String("target"),
|
Target: c.String("target"),
|
||||||
Repo: fmt.Sprintf("%s/%s", c.String("registry"), c.String("repo")),
|
Repo: fmt.Sprintf("%s/%s", c.String("registry"), c.String("repo")),
|
||||||
Mirrors: c.StringSlice("registry-mirrors"),
|
Mirrors: c.StringSlice("registry-mirrors"),
|
||||||
@@ -518,7 +541,7 @@ func run(c *cli.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func setDockerAuth(dockerRegistry, dockerUsername, dockerPassword, accessKey, secretKey,
|
func setDockerAuth(dockerRegistry, dockerUsername, dockerPassword, accessKey, secretKey,
|
||||||
registry, assumeRole, externalId, region string, noPush bool) error {
|
registry, assumeRole, externalId, region string, noPush bool, oidcToken string) error {
|
||||||
dockerConfig := docker.NewConfig()
|
dockerConfig := docker.NewConfig()
|
||||||
credentials := []docker.RegistryCredentials{}
|
credentials := []docker.RegistryCredentials{}
|
||||||
// set docker credentials for base image registry
|
// set docker credentials for base image registry
|
||||||
@@ -531,7 +554,24 @@ func setDockerAuth(dockerRegistry, dockerUsername, dockerPassword, accessKey, se
|
|||||||
credentials = append(credentials, pullFromRegistryCreds)
|
credentials = append(credentials, pullFromRegistryCreds)
|
||||||
}
|
}
|
||||||
|
|
||||||
if assumeRole != "" {
|
if assumeRole != "" && oidcToken != "" {
|
||||||
|
oidcAccessKey, oidcSecretKey, oidcSessionKey, err := getOidcCreds(oidcToken, assumeRole)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = os.Setenv(accessKeyEnv, oidcAccessKey)
|
||||||
|
_ = os.Setenv(secretKeyEnv, oidcSecretKey)
|
||||||
|
_ = os.Setenv(sessionKeyEnv, oidcSessionKey)
|
||||||
|
|
||||||
|
// kaniko-executor >=1.8.0 does not require additional cred helper logic for ECR,
|
||||||
|
// as it discovers ECR repositories automatically and acts accordingly.
|
||||||
|
if isKanikoVersionBelowOneDotEight(os.Getenv(kanikoVersionEnv)) {
|
||||||
|
dockerConfig.SetCredHelper(ecrPublicDomain, "ecr-login")
|
||||||
|
dockerConfig.SetCredHelper(registry, "ecr-login")
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if assumeRole != "" {
|
||||||
var err error
|
var err error
|
||||||
username, password, registry, err := getAssumeRoleCreds(region, assumeRole, externalId, "")
|
username, password, registry, err := getAssumeRoleCreds(region, assumeRole, externalId, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -771,3 +811,37 @@ func isKanikoVersionBelowOneDotEight(v string) bool {
|
|||||||
|
|
||||||
return currVer.LessThan(oneEightVer)
|
return currVer.LessThan(oneEightVer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getOidcCreds(oidcToken, assumeRole string) (string, string, string, error) {
|
||||||
|
// Create a new session
|
||||||
|
sess, err := session.NewSession()
|
||||||
|
if err != nil {
|
||||||
|
return "", "", "", fmt.Errorf("failed to create AWS session: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new STS client
|
||||||
|
svc := sts.New(sess)
|
||||||
|
|
||||||
|
// Prepare the input parameters for the STS call
|
||||||
|
duration := int64(time.Hour / time.Second)
|
||||||
|
input := &sts.AssumeRoleWithWebIdentityInput{
|
||||||
|
RoleArn: aws.String(assumeRole),
|
||||||
|
RoleSessionName: aws.String("kaniko-ecr-oidc"),
|
||||||
|
WebIdentityToken: aws.String(oidcToken),
|
||||||
|
DurationSeconds: aws.Int64(duration),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call the AssumeRoleWithWebIdentity function
|
||||||
|
result, err := svc.AssumeRoleWithWebIdentity(input)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", "", fmt.Errorf("failed to assume role with web identity: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if credentials exist in the result
|
||||||
|
if result.Credentials == nil {
|
||||||
|
return "", "", "", errors.New("no credentials returned by AssumeRoleWithWebIdentity")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the credentials
|
||||||
|
return *result.Credentials.AccessKeyId, *result.Credentials.SecretAccessKey, *result.Credentials.SessionToken, nil
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,30 +16,32 @@ import (
|
|||||||
type (
|
type (
|
||||||
// Build defines Docker build parameters.
|
// Build defines Docker build parameters.
|
||||||
Build struct {
|
Build struct {
|
||||||
DroneCommitRef string // Drone git commit reference
|
DroneCommitRef string // Drone git commit reference
|
||||||
DroneRepoBranch string // Drone repo branch
|
DroneRepoBranch string // Drone repo branch
|
||||||
Dockerfile string // Docker build Dockerfile
|
Dockerfile string // Docker build Dockerfile
|
||||||
Context string // Docker build context
|
Context string // Docker build context
|
||||||
Tags []string // Docker build tags
|
Tags []string // Docker build tags
|
||||||
AutoTag bool // Set this to auto detect tags from git commits and semver-tagged labels
|
AutoTag bool // Set this to auto detect tags from git commits and semver-tagged labels
|
||||||
AutoTagSuffix string // Suffix to append to the auto detect tags
|
AutoTagSuffix string // Suffix to append to the auto detect tags
|
||||||
ExpandTag bool // Set this to expand the `Tags` into semver-tagged labels
|
ExpandTag bool // Set this to expand the `Tags` into semver-tagged labels
|
||||||
Args []string // Docker build args
|
Args []string // Docker build args
|
||||||
Target string // Docker build target
|
ArgsNew []string // docker build args with comma seperated values
|
||||||
Repo string // Docker build repository
|
IsMultipleBuildArgs bool // env variable for fallback for docker build args
|
||||||
Mirrors []string // Docker repository mirrors
|
Target string // Docker build target
|
||||||
Labels []string // Label map
|
Repo string // Docker build repository
|
||||||
SkipTlsVerify bool // Docker skip tls certificate verify for registry
|
Mirrors []string // Docker repository mirrors
|
||||||
SnapshotMode string // Kaniko snapshot mode
|
Labels []string // Label map
|
||||||
EnableCache bool // Whether to enable kaniko cache
|
SkipTlsVerify bool // Docker skip tls certificate verify for registry
|
||||||
CacheRepo string // Remote repository that will be used to store cached layers
|
SnapshotMode string // Kaniko snapshot mode
|
||||||
CacheTTL int // Cache timeout in hours
|
EnableCache bool // Whether to enable kaniko cache
|
||||||
DigestFile string // Digest file location
|
CacheRepo string // Remote repository that will be used to store cached layers
|
||||||
NoPush bool // Set this flag if you only want to build the image, without pushing to a registry
|
CacheTTL int // Cache timeout in hours
|
||||||
Verbosity string // Log level
|
DigestFile string // Digest file location
|
||||||
Platform string // Allows to build with another default platform than the host, similarly to docker build --platform
|
NoPush bool // Set this flag if you only want to build the image, without pushing to a registry
|
||||||
SkipUnusedStages bool // Build only used stages
|
Verbosity string // Log level
|
||||||
TarPath string // Set this flag to save the image as a tarball at path
|
Platform string // Allows to build with another default platform than the host, similarly to docker build --platform
|
||||||
|
SkipUnusedStages bool // Build only used stages
|
||||||
|
TarPath string // Set this flag to save the image as a tarball at path
|
||||||
|
|
||||||
Cache bool // Enable or disable caching during the build process.
|
Cache bool // Enable or disable caching during the build process.
|
||||||
CacheDir string // Directory to store cached layers.
|
CacheDir string // Directory to store cached layers.
|
||||||
@@ -202,8 +204,14 @@ func (p Plugin) Exec() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set the build arguments
|
// Set the build arguments
|
||||||
for _, arg := range p.Build.Args {
|
if p.Build.IsMultipleBuildArgs {
|
||||||
cmdArgs = append(cmdArgs, fmt.Sprintf("--build-arg=%s", arg))
|
for _, arg := range p.Build.ArgsNew {
|
||||||
|
cmdArgs = append(cmdArgs, "--build-arg", arg)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for _, arg := range p.Build.Args {
|
||||||
|
cmdArgs = append(cmdArgs, "--build-arg", arg)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Set the labels
|
// Set the labels
|
||||||
for _, label := range p.Build.Labels {
|
for _, label := range p.Build.Labels {
|
||||||
|
|||||||
Reference in New Issue
Block a user