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

Add new UDC to perform an optimized git deep clone #22

Merged
merged 14 commits into from
Nov 14, 2023
5 changes: 4 additions & 1 deletion Earthfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@ install-dind-script:
SAVE ARTIFACT ./install-dind.sh

test:
FROM alpine:3.18
BUILD +test-install-dind-amd64
BUILD ./ssh+test-add-known-hosts
FOR dir IN "ssh git"
idodod marked this conversation as resolved.
Show resolved Hide resolved
BUILD ./$dir+test
END

test-install-dind-amd64:
BUILD --platform=linux/amd64 +test-install-dind-for-image \
Expand Down
32 changes: 32 additions & 0 deletions git/Earthfile
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@vladaionescu should I maybe move git and ssh folders into a new tools folder
(and later also DIND_INSTALL into dind)?

Copy link
Member

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 move all three into such a common / misc / utitlities folder. We can keep DIND_INSTALL in the root too for backwards compatibility.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yep, that's what I was trying to suggest :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I moved everything under utils, lmk if you prefer a different name.

Copy link
Member

Choose a reason for hiding this comment

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

Looks good!

Should github.com/earthly/lib/utils expose the UDCs directly? (We can still have the implementation in subdirs)

Copy link
Member

Choose a reason for hiding this comment

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

Hmm.. I wouldn't do it. It just adds more complexity to the language, with little benefit.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

so we're left only with some variation of exposing the UDCs in utils/Earthfile, aren't we?

Copy link
Member

Choose a reason for hiding this comment

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

I think that's the best option

Copy link
Contributor Author

@idodod idodod Nov 8, 2023

Choose a reason for hiding this comment

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

This is the alternative

IMPORT github.com/earthly/lib/utils/git:<tag>
IMPORT github.com/earthly/lib/utils/ssh:<tag>

but this would probably mean cloning more than once, unless it's cached/deduped?

Copy link
Member

Choose a reason for hiding this comment

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

It's a reasonable alternative - especially if sticking with the naming dind+INSTALL (as opposed to utils+INSTALL_DIND). The main downside of this is having to import each UDC separately. Arguably, you might not use multiple lib UDCs for this to be a problem. Maybe it can be in the future?

Having utils split up into subdirectories helps with segregating UDCs into different areas of concern nicely. But it also has the drawback that it's slightly more confusing what tag to use for each.

All in all, I'm ok with either option. There are pros and cons for each.

Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
VERSION --arg-scope-and-set 0.7

# DEEP_CLONE deep clones the provided git url
DEEP_CLONE:
COMMAND
ARG USE_GIT_ENV="false"
IF [ $USE_GIT_ENV = "true" ]
FROM alpine/git:v2.40.1
END
DO ../ssh+ADD_KNOWN_HOSTS
ARG --required GIT_URL
ARG DEST_DIR
LET dest_dir=$DEST_DIR
IF [ -z $dest_dir ]
SET dest_dir=$(basename ${GIT_URL%.git})
END
GIT CLONE $GIT_URL $dest_dir
WORKDIR $dest_dir
RUN git remote set-url origin $GIT_URL
ARG git_hash=$(git rev-parse HEAD)
ARG SECRET_PATH
IF [ -z $SECRET_PATH ]
RUN echo secrets path is z
RUN --ssh git fetch --unshallow
ELSE
RUN echo secrets path is NOT z
RUN --mount=type=secret,id=$SECRET_PATH,mode=0400,target=/root/.ssh/id_rsa \
git fetch --unshallow
END

test:
BUILD ./tests+all
48 changes: 48 additions & 0 deletions git/tests/Earthfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
VERSION --arg-scope-and-set --pass-args 0.7

PROJECT earthly-technologies/core

all:
BUILD --platform=linux/amd64 --platform=linux/arm64 +test-deep-clone-image \
--base_image=alpine/git:latest \
--base_image=alpine:latest \
--base_image=debian:stable \
--base_image=debian:stable-slim \
--base_image=ubuntu:latest \
--base_image=amazonlinux:1 \
--base_image=amazonlinux:2 \
--GIT_URL=https://github.com/earthly/lib.git \
[email protected]:earthly/cloud.git \
[email protected]:earthly/cloud \
--SECRET_PATH="" \
--SECRET_PATH="littleredcorvette-id_rsa" \
--DEST_DIR="" \
--DEST_DIR="some-other-dir"

