Skip to content

Commit 5349ecf

Browse files
committed
Addressed Docker test results:
* Provide DataDog helper scripts (to test later) * Use stdout_open instead of duplicating stderr_open * Support Docker output format * Improve metadata detection handling * Run build as root (Docker seems to ignore USER when copying files) * Updated integration test
1 parent 5da05de commit 5349ecf

8 files changed

Lines changed: 54 additions & 36 deletions

File tree

Dockerfile

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,23 @@ FROM ${ROOTFS_IMAGE}
5454
LABEL Author="Mendix Digital Ecosystems"
5555
LABEL maintainer="digitalecosystems@mendix.com"
5656

57+
# Install Ruby if Datadog is detected
58+
ARG DD_API_KEY
59+
RUN if [ ! -z "$DD_API_KEY" ] ; then\
60+
microdnf update -y && \
61+
microdnf install -y ruby && \
62+
microdnf clean all && rm -rf /var/cache/yum \
63+
; fi
64+
5765
# Set the home path
5866
ENV HOME=/opt/mendix/build
5967

6068
# Add the buildpack modules
6169
ENV PYTHONPATH "/opt/mendix/buildpack/lib/:/opt/mendix/buildpack/:/opt/mendix/buildpack/lib/python3.11/site-packages/"
6270

71+
# Set the user ID
72+
ARG USER_UID=1001
73+
6374
USER ${USER_UID}
6475

6576
# Copy build artifacts from build container

build.py

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
import selectors
1515
import logging
1616
import platform
17-
import urllib.request
1817

1918
logging.basicConfig(
2019
level=logging.INFO,
@@ -75,13 +74,13 @@ def container_call(args):
7574

7675
last_line_stdout = None
7776
last_line_stderr = None
78-
stderr_open, stderr_open = True, True
79-
while stderr_open or stderr_open:
77+
stdout_open, stderr_open = True, True
78+
while stdout_open or stderr_open:
8079
for key, _ in sel.select():
8180
data = key.fileobj.readline()
8281
if data == '':
8382
if key.fileobj is proc.stdout:
84-
stdin_open = False
83+
stdout_open = False
8584
elif key.fileobj is proc.stderr:
8685
stderr_open = False
8786
continue
@@ -118,9 +117,11 @@ def build_mpr_builder(mx_version, dotnet, artifacts_repository=None):
118117
builder_image_url = None
119118
if artifacts_repository is not None:
120119
builder_image_url = f"{artifacts_repository}:{builder_image_tag}"
121-
image_hash = pull_image(builder_image_url)
122-
if image_hash is not None:
123-
return builder_image_url
120+
image_url = pull_image(builder_image_url)
121+
if image_url is not None:
122+
return image_url
123+
else:
124+
builder_image_url = f"mendix-buildpack:{builder_image_tag}"
124125

125126
prefix = ''
126127
if platform.machine() == 'arm64' and dotnet == 'dotnet':
@@ -130,33 +131,32 @@ def build_mpr_builder(mx_version, dotnet, artifacts_repository=None):
130131
mxbuild_url = f"https://download.mendix.com/runtimes/{mxbuild_filename}"
131132

132133
build_args = ['--build-arg', f"MXBUILD_DOWNLOAD_URL={mxbuild_url}",
133-
'--file', f"mxbuild/{dotnet}.dockerfile"]
134-
if artifacts_repository is not None:
135-
build_args += ['--tag', builder_image_url]
134+
'--file', os.path.join('mxbuild', f"{dotnet}.dockerfile"),
135+
'--tag', builder_image_url]
136136

137-
image_id = container_call(['image', 'build'] + build_args + ['mxbuild'])
137+
container_call(['image', 'build'] + build_args + ['mxbuild'])
138138
if artifacts_repository is not None:
139139
try:
140140
container_call(['image', 'push', builder_image_url])
141141
except Exception as e:
142142
logging.warning('Failed to push mxbuild into artifacts repository: {}; continuing with the build'.format(e))
143-
return image_id
143+
return builder_image_url
144144

