mirror of
https://github.com/harness/drone.git
synced 2025-05-21 11:29:52 +08:00
feat: [CDE-508]: add image auth (#3053)
* add comment * split pull image func into smaller parts * split pull image func into smaller parts * use MaskSecret type * fix lint * add image auth * Merge branch 'main' of https://git0.harness.io/l7B_kbSEQD2wjrM7PShm5w/PROD/Harness_Commons/gitness into add-image-auth * add image auth
This commit is contained in:
parent
dbe74b149d
commit
3b2db60eea
@ -16,6 +16,7 @@ package container
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
@ -32,6 +33,7 @@ import (
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
"github.com/docker/docker/api/types/image"
|
||||
"github.com/docker/docker/api/types/mount"
|
||||
"github.com/docker/docker/api/types/registry"
|
||||
"github.com/docker/docker/api/types/strslice"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/docker/go-connections/nat"
|
||||
@ -304,6 +306,7 @@ func PullImage(
|
||||
dockerClient *client.Client,
|
||||
runArgsMap map[types.RunArg]*types.RunArgValue,
|
||||
gitspaceLogger gitspaceTypes.GitspaceLogger,
|
||||
dockerRegistryAuth gitspaceTypes.DockerRegistryAuth,
|
||||
) error {
|
||||
imagePullRunArg := getImagePullPolicy(runArgsMap)
|
||||
gitspaceLogger.Info("Image pull policy is: " + imagePullRunArg)
|
||||
@ -312,26 +315,28 @@ func PullImage(
|
||||
}
|
||||
if imagePullRunArg == "missing" {
|
||||
gitspaceLogger.Info("Checking if image " + imageName + " is present locally")
|
||||
|
||||
filterArgs := filters.NewArgs()
|
||||
filterArgs.Add("reference", imageName)
|
||||
|
||||
images, err := dockerClient.ImageList(ctx, image.ListOptions{Filters: filterArgs})
|
||||
ok, err := isImagePresentLocally(ctx, imageName, dockerClient)
|
||||
if err != nil {
|
||||
gitspaceLogger.Error("Error listing images locally", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if len(images) > 0 {
|
||||
if ok {
|
||||
gitspaceLogger.Info("Image " + imageName + " is present locally")
|
||||
return nil
|
||||
}
|
||||
|
||||
gitspaceLogger.Info("Image " + imageName + " is not present locally")
|
||||
}
|
||||
|
||||
gitspaceLogger.Info("Pulling image: " + imageName)
|
||||
|
||||
pullResponse, err := dockerClient.ImagePull(ctx, imageName, image.PullOptions{Platform: getPlatform(runArgsMap)})
|
||||
pullOpts, err := buildImagePullOptions(getPlatform(runArgsMap), dockerRegistryAuth)
|
||||
if err != nil {
|
||||
return logStreamWrapError(gitspaceLogger, "Error building image pull options", err)
|
||||
}
|
||||
|
||||
pullResponse, err := dockerClient.ImagePull(ctx, imageName, pullOpts)
|
||||
defer func() {
|
||||
if pullResponse == nil {
|
||||
return
|
||||
@ -382,6 +387,40 @@ func PullImage(
|
||||
return nil
|
||||
}
|
||||
|
||||
func isImagePresentLocally(ctx context.Context, imageName string, dockerClient *client.Client) (bool, error) {
|
||||
filterArgs := filters.NewArgs()
|
||||
filterArgs.Add("reference", imageName)
|
||||
|
||||
images, err := dockerClient.ImageList(ctx, image.ListOptions{Filters: filterArgs})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return len(images) > 0, nil
|
||||
}
|
||||
|
||||
func buildImagePullOptions(
|
||||
platform string,
|
||||
dockerRegistryAuth gitspaceTypes.DockerRegistryAuth,
|
||||
) (image.PullOptions, error) {
|
||||
pullOpts := image.PullOptions{Platform: platform}
|
||||
if dockerRegistryAuth.RegistryURL != "" {
|
||||
authConfig := registry.AuthConfig{
|
||||
Username: dockerRegistryAuth.Username.Value(),
|
||||
Password: dockerRegistryAuth.Password.Value(),
|
||||
ServerAddress: dockerRegistryAuth.RegistryURL,
|
||||
}
|
||||
auth, err := encodeAuthToBase64(authConfig)
|
||||
if err != nil {
|
||||
return image.PullOptions{}, fmt.Errorf("encoding auth for docker registry: %w", err)
|
||||
}
|
||||
|
||||
pullOpts.RegistryAuth = auth
|
||||
}
|
||||
|
||||
return pullOpts, nil
|
||||
}
|
||||
|
||||
func ExtractRunArgsWithLogging(
|
||||
ctx context.Context,
|
||||
spaceID int64,
|
||||
@ -404,7 +443,7 @@ func ExtractRunArgsWithLogging(
|
||||
return runArgsMap, nil
|
||||
}
|
||||
|
||||
// getContainerResponse retrieves container information and prepares the start response.
|
||||
// GetContainerResponse retrieves container information and prepares the start response.
|
||||
func GetContainerResponse(
|
||||
ctx context.Context,
|
||||
dockerClient *client.Client,
|
||||
@ -423,3 +462,12 @@ func GetContainerResponse(
|
||||
AbsoluteRepoPath: codeRepoDir,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Helper function to encode the AuthConfig into a Base64 string.
|
||||
func encodeAuthToBase64(authConfig registry.AuthConfig) (string, error) {
|
||||
authJSON, err := json.Marshal(authConfig)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("encoding auth config: %w", err)
|
||||
}
|
||||
return base64.URLEncoding.EncodeToString(authJSON), nil
|
||||
}
|
||||
|
@ -114,6 +114,9 @@ func (e *EmbeddedDockerOrchestrator) CreateAndStartGitspace(
|
||||
}
|
||||
defer e.closeDockerClient(dockerClient)
|
||||
|
||||
// todo : update the code when private repository integration is supported in gitness
|
||||
dockerRegistryAuth := gitspaceTypes.DockerRegistryAuth{}
|
||||
|
||||
// Step 3: Check the current state of the container
|
||||
state, err := e.checkContainerState(ctx, dockerClient, containerName)
|
||||
if err != nil {
|
||||
@ -144,7 +147,8 @@ func (e *EmbeddedDockerOrchestrator) CreateAndStartGitspace(
|
||||
resolvedRepoDetails,
|
||||
infra,
|
||||
defaultBaseImage,
|
||||
ideService); err != nil {
|
||||
ideService,
|
||||
dockerRegistryAuth); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case ContainerStatePaused, ContainerStateCreated, ContainerStateUnknown, ContainerStateDead:
|
||||
@ -369,6 +373,7 @@ func (e *EmbeddedDockerOrchestrator) runGitspaceSetupSteps(
|
||||
resolvedRepoDetails scm.ResolvedDetails,
|
||||
defaultBaseImage string,
|
||||
gitspaceLogger gitspaceTypes.GitspaceLogger,
|
||||
dockerRegistryAuth gitspaceTypes.DockerRegistryAuth,
|
||||
) error {
|
||||
homeDir := GetUserHomeDir(gitspaceConfig.GitspaceUser.Identifier)
|
||||
containerName := GetGitspaceContainerName(gitspaceConfig)
|
||||
@ -386,7 +391,7 @@ func (e *EmbeddedDockerOrchestrator) runGitspaceSetupSteps(
|
||||
}
|
||||
|
||||
// Pull the required image
|
||||
if err := PullImage(ctx, imageName, dockerClient, runArgsMap, gitspaceLogger); err != nil {
|
||||
if err := PullImage(ctx, imageName, dockerClient, runArgsMap, gitspaceLogger, dockerRegistryAuth); err != nil {
|
||||
return err
|
||||
}
|
||||
portMappings := infrastructure.GitspacePortMappings
|
||||
@ -665,6 +670,7 @@ func (e *EmbeddedDockerOrchestrator) createAndStartNewGitspace(
|
||||
infrastructure types.Infrastructure,
|
||||
defaultBaseImage string,
|
||||
ideService ide.IDE,
|
||||
dockerRegistryAuth gitspaceTypes.DockerRegistryAuth,
|
||||
) error {
|
||||
logStreamInstance, err := e.statefulLogger.CreateLogStream(ctx, gitspaceConfig.ID)
|
||||
if err != nil {
|
||||
@ -681,6 +687,7 @@ func (e *EmbeddedDockerOrchestrator) createAndStartNewGitspace(
|
||||
resolvedRepoDetails,
|
||||
defaultBaseImage,
|
||||
logStreamInstance,
|
||||
dockerRegistryAuth,
|
||||
)
|
||||
if startErr != nil {
|
||||
return fmt.Errorf("failed to start gitspace %s: %w", gitspaceConfig.Identifier, startErr)
|
||||
|
@ -18,6 +18,7 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/harness/gitness/app/gitspace/orchestrator/devcontainer"
|
||||
"github.com/harness/gitness/types"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
@ -38,3 +39,11 @@ type Step struct {
|
||||
type ZerologAdapter struct {
|
||||
logger *zerolog.Logger
|
||||
}
|
||||
|
||||
type DockerRegistryAuth struct {
|
||||
// only host name is required
|
||||
// eg: docker.io instead of https://docker.io
|
||||
RegistryURL string
|
||||
Username *types.MaskSecret
|
||||
Password *types.MaskSecret
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user