Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add support for zip projects in project-clone init container #460

Merged
merged 10 commits into from
Jun 24, 2021

Conversation

amisevsk
Copy link
Collaborator

What does this PR do?

  • Add support for zip-type projects in devfiles. Zip files are downloaded and extracted as-is.
  • Delegate git clone step to standard git binary rather than relying on the go-git library

Using git instead of go-git for cloning projects results in the project-clone image being ~180MB larger (due to requiring git). However, from some brief testing, it also reduces the memory requirement of project clone by around 5x for large projects.

What issues does this PR fix or reference?

Closes #416
Closes #454

Is it tested? How?

Changes are built and pushed to quay.io/amisevsk/project-clone:zip-support and can be tested with the devfile below

cat <<EOF | kubectl apply -f -
kind: DevWorkspace
apiVersion: workspace.devfile.io/v1alpha2
metadata:
  name: projects-testing
spec:
  started: true
  template:
    projects:
      - name: dwo
        zip:
          location: https://github.com/devfile/devworkspace-operator/archive/refs/heads/0.6.x.zip
        clonePath: test-project-zip
      - name: dwo-2
        git:
          checkoutFrom:
            revision: 0.6.x
          remotes:
            origin: https://github.com/devfile/devworkspace-operator.git
        clonePath: "test-project-git"

    components:
      - name: tools
        container:
          image: quay.io/amisevsk/project-clone:debug
          command:
            - "tail"
            - "-f"
            - "/dev/null"
EOF

Alternatively, the project clone image can be tested directly:

TMPDIR=$(mktemp -d)
cat <<EOF > "$TMPDIR/dw.yaml"
projects:
  - name: dwo
    zip:
      location: https://github.com/devfile/devworkspace-operator/archive/refs/heads/0.6.x.zip
    clonePath: test-project-zip
  - name: dwo-2
    git:
      checkoutFrom:
        revision: 0.6.x
      remotes:
        origin: https://github.com/devfile/devworkspace-operator.git
    clonePath: "test-project-git"
EOF

podman run \
  -e DEVWORKSPACE_FLATTENED_DEVFILE=/tmp/dw.yaml \
  -e PROJECTS_ROOT=/projects \
  --mount type=bind,src=$TMPDIR/dw.yaml,dst=/tmp/dw.yaml,z \
  --mount type=tmpfs,tmpfs-size=500M,dst=/projects/ \
  quay.io/amisevsk/project-clone:zip-support -- /bin/bash -c "/usr/local/bin/project-clone; sleep 10d"

(once clone is completed, run podman exec -it <the container> /bin/bash and check /projects manually)

@amisevsk amisevsk changed the title Zip project clone feat: add support for zip projects in project-clone init container Jun 16, 2021
@amisevsk amisevsk force-pushed the zip-project-clone branch from ff47006 to 9510936 Compare June 16, 2021 20:41
@benoitf
Copy link
Collaborator

benoitf commented Jun 17, 2021

hello, do you think we could use https://github.com/kubernetes/git-sync instead as the utility to clone projects ?

@amisevsk
Copy link
Collaborator Author

git-sync may be overkill or targeting a different use-case. We basically only ever want to sync the git repo once -- otherwise we risk overwriting user changes on start.

amisevsk added 6 commits June 21, 2021 14:58
…unctionality

Signed-off-by: Angel Misevski <amisevsk@redhat.com>
Signed-off-by: Angel Misevski <amisevsk@redhat.com>
…chives

Signed-off-by: Angel Misevski <amisevsk@redhat.com>
Instead of using PlainClone() from go-git, delegate the cloning step to
the standard git binary. This is required as go-git's clone operation
takes significant memory when cloning large projects.

This commit installs git in the project-clone container, which increases
its size by ~180MB.

Signed-off-by: Angel Misevski <amisevsk@redhat.com>
Signed-off-by: Angel Misevski <amisevsk@redhat.com>
Change entrypoint used for devworkspace operator and project clone to
use /bin/bash (shellcheck warns that some syntax in the devfile is not
POSIX sh compatible) and double quotes the `exec $@` line to allow
overriding entrypoint with e.g. /bin/bash -c "echo one && echo two"