145145
def get_git_commit(source_dir):
146146
git_head = os.path.join(source_dir, '.git', 'HEAD')
147147
if not os.path.isfile(git_head):
148-
return None
148+
raise Exception('Project source doesn\'t contain git metadata')
149149
with open(git_head) as git_head:
150150
git_head_line = git_head.readline().split()
151151
if len(git_head_line) == 1:
152152
# Detached commit
153153
return git_head_line[0]
154154
if len(git_head_line) > 2:
155-
return Exception(f"Unsupported Git HEAD format {git_head_line}")
155+
raise Exception(f"Unsupported Git HEAD format {git_head_line}")
156156
git_branch = git_head_line[1].split('/')
157157
git_branch_file = os.path.join(*([source_dir, '.git'] + git_branch))
158158
if not os.path.isfile(git_branch_file):
159-
return Exception('Git branch file doesn\'t exist')
159+
raise Exception('Git branch file doesn\'t exist')
160160
with open(git_branch_file) as git_branch_file:
161161
return git_branch_file.readline()
162162

@@ -169,9 +169,12 @@ def build_mpr(source_dir, mpr_file, destination, artifacts_repository=None):
169169
logging.debug('Detected Mendix version {}'.format('.'.join(map(str,mx_version_value))))
170170
dotnet = 'dotnet' if mx_version_value >= (10, 0, 0, 0) else 'mono'
171171
builder_image = build_mpr_builder(mx_version, dotnet, artifacts_repository)
172-
model_version = get_git_commit(source_dir)
173-
model_version = 'unversioned' if model_version is None else model_version
174-
172+
model_version = None
173+
try:
174+
model_version = get_git_commit(source_dir)
175+
except Exception as e:
176+
model_version = 'unversioned'
177+
logging.warning('Cannot determine git commit ({}), will set model version to unversioned'.format(e))
175178
container_id = container_call(['container', 'create', builder_image, os.path.basename(mpr_file), model_version])
176179
atexit.register(delete_container, container_id)
177180
container_call(['container', 'cp', os.path.abspath(source_dir)+'/.', f"{container_id}:/workdir/project"])
@@ -212,7 +215,9 @@ def prepare_mda(source_path, destination_path, artifacts_repository=None):
212215
mda_file = find_default_file(source_path, '.mda')
213216
if mda_file is not None:
214217
with zipfile.ZipFile(mda_file) as zip_file:
215-
zip_file.extractall(project_path)
218+
zip_file.extractall(destination_path)
219+
elif os.path.isdir(source_path):
220+
shutil.copytree(source_path, destination_path, dirs_exist_ok=True)
216221
extracted_mda_file = get_metadata_value(destination_path)
217222
if extracted_mda_file is not None:
218223
return destination_path
@@ -225,15 +230,14 @@ def build_image(mda_dir):
225230
mda_metadata = get_metadata_value(mda_path)
226231
mx_version = mda_metadata['RuntimeVersion']
227232
java_version = mda_metadata.get('JavaVersion', 11)
228-
print(mda_metadata['RuntimeVersion'])
229-
print(mda_metadata['JavaVersion'])
233+
logging.debug("Detected Mendix {} Java {}".format(mx_version, java_version))
230234

231235
if __name__ == '__main__':
232236
parser = argparse.ArgumentParser(description='Build a Mendix app')
233237
parser.add_argument('--source', metavar='source', required=True, nargs='?', type=pathlib.Path, help='Path to source Mendix app (MDA file, MPK file, MPR directory or extracted MDA directory)')
234238
parser.add_argument('--destination', metavar='destination', required=True, nargs='?', type=pathlib.Path, help='Destination for MDA')
235239
parser.add_argument('--artifacts-repository', required=False, nargs='?', metavar='artifacts_repository', type=str, help='Repository to use for caching build images')
236-
parser.add_argument('action', metavar='action', choices=['build-mda'], help='Action to perform')
240+
parser.add_argument('action', metavar='action', choices=['build-mda-dir'], help='Action to perform')
237241

