feat: [CDE-472]: add search gitspace, user dir fixed for life-cycle command (#3087)

* feat: [CDE-472]: add search gitspace, user dir fixed for life-cycle command
pull/3597/head
Ansuman Satapathy 2024-12-01 06:50:59 +00:00 committed by Harness
parent 1086397b3f
commit 293aa5ff29
3 changed files with 82 additions and 63 deletions

View File

@ -349,13 +349,13 @@ func PullImage(
}
if imagePullRunArg == "missing" {
gitspaceLogger.Info("Checking if image " + imageName + " is present locally")
ok, err := isImagePresentLocally(ctx, imageName, dockerClient)
imagePresentLocally, err := isImagePresentLocally(ctx, imageName, dockerClient)
if err != nil {
gitspaceLogger.Error("Error listing images locally", err)
return err
}
if ok {
if imagePresentLocally {
gitspaceLogger.Info("Image " + imageName + " is present locally")
return nil
}
@ -391,71 +391,13 @@ func PullImage(
}
}
}()
// Process JSON stream
decoder := json.NewDecoder(pullResponse)
layerStatus := make(map[string]string) // Track last status of each layer
for {
var pullEvent map[string]interface{}
if err := decoder.Decode(&pullEvent); err != nil {
if errors.Is(err, io.EOF) {
break
}
return logStreamWrapError(gitspaceLogger, "Error while decoding image pull response", err)
}
// Extract relevant fields from the JSON object
layerID, _ := pullEvent["id"].(string) // Layer ID (if available)
status, _ := pullEvent["status"].(string) // Current status
// Update logs only when the status changes
if layerID != "" {
if lastStatus, exists := layerStatus[layerID]; !exists || lastStatus != status {
layerStatus[layerID] = status
gitspaceLogger.Info(fmt.Sprintf("Layer %s: %s", layerID, status))
}
} else if status != "" {
// Log non-layer-specific status
gitspaceLogger.Info(status)
}
if err = processImagePullResponse(pullResponse, gitspaceLogger); err != nil {
return err
}
gitspaceLogger.Info("Image pull completed successfully")
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(
imageName,
platform string,
imageAuthMap map[string]gitspaceTypes.DockerRegistryAuth,
) (image.PullOptions, error) {
pullOpts := image.PullOptions{Platform: platform}
if imageAuth, ok := imageAuthMap[imageName]; ok {
authConfig := registry.AuthConfig{
Username: imageAuth.Username.Value(),
Password: imageAuth.Password.Value(),
ServerAddress: imageAuth.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,
@ -525,3 +467,68 @@ func encodeAuthToBase64(authConfig registry.AuthConfig) (string, error) {
}
return base64.URLEncoding.EncodeToString(authJSON), nil
}
func processImagePullResponse(pullResponse io.ReadCloser, gitspaceLogger gitspaceTypes.GitspaceLogger) error {
// Process JSON stream
decoder := json.NewDecoder(pullResponse)
layerStatus := make(map[string]string) // Track last status of each layer
for {
var pullEvent map[string]interface{}
if err := decoder.Decode(&pullEvent); err != nil {
if errors.Is(err, io.EOF) {
break
}
return logStreamWrapError(gitspaceLogger, "Error while decoding image pull response", err)
}
// Extract relevant fields from the JSON object
layerID, _ := pullEvent["id"].(string) // Layer ID (if available)
status, _ := pullEvent["status"].(string) // Current status
// Update logs only when the status changes
if layerID != "" {
if lastStatus, exists := layerStatus[layerID]; !exists || lastStatus != status {
layerStatus[layerID] = status
gitspaceLogger.Info(fmt.Sprintf("Layer %s: %s", layerID, status))
}
} else if status != "" {
// Log non-layer-specific status
gitspaceLogger.Info(status)
}
}
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(
imageName,
platform string,
imageAuthMap map[string]gitspaceTypes.DockerRegistryAuth,
) (image.PullOptions, error) {
pullOpts := image.PullOptions{Platform: platform}
if imageAuth, ok := imageAuthMap[imageName]; ok {
authConfig := registry.AuthConfig{
Username: imageAuth.Username.Value(),
Password: imageAuth.Password.Value(),
ServerAddress: imageAuth.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
}

View File

@ -627,7 +627,7 @@ func (e *EmbeddedDockerOrchestrator) setupGitspaceAndIDE(
defaultBaseImage string,
environment []string,
) error {
homeDir := GetUserHomeDir(gitspaceConfig.GitspaceUser.Identifier)
homeDir := GetUserHomeDir(exec.RemoteUser)
devcontainerConfig := resolvedRepoDetails.DevcontainerConfig
codeRepoDir := filepath.Join(homeDir, resolvedRepoDetails.RepoName)

View File

@ -122,6 +122,7 @@ func (s gitspaceConfigStore) Count(ctx context.Context, filter *types.GitspaceFi
PlaceholderFormat(squirrel.Dollar)
countStmt = addGitspaceFilter(countStmt, filter)
countStmt = addGitspaceQueryFilter(countStmt, filter.QueryFilter)
sql, args, err := countStmt.ToSql()
if err != nil {
@ -285,6 +286,7 @@ func (s gitspaceConfigStore) ListWithLatestInstance(
PlaceholderFormat(squirrel.Dollar)
stmt = addGitspaceFilter(stmt, filter)
stmt = addGitspaceQueryFilter(stmt, filter.QueryFilter)
stmt = addOrderBy(stmt, filter)
stmt = stmt.Limit(database.Limit(filter.QueryFilter.Size))
stmt = stmt.Offset(database.Offset(filter.QueryFilter.Page, filter.QueryFilter.Size))
@ -504,3 +506,13 @@ func (s gitspaceConfigStore) ToGitspaceConfigs(
}
return res, nil
}
func addGitspaceQueryFilter(stmt squirrel.SelectBuilder, filter types.ListQueryFilter) squirrel.SelectBuilder {
if filter.Query != "" {
stmt = stmt.Where(squirrel.Or{
squirrel.Expr(PartialMatch("gconf_uid", filter.Query)),
squirrel.Expr(PartialMatch("gconf_display_name", filter.Query)),
})
}
return stmt
}