feat: [CDE-231]: Adding logs method to orchestrator and fixing logic to catch cmd execuction errors in devcontainer.Exec. (#2472)

* feat: [CDE-231]: Adding logs method to orchestrator and fixing logic to catch cmd execuction errors in devcontainer.Exec.
pull/3545/head
Dhruv Dhruv 2024-08-13 04:27:04 +00:00 committed by Harness
parent 5bea61a139
commit 1e3c910c07
6 changed files with 65 additions and 10 deletions

View File

@ -43,4 +43,7 @@ type Orchestrator interface {
// Status checks if the infra is reachable and ready to orchestrate containers.
Status(ctx context.Context, infra types.Infrastructure) error
// StreamLogs is used to fetch gitspace's start/stop logs from the container orchestrator.
StreamLogs(ctx context.Context, gitspaceConfig types.GitspaceConfig, infra types.Infrastructure) (string, error)
}

View File

@ -941,3 +941,10 @@ func (e EmbeddedDockerOrchestrator) removeContainer(
return nil
}
func (e *EmbeddedDockerOrchestrator) StreamLogs(
_ context.Context,
_ types.GitspaceConfig,
_ types.Infrastructure) (string, error) {
return "", fmt.Errorf("not implemented")
}

View File

@ -35,8 +35,9 @@ type Exec struct {
}
type execResult struct {
StdOut []byte
StdErr []byte
StdOut []byte
StdErr []byte
ExitCode int
}
func (e *Exec) ExecuteCommand(
@ -67,14 +68,24 @@ func (e *Exec) ExecuteCommand(
return nil, fmt.Errorf("failed to create docker exec for container %s: %w", e.ContainerName, err)
}
attachResult, err := e.attachExec(ctx, execID.ID, detach)
resp, err := e.attachAndInspectExec(ctx, execID.ID, detach)
if err != nil && err.Error() != "unable to upgrade to tcp, received 200" {
return nil, fmt.Errorf("failed to start docker exec for container %s: %w", e.ContainerName, err)
}
if resp != nil && resp.ExitCode != 0 {
var errLog string
if resp.StdErr != nil {
errLog = string(resp.StdErr)
}
return nil, fmt.Errorf("error during command execution in container %s. exit code %d. log: %s",
e.ContainerName, resp.ExitCode, errLog)
}
var stdOutput []byte
if attachResult != nil {
stdOutput = attachResult.StdOut
if resp != nil {
stdOutput = resp.StdOut
}
return stdOutput, nil
@ -89,7 +100,7 @@ func (e *Exec) ExecuteCommandInHomeDirectory(
return e.ExecuteCommand(ctx, command, root, detach, e.HomeDir)
}
func (e *Exec) attachExec(ctx context.Context, id string, detach bool) (*execResult, error) {
func (e *Exec) attachAndInspectExec(ctx context.Context, id string, detach bool) (*execResult, error) {
resp, attachErr := e.DockerClient.ContainerExecAttach(ctx, id, container.ExecStartOptions{Detach: detach})
if attachErr != nil {
return nil, attachErr
@ -126,8 +137,14 @@ func (e *Exec) attachExec(ctx context.Context, id string, detach bool) (*execRes
return nil, fmt.Errorf("failed to read stderr of exec for container %s: %w", e.ContainerName, err)
}
inspectRes, err := e.DockerClient.ContainerExecInspect(ctx, id)
if err != nil {
return nil, fmt.Errorf("failed to inspect exec for container %s: %w", e.ContainerName, err)
}
return &execResult{
StdOut: stdout,
StdErr: stderr,
StdOut: stdout,
StdErr: stderr,
ExitCode: inspectRes.ExitCode,
}, nil
}

View File

@ -53,4 +53,7 @@ type Orchestrator interface {
gitspaceConfig types.GitspaceConfig,
deprovisionedInfra types.Infrastructure,
) (enum.GitspaceInstanceStateType, error)
// GetGitspaceLogs fetches gitspace's start/stop logs.
GetGitspaceLogs(ctx context.Context, gitspaceConfig types.GitspaceConfig) (string, error)
}

View File

@ -489,3 +489,28 @@ func (o orchestrator) getPortsRequiredForGitspace(
idePort := ideSvc.Port()
return []int{idePort}, nil
}
func (o orchestrator) GetGitspaceLogs(ctx context.Context, gitspaceConfig types.GitspaceConfig) (string, error) {
infraProviderResource, err := o.infraProviderResourceStore.Find(ctx, gitspaceConfig.InfraProviderResourceID)
if err != nil {
return "", fmt.Errorf(
"cannot get the infraProviderResource with ID %d: %w", gitspaceConfig.InfraProviderResourceID, err)
}
requiredGitspacePorts, err := o.getPortsRequiredForGitspace(gitspaceConfig)
if err != nil {
return "", fmt.Errorf("cannot get the ports required for gitspace during get logs: %w", err)
}
infra, err := o.infraProvisioner.Find(ctx, *infraProviderResource, gitspaceConfig, requiredGitspacePorts)
if err != nil {
return "", fmt.Errorf("cannot find the provisioned infra: %w", err)
}
logs, err := o.containerOrchestrator.StreamLogs(ctx, gitspaceConfig, *infra)
if err != nil {
return "", fmt.Errorf("error while fetching logs from container orchestrator: %w", err)
}
return logs, nil
}

View File

@ -33,9 +33,9 @@ fi
git config --global user.email $email
git config --global user.name $name
# Clone the repository inside the working directory if it doesn't exist
if [ ! -d ".git" ]; then
if [ ! -d "$HOME/$repo_name/.git" ]; then
echo "Cloning the repository..."
if ! git clone "$repo_url" --branch "$branch" ; then
if ! git clone "$repo_url" --branch "$branch" "$HOME/$repo_name"; then
echo "Failed to clone the repository. Exiting..."
rm $HOME/.git-askpass
exit 1