Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions project-clone/internal/git/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ func doInitialGitClone(project *dw.Project) error {
// Clone into a temp dir and then move set up project to PROJECTS_ROOT to try and make clone atomic in case
// project-clone container is terminated
tmpClonePath := path.Join(internal.CloneTmpDir, projectslib.GetClonePath(project))
if err := os.MkdirAll(path.Dir(tmpClonePath), 0755); err != nil {
return fmt.Errorf("failed to create parent directories for temp clone path %s: %w", tmpClonePath, err)
}
var cloneErr error
for attempt := 0; attempt <= internal.CloneRetries; attempt++ {
if attempt > 0 {
Expand Down Expand Up @@ -120,6 +123,11 @@ func setupRemotesForExistingProject(project *dw.Project) error {
}

func copyProjectFromTmpDir(project *dw.Project, tmpClonePath string) error {
projectPath := path.Join(internal.ProjectsRoot, projectslib.GetClonePath(project))
if err := os.MkdirAll(path.Dir(projectPath), 0755); err != nil {
return fmt.Errorf("failed to create parent directories for project path %s: %w", projectPath, err)
}

if project.Attributes.Exists(internal.ProjectSubDir) {
// Only want one directory from the project
var err error
Expand All @@ -128,13 +136,11 @@ func copyProjectFromTmpDir(project *dw.Project, tmpClonePath string) error {
return fmt.Errorf("failed to process subDir on project: %w", err)
}
subDirPath := path.Join(tmpClonePath, subDirSubPath)
projectPath := path.Join(internal.ProjectsRoot, projectslib.GetClonePath(project))
log.Printf("Moving subdirectory %s in project %s from temporary directory to %s", subDirSubPath, project.Name, projectPath)
if err := os.Rename(subDirPath, projectPath); err != nil {
return fmt.Errorf("failed to move subdirectory of cloned project to %s: %w", internal.ProjectsRoot, err)
}
} else {
projectPath := path.Join(internal.ProjectsRoot, projectslib.GetClonePath(project))
log.Printf("Moving cloned project %s from temporary directory %s to %s", project.Name, tmpClonePath, projectPath)
if err := os.Rename(tmpClonePath, projectPath); err != nil {
return fmt.Errorf("failed to move cloned project to %s: %w", internal.ProjectsRoot, err)
Expand Down
6 changes: 6 additions & 0 deletions project-clone/internal/zip/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ func SetupZipProject(project v1alpha2.Project, httpClient *http.Client) error {
}

tmpProjectsPath := path.Join(internal.CloneTmpDir, clonePath)
if err := os.MkdirAll(path.Dir(tmpProjectsPath), 0755); err != nil {
return fmt.Errorf("failed to create parent directories for temp path %s: %w", tmpProjectsPath, err)
}

zipFilePath := path.Join(tmpDir, fmt.Sprintf("%s.zip", clonePath))
log.Printf("Downloading project archive from %s", url)
Expand All @@ -67,6 +70,9 @@ func SetupZipProject(project v1alpha2.Project, httpClient *http.Client) error {
}

// Move unzipped project from tmp dir to final destination
if err := os.MkdirAll(path.Dir(projectPath), 0755); err != nil {
return fmt.Errorf("failed to create parent directories for project path %s: %w", projectPath, err)
}
log.Printf("Moving extracted project archive to %s", projectPath)
if err := os.Rename(tmpProjectsPath, projectPath); err != nil {
return fmt.Errorf("failed to move unzipped project to PROJECTS_ROOT: %w", err)
Expand Down
121 changes: 121 additions & 0 deletions project-clone/test/nested-clone-path-test.devworkspace.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
apiVersion: workspace.devfile.io/v1alpha2
kind: DevWorkspace
metadata:
name: nested-clone-path-test
labels:
app.kubernetes.io/name: devworkspace-project-clone-tests
app.kubernetes.io/part-of: devworkspace-operator
annotations:
controller.devfile.io/debug-start: "true"
spec:
started: true
routingClass: 'basic'
template:
attributes:
controller.devfile.io/storage-type: ephemeral
variables:
test_runner_image: quay.io/devfile/project-clone:next # Requires git, bash
main_repo: https://github.com/devfile/devworkspace-operator.git
default_branch_name: main
projects:
- name: backend-api
clonePath: back/api
git:
remotes:
origin: "{{main_repo}}"
- name: backend-worker
clonePath: back/worker
git:
remotes:
origin: "{{main_repo}}"
- name: frontend-app
clonePath: ui/app
git:
remotes:
origin: "{{main_repo}}"
- name: flat-project
git:
remotes:
origin: "{{main_repo}}"
components:
- name: test-project-clone
container:
image: "{{test_runner_image}}"
memoryLimit: 512Mi
mountSources: true
command:
- "/bin/bash"
- "-c"
- |
set -e

fail() {
echo "[ERROR] $1"
echo "[ERROR] See project-clone logs: "
echo "[ERROR] oc logs -n $DEVWORKSPACE_NAMESPACE deploy/$DEVWORKSPACE_ID -c project-clone"
exit 1
}

if [ -f "${PROJECTS_ROOT}/project-clone-errors.log" ]; then
echo "==== BEGIN PROJECT CLONE LOGS ===="
sed 's/^/ /g' "${PROJECTS_ROOT}/project-clone-errors.log"
echo "==== END PROJECT CLONE LOGS ===="
echo -e "\n\n"
fi

for project_dir in "back/api" "back/worker" "ui/app" "flat-project"; do
if [ ! -d "${PROJECTS_ROOT}/${project_dir}" ]; then
fail "Project at ${project_dir} not cloned successfully"
fi
done

echo "Testing nested clonePath project: back/api"
cd "${PROJECTS_ROOT}/back/api"
branch_name=$(git rev-parse --abbrev-ref HEAD)
if [ "$branch_name" != "{{default_branch_name}}" ]; then
fail "Project back/api does not have default branch checked out"
fi
remote_url=$(git config remote.origin.url)
if [ "$remote_url" != "{{main_repo}}" ]; then
fail "Remote 'origin' not configured for back/api"
fi
echo "back/api: on $branch_name, remotes configured"

echo "Testing nested clonePath project: back/worker"
cd "${PROJECTS_ROOT}/back/worker"
branch_name=$(git rev-parse --abbrev-ref HEAD)
if [ "$branch_name" != "{{default_branch_name}}" ]; then
fail "Project back/worker does not have default branch checked out"
fi
remote_url=$(git config remote.origin.url)
if [ "$remote_url" != "{{main_repo}}" ]; then
fail "Remote 'origin' not configured for back/worker"
fi
echo "back/worker: on $branch_name, remotes configured"

echo "Testing nested clonePath project: ui/app"
cd "${PROJECTS_ROOT}/ui/app"
branch_name=$(git rev-parse --abbrev-ref HEAD)
if [ "$branch_name" != "{{default_branch_name}}" ]; then
fail "Project ui/app does not have default branch checked out"
fi
remote_url=$(git config remote.origin.url)
if [ "$remote_url" != "{{main_repo}}" ]; then
fail "Remote 'origin' not configured for ui/app"
fi
echo "ui/app: on $branch_name, remotes configured"

echo "Testing flat clonePath project (no nesting)"
cd "${PROJECTS_ROOT}/flat-project"
branch_name=$(git rev-parse --abbrev-ref HEAD)
if [ "$branch_name" != "{{default_branch_name}}" ]; then
fail "Project flat-project does not have default branch checked out"
fi
remote_url=$(git config remote.origin.url)
if [ "$remote_url" != "{{main_repo}}" ]; then
fail "Remote 'origin' not configured for flat-project"
fi
echo "flat-project: on $branch_name, remotes configured"

echo "[SUCCESS] Test succeeded. Sleeping indefinitely"
tail -f /dev/null