238242
args = parser.parse_args()
239243

@@ -244,4 +248,3 @@ def build_image(mda_dir):
244248
stop_processes()
245249
raise
246250
# build_image(args.destination)
247-

mxbuild/dotnet.dockerfile

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,4 @@ RUN mkdir -p /workdir/project /workdir/output /workdir/.local/share/Mendix &&\
3030
chown -R ${USER_UID}:${USER_UID} /workdir &&\
3131
chmod -R 755 /workdir
3232

33-
USER $USER_UID
34-
3533
ENTRYPOINT ["/opt/mendix/build"]

mxbuild/mono.dockerfile

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,4 @@ RUN mkdir -p /workdir/project /workdir/output /workdir/.local/share/Mendix &&\
3131
chown -R ${USER_UID}:${USER_UID} /workdir &&\
3232
chmod -R 755 /workdir
3333

34-
USER $USER_UID
35-
3634
ENTRYPOINT ["/opt/mendix/build"]

rootfs-app.dockerfile

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,13 @@ RUN if [ -f /usr/bin/python ] ; then rm /usr/bin/python; fi &&\
3030
ln -s /usr/bin/python3.11 /usr/bin/python
3131

3232
# Create vcap home directory for Datadog configuration
33-
RUN mkdir -p /home/vcap /opt/datadog-agent/run &&\
34-
chown -R ${USER_UID}:0 /home/vcap /opt/datadog-agent/run &&\
35-
chmod -R g=u /home/vcap /opt/datadog-agent/run
33+
RUN mkdir -p /home /app/log /opt/mendix/build /opt/datadog-agent/run &&\
34+
ln -s /opt/mendix/build /home/vcap &&\
35+
chown -R ${USER_UID}:0 /home/vcap /opt/datadog-agent/run /app/log &&\
36+
chmod -R g=u /home/vcap /opt/datadog-agent/run /app/log
37+
38+
# Copy Cloud Foundry emulation scripts
39+
COPY --chmod=0755 --chown=0:0 scripts/host /usr/local/bin/
3640

3741
# Prepare home directory and set permissions
3842
RUN mkdir -p /opt/mendix &&\

scripts/host

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#!/bin/sh
2+
cat /etc/hostname

scripts/vcap_application.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
2-
"application_name": "docker_example",
3-
"application_uris": [ "docker_example.com" ],
2+
"application_name": "dockerexample",
3+
"application_uris": [ "docker-buildpack.example.com" ],
44
"limits": {
55
"disk": 1024,
66
"fds": 16384,

tests/integrationtest.sh

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@ docker version
44
docker-compose version
55

66
echo "Downloading test project"
7-
mkdir -p downloads build
7+
mkdir -p downloads
88
curl -L https://s3-eu-west-1.amazonaws.com/mx-buildpack-ci/BuildpackTestApp-mx-7-16.mda -o downloads/application.mpk
9-
unzip downloads/application.mpk -d build/
9+
10+
echo "Building MDA file"
11+
mkdir -p /tmp/mda-dir
12+
./build.py --source downloads/application.mpk --destination /tmp/mda-dir build-mda-dir
1013

1114
echo "Building app rootfs"
1215
docker build -t mendix-rootfs:app -f rootfs-app.dockerfile .
@@ -17,10 +20,9 @@ docker build -t mendix-rootfs:builder -f rootfs-builder.dockerfile .
1720
echo "Building test app"
1821
export BUILDPACK_VERSION=`git rev-parse HEAD`
1922
docker build \
20-
--build-arg BUILD_PATH=build \
2123
--build-arg BUILDER_ROOTFS_IMAGE=mendix-rootfs:builder \
2224
--build-arg ROOTFS_IMAGE=mendix-rootfs:app \
23-
-t mendix-testapp:$BUILDPACK_VERSION .
25+
-t mendix-testapp:$BUILDPACK_VERSION /tmp/mda-dir
2426

2527

2628
tests/test-generic.sh tests/docker-compose-postgres.yml

0 commit comments

Comments
 (0)