test-deep-clone-image:
ARG --required base_image
ARG TARGETPLATFORM
FROM alpine
IF [ "$base_image" = "amazonlinux:1" ] && [ "$TARGETPLATFORM" = "linux/arm64" ] # no amazonlinux:1 for arm64, skipping
RUN echo skipping $base_image with platform $TARGETPLATFORM
ELSE
FROM "$base_image"
LET use_git_env="true"
IF [ "${base_image%:*}" = "alpine/git" ]
SET use_git_env="false"
RUN apk add git
ELSE IF [ "${base_image%:*}" = "alpine" ]
RUN apk add git
ELSE IF [ "${base_image%:*}" = "debian" ]
RUN apt update && apt install -y git
ELSE IF [ "${base_image%:*}" = "ubuntu" ]
RUN apt-get update && apt-get -y install git
ELSE IF [[ $base_image == amazonlinux* ]]
RUN yum -y install git
END
DO --pass-args ..+DEEP_CLONE --USE_GIT_ENV=$use_git_env
IF [ -n $DEST_DIR ]
WORKDIR $DEST_DIR
END
RUN git checkout main
END
48 changes: 5 additions & 43 deletions ssh/Earthfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
VERSION --pass-args --arg-scope-and-set 0.7
VERSION 0.7

# ADD_KNOWN_HOSTS will append some known public keys into the $target_file
# ADD_KNOWN_HOSTS appends some known public keys into the $target_file
ADD_KNOWN_HOSTS:
COMMAND
ARG target_file=~/.ssh/known_hosts
Expand All @@ -11,47 +11,9 @@ ADD_KNOWN_HOSTS:

# known-hosts is used to copy the known_hosts file into the build context (internal use)
known-hosts:
FROM alpine
FROM alpine:3.18.4
COPY known_hosts .
idodod marked this conversation as resolved.
Show resolved Hide resolved
SAVE ARTIFACT known_hosts

#######################
# Tests:
#######################

test-add-known-hosts:
BUILD --platform=linux/amd64 +test-add-known-hosts-image \
--base_image=alpine:latest \
--base_image=debian:stable \
--base_image=debian:stable-slim \
--base_image=ubuntu:latest \
--base_image=amazonlinux:1 \
--base_image=amazonlinux:2 \
--target_file=~/to_interpolate/known_hosts \
--target_file=no_dir_new_known_hosts \
--target_file=/some/dir/to/file/new_known_hosts \
--target_file=existing_known_hosts # this will be handled in the test target

test-add-known-hosts-image:
ARG --required base_image
ARG TARGETPLATFORM
FROM alpine
IF [ "$base_image" = "amazonlinux:1" ] && [ "$TARGETPLATFORM" = "linux/arm64" ] # no amazonlinux:1 for arm64, skipping
RUN echo skipping $base_image with platform $TARGETPLATFORM
ELSE
FROM "$base_image"
IF [ "$base_image" = "amazonlinux:1" ]
RUN yum -y install diffutils.x86_64
END
COPY ./known_hosts /tmp/expected-temp
RUN test -s /tmp/expected-temp
ARG target_file
IF [ "$target_file" = "existing_known_hosts" ]
RUN echo some-key >> /tmp/expected
RUN echo some-key >> $target_file
END
RUN cat /tmp/expected-temp >> /tmp/expected
DO --pass-args +ADD_KNOWN_HOSTS
LET expanded_target_file="$(eval echo $target_file)"
RUN diff /tmp/expected $(eval echo $expanded_target_file)
END
test:
BUILD ./tests+all
38 changes: 38 additions & 0 deletions ssh/tests/Earthfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
VERSION --pass-args --arg-scope-and-set 0.7

all:
BUILD --platform=linux/amd64 --platform=linux/arm64 +test-add-known-hosts-image \
--base_image=alpine:latest \
--base_image=debian:stable \
--base_image=debian:stable-slim \
--base_image=ubuntu:latest \
--base_image=amazonlinux:1 \
--base_image=amazonlinux:2 \
--target_file=~/to_interpolate/known_hosts \
--target_file=no_dir_new_known_hosts \
--target_file=/some/dir/to/file/new_known_hosts \
--target_file=existing_known_hosts # this will be handled in the test target

test-add-known-hosts-image:
ARG --required base_image
ARG TARGETPLATFORM
FROM alpine
IF [ "$base_image" = "amazonlinux:1" ] && [ "$TARGETPLATFORM" = "linux/arm64" ] # no amazonlinux:1 for arm64, skipping
RUN echo skipping $base_image with platform $TARGETPLATFORM
ELSE
FROM "$base_image"
IF [ "$base_image" = "amazonlinux:1" ]
RUN yum -y install diffutils.x86_64
END
COPY ..+known-hosts/known_hosts /tmp/expected-temp
RUN test -s /tmp/expected-temp
ARG target_file
IF [ "$target_file" = "existing_known_hosts" ]
RUN echo some-key >> /tmp/expected
RUN echo some-key >> $target_file
END
RUN cat /tmp/expected-temp >> /tmp/expected
DO --pass-args ..+ADD_KNOWN_HOSTS
LET expanded_target_file="$(eval echo $target_file)"
RUN diff /tmp/expected $(eval echo $expanded_target_file)
END
Loading