Signed-off-by: Angel Misevski <amisevsk@redhat.com>
// TODO: Handle sparse checkout
// TODO: Add support for auth
func main() {
workspace, err := readFlattenedDevWorkspace()
workspace, err := internal.ReadFlattenedDevWorkspace()
if err != nil {
log.Printf("Failed to read current DevWorkspace: %s", err)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems it can be Failed to read current DevWorkspace: error reading current DevWorkspace YAML which is a bit of duplication

maybe error reading current DevWorkspace YAML -> error reading file %s

} else {
log.Printf("Project '%s' is already cloned and has all remotes configured", project.Name)
if err != nil {
log.Printf("Encountered error while setting up project %s: %s", project.Name, err)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
log.Printf("Encountered error while setting up project %s: %s", project.Name, err)
log.Printf("Encountered error while setting up project %s: %s", project.Name, err)
os.Exit(1)

?

Also, probably git/setup.go is suppose to be adapted since zip return error while git log error and go os.Exit(1).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

// closeSafe is a wrapper on io.Closer.Close() that just prints an error if encountered.
//
// Adapted from the Che plugin broker:
// https://github.com/eclipse/che-plugin-broker/blob/27e7c6953c92633cbe7e8ce746a16ca10d240ea2/utils/ioutil.go#L326
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how these references from sources could help us in future? Maybe just drop them?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels strange to copy-paste code from another project without referencing its source, even if I helped write both functions :)

}

log.Printf("Extracting project archive to %s", zipFilePath)
err = unzip(zipFilePath, projectPath)
Copy link
Member

@sleshchenko sleshchenko Jun 22, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should not drop the top level folder.
Like

cat <<EOF | kubectl apply -f -
kind: DevWorkspace
apiVersion: workspace.devfile.io/v1alpha2
metadata:
  name: projects-testing
spec:
  started: true
  template:
    projects:
      - name: dwo
        zip:
          location: https://github.com/devfile/devworkspace-operator/archive/refs/heads/main.zip
        clonePath: test-project-zip
      - name: dwo-2
        git:
          checkoutFrom:
            revision: 0.6.x
          remotes:
            origin: https://github.com/devfile/devworkspace-operator.git
        clonePath: "test-project-git"

    components:
      - name: tools
        container:
          image: quay.io/amisevsk/project-clone:debug
          command:
            - "tail"
            - "-f"
            - "/dev/null"
EOF

^ the project is the same but git will be in test-project-git when zip in test-project-zip/devworkspace-operator-main.
I'm not sure about the current Theia behavior
Screenshot_20210622_160606
Screenshot_20210622_161354

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll work on it 👍

I was mostly going for compatibility with how Theia currently does it, but there's no real reason for that :)

Co-authored-by: Serhii Leshchenko <sleshche@redhat.com>
@openshift-ci openshift-ci bot removed lgtm labels Jun 23, 2021
amisevsk added 2 commits June 22, 2021 23:48
Signed-off-by: Angel Misevski <amisevsk@redhat.com>
Fix an issue where if a project does not specify checkoutFrom.Remote
when using only one remote, the remote name in logs is empty.

Signed-off-by: Angel Misevski <amisevsk@redhat.com>
Change project-clone functionality to extract zip projects while
dropping top-level directories in the archive, e.g. change

  /projects/my-project/my-project-main/[files]

to

  /projects/my-project/[files]

when /projects/my-project/ contains only a single directory

Signed-off-by: Angel Misevski <amisevsk@redhat.com>
Copy link
Member

@sleshchenko sleshchenko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tested and it works fine

@openshift-ci
Copy link

openshift-ci bot commented Jun 23, 2021

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: amisevsk, JPinkney, sleshchenko

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:
  • OWNERS [JPinkney,amisevsk,sleshchenko]

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@sleshchenko
Copy link
Member

/test v7-devworkspaces-operator-e2e, v7-devworkspace-happy-path

@amisevsk amisevsk merged commit cc86aac into devfile:main Jun 24, 2021
@amisevsk amisevsk deleted the zip-project-clone branch June 24, 2021 01:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants