Skip to content

Commit 2596305

Browse files
committed
Add support for 'hollow' eden_simulator wheels
* Auxiliary 'eden_tools' validation functions moved to validation scripts * Update documentation * Improve OSX build environment setup
1 parent 5916224 commit 2596305

24 files changed

+397
-232
lines changed

Dockerfile

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ RUN apt-get install -y wget bzip2 ca-certificates \
2626
default-jre default-jdk maven emacs \
2727
libxml2-dev libxslt-dev python-dev sudo
2828

29-
RUN pip install --upgrade pip
29+
# RUN python3 -m pip install --upgrade pip venv
3030

3131
# Upgrade to version 2.0
3232
# RUN conda update -n base conda anaconda=2019.10
@@ -40,6 +40,7 @@ RUN find -L /opt/conda -type l -delete
4040
# Make sure every Python file is writable
4141
RUN find /opt/conda ! -writable -print0 | xargs -0 -I {} chmod 744 {}
4242

43+
# TODO disallow sudo!!
4344
RUN chown -R $NB_USER $HOME
4445
RUN rm -rf /var/lib/apt/lists/*
4546
RUN echo "${NB_USER} ALL=NOPASSWD: ALL" >> /etc/sudoers
@@ -127,12 +128,12 @@ RUN git clone https://github.com/NeuroML/pyNeuroML.git
127128
# Build from source code
128129

129130
WORKDIR $HOME/libNeuroML
130-
# 2020-05 version
131+
# 2021-03 version
131132
RUN git checkout 632c1bce797d44308d5ec8246c0aac360c862f1a
132133
RUN pip3 install . -r requirements.txt
133134

134135
WORKDIR $HOME/pyNeuroML
135-
# 2020-05 version
136+
# 2021-03 version
136137
RUN git checkout 9e070467498c57d4244d44f9996bb8e0eecc5dc3
137138
RUN python3 -m pip install .
138139

@@ -143,7 +144,9 @@ WORKDIR $WORK_HOME
143144
RUN python3 -c "import neuroml"
144145
RUN python3 -c "import neuroml; from pyneuroml import pynml"
145146

146-
# TODO some testing on NeuroML examples, to verify it's working properly (like with POisson sources and such)
147+
RUN ExampleDir=$(mktemp -d); cp -r ~/pyNeuroML/examples/ $ExampleDir; cd $ExampleDir/examples; python run_jneuroml_plot_matplotlib.py -nogui <&-
148+
149+
# TODO some testing on NeuroML examples, to verify it's working properly (like with Poisson sources and such)
147150

148151
#onward
149152
WORKDIR $WORK_HOME
@@ -152,7 +155,7 @@ WORKDIR $WORK_HOME
152155

153156
USER $NB_USER
154157
# Get some auxiliar packages, for network generation on the test environment
155-
RUN pip install netpyne==0.9.6
158+
RUN python3 -m pip install netpyne==1.0.0.2
156159

157160

158161
# ------------> Install EDEN
@@ -191,17 +194,23 @@ COPY . ${EDEN_CODE_REPO}
191194

192195
WORKDIR ${EDEN_CODE_REPO}
193196

194-
# Add some basic Python integration
195-
RUN pip install testing/python_package
197+
ENV OUT_DIR ${EDEN_INSTALL_DIR}
198+
RUN TARGETS="eden hollow_wheel" bash ./testing/docker/build_on_docker.bash
196199

197-
RUN \
198-
mkdir -p ${EDEN_INSTALL_DIR}/bin && \
199-
mkdir -p ${EDEN_INSTALL_DIR}/obj && \
200-
CC=gcc OUT_DIR=${EDEN_INSTALL_DIR} BUILD=release make -j$(nproc) eden
200+
# one more time, for MPI
201+
ENV OUT_DIR ${EDEN_INSTALL_DIR}_MPI
202+
RUN USE_MPI=1 WHEEL_VERSION=$(cat VERSION) bash ./testing/docker/build_on_docker.bash
201203

202204
RUN rm -r ${EDEN_CODE_REPO}
203205

206+
USER $NB_USER
207+
# Install the Python package but use the installed binary
208+
RUN python3 -m pip install ${EDEN_INSTALL_DIR}/bin/*.whl
209+
210+
USER root
211+
204212
RUN ln -s ${EDEN_INSTALL_DIR}/bin/eden.release.gcc.cpu.x /usr/local/bin/eden
213+
RUN ln -s ${EDEN_INSTALL_DIR}_MPI/bin/eden.release.gcc.cpu.x /usr/local/bin/eden-mpi
205214

206215
WORKDIR $HOME
207216

Makefile

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ BUILD_STAMP ?= $(shell "date" +"%Y-%m-%d")
66
BUILD ?= debug
77
PLATFORM ?= cpu
88

9+
WHEEL_VERSION ?= $(shell cat VERSION)
10+
11+
912
PROJ_BASE ?= .
1013

1114
# where to generate build output, in general?
@@ -17,7 +20,8 @@ BIN_DIR ?= $(OUT_DIR)/bin
1720
# i.e. intermediate artifacts
1821
OBJ_DIR ?= $(OUT_DIR)/obj
1922

20-
# TODO WHEEL_DIR
23+
# i.e. Python wheel artifacts
24+
WHEEL_DIR ?= $(BIN_DIR)
2125

2226
# Main product's source code
2327
SRC_EDEN := $(PROJ_BASE)/eden
@@ -228,17 +232,45 @@ ${OBJ_DIR}/LEMS_Expr_Test${DOT_O}: ${SRC_EDEN}/neuroml/LEMS_Expr_Test.cpp ${SRC_
228232
EXTRA_WHEEL_PACKAGE_TAGS ?=
229233
# Python wheel with embedded executable of EDEN
230234
# building a wheel out of tree simply doesn't work, without warning. Copy the package tree in a temporary location and build there (cwd must also be on location of setup.py or the files won't be added)
231-
WHEEL_FILE ?= $(TESTING_DIR)/sandbox/python_package/dist/eden_simulator-${WHEEL_VERSION}-py3-none-${WHEEL_PLAT_NAME_FILENAME}.whl
235+
WHEEL_PREFIX ?= $(TESTING_DIR)/sandbox
236+
# building tow wheels at once can't happen in the same folder. break them into separarte directories like in: https://stackoverflow.com/questions/51300874/how-do-i-build-multiple-wheel-files-from-a-single-setup-py
237+
238+
# TODO improve verification for auditwheel and delocate, when the authors add such an option
239+
240+
# haven't found out yet how to mix static patterns with per-target variables yet
241+
# https://stackoverflow.com/questions/23017477/post-build-step-for-multiple-targets
242+
243+
wheel: WHEEL_BUILD_DIR=${WHEEL_PREFIX}/wheel
244+
wheel: WHEEL_FILE=$(WHEEL_BUILD_DIR)/dist/eden_simulator-${WHEEL_VERSION}-py3-none-${WHEEL_PLAT_NAME_FILENAME}.whl
232245
wheel: eden
233-
rm -rf $(TESTING_DIR)/sandbox/python_package/
234-
cp -r $(TESTING_DIR)/python_package $(TESTING_DIR)/sandbox/
235-
"mkdir" -p $(TESTING_DIR)/sandbox/python_package/bin/
236-
mv $(TESTING_DIR)/sandbox/python_package/eden_tools $(TESTING_DIR)/sandbox/python_package/eden_simulator
237-
python3 -c "import sys; a=sys.argv[1]; print('__version__=\"%s\"\n__version_info__=%s\n' % (a, str(tuple(a.split('.')))))" "${WHEEL_VERSION}" > $(TESTING_DIR)/sandbox/python_package/eden_simulator/version.py
238-
mkdir -p $(TESTING_DIR)/sandbox/python_package/eden_simulator/data/bin && cp ${BIN_DIR}/eden${DOT_X} $(TESTING_DIR)/sandbox/python_package/eden_simulator/data/bin/eden$(EXE_EXTENSION_DIST)
239-
cd $(TESTING_DIR)/sandbox/python_package && python3 setup_wheel.py --package-version ${WHEEL_VERSION} bdist_wheel $(EXTRA_WHEEL_PACKAGE_TAGS)
240-
$(MAYBE_NOT_TARGET_MAC) || delocate-wheel -k --wheel-dir $(TESTING_DIR)/sandbox/python_package/dist/ $(WHEEL_FILE) && delocate-listdeps $(WHEEL_FILE)
241-
$(MAYBE_NOT_TARGET_LINUX) || python3 -m auditwheel repair --plat ${WHEEL_TARGET_PLAT} --only-plat --wheel-dir $(TESTING_DIR)/sandbox/python_package/dist/ $(WHEEL_FILE)
246+
rm -rf $(WHEEL_BUILD_DIR)
247+
cp -r $(TESTING_DIR)/python_package $(WHEEL_BUILD_DIR)
248+
python3 -c "import sys; a=sys.argv[1]; print('__version__=\"%s\"\n__version_info__=%s\n' % (a, str(tuple(a.split('.')))))" "${WHEEL_VERSION}" > $(WHEEL_BUILD_DIR)/eden_simulator/version.py
249+
250+
"mkdir" -p $(WHEEL_BUILD_DIR)/eden_simulator/data/bin && cp ${BIN_DIR}/eden${DOT_X} $(WHEEL_BUILD_DIR)/eden_simulator/data/bin/eden$(EXE_EXTENSION_DIST)
251+
252+
cd $(WHEEL_BUILD_DIR) && python3 setup_wheel.py --package-version ${WHEEL_VERSION} bdist_wheel $(EXTRA_WHEEL_PACKAGE_TAGS)
253+
254+
$(MAYBE_NOT_TARGET_MAC) || ( delocate-wheel -k --wheel-dir $(WHEEL_BUILD_DIR)/dist/ $(WHEEL_FILE) && delocate-listdeps $(WHEEL_FILE) )
255+
$(MAYBE_NOT_TARGET_LINUX) || python3 -m auditwheel repair --plat ${WHEEL_TARGET_PLAT} --only-plat --wheel-dir $(WHEEL_BUILD_DIR)/dist/ $(WHEEL_FILE)
256+
$(MAYBE_NOT_TARGET_LINUX) || rm -f $(WHEEL_FILE) # just to avoid confusion with non-manylinux wheel
257+
258+
cp $(WHEEL_BUILD_DIR)/dist/*.whl ${WHEEL_DIR}
259+
260+
hollow_wheel: WHEEL_BUILD_DIR=${WHEEL_PREFIX}/wheel_hollow
261+
hollow_wheel: WHEEL_FILE=$(WHEEL_BUILD_DIR)/dist/eden_simulator-${WHEEL_VERSION}-py3-none-any.whl
262+
hollow_wheel:
263+
rm -rf $(WHEEL_BUILD_DIR)
264+
cp -r $(TESTING_DIR)/python_package $(WHEEL_BUILD_DIR)
265+
python3 -c "import sys; a=sys.argv[1]; print('__version__=\"%s\"\n__version_info__=%s\n' % (a, str(tuple(a.split('.')))))" "${WHEEL_VERSION}" > $(WHEEL_BUILD_DIR)/eden_simulator/version.py
266+
267+
cd $(WHEEL_BUILD_DIR) && python3 setup_wheel.py --package-version ${WHEEL_VERSION} --no-eden-exe bdist_wheel $(EXTRA_WHEEL_PACKAGE_TAGS)
268+
269+
$(MAYBE_NOT_TARGET_LINUX) || ! python3 -m auditwheel show $(WHEEL_FILE)
270+
271+
cp $(WHEEL_FILE) ${WHEEL_DIR}
272+
# add here any common post-processing steps for wheels
273+
242274

243275
# external libraries
244276
cJSON: ${OBJ_DIR}/${CJSON_NAME}${DOT_O}

README.md

Lines changed: 57 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,15 @@ This software is released as open-source, under the GPL v3 licence. Refer to LIC
99

1010

1111
## Quickstart
12+
13+
The easiest way to get started is to get the Python package: `pip install eden-simiulator`
14+
and then invoke EDEN from Python:
15+
```python
16+
from eden_simulator import runEden
17+
sim_results = runEden('<LEMS simulation file>.xml') # replace filename with your own
18+
```
19+
20+
For a demo run of NeuroML networks and performance comparison with NEURON:
1221
A Jupyter environment with EDEN and associated tooling pre-installed is available at https://github.com/spanag/eden-sim-jupyter-demo .
1322
Just click the Binder link on that page and you can use EDEN as shown on the bundled Python notebook.
1423

@@ -37,33 +46,10 @@ On Linux setups, GCC is commonly installed; if it is not, refer to your distribu
3746

3847
In all cases, make sure that the compiler targets the same architecture as the executable, see also [Usage](#usage) for more details.
3948

40-
### Building from source
41-
The following software packages are required to build the source code:
42-
- `gcc` compiler, or alternatively the `icc` compiler. Specifically, a compiler version that supports C++14.
43-
- `flex` version 2.6 or later
44-
- `bison` version 3.0 or later
45-
46-
On Linux, most other tools for building are pre-installed or they can be easily installed; consult your distribution's reference on installing essential build tools.
47-
48-
For building on Windows, batch scripts are available on the [testing/windows](testing/windows) directory for installing all the necessary build tools and libraries, setting the shell's PATH to use them and building the standalone executable or Python wheel, all without affecting the system or user setup.
49-
50-
For building on macOS, shell scripts are available on the [testing/mac](testing/mac) directory for installing all the necessary build tools and libraries, setting the shell's PATH to use them and building the standalone executable or Python wheel.
51-
*Note* The `testing/mac/download-setup-requirements.bash` script installs Command Line Developer Tools for Mac, Homebrew and various Homebrew packages in the system, in the process installing the required tooling.
52-
53-
Use environment variable `BUILD=release` or `BUILD=debug` to run a production or debugging build of the program executable, respectively. The executable will be available on `bin/eden.<build>.<compiler>.cpu.x` (`.exe` on Windows)
54-
55-
If the NeuroML Python package `pyNeuroML` is installed, a Python wrapper for the local build of EDEN, `eden_tools`, can also be installed - run `pip` on directory `testing/python_package` . EDEN should then be on `PATH` to be invoked by the Python package.
56-
57-
If MPI is also installed, a MPI-enabled version of EDEN (with hybrid MPI/OpenMP parallelization) can be built, by running `make` with the `USE_MPI` flag. This configuration has been tested with standard MPICH on Linux; consult your HPC cluster's documentation for specific details on the MPI build process.
58-
59-
### Docker images
60-
Alternatively, Docker images with EDEN and an assortment of tools are available and can also be built, for containerized environments. The Dockerfiles are available on the `testing/docker` folder, and they can be built in the proper order through the Makefile in the folder.
61-
The Dockerfiles are at the moment available for Linux; support for other platforms is pending.
62-
63-
If Docker is installed and accessible to the user, an automated testing suite can also be run to verify EDEN's results against the NEURON simulator's for deterministic models. Run `make test` to run the automated tests.
64-
6549

6650
## Usage
51+
52+
### From the command line
6753
EDEN directly runs NeuroML models of neural networks. (For more information about the NeuroML model format, refer to http://neuroml.org )
6854
It can be run from the command line, with the following command referencing the LEMS simulation file of the NeuroML model to be run:
6955
```
@@ -79,15 +65,21 @@ Some `.gen.c` and `.gen.so` temporary files may also be generated, these can be
7965

8066
Per-thread parallelism can be adjusted through the `OMP_NUM_THREADS` environment variable.
8167

82-
Alternatively to the command line, the simulator can also be run within a Python program, if the standalone `eden_simulator` Python package (or the equivalent wrapper-only `eden_tools` package) is installed.
68+
### From Python
69+
Alternatively to the command line, the simulator can also be run within a Python program, if the `eden_simulator` Python package is installed.
8370
The Python lines to run EDEN are then:
8471
```python
8572
import eden_simulator
86-
results = eden_simulator.runEden('<LEMS simulation file>.xml')
73+
results = eden_simulator.runEden('<LEMS simulation file>.xml') # replace filename with your own
8774
```
8875
This interface returns the recorded trajectories specified in the simulation files in a Python dictionary, same as pyNeuroML does with other simulation backends.
76+
8977
Thread-level parallelism can also be controlled with the `threads` optional argument.
9078

79+
If other command-line arguments should be added, they can be specified as a list of strings in the optional parameter `extra_cmdline_args`.
80+
In case a specific instance of the EDEN executable is preferred, it can be selected with the optional parameter `executable_path`.
81+
Both options can be combined into a fully custom command to be run from Python: it can be passed as a list of strings in the optional parameter `full_cmdline`.
82+
9183
### Setting `PATH` to include a compiler
9284

9385
When running EDEN, make sure that the selected compiler (`gcc` by default) is available on PATH and has the same bitness and architecture as the build of EDEN in use. This is a concern on Windows (where both 32 and 64 bit programs are common) and on certain HPC clusters where the login and job nodes may run different instruction sets.
@@ -107,6 +99,44 @@ os.environ["PATH"] = <path to compiler executable> + os.pathsep + os.environ["PA
10799
runEden(...)
108100
```
109101

102+
103+
## Building from source
104+
The following software packages are required to build the source code:
105+
- `gcc` compiler, or alternatively the `icc` compiler. Specifically, a compiler version that supports C++14.
106+
- `flex` version 2.6 or later
107+
- `bison` version 3.0 or later
108+
109+
On Linux, most other tools for building are pre-installed or they can be easily installed; consult your distribution's reference on installing essential build tools.
110+
111+
For building on Windows, batch scripts are available on the [testing/windows](testing/windows) directory for installing all the necessary build tools and libraries, setting the shell's PATH to use them and building the standalone executable or Python wheel, all without affecting the system or user setup.
112+
113+
For building on macOS, shell scripts are available on the [testing/mac](testing/mac) directory for installing all the necessary build tools and libraries, setting the shell's PATH to use them and building the standalone executable or Python wheel.
114+
*Note* The `testing/mac/download-setup-requirements.bash` script installs Command Line Developer Tools for Mac, Homebrew and various Homebrew packages in the system, in the process installing the required tooling.
115+
*Note 2* The Apple developer tools are not suitable to build EDEN, because they lack OpenMP support which is required by EDEN. Instead, we recommend the developer tools installed by `download-setup-requirements.bash`.
116+
117+
Before attempting to build manually, source the `setpath` script for the platform you are building against so that the necessary tools are on PATH. (See platform-spacific instructions above.)
118+
119+
Use environment variable `BUILD=release` or `BUILD=debug` to run a production or debugging build of the program executable, respectively. The executable will be available on `bin/eden.<build>.<compiler>.cpu.x` (`.exe` on Windows)
120+
121+
### Building Python wheels
122+
Beside the program itself, EDEN can also be built as a Python package, which offers more integrated interface to the program. The python package is created in the installable `.whl` (wheel) format.
123+
124+
There are two options to build a Python wheel:
125+
- The first is as a standalone wheel containing the EDEN executable (hence the wheel is specific to one OS and processor type). This is the type of wheels avcailable through `pip install`.
126+
- The second option is as a 'hollow' wheel which works everywhere, but relies on EDEN already being available on PATH through different means. This type is useful in classes where a special (e.g. custom-built) version of EDEN is preferred to the generic version of 'standalone' wheels.
127+
128+
Both types of wheel can be built as the respective targets `wheel` and `hollow_wheel` of the Makefile. The resulting `.whl` files are located in the paths `testing/sandbox/{wheel, wheel_hollow}/dist`.
129+
130+
### Building for MPI
131+
If MPI is also installed, a MPI-enabled version of EDEN (with hybrid MPI/OpenMP parallelization) can be built, by running `make` with the `USE_MPI` flag. This configuration has been tested with standard MPICH on Linux; consult your HPC cluster's documentation for specific details on the process for MPI-enabled builds.
132+
133+
## Docker images
134+
Alternatively, Docker images with EDEN and an assortment of tools are available and can also be built, for containerized environments. The Dockerfiles are available on the `testing/docker` folder, and they can be built in the proper order through the Makefile in the folder.
135+
The Docker images are Linux-native but they can as well run on Windows and MacOS through [Docker Desktop]( https://www.docker.com/products/docker-desktop/ ).
136+
137+
If Docker is installed and accessible to the user, an automated testing suite can also be run to verify EDEN's results against the NEURON simulator's for deterministic models. Run `make test` to run the automated tests.
138+
139+
110140
## Dockerfile
111141

112142
A demonstration-ready Docker image is available, using the Dockerfile on this top-level directory.

bin/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@
33
*.x
44
*.exe
55
*.o
6+
7+
*.whl

eden/Common.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@
3737
#define _USE_MATH_DEFINES // maybe more elegant LATER, but since it works ...
3838
#include <cmath> // apparently including <algorithm> undefines ::isfinite() function, on ICC
3939

40-
//for model representation and more
40+
// for model representation and more
41+
// TODO keep only what is really necessary
4142
#include <vector>
4243
#include <functional>
4344
#include <algorithm>

eden/NeuroML.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -695,7 +695,7 @@ struct DimensionSet{
695695
if(!Has(dim)) return Nothing;
696696
return info_by_dimension.at(dim).units;
697697
}
698-
// assume SI units for unknown dimensions
698+
// assume fundamental units for unknown dimensions
699699
const LemsUnit &GetNative( Dimension dim ) const {
700700
if(!Has(dim)) return GetNative(Dimension::Unity());
701701
return info_by_dimension.at(dim).native;
@@ -1686,7 +1686,7 @@ struct IonChannel{
16861686
Int instances; // positive integer gating power in the HH model
16871687
};
16881688
struct GateBaseDynamic : public GateBase{
1689-
Q10Settings q10;
1689+
Q10Settings q10; // since there is no "none" option this value must be set always, default value is fixed q10 = 1
16901690
};
16911691

16921692
struct GateHHRates : public GateBaseDynamic{
@@ -2003,7 +2003,7 @@ struct Network{
20032003
Real weight; // is NaN if missing
20042004
Real delay; // is NaN if missing
20052005
union{
2006-
Int synapse; // synapstic component for one-way chemical or two-way electrical synapses
2006+
Int synapse; // synaptic component for one-way chemical or two-way electrical synapses
20072007
struct{
20082008
Int preComponent; // synaptic components
20092009
Int postComponent; // until LEMS components are supported
@@ -2039,7 +2039,7 @@ struct Network{
20392039
std::vector<Input> inputs;
20402040
};
20412041

2042-
// A NEuroML simulation, targeting a specific network
2042+
// A NeuroML simulation, targeting a specific network
20432043
struct Simulation{
20442044

20452045
// network is assumed to be the only one used in the simulation
@@ -2273,8 +2273,8 @@ struct Simulation{
22732273
CollectionWithNames<EventSelection> outputs;
22742274
};
22752275

2276-
Real length;
2277-
Real step;
2276+
Real length; // duration, that's how it's called in LEMS
2277+
Real step; // timestep, likewise
22782278

22792279
Int target_network;
22802280

testing/docker/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ build_eden_for_docker: ${DOCKER_TESTING_DIR}/eden_standalone.Dockerfile docker_b
3333
${SUDO_DOCKER} build --file $< -t ${EDEN_DOCKER_IMAGE_FULLNAME} ${PROJ_BASE}
3434

3535
# automatic, containerized testing
36-
test: docker_test_env
36+
# add all containers as dependencies to ensure that at least, they are built, LATER actually run the tests for all images
37+
test: docker_test_env build_eden_for_docker
3738
rm -rf testing/sandbox/validation_tests
3839
cp -rT ${PROJ_BASE}testing/validation_tests testing/sandbox/validation_tests
3940
chmod -R 777 testing/sandbox/validation_tests

testing/docker/build_on_docker.bash

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
1+
#!/bin/bash
22
# Assume runnning from Parallel_HH/ directory, on Docker container
33

44
# Default parameters
5-
5+
# https://stackoverflow.com/questions/28085062/assigning-default-values-to-shell-variables-with-a-single-command-in-bash
66
# Make Targets to build
77
: "${TARGETS:=eden}"
88

testing/docker/eden_standalone.Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,5 @@ RUN apt-get update \
2626
WORKDIR /app
2727

2828
COPY --from=0 /app/bin /app/bin
29-
29+
# TODO add hollow wheel maybe?
3030
CMD ["bash"]

0 commit comments

Comments
 (0)