Diff of /justfile [000000] .. [b9e282]

Switch to unified view

a b/justfile
1
#!/usr/bin/env -S just --justfile
2
3
# https://github.com/casey/just?tab=readme-ov-file#dotenv-settings
4
set dotenv-load
5
6
# https://github.com/casey/just?tab=readme-ov-file#export
7
set export
8
9
# don't fail fast here --> the `setup` command will check this!
10
COMMIT := `git rev-parse HEAD || true`
11
IMAGE_TAG := "bionemo2-" + COMMIT
12
DEV_IMAGE_TAG := "dev-" + IMAGE_TAG
13
DATE := `date --iso-8601=seconds -u`
14
LOCAL_ENV := '.env'
15
DOCKER_REPO_PATH := '/workspace/bionemo2'
16
LOCAL_REPO_PATH := `realpath $(pwd)`
17
18
[private]
19
default:
20
  @just --list
21
22
###############################################################################
23
24
[private]
25
check_preconditions:
26
  #!/usr/bin/env bash
27
28
  version_ge() {
29
      # Returns 0 (true) if $1 >= $2, 1 (false) otherwise
30
      [ "$(printf '%s\n' "$1" "$2" | sort -V | head -n1)" = "$2" ]
31
  }
32
33
  if [[ $(command -v git) ]]; then
34
    commit=$(git rev-parse HEAD)
35
    if [[ "$?" != "0" ]]; then
36
      echo "ERROR: must run from within git repository!"
37
      exit 1
38
    fi
39
  else
40
    echo "ERROR: git is not installed!"
41
    exit 1
42
  fi
43
44
  if [[ ! $(command -v docker) ]]; then
45
    echo "ERROR: docker is not installed!"
46
    exit 1
47
  fi
48
49
  docker_version=$(docker --version | awk -F'[, ]' '{print $3}')
50
  required_docker_version='23.0.1'
51
52
  if ! version_ge "$docker_version" "$required_docker_version"; then
53
      echo "Error: Docker version $required_docker_version or higher is required. Current version: $docker_version"
54
      exit 1
55
  fi
56
57
58
# Checks for installed programs (docker, git, etc.), their versions, and grabs the latest cache image.
59
setup: check_preconditions
60
  ./internal/scripts/setup_env_file.sh
61
  @echo "Pulling updated cache..."
62
  docker pull ${IMAGE_REPO}:${CACHE_TAG} || true
63
64
65
[private]
66
assert_clean_git_repo:
67
  #!/usr/bin/env bash
68
69
  git diff-index --quiet HEAD --
70
  exit_code="$?"
71
72
  if [[ "${exit_code}" == "128" ]]; then
73
      echo "ERROR: Cannot build image if not in bionemo git repository!"
74
      exit 1
75
76
  elif [[ "${exit_code}" == "1" ]]; then
77
      echo "ERROR: Repository is dirty! Commit all changes before building image!"
78
      exit  2
79
80
  elif [[ "${exit_code}" == "0" ]]; then
81
      echo "ok" 2> /dev/null
82
83
  else
84
      echo "ERROR: Unknown exit code for `git diff-index`: ${exit_code}"
85
      exit 1
86
  fi
87
88
###############################################################################
89
90
[private]
91
build image_tag target: setup assert_clean_git_repo
92
  DOCKER_BUILDKIT=1 docker buildx build \
93
  -t ${IMAGE_REPO}:{{image_tag}} \
94
  --target={{target}} \
95
  --load \
96
  --cache-to type=inline \
97
  --cache-from ${IMAGE_REPO}:${CACHE_TAG} \
98
  --label com.nvidia.bionemo.git_sha=${COMMIT} \
99
  --label com.nvidia.bionemo.created_at=${DATE} \
100
  -f ./Dockerfile \
101
  .
102
103
# Builds the release image.
104
build-release:
105
  @just build ${IMAGE_TAG} release
106
107
# Builds the development image.
108
build-dev:
109
  @just build ${DEV_IMAGE_TAG} development
110
111
###############################################################################
112
113
[private]
114
run is_dev is_interactive image_tag cmd: setup
115
  #!/usr/bin/env bash
116
117
  DOCKER_VERSION=$(docker version | grep -i version | head -1 | awk '{print $2}')
118
  DOCKER_VERSION_WITH_GPU_SUPPORT='19.03.0'
119
  if [ "$DOCKER_VERSION_WITH_GPU_SUPPORT" == "$(echo -e "$DOCKER_VERSION\n$DOCKER_VERSION_WITH_GPU_SUPPORT" | sort -V | head -1)" ]; then
120
      PARAM_RUNTIME="--gpus all"
121
  else
122
      PARAM_RUNTIME="--runtime=nvidia"
123
  fi
124
125
  docker_cmd="docker run \
126
  --rm \
127
  --network host \
128
  ${PARAM_RUNTIME} \
129
  -p ${JUPYTER_PORT}:8888 \
130
  --shm-size=4g \
131
  -e TMPDIR=/tmp/ \
132
  -e NUMBA_CACHE_DIR=/tmp/ \
133
  -e WANDB_API_KEY=$WANDB_API_KEY \
134
  -e NGC_CLI_API_KEY=$NGC_CLI_API_KEY \
135
  -e NGC_CLI_ORG=$NGC_CLI_ORG \
136
  -e NGC_CLI_TEAM=$NGC_CLI_TEAM \
137
  -e NGC_CLI_FORMAT_TYPE=$NGC_CLI_FORMAT_TYPE \
138
  -e AWS_ENDPOINT_URL \
139
  -e AWS_REGION \
140
  -e AWS_SECRET_ACCESS_KEY \
141
  -e AWS_ACCESS_KEY_ID \
142
  -e HOME=${DOCKER_REPO_PATH} \
143
  -w ${DOCKER_REPO_PATH} \
144
  -v ${LOCAL_RESULTS_PATH}:${DOCKER_RESULTS_PATH} \
145
  -v ${LOCAL_DATA_PATH}:${DOCKER_DATA_PATH} \
146
  -v ${LOCAL_MODELS_PATH}:${DOCKER_MODELS_PATH} \
147
  -v /etc/passwd:/etc/passwd:ro \
148
  -v /etc/group:/etc/group:ro \
149
  -v /etc/shadow:/etc/shadow:ro \
150
  -v ${HOME}/.ssh:${DOCKER_REPO_PATH}/.ssh:ro \
151
  -v ${LOCAL_REPO_PATH}/htmlcov:/${DOCKER_REPO_PATH}/htmlcov \
152
  -u $(id -u):$(id -g)"
153
154
  if [[ "{{is_dev}}" == "true" ]]; then
155
    docker_cmd="${docker_cmd} -v ${LOCAL_REPO_PATH}:${DOCKER_REPO_PATH}"
156
  fi
157
158
  if [[ "{{is_interactive}}" == "true" ]]; then
159
    docker_cmd="${docker_cmd} -it"
160
  fi
161
162
  docker_cmd="${docker_cmd} ${IMAGE_REPO}:{{image_tag}} {{cmd}}"
163
164
  set -xeuo pipefail
165
  DOCKER_BUILDKIT=1 ${docker_cmd}
166
167
[private]
168
ensure-dev-or-build:
169
  #!/usr/bin/env bash
170
  if [[ $(docker images -q "${IMAGE_REPO}:${DEV_IMAGE_TAG}" 2> /dev/null) == "" ]]; then
171
    echo "Building development image: ${IMAGE_REPO}:${DEV_IMAGE_TAG}"
172
    just build-dev
173
  else
174
    echo "Development image exists:   ${IMAGE_REPO}:${DEV_IMAGE_TAG}"
175
  fi
176
177
# run-dev lets us work with a dirty repository,
178
# beacuse this is a common state during development
179
# **AND** we're volume mounting the code, so we'll have the latest state.
180
# **BUT** we can only do this if we have built an image for DEV_IMAGE_TAG already,
181
# so we use ensure-dev-or-build which will build the image if it is necessary.
182
# Image building requires that the git repo state is clean!
183
#
184
# Runs an interactive program in the development bionemo image.
185
run-dev cmd='bash': ensure-dev-or-build
186
  @just run true true ${DEV_IMAGE_TAG} {{cmd}}
187
188
# in contrast, run-release requires a clean repository,
189
# because users want to know that they're running the **exact** version they expect
190
# and we're **NOT** volume mounting the code
191
#
192
# Runs an interactive program in the release bionemo image.
193
run-release cmd='bash': build-release assert_clean_git_repo
194
  @just run false true ${IMAGE_TAG} {{cmd}}
195
196
197
###############################################################################
198
199
# Executes pytest in the release image.
200
test: build-release
201
  @just run true false ${IMAGE_TAG} 'pytest -v --nbval-lax --cov=bionemo --cov-report term --cov-report=html docs/ scripts/ sub-packages/'