From d7bfb61fe7a7e91f0c731f24be337e7da42010d1 Mon Sep 17 00:00:00 2001 From: Nicolas Da Mutten Date: Sat, 25 Mar 2023 14:11:51 +0100 Subject: [PATCH 01/21] WIP: add devcontainer --- .devcontainer/devcontainer.json | 49 ++++++++++++++++++++++++++++++++ .devcontainer/docker-compose.yml | 20 +++++++++++++ .devcontainer/initialize.sh | 9 ++++++ .gitignore | 3 ++ app/.gitignore | 1 - app/.vscode/launch.json | 26 +++++++++++++++++ docker-compose.yml | 1 + docker/rails.dockerfile | 21 +++++++++++++- 8 files changed, 128 insertions(+), 2 deletions(-) create mode 100644 .devcontainer/devcontainer.json create mode 100644 .devcontainer/docker-compose.yml create mode 100755 .devcontainer/initialize.sh delete mode 100644 app/.gitignore create mode 100644 app/.vscode/launch.json diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..748619b --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,49 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: +// https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/docker-existing-docker-compose +// If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml. +{ + "name": "Existing Docker Compose (Extend)", + + // Update the 'dockerComposeFile' list if you have more compose files or use different names. + // The .devcontainer/docker-compose.yml file contains any overrides you need/want to make. + "dockerComposeFile": [ + "../docker-compose.yml", + "docker-compose.yml" + ], + + // The 'service' property is the name of the service for the container that VS Code should + // use. Update this value and .devcontainer/docker-compose.yml to the real service name. + "service": "rails", + + // The optional 'workspaceFolder' property is the path VS Code should open by default when + // connected. This is typically a file mount in .devcontainer/docker-compose.yml + "workspaceFolder": "/usr/src/app", + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + + // Uncomment the next line if you want start specific services in your Docker Compose config. + // runServices": [], + + // Uncomment the next line if you want to keep your containers running after VS Code shuts down. + // "shutdownAction": "none", + + "initializeCommand": ".devcontainer/initialize.sh", + + //"postStartCommand": "/usr/local/bin/rails-entrypoint", + + // Uncomment the next line to run commands after the container is created - for example installing curl. + "postCreateCommand": "sudo gem install debug", + + // Uncomment to connect as a non-root user if you've added one. See https://aka.ms/vscode-remote/containers/non-root. + //"remoteUser": "vscode", + "customizations": { + "vscode": { + "extensions": [ + "KoichiSasada.vscode-rdbg", + "Shopify.ruby-lsp", + "sorbet.sorbet-vscode-extension" + ] + } + } +} diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml new file mode 100644 index 0000000..0e32ced --- /dev/null +++ b/.devcontainer/docker-compose.yml @@ -0,0 +1,20 @@ +version: '3.4' +services: + rails: + + volumes: + # Update this to wherever you want VS Code to mount the folder of your project + - .:/workspace:cached + + # Uncomment the next line to use Docker from inside the container. See https://aka.ms/vscode-remote/samples/docker-from-docker-compose for details. + # - /var/run/docker.sock:/var/run/docker.sock + + # Uncomment the next four lines if you will use a ptrace-based debugger like C++, Go, and Rust. + #cap_add: + # - SYS_PTRACE + #security_opt: + # - seccomp:unconfined + + # Overrides default command so things don't shut down after the process ends. + entrypoint: [] + command: /bin/bash -c "while sleep 1000; do :; done" \ No newline at end of file diff --git a/.devcontainer/initialize.sh b/.devcontainer/initialize.sh new file mode 100755 index 0000000..e69c493 --- /dev/null +++ b/.devcontainer/initialize.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +docker volume create hitobito_bundle +docker volume create hitobito_yarn_cache + +if [ ! -d "app/hitobito" ]; then + mkdir -p app/hitobito + git clone https://github.com/hitobito/hitobito.git app/hitobito +fi \ No newline at end of file diff --git a/.gitignore b/.gitignore index 6092f1e..2b900de 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,6 @@ .local .yarnrc /dumps +docker/home/rails +app/* +!app/.vscode \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore deleted file mode 100644 index 72e8ffc..0000000 --- a/app/.gitignore +++ /dev/null @@ -1 +0,0 @@ -* diff --git a/app/.vscode/launch.json b/app/.vscode/launch.json new file mode 100644 index 0000000..5462edb --- /dev/null +++ b/app/.vscode/launch.json @@ -0,0 +1,26 @@ +{ + // Verwendet IntelliSense zum Ermitteln möglicher Attribute. + // Zeigen Sie auf vorhandene Attribute, um die zugehörigen Beschreibungen anzuzeigen. + // Weitere Informationen finden Sie unter https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "rdbg", + "name": "Debug Server", + "request": "launch", + "script": "bin/rails", + "args": ["server", "-b", "0.0.0.0"], + "useBundler": true, + "cwd": "${workspaceFolder}/hitobito" + }, + { + "type": "rdbg", + "name": "Debug Tests", + "request": "launch", + "script": "bin/rspec", + "useBundler": true, + "askParameters": true, + "cwd": "${workspaceFolder}/hitobito" + } + ] +} \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 8e9514e..5ceee7b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -82,6 +82,7 @@ services: db: image: mysql:5.7 + platform: linux/amd64 command: - --sort_buffer_size=2M - --character-set-server=utf8mb4 diff --git a/docker/rails.dockerfile b/docker/rails.dockerfile index ea11163..c9a156a 100644 --- a/docker/rails.dockerfile +++ b/docker/rails.dockerfile @@ -7,6 +7,9 @@ USER root ENV RAILS_ENV=development ENV RAILS_DB_ADAPTER=mysql2 ENV BUNDLE_PATH=/opt/bundle +ARG USERNAME=hitobito +ARG USER_UID=1000 +ARG USER_GID=$USER_UID WORKDIR /usr/src/app/hitobito @@ -18,10 +21,19 @@ RUN \ python3-pip direnv \ xvfb chromium chromium-driver \ default-mysql-client pv \ - less && \ + less \ + sudo && \ curl -o- https://raw.githubusercontent.com/transifex/cli/master/install.sh | bash && \ npm install -g yarn +# Create the user +RUN groupadd --gid $USER_GID $USERNAME \ + && useradd --uid $USER_UID --gid $USER_GID -m $USERNAME -s /bin/bash \ + # + # [Optional] Add sudo support. Omit if you don't need to install software after connecting. + && echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \ + && chmod 0440 /etc/sudoers.d/$USERNAME + RUN bash -c 'gem install bundler -v 2.1.4' COPY ./rails-entrypoint /usr/local/bin @@ -34,5 +46,12 @@ RUN mkdir /home/developer && chmod 777 /home/developer ENV HOME=/home/developer ENV NODE_PATH=/usr/lib/nodejs +# ******************************************************** +# * Anything else you want to do like clean up goes here * +# ******************************************************** + +# [Optional] Set the default user. Omit if you want to keep the default as root. +USER $USERNAME + ENTRYPOINT ["rails-entrypoint"] CMD [ "rails", "server", "-b", "0.0.0.0" ] From e576930c8ee59bae644eb427c2ac6f122fc9c409 Mon Sep 17 00:00:00 2001 From: Nicolas Da Mutten Date: Sat, 25 Mar 2023 22:59:05 +0100 Subject: [PATCH 02/21] WIP: multiple containers --- .devcontainer/create.sh | 3 ++ .devcontainer/devcontainer.json | 49 ------------------------- .devcontainer/docker-compose.yml | 14 +------ .devcontainer/generic/devcontainer.json | 40 ++++++++++++++++++++ .devcontainer/initialize.sh | 26 +++++++++++-- .devcontainer/pbs/devcontainer.json | 40 ++++++++++++++++++++ .devcontainer/update.sh | 21 +++++++++++ docker/rails.dockerfile | 10 ++--- 8 files changed, 131 insertions(+), 72 deletions(-) create mode 100644 .devcontainer/create.sh delete mode 100644 .devcontainer/devcontainer.json create mode 100644 .devcontainer/generic/devcontainer.json create mode 100644 .devcontainer/pbs/devcontainer.json create mode 100644 .devcontainer/update.sh diff --git a/.devcontainer/create.sh b/.devcontainer/create.sh new file mode 100644 index 0000000..f44e421 --- /dev/null +++ b/.devcontainer/create.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +sudo gem install debug \ No newline at end of file diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json deleted file mode 100644 index 748619b..0000000 --- a/.devcontainer/devcontainer.json +++ /dev/null @@ -1,49 +0,0 @@ -// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: -// https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/docker-existing-docker-compose -// If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml. -{ - "name": "Existing Docker Compose (Extend)", - - // Update the 'dockerComposeFile' list if you have more compose files or use different names. - // The .devcontainer/docker-compose.yml file contains any overrides you need/want to make. - "dockerComposeFile": [ - "../docker-compose.yml", - "docker-compose.yml" - ], - - // The 'service' property is the name of the service for the container that VS Code should - // use. Update this value and .devcontainer/docker-compose.yml to the real service name. - "service": "rails", - - // The optional 'workspaceFolder' property is the path VS Code should open by default when - // connected. This is typically a file mount in .devcontainer/docker-compose.yml - "workspaceFolder": "/usr/src/app", - - // Use 'forwardPorts' to make a list of ports inside the container available locally. - // "forwardPorts": [], - - // Uncomment the next line if you want start specific services in your Docker Compose config. - // runServices": [], - - // Uncomment the next line if you want to keep your containers running after VS Code shuts down. - // "shutdownAction": "none", - - "initializeCommand": ".devcontainer/initialize.sh", - - //"postStartCommand": "/usr/local/bin/rails-entrypoint", - - // Uncomment the next line to run commands after the container is created - for example installing curl. - "postCreateCommand": "sudo gem install debug", - - // Uncomment to connect as a non-root user if you've added one. See https://aka.ms/vscode-remote/containers/non-root. - //"remoteUser": "vscode", - "customizations": { - "vscode": { - "extensions": [ - "KoichiSasada.vscode-rdbg", - "Shopify.ruby-lsp", - "sorbet.sorbet-vscode-extension" - ] - } - } -} diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml index 0e32ced..3e4d1af 100644 --- a/.devcontainer/docker-compose.yml +++ b/.devcontainer/docker-compose.yml @@ -1,20 +1,10 @@ version: '3.4' services: rails: - volumes: - # Update this to wherever you want VS Code to mount the folder of your project - .:/workspace:cached - # Uncomment the next line to use Docker from inside the container. See https://aka.ms/vscode-remote/samples/docker-from-docker-compose for details. - # - /var/run/docker.sock:/var/run/docker.sock - - # Uncomment the next four lines if you will use a ptrace-based debugger like C++, Go, and Rust. - #cap_add: - # - SYS_PTRACE - #security_opt: - # - seccomp:unconfined - - # Overrides default command so things don't shut down after the process ends. + # Skip entrypoint which would try to migrate on entry entrypoint: [] + # Overrides default command so things don't shut down after the process ends. command: /bin/bash -c "while sleep 1000; do :; done" \ No newline at end of file diff --git a/.devcontainer/generic/devcontainer.json b/.devcontainer/generic/devcontainer.json new file mode 100644 index 0000000..e0cf722 --- /dev/null +++ b/.devcontainer/generic/devcontainer.json @@ -0,0 +1,40 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: +// https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/docker-existing-docker-compose +// If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml. +{ + "name": "Hitobito Generic", + + "dockerComposeFile": [ + "../../docker-compose.yml", + "../docker-compose.yml" + ], + + // The 'service' property is the name of the service for the container that VS Code should + // use. Update this value and .devcontainer/docker-compose.yml to the real service name. + "service": "rails", + + "workspaceFolder": "/usr/src/app", + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + "forwardPorts": [ + 3000, + 1080, + 3306 + ], + + "initializeCommand": ".devcontainer/initialize.sh https://github.com/hitobito/hitobito.git https://github.com/hitobito/hitobito_generic.git", + + "onCreateCommand": ".devcontainer/create.sh", + + "updateContentCommand": ".devcontainer/update.sh", + + "customizations": { + "vscode": { + "extensions": [ + "KoichiSasada.vscode-rdbg", + "Shopify.ruby-lsp", + "sorbet.sorbet-vscode-extension" + ] + } + } +} diff --git a/.devcontainer/initialize.sh b/.devcontainer/initialize.sh index e69c493..d8300c9 100755 --- a/.devcontainer/initialize.sh +++ b/.devcontainer/initialize.sh @@ -3,7 +3,25 @@ docker volume create hitobito_bundle docker volume create hitobito_yarn_cache -if [ ! -d "app/hitobito" ]; then - mkdir -p app/hitobito - git clone https://github.com/hitobito/hitobito.git app/hitobito -fi \ No newline at end of file +# Check if an argument was provided +if [ $# -eq 0 ] +then + echo "Usage: $0 url1 url2 url3 ..." + exit 1 +fi + +if [ -d "app/hitobito" ]; then + exit 0 +fi + +# Create the app directory if it doesn't exist +mkdir -p app + +# Loop over the URLs and clone each repository into the app directory +for url in "$@" +do + echo "Cloning $url into app/$(basename $url .git)" + git clone "$url" "app/$(basename $url .git)" +done + +/usr/local/bin/rails-entrypoint exit 0 \ No newline at end of file diff --git a/.devcontainer/pbs/devcontainer.json b/.devcontainer/pbs/devcontainer.json new file mode 100644 index 0000000..6dad884 --- /dev/null +++ b/.devcontainer/pbs/devcontainer.json @@ -0,0 +1,40 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: +// https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/docker-existing-docker-compose +// If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml. +{ + "name": "Hitobito PBS", + + "dockerComposeFile": [ + "../../docker-compose.yml", + "../docker-compose.yml" + ], + + // The 'service' property is the name of the service for the container that VS Code should + // use. Update this value and .devcontainer/docker-compose.yml to the real service name. + "service": "rails", + + "workspaceFolder": "/usr/src/app", + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + "forwardPorts": [ + 3000, + 1080, + 3306 + ], + + "initializeCommand": ".devcontainer/initialize.sh https://github.com/hitobito/hitobito.git https://github.com/hitobito/hitobito_youth.git https://github.com/hitobito/hitobito_pbs.git", + + "onCreateCommand": ".devcontainer/create.sh", + + "updateContentCommand": ".devcontainer/update.sh", + + "customizations": { + "vscode": { + "extensions": [ + "KoichiSasada.vscode-rdbg", + "Shopify.ruby-lsp", + "sorbet.sorbet-vscode-extension" + ] + } + } +} diff --git a/.devcontainer/update.sh b/.devcontainer/update.sh new file mode 100644 index 0000000..e2f3876 --- /dev/null +++ b/.devcontainer/update.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +# Set the directory containing git repositories +repositories_dir=app + +# Loop over the directories in the repositories directory +for repository_dir in "$repositories_dir"/*/ +do + # Check if the directory is a git repository + if [ -d "$repository_dir/.git" ] + then + # Change into the repository directory, discard all local changes, and pull the latest changes + cd "$repository_dir" + echo "Updating repository: $(basename $repository_dir)" + git reset --hard HEAD + git clean -f -d + git pull + fi +done + +SKIP_SEEDS=1 SKIP_WAGONFILE=1 /usr/local/bin/rails-entrypoint exit 0 \ No newline at end of file diff --git a/docker/rails.dockerfile b/docker/rails.dockerfile index c9a156a..6dc57ce 100644 --- a/docker/rails.dockerfile +++ b/docker/rails.dockerfile @@ -43,15 +43,11 @@ COPY ./waitfortcp /usr/local/bin RUN mkdir /opt/bundle && chmod 777 /opt/bundle RUN mkdir /seed && chmod 777 /seed RUN mkdir /home/developer && chmod 777 /home/developer -ENV HOME=/home/developer -ENV NODE_PATH=/usr/lib/nodejs - -# ******************************************************** -# * Anything else you want to do like clean up goes here * -# ******************************************************** -# [Optional] Set the default user. Omit if you want to keep the default as root. USER $USERNAME +ENV HOME=/home/developer +ENV NODE_PATH=/usr/lib/nodejs + ENTRYPOINT ["rails-entrypoint"] CMD [ "rails", "server", "-b", "0.0.0.0" ] From 1da9d39c3f281f2d4f72c5fa542fa742b7e08c4d Mon Sep 17 00:00:00 2001 From: Nicolas Da Mutten Date: Sun, 26 Mar 2023 00:13:03 +0100 Subject: [PATCH 03/21] WIP: fix builds --- .devcontainer/create.sh | 4 +++- .devcontainer/generic/devcontainer.json | 4 ++-- .devcontainer/initialize.sh | 2 -- .devcontainer/pbs/devcontainer.json | 4 ++-- .devcontainer/update.sh | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) mode change 100644 => 100755 .devcontainer/create.sh mode change 100644 => 100755 .devcontainer/update.sh diff --git a/.devcontainer/create.sh b/.devcontainer/create.sh old mode 100644 new mode 100755 index f44e421..cff4dbd --- a/.devcontainer/create.sh +++ b/.devcontainer/create.sh @@ -1,3 +1,5 @@ #!/bin/bash -sudo gem install debug \ No newline at end of file +sudo gem install debug + +/usr/local/bin/rails-entrypoint echo "Finished initializing!" diff --git a/.devcontainer/generic/devcontainer.json b/.devcontainer/generic/devcontainer.json index e0cf722..4b03e89 100644 --- a/.devcontainer/generic/devcontainer.json +++ b/.devcontainer/generic/devcontainer.json @@ -24,9 +24,9 @@ "initializeCommand": ".devcontainer/initialize.sh https://github.com/hitobito/hitobito.git https://github.com/hitobito/hitobito_generic.git", - "onCreateCommand": ".devcontainer/create.sh", + "onCreateCommand": "/workspace/.devcontainer/create.sh", - "updateContentCommand": ".devcontainer/update.sh", + "updateContentCommand": "/workspace/.devcontainer/update.sh", "customizations": { "vscode": { diff --git a/.devcontainer/initialize.sh b/.devcontainer/initialize.sh index d8300c9..5c74c1c 100755 --- a/.devcontainer/initialize.sh +++ b/.devcontainer/initialize.sh @@ -23,5 +23,3 @@ do echo "Cloning $url into app/$(basename $url .git)" git clone "$url" "app/$(basename $url .git)" done - -/usr/local/bin/rails-entrypoint exit 0 \ No newline at end of file diff --git a/.devcontainer/pbs/devcontainer.json b/.devcontainer/pbs/devcontainer.json index 6dad884..4ce34ca 100644 --- a/.devcontainer/pbs/devcontainer.json +++ b/.devcontainer/pbs/devcontainer.json @@ -24,9 +24,9 @@ "initializeCommand": ".devcontainer/initialize.sh https://github.com/hitobito/hitobito.git https://github.com/hitobito/hitobito_youth.git https://github.com/hitobito/hitobito_pbs.git", - "onCreateCommand": ".devcontainer/create.sh", + "onCreateCommand": "/workspace/.devcontainer/create.sh", - "updateContentCommand": ".devcontainer/update.sh", + "updateContentCommand": "/workspace/.devcontainer/update.sh", "customizations": { "vscode": { diff --git a/.devcontainer/update.sh b/.devcontainer/update.sh old mode 100644 new mode 100755 index e2f3876..cb91195 --- a/.devcontainer/update.sh +++ b/.devcontainer/update.sh @@ -18,4 +18,4 @@ do fi done -SKIP_SEEDS=1 SKIP_WAGONFILE=1 /usr/local/bin/rails-entrypoint exit 0 \ No newline at end of file +SKIP_SEEDS=1 SKIP_WAGONFILE=1 /usr/local/bin/rails-entrypoint echo "All up to date!" From 6a17c205b2e75f2bf2205f5846bed4fdf5d6e829 Mon Sep 17 00:00:00 2001 From: Nicolas Da Mutten Date: Sun, 26 Mar 2023 01:03:19 +0100 Subject: [PATCH 04/21] WIP: add configs --- .devcontainer/cevi/devcontainer.json | 40 +++++++++++++++++++++ .devcontainer/die_mitte/devcontainer.json | 40 +++++++++++++++++++++ .devcontainer/digisus_lab/devcontainer.json | 40 +++++++++++++++++++++ .devcontainer/dsj/devcontainer.json | 40 +++++++++++++++++++++ .devcontainer/glp/devcontainer.json | 40 +++++++++++++++++++++ .devcontainer/insieme/devcontainer.json | 40 +++++++++++++++++++++ .devcontainer/jubla/devcontainer.json | 40 +++++++++++++++++++++ .devcontainer/kljb/devcontainer.json | 40 +++++++++++++++++++++ .devcontainer/pro_natura/devcontainer.json | 40 +++++++++++++++++++++ .devcontainer/sbv/devcontainer.json | 40 +++++++++++++++++++++ .devcontainer/sjas/devcontainer.json | 40 +++++++++++++++++++++ .devcontainer/skv/devcontainer.json | 40 +++++++++++++++++++++ .devcontainer/svse/devcontainer.json | 40 +++++++++++++++++++++ .devcontainer/sww/devcontainer.json | 40 +++++++++++++++++++++ .devcontainer/tpunkt/devcontainer.json | 40 +++++++++++++++++++++ 15 files changed, 600 insertions(+) create mode 100644 .devcontainer/cevi/devcontainer.json create mode 100644 .devcontainer/die_mitte/devcontainer.json create mode 100644 .devcontainer/digisus_lab/devcontainer.json create mode 100644 .devcontainer/dsj/devcontainer.json create mode 100644 .devcontainer/glp/devcontainer.json create mode 100644 .devcontainer/insieme/devcontainer.json create mode 100644 .devcontainer/jubla/devcontainer.json create mode 100644 .devcontainer/kljb/devcontainer.json create mode 100644 .devcontainer/pro_natura/devcontainer.json create mode 100644 .devcontainer/sbv/devcontainer.json create mode 100644 .devcontainer/sjas/devcontainer.json create mode 100644 .devcontainer/skv/devcontainer.json create mode 100644 .devcontainer/svse/devcontainer.json create mode 100644 .devcontainer/sww/devcontainer.json create mode 100644 .devcontainer/tpunkt/devcontainer.json diff --git a/.devcontainer/cevi/devcontainer.json b/.devcontainer/cevi/devcontainer.json new file mode 100644 index 0000000..f4ca3ce --- /dev/null +++ b/.devcontainer/cevi/devcontainer.json @@ -0,0 +1,40 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: +// https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/docker-existing-docker-compose +// If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml. +{ + "name": "Hitobito PBS", + + "dockerComposeFile": [ + "../../docker-compose.yml", + "../docker-compose.yml" + ], + + // The 'service' property is the name of the service for the container that VS Code should + // use. Update this value and .devcontainer/docker-compose.yml to the real service name. + "service": "rails", + + "workspaceFolder": "/usr/src/app", + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + "forwardPorts": [ + 3000, + 1080, + 3306 + ], + + "initializeCommand": ".devcontainer/initialize.sh https://github.com/hitobito/hitobito.git https://github.com/hitobito/hitobito_youth.git https://github.com/hitobito/hitobito_cevi.git", + + "onCreateCommand": "/workspace/.devcontainer/create.sh", + + "updateContentCommand": "/workspace/.devcontainer/update.sh", + + "customizations": { + "vscode": { + "extensions": [ + "KoichiSasada.vscode-rdbg", + "Shopify.ruby-lsp", + "sorbet.sorbet-vscode-extension" + ] + } + } +} diff --git a/.devcontainer/die_mitte/devcontainer.json b/.devcontainer/die_mitte/devcontainer.json new file mode 100644 index 0000000..438cf04 --- /dev/null +++ b/.devcontainer/die_mitte/devcontainer.json @@ -0,0 +1,40 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: +// https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/docker-existing-docker-compose +// If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml. +{ + "name": "Hitobito PBS", + + "dockerComposeFile": [ + "../../docker-compose.yml", + "../docker-compose.yml" + ], + + // The 'service' property is the name of the service for the container that VS Code should + // use. Update this value and .devcontainer/docker-compose.yml to the real service name. + "service": "rails", + + "workspaceFolder": "/usr/src/app", + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + "forwardPorts": [ + 3000, + 1080, + 3306 + ], + + "initializeCommand": ".devcontainer/initialize.sh https://github.com/hitobito/hitobito.git https://github.com/hitobito/hitobito_die_mitte.git", + + "onCreateCommand": "/workspace/.devcontainer/create.sh", + + "updateContentCommand": "/workspace/.devcontainer/update.sh", + + "customizations": { + "vscode": { + "extensions": [ + "KoichiSasada.vscode-rdbg", + "Shopify.ruby-lsp", + "sorbet.sorbet-vscode-extension" + ] + } + } +} diff --git a/.devcontainer/digisus_lab/devcontainer.json b/.devcontainer/digisus_lab/devcontainer.json new file mode 100644 index 0000000..f4a30a8 --- /dev/null +++ b/.devcontainer/digisus_lab/devcontainer.json @@ -0,0 +1,40 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: +// https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/docker-existing-docker-compose +// If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml. +{ + "name": "Hitobito PBS", + + "dockerComposeFile": [ + "../../docker-compose.yml", + "../docker-compose.yml" + ], + + // The 'service' property is the name of the service for the container that VS Code should + // use. Update this value and .devcontainer/docker-compose.yml to the real service name. + "service": "rails", + + "workspaceFolder": "/usr/src/app", + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + "forwardPorts": [ + 3000, + 1080, + 3306 + ], + + "initializeCommand": ".devcontainer/initialize.sh https://github.com/hitobito/hitobito.git https://github.com/hitobito/hitobito_digisus_lab.git", + + "onCreateCommand": "/workspace/.devcontainer/create.sh", + + "updateContentCommand": "/workspace/.devcontainer/update.sh", + + "customizations": { + "vscode": { + "extensions": [ + "KoichiSasada.vscode-rdbg", + "Shopify.ruby-lsp", + "sorbet.sorbet-vscode-extension" + ] + } + } +} diff --git a/.devcontainer/dsj/devcontainer.json b/.devcontainer/dsj/devcontainer.json new file mode 100644 index 0000000..7731b3b --- /dev/null +++ b/.devcontainer/dsj/devcontainer.json @@ -0,0 +1,40 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: +// https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/docker-existing-docker-compose +// If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml. +{ + "name": "Hitobito PBS", + + "dockerComposeFile": [ + "../../docker-compose.yml", + "../docker-compose.yml" + ], + + // The 'service' property is the name of the service for the container that VS Code should + // use. Update this value and .devcontainer/docker-compose.yml to the real service name. + "service": "rails", + + "workspaceFolder": "/usr/src/app", + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + "forwardPorts": [ + 3000, + 1080, + 3306 + ], + + "initializeCommand": ".devcontainer/initialize.sh https://github.com/hitobito/hitobito.git https://github.com/hitobito/hitobito_dsj.git", + + "onCreateCommand": "/workspace/.devcontainer/create.sh", + + "updateContentCommand": "/workspace/.devcontainer/update.sh", + + "customizations": { + "vscode": { + "extensions": [ + "KoichiSasada.vscode-rdbg", + "Shopify.ruby-lsp", + "sorbet.sorbet-vscode-extension" + ] + } + } +} diff --git a/.devcontainer/glp/devcontainer.json b/.devcontainer/glp/devcontainer.json new file mode 100644 index 0000000..5a66b56 --- /dev/null +++ b/.devcontainer/glp/devcontainer.json @@ -0,0 +1,40 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: +// https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/docker-existing-docker-compose +// If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml. +{ + "name": "Hitobito PBS", + + "dockerComposeFile": [ + "../../docker-compose.yml", + "../docker-compose.yml" + ], + + // The 'service' property is the name of the service for the container that VS Code should + // use. Update this value and .devcontainer/docker-compose.yml to the real service name. + "service": "rails", + + "workspaceFolder": "/usr/src/app", + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + "forwardPorts": [ + 3000, + 1080, + 3306 + ], + + "initializeCommand": ".devcontainer/initialize.sh https://github.com/hitobito/hitobito.git https://github.com/hitobito/hitobito_glp.git", + + "onCreateCommand": "/workspace/.devcontainer/create.sh", + + "updateContentCommand": "/workspace/.devcontainer/update.sh", + + "customizations": { + "vscode": { + "extensions": [ + "KoichiSasada.vscode-rdbg", + "Shopify.ruby-lsp", + "sorbet.sorbet-vscode-extension" + ] + } + } +} diff --git a/.devcontainer/insieme/devcontainer.json b/.devcontainer/insieme/devcontainer.json new file mode 100644 index 0000000..e8bc275 --- /dev/null +++ b/.devcontainer/insieme/devcontainer.json @@ -0,0 +1,40 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: +// https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/docker-existing-docker-compose +// If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml. +{ + "name": "Hitobito PBS", + + "dockerComposeFile": [ + "../../docker-compose.yml", + "../docker-compose.yml" + ], + + // The 'service' property is the name of the service for the container that VS Code should + // use. Update this value and .devcontainer/docker-compose.yml to the real service name. + "service": "rails", + + "workspaceFolder": "/usr/src/app", + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + "forwardPorts": [ + 3000, + 1080, + 3306 + ], + + "initializeCommand": ".devcontainer/initialize.sh https://github.com/hitobito/hitobito.git https://github.com/hitobito/hitobito_insieme.git", + + "onCreateCommand": "/workspace/.devcontainer/create.sh", + + "updateContentCommand": "/workspace/.devcontainer/update.sh", + + "customizations": { + "vscode": { + "extensions": [ + "KoichiSasada.vscode-rdbg", + "Shopify.ruby-lsp", + "sorbet.sorbet-vscode-extension" + ] + } + } +} diff --git a/.devcontainer/jubla/devcontainer.json b/.devcontainer/jubla/devcontainer.json new file mode 100644 index 0000000..d8af7d8 --- /dev/null +++ b/.devcontainer/jubla/devcontainer.json @@ -0,0 +1,40 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: +// https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/docker-existing-docker-compose +// If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml. +{ + "name": "Hitobito PBS", + + "dockerComposeFile": [ + "../../docker-compose.yml", + "../docker-compose.yml" + ], + + // The 'service' property is the name of the service for the container that VS Code should + // use. Update this value and .devcontainer/docker-compose.yml to the real service name. + "service": "rails", + + "workspaceFolder": "/usr/src/app", + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + "forwardPorts": [ + 3000, + 1080, + 3306 + ], + + "initializeCommand": ".devcontainer/initialize.sh https://github.com/hitobito/hitobito.git https://github.com/hitobito/hitobito_youth.git https://github.com/hitobito/hitobito_jubla.git", + + "onCreateCommand": "/workspace/.devcontainer/create.sh", + + "updateContentCommand": "/workspace/.devcontainer/update.sh", + + "customizations": { + "vscode": { + "extensions": [ + "KoichiSasada.vscode-rdbg", + "Shopify.ruby-lsp", + "sorbet.sorbet-vscode-extension" + ] + } + } +} diff --git a/.devcontainer/kljb/devcontainer.json b/.devcontainer/kljb/devcontainer.json new file mode 100644 index 0000000..30d0a9b --- /dev/null +++ b/.devcontainer/kljb/devcontainer.json @@ -0,0 +1,40 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: +// https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/docker-existing-docker-compose +// If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml. +{ + "name": "Hitobito PBS", + + "dockerComposeFile": [ + "../../docker-compose.yml", + "../docker-compose.yml" + ], + + // The 'service' property is the name of the service for the container that VS Code should + // use. Update this value and .devcontainer/docker-compose.yml to the real service name. + "service": "rails", + + "workspaceFolder": "/usr/src/app", + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + "forwardPorts": [ + 3000, + 1080, + 3306 + ], + + "initializeCommand": ".devcontainer/initialize.sh https://github.com/hitobito/hitobito.git https://github.com/hitobito/hitobito_youth.git https://github.com/hitobito/hitobito_kljb.git", + + "onCreateCommand": "/workspace/.devcontainer/create.sh", + + "updateContentCommand": "/workspace/.devcontainer/update.sh", + + "customizations": { + "vscode": { + "extensions": [ + "KoichiSasada.vscode-rdbg", + "Shopify.ruby-lsp", + "sorbet.sorbet-vscode-extension" + ] + } + } +} diff --git a/.devcontainer/pro_natura/devcontainer.json b/.devcontainer/pro_natura/devcontainer.json new file mode 100644 index 0000000..6fc9e5f --- /dev/null +++ b/.devcontainer/pro_natura/devcontainer.json @@ -0,0 +1,40 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: +// https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/docker-existing-docker-compose +// If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml. +{ + "name": "Hitobito PBS", + + "dockerComposeFile": [ + "../../docker-compose.yml", + "../docker-compose.yml" + ], + + // The 'service' property is the name of the service for the container that VS Code should + // use. Update this value and .devcontainer/docker-compose.yml to the real service name. + "service": "rails", + + "workspaceFolder": "/usr/src/app", + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + "forwardPorts": [ + 3000, + 1080, + 3306 + ], + + "initializeCommand": ".devcontainer/initialize.sh https://github.com/hitobito/hitobito.git https://github.com/hitobito/hitobito_youth.git https://github.com/hitobito/hitobito_pro_natura.git", + + "onCreateCommand": "/workspace/.devcontainer/create.sh", + + "updateContentCommand": "/workspace/.devcontainer/update.sh", + + "customizations": { + "vscode": { + "extensions": [ + "KoichiSasada.vscode-rdbg", + "Shopify.ruby-lsp", + "sorbet.sorbet-vscode-extension" + ] + } + } +} diff --git a/.devcontainer/sbv/devcontainer.json b/.devcontainer/sbv/devcontainer.json new file mode 100644 index 0000000..1597484 --- /dev/null +++ b/.devcontainer/sbv/devcontainer.json @@ -0,0 +1,40 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: +// https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/docker-existing-docker-compose +// If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml. +{ + "name": "Hitobito PBS", + + "dockerComposeFile": [ + "../../docker-compose.yml", + "../docker-compose.yml" + ], + + // The 'service' property is the name of the service for the container that VS Code should + // use. Update this value and .devcontainer/docker-compose.yml to the real service name. + "service": "rails", + + "workspaceFolder": "/usr/src/app", + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + "forwardPorts": [ + 3000, + 1080, + 3306 + ], + + "initializeCommand": ".devcontainer/initialize.sh https://github.com/hitobito/hitobito.git https://github.com/hitobito/hitobito_sbv.git", + + "onCreateCommand": "/workspace/.devcontainer/create.sh", + + "updateContentCommand": "/workspace/.devcontainer/update.sh", + + "customizations": { + "vscode": { + "extensions": [ + "KoichiSasada.vscode-rdbg", + "Shopify.ruby-lsp", + "sorbet.sorbet-vscode-extension" + ] + } + } +} diff --git a/.devcontainer/sjas/devcontainer.json b/.devcontainer/sjas/devcontainer.json new file mode 100644 index 0000000..74880ff --- /dev/null +++ b/.devcontainer/sjas/devcontainer.json @@ -0,0 +1,40 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: +// https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/docker-existing-docker-compose +// If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml. +{ + "name": "Hitobito PBS", + + "dockerComposeFile": [ + "../../docker-compose.yml", + "../docker-compose.yml" + ], + + // The 'service' property is the name of the service for the container that VS Code should + // use. Update this value and .devcontainer/docker-compose.yml to the real service name. + "service": "rails", + + "workspaceFolder": "/usr/src/app", + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + "forwardPorts": [ + 3000, + 1080, + 3306 + ], + + "initializeCommand": ".devcontainer/initialize.sh https://github.com/hitobito/hitobito.git https://github.com/hitobito/hitobito_youth.git https://github.com/hitobito/hitobito_sjas.git", + + "onCreateCommand": "/workspace/.devcontainer/create.sh", + + "updateContentCommand": "/workspace/.devcontainer/update.sh", + + "customizations": { + "vscode": { + "extensions": [ + "KoichiSasada.vscode-rdbg", + "Shopify.ruby-lsp", + "sorbet.sorbet-vscode-extension" + ] + } + } +} diff --git a/.devcontainer/skv/devcontainer.json b/.devcontainer/skv/devcontainer.json new file mode 100644 index 0000000..845804a --- /dev/null +++ b/.devcontainer/skv/devcontainer.json @@ -0,0 +1,40 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: +// https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/docker-existing-docker-compose +// If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml. +{ + "name": "Hitobito PBS", + + "dockerComposeFile": [ + "../../docker-compose.yml", + "../docker-compose.yml" + ], + + // The 'service' property is the name of the service for the container that VS Code should + // use. Update this value and .devcontainer/docker-compose.yml to the real service name. + "service": "rails", + + "workspaceFolder": "/usr/src/app", + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + "forwardPorts": [ + 3000, + 1080, + 3306 + ], + + "initializeCommand": ".devcontainer/initialize.sh https://github.com/hitobito/hitobito.git https://github.com/hitobito/hitobito_skv.git", + + "onCreateCommand": "/workspace/.devcontainer/create.sh", + + "updateContentCommand": "/workspace/.devcontainer/update.sh", + + "customizations": { + "vscode": { + "extensions": [ + "KoichiSasada.vscode-rdbg", + "Shopify.ruby-lsp", + "sorbet.sorbet-vscode-extension" + ] + } + } +} diff --git a/.devcontainer/svse/devcontainer.json b/.devcontainer/svse/devcontainer.json new file mode 100644 index 0000000..1cc0838 --- /dev/null +++ b/.devcontainer/svse/devcontainer.json @@ -0,0 +1,40 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: +// https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/docker-existing-docker-compose +// If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml. +{ + "name": "Hitobito PBS", + + "dockerComposeFile": [ + "../../docker-compose.yml", + "../docker-compose.yml" + ], + + // The 'service' property is the name of the service for the container that VS Code should + // use. Update this value and .devcontainer/docker-compose.yml to the real service name. + "service": "rails", + + "workspaceFolder": "/usr/src/app", + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + "forwardPorts": [ + 3000, + 1080, + 3306 + ], + + "initializeCommand": ".devcontainer/initialize.sh https://github.com/hitobito/hitobito.git https://github.com/hitobito/hitobito_svse.git", + + "onCreateCommand": "/workspace/.devcontainer/create.sh", + + "updateContentCommand": "/workspace/.devcontainer/update.sh", + + "customizations": { + "vscode": { + "extensions": [ + "KoichiSasada.vscode-rdbg", + "Shopify.ruby-lsp", + "sorbet.sorbet-vscode-extension" + ] + } + } +} diff --git a/.devcontainer/sww/devcontainer.json b/.devcontainer/sww/devcontainer.json new file mode 100644 index 0000000..a55bfaa --- /dev/null +++ b/.devcontainer/sww/devcontainer.json @@ -0,0 +1,40 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: +// https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/docker-existing-docker-compose +// If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml. +{ + "name": "Hitobito PBS", + + "dockerComposeFile": [ + "../../docker-compose.yml", + "../docker-compose.yml" + ], + + // The 'service' property is the name of the service for the container that VS Code should + // use. Update this value and .devcontainer/docker-compose.yml to the real service name. + "service": "rails", + + "workspaceFolder": "/usr/src/app", + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + "forwardPorts": [ + 3000, + 1080, + 3306 + ], + + "initializeCommand": ".devcontainer/initialize.sh https://github.com/hitobito/hitobito.git https://github.com/hitobito/hitobito_sww.git", + + "onCreateCommand": "/workspace/.devcontainer/create.sh", + + "updateContentCommand": "/workspace/.devcontainer/update.sh", + + "customizations": { + "vscode": { + "extensions": [ + "KoichiSasada.vscode-rdbg", + "Shopify.ruby-lsp", + "sorbet.sorbet-vscode-extension" + ] + } + } +} diff --git a/.devcontainer/tpunkt/devcontainer.json b/.devcontainer/tpunkt/devcontainer.json new file mode 100644 index 0000000..fec8ee0 --- /dev/null +++ b/.devcontainer/tpunkt/devcontainer.json @@ -0,0 +1,40 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: +// https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/docker-existing-docker-compose +// If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml. +{ + "name": "Hitobito PBS", + + "dockerComposeFile": [ + "../../docker-compose.yml", + "../docker-compose.yml" + ], + + // The 'service' property is the name of the service for the container that VS Code should + // use. Update this value and .devcontainer/docker-compose.yml to the real service name. + "service": "rails", + + "workspaceFolder": "/usr/src/app", + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + "forwardPorts": [ + 3000, + 1080, + 3306 + ], + + "initializeCommand": ".devcontainer/initialize.sh https://github.com/hitobito/hitobito.git https://github.com/hitobito/hitobito_tpunkt.git", + + "onCreateCommand": "/workspace/.devcontainer/create.sh", + + "updateContentCommand": "/workspace/.devcontainer/update.sh", + + "customizations": { + "vscode": { + "extensions": [ + "KoichiSasada.vscode-rdbg", + "Shopify.ruby-lsp", + "sorbet.sorbet-vscode-extension" + ] + } + } +} From af619d0c917118803327ebc09f43dde9e21093df Mon Sep 17 00:00:00 2001 From: Nicolas Da Mutten Date: Sun, 26 Mar 2023 01:20:02 +0100 Subject: [PATCH 05/21] WIP: correctly name dev containers --- .devcontainer/cevi/devcontainer.json | 2 +- .devcontainer/die_mitte/devcontainer.json | 2 +- .devcontainer/digisus_lab/devcontainer.json | 2 +- .devcontainer/dsj/devcontainer.json | 2 +- .devcontainer/glp/devcontainer.json | 2 +- .devcontainer/insieme/devcontainer.json | 2 +- .devcontainer/jubla/devcontainer.json | 2 +- .devcontainer/kljb/devcontainer.json | 2 +- .devcontainer/pro_natura/devcontainer.json | 2 +- .devcontainer/sbv/devcontainer.json | 2 +- .devcontainer/sjas/devcontainer.json | 2 +- .devcontainer/skv/devcontainer.json | 2 +- .devcontainer/svse/devcontainer.json | 2 +- .devcontainer/sww/devcontainer.json | 2 +- .devcontainer/tpunkt/devcontainer.json | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/.devcontainer/cevi/devcontainer.json b/.devcontainer/cevi/devcontainer.json index f4ca3ce..b9a18d2 100644 --- a/.devcontainer/cevi/devcontainer.json +++ b/.devcontainer/cevi/devcontainer.json @@ -2,7 +2,7 @@ // https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/docker-existing-docker-compose // If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml. { - "name": "Hitobito PBS", + "name": "Hitobito CEVI", "dockerComposeFile": [ "../../docker-compose.yml", diff --git a/.devcontainer/die_mitte/devcontainer.json b/.devcontainer/die_mitte/devcontainer.json index 438cf04..36f5fe2 100644 --- a/.devcontainer/die_mitte/devcontainer.json +++ b/.devcontainer/die_mitte/devcontainer.json @@ -2,7 +2,7 @@ // https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/docker-existing-docker-compose // If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml. { - "name": "Hitobito PBS", + "name": "Hitobito Die Mitte", "dockerComposeFile": [ "../../docker-compose.yml", diff --git a/.devcontainer/digisus_lab/devcontainer.json b/.devcontainer/digisus_lab/devcontainer.json index f4a30a8..2cc3de7 100644 --- a/.devcontainer/digisus_lab/devcontainer.json +++ b/.devcontainer/digisus_lab/devcontainer.json @@ -2,7 +2,7 @@ // https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/docker-existing-docker-compose // If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml. { - "name": "Hitobito PBS", + "name": "Hitobito Digisus Lab", "dockerComposeFile": [ "../../docker-compose.yml", diff --git a/.devcontainer/dsj/devcontainer.json b/.devcontainer/dsj/devcontainer.json index 7731b3b..665a05b 100644 --- a/.devcontainer/dsj/devcontainer.json +++ b/.devcontainer/dsj/devcontainer.json @@ -2,7 +2,7 @@ // https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/docker-existing-docker-compose // If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml. { - "name": "Hitobito PBS", + "name": "Hitobito DSJ", "dockerComposeFile": [ "../../docker-compose.yml", diff --git a/.devcontainer/glp/devcontainer.json b/.devcontainer/glp/devcontainer.json index 5a66b56..f3c013d 100644 --- a/.devcontainer/glp/devcontainer.json +++ b/.devcontainer/glp/devcontainer.json @@ -2,7 +2,7 @@ // https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/docker-existing-docker-compose // If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml. { - "name": "Hitobito PBS", + "name": "Hitobito GLP", "dockerComposeFile": [ "../../docker-compose.yml", diff --git a/.devcontainer/insieme/devcontainer.json b/.devcontainer/insieme/devcontainer.json index e8bc275..a004996 100644 --- a/.devcontainer/insieme/devcontainer.json +++ b/.devcontainer/insieme/devcontainer.json @@ -2,7 +2,7 @@ // https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/docker-existing-docker-compose // If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml. { - "name": "Hitobito PBS", + "name": "Hitobito Insieme", "dockerComposeFile": [ "../../docker-compose.yml", diff --git a/.devcontainer/jubla/devcontainer.json b/.devcontainer/jubla/devcontainer.json index d8af7d8..80a7055 100644 --- a/.devcontainer/jubla/devcontainer.json +++ b/.devcontainer/jubla/devcontainer.json @@ -2,7 +2,7 @@ // https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/docker-existing-docker-compose // If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml. { - "name": "Hitobito PBS", + "name": "Hitobito Jubla", "dockerComposeFile": [ "../../docker-compose.yml", diff --git a/.devcontainer/kljb/devcontainer.json b/.devcontainer/kljb/devcontainer.json index 30d0a9b..2a5c213 100644 --- a/.devcontainer/kljb/devcontainer.json +++ b/.devcontainer/kljb/devcontainer.json @@ -2,7 +2,7 @@ // https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/docker-existing-docker-compose // If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml. { - "name": "Hitobito PBS", + "name": "Hitobito KLJB", "dockerComposeFile": [ "../../docker-compose.yml", diff --git a/.devcontainer/pro_natura/devcontainer.json b/.devcontainer/pro_natura/devcontainer.json index 6fc9e5f..83bede6 100644 --- a/.devcontainer/pro_natura/devcontainer.json +++ b/.devcontainer/pro_natura/devcontainer.json @@ -2,7 +2,7 @@ // https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/docker-existing-docker-compose // If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml. { - "name": "Hitobito PBS", + "name": "Hitobito Pro Natura", "dockerComposeFile": [ "../../docker-compose.yml", diff --git a/.devcontainer/sbv/devcontainer.json b/.devcontainer/sbv/devcontainer.json index 1597484..1123ba1 100644 --- a/.devcontainer/sbv/devcontainer.json +++ b/.devcontainer/sbv/devcontainer.json @@ -2,7 +2,7 @@ // https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/docker-existing-docker-compose // If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml. { - "name": "Hitobito PBS", + "name": "Hitobito SBV", "dockerComposeFile": [ "../../docker-compose.yml", diff --git a/.devcontainer/sjas/devcontainer.json b/.devcontainer/sjas/devcontainer.json index 74880ff..0c40b7c 100644 --- a/.devcontainer/sjas/devcontainer.json +++ b/.devcontainer/sjas/devcontainer.json @@ -2,7 +2,7 @@ // https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/docker-existing-docker-compose // If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml. { - "name": "Hitobito PBS", + "name": "Hitobito SJAS", "dockerComposeFile": [ "../../docker-compose.yml", diff --git a/.devcontainer/skv/devcontainer.json b/.devcontainer/skv/devcontainer.json index 845804a..4cb403e 100644 --- a/.devcontainer/skv/devcontainer.json +++ b/.devcontainer/skv/devcontainer.json @@ -2,7 +2,7 @@ // https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/docker-existing-docker-compose // If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml. { - "name": "Hitobito PBS", + "name": "Hitobito SKV", "dockerComposeFile": [ "../../docker-compose.yml", diff --git a/.devcontainer/svse/devcontainer.json b/.devcontainer/svse/devcontainer.json index 1cc0838..72f4f2a 100644 --- a/.devcontainer/svse/devcontainer.json +++ b/.devcontainer/svse/devcontainer.json @@ -2,7 +2,7 @@ // https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/docker-existing-docker-compose // If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml. { - "name": "Hitobito PBS", + "name": "Hitobito SVSE", "dockerComposeFile": [ "../../docker-compose.yml", diff --git a/.devcontainer/sww/devcontainer.json b/.devcontainer/sww/devcontainer.json index a55bfaa..220e1af 100644 --- a/.devcontainer/sww/devcontainer.json +++ b/.devcontainer/sww/devcontainer.json @@ -2,7 +2,7 @@ // https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/docker-existing-docker-compose // If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml. { - "name": "Hitobito PBS", + "name": "Hitobito SWW", "dockerComposeFile": [ "../../docker-compose.yml", diff --git a/.devcontainer/tpunkt/devcontainer.json b/.devcontainer/tpunkt/devcontainer.json index fec8ee0..7faf86e 100644 --- a/.devcontainer/tpunkt/devcontainer.json +++ b/.devcontainer/tpunkt/devcontainer.json @@ -2,7 +2,7 @@ // https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/docker-existing-docker-compose // If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml. { - "name": "Hitobito PBS", + "name": "Hitobito Tpunkt", "dockerComposeFile": [ "../../docker-compose.yml", From 43fbd2b0ee28830e63971decfe6d7333deea7e39 Mon Sep 17 00:00:00 2001 From: Nicolas Da Mutten Date: Sun, 26 Mar 2023 01:24:38 +0100 Subject: [PATCH 06/21] feat: add tenant devcontainer --- .devcontainer/tenant/devcontainer.json | 40 ++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 .devcontainer/tenant/devcontainer.json diff --git a/.devcontainer/tenant/devcontainer.json b/.devcontainer/tenant/devcontainer.json new file mode 100644 index 0000000..6d93fa6 --- /dev/null +++ b/.devcontainer/tenant/devcontainer.json @@ -0,0 +1,40 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: +// https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/docker-existing-docker-compose +// If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml. +{ + "name": "Hitobito Tenant", + + "dockerComposeFile": [ + "../../docker-compose.yml", + "../docker-compose.yml" + ], + + // The 'service' property is the name of the service for the container that VS Code should + // use. Update this value and .devcontainer/docker-compose.yml to the real service name. + "service": "rails", + + "workspaceFolder": "/usr/src/app", + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + "forwardPorts": [ + 3000, + 1080, + 3306 + ], + + "initializeCommand": ".devcontainer/initialize.sh https://github.com/hitobito/hitobito.git https://github.com/hitobito/hitobito_generic.git https://github.com/hitobito/hitobito_tenant.git", + + "onCreateCommand": "/workspace/.devcontainer/create.sh", + + "updateContentCommand": "/workspace/.devcontainer/update.sh", + + "customizations": { + "vscode": { + "extensions": [ + "KoichiSasada.vscode-rdbg", + "Shopify.ruby-lsp", + "sorbet.sorbet-vscode-extension" + ] + } + } +} From 30639e636024f06ecf5d1e10e07202e2ce67874c Mon Sep 17 00:00:00 2001 From: Nicolas Da Mutten Date: Sun, 26 Mar 2023 15:14:23 +0200 Subject: [PATCH 07/21] WIP: add documentation for codespaces --- README.md | 4 ++++ docs/Devcontainer.md | 37 +++++++++++++++++++++++++++++++++++++ docs/remote-dev-button.png | Bin 0 -> 33258 bytes 3 files changed, 41 insertions(+) create mode 100644 docs/Devcontainer.md create mode 100644 docs/remote-dev-button.png diff --git a/README.md b/README.md index b223a05..083e198 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,10 @@ We're glad you want to setup your machine for hitobito development 💃 +> For an easy to use quick start solution you can use [devcontainers and codespaces][devcontainers]. + +[devcontainers]: docs/Devcontainer.md + ## System Requirements You need to have [Docker][docker] and _[docker-compose][doco]_ installed on your computer. diff --git a/docs/Devcontainer.md b/docs/Devcontainer.md new file mode 100644 index 0000000..33cb052 --- /dev/null +++ b/docs/Devcontainer.md @@ -0,0 +1,37 @@ +# Devcontainers & GitHub Codespaces + +This repository has devcontainers available. They are a standard way to run development completely isolated. You find more information about them on https://containers.dev. +This documentation focuses on getting up and running and will not get into details about how devcontainers work. + +Devcontainers can be run locally or in the cloud with GitHub Codespaces. Each have their advantages and drawbacks. +**Codespaces** are generally instant to start and immediately ready to run. However you need a (somewhat) stable internetconnection to work and they might cost something (for hobby use the free usafe will probably be enough: https://github.com/features/codespaces#pricing). +**Locallly** running the devcontainers has the advantage that it's always free and doesn't need an internet connection to work but they need some time to pull all the docker images and ruby gems and to seed the database with initial test data. + +## Locally running + +To get started with locally running the devcontainers, you need the following: +- [docker](https://docs.docker.com/get-docker/) and the [docker compose plugin](https://docs.docker.com/compose/install/) +- [Visual studio code](https://code.visualstudio.com) +- The [dev container extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) + +_You'll find more detailed requirements [here](https://code.visualstudio.com/docs/devcontainers/containers#_getting-started)._ + +1. To start testing, open this repository in VS Code and click on the green remote development button in the lower left corner of the window: +![](remote-dev-button.png) +2. In the menu that pops up, select "Reopen in Container" +3. Select the variant (wagon) you want to run. +4. Grab a coffee! The dev container will start which takes quite some time (depending on your computer this might take over 15min). It will clone the wagons, install all the ruby gems and migrate as well as seed the database. + +## Running on GitHub Codespaces + +_TBD_ + +## Rebuilding + +_TBD_ + +## A note about committing and pushing + +When running the devcontainer locally, you should be able to commit and push as normal even from inside the container (vs code passes through authentication). Please keep in mind though, that the devcontainer clones the core and wagons via http and from the main repositories, so you probably first need to add your fork as a git remote (`git remote add `) + +When running in codespaces, it becomes a bit more tricky. I did not yet fully investigate this scenario, you might find some hints [here](https://docs.github.com/en/codespaces/managing-your-codespaces/managing-repository-access-for-your-codespaces) or [here](https://docs.github.com/en/codespaces/prebuilding-your-codespaces/allowing-a-prebuild-to-access-other-repositories). Please open a PR if you have this working and extend this documentation! \ No newline at end of file diff --git a/docs/remote-dev-button.png b/docs/remote-dev-button.png new file mode 100644 index 0000000000000000000000000000000000000000..716630e2c0bc275ce762b09cb194037f080f0b9d GIT binary patch literal 33258 zcmZ^~1y~%-voDN<5FkK+1a}D%+#Q0uyE`l{i?g`96Fj&>fW?D51b25?++9BMzW;O2 z`Ob6i>@zzxRrTxcs;Qo;?U@ZzkP}Bn#6^UHf1@x(1|d6urt&8i22~C6kwqmp=eUnsmyx#Ex=U-ZXw?Kc= z^qf&FydHab)ndK(7b1j`pzXnV64K-EfrsuWb2E}egA&29V=9rL?fwO0gYfawCLD7{ zL5C`HMox$44tvOP|pJ9JoOVB5th&v%PsDqE8&zF}-cb|%c zt&wbcJ`G=`;t1@UJj=2eOC$`B;C6*K4Ma%&`lXQ3pLyX^xaE`b#0&X}YNb)K5P#;j zkYTuLyNf9@#Q0@XPf-l`u}ABZ&!>x>n@@R()&RHoE<(1=FExgvzVtn#Ubgn+Jz}3i z!Y^|361~I<853cdbV&A14ACgjj6k7S9}tDn6WPEkK2VBT5&0jp$AKsa21Y z%jC&Qug>+pdDH#VQZ*RL#D#*^nzS;}!Pu3&e@YlRNR$99HRS08d=_MJeZ!j#ft-58 zh)7EN#=WWW<8B2YP4A6$uWH!^AvrMmDZ`N5NA+!Zs~v}(^X?{t6gX0~$)C|b?Sa$l zI(Po-pL&<8&0!Rk{FU|s8mXxCm@tb%FO8CJ8k>k2Wct#DkMuM$e&R<^Vs*lmjQ6wj zidKh(bDqcJ+lrKv5_(aG!dQR$h%Ja{^_~ifOK^U5X&mYFGhdD`5;-x_2j9GS9Q-)a zQ?yPi7%FHVA#$i7;Vu8|Rv3kk_f^8>n+G45cUpTd(3;i}dhUtQw>v#cyb>)2w3*#L z;%o@~b~4=Qbh|W2x_{ba}bc+^T~*jDFa&y+>Pwuvy2tvKPRZ6 z>+to2k2B`Y(Q2Pt8HP)ufHRX)nlP^mjz1?u7cxqU1C=TOb2kQl5RBF{Pv6bR>9{QiC zj7G4BI6RB@%wLa)YQ{orw#Sm^VUD0&FnPi<`=gDJef`*sqcrebWP(G~=8W$TaIY{K zVkof=KD=(&oed5#YwqhDE^j@FPN9=|6EnY;c#*KK6mLRGyM@B%6kMB7FN8?32g-G=+b}b^~`lN89{)c6e@$~Pl8nV z7kv7bPwU!31ShPp1~9a~bQv+<&fc{Ve+u;d@Cg?EI}J8!-dOOV4$N0SfB`!d+>QaY z2HdP)lmXH_v`fJAPiTBN%1#`6G@bWzodk^@&7DZ&@T-1fAN*rK;R=a={G{B2=pd+r z_H{ERkXTWIH$FU{Of&RD9O+bSlLS`{zGjHEm}M+zz;K(~kq{ziOM)6pxXpHf(5paG z8ikuTyZ<3EtY%z-6^$UoEC*u(9Z1-Wts9`0*D~&LMec#t8tsz9Fz)@)p!5g5SumH8 zOk`BA0YKyH*G@A7Qw=z^s2M}qGcNt!=3jb8WO6+aPFUB#Z=Cq@UG8@xUhmsJ=!cwk z9GVUh@d3n;fj}j>40!kmlq-jW#;%DPs;?gA5C06oLX-a7dX)0-Q zXaH{lE}AbiJgU)UI*RV47pdjn>q#GDjR(9gK3||;s5xTXqc^2LrRGXj=iDixQ*$LQ zB(f!P4*`aBhwxNYRh?ArW;j)I4rpiCN4R2W6J#so`uFO_!D0n{hEZ}+-m=Yw5oVEQZM&o+nQ41$*?>53d7TjWPU{j}Z;?6a zA=1B(31rU{&z4@35|BNe{c5>n;RJR957)U`HCWw3EFg`CyI8%*RrIv=h4EPs_+TdOgX9^yAJ0XFC9AsCn9PNH=Fr{ zZGsJfb&yFD;JBRMpJ;nvN5iTMShRk~$mupQNe{IG`wC+^|)+-@eQK zbR&0TrkjVLB$~G0s9&oeUanbAQO+p?H$yM_7k(VO(L!h~SsRxp=N^}xbK6$#4*CXj zf5G5RU0Lh5vAW6YG`tbIX`4dryrplh@UDK3?{Cuyfia4NmwZ~hZ5|%(QoM(}p1)~Z zCtFK@bEhu;(by&3<+Ag4jlGpQ&08e`@q)s=ZXTa@4)@a!Tc&OoB+}#jbm$eguEmhPOrX8mckg`Q=ir_nr%0(jNt`)%@{SQLX$t z<4(g))6QcOEfPtRL!pz9v=FnP+2ETX_dr=>9yGZRF(36YR|lDP&p6pK+CEf;LeMJW zrUwECoa0dQj`GMAW%I@r(el(HoAGSE(1qKELNjIj_`-B+WMf3xM;J!d*W0Js#~0=r zmW}Dd?w7?#Vrbsg((|*2BFr`3Iw4<@Zt!5xIKe7@t>|45tvm#m&*(7RlXC3(-g&*mWXgA8;(NOZ5 z8;?FN|5!e5f_0~M_qRTIG)QsA4>l$Hm(ONo+KB z^^w}#k*$5LOL`#%DIDqRXg(P#UF5?iuu(>QZIG?buCX7QiXV?(E8J9eSJo~}l}+b6 z?gY+Wjj+Vx;IL?!Y5mFIsP$BvFDIy_u5~hhuEIOCMZXA8#5&;I+PP(zRvmiM=<6kRG;`YNi|n$U**t}6QW%6n%6huzH^iY#e% zS_=9vbgk921`E+UX~WXV0$NO#qR&!&Lp4cu>arTnZC$NKTb4tXkb_D#MJwDntxDbI zo8jgo=echIG`A`^s&wTZ?OE+FL%|)$&UjHA$#zd*$wtWT?yr&Snc0~y+M(Lv4ZI6! zzpsz%{;XNn|g&YMg1jvdh=( zIdtp)7TIIB1*a|50**ez(7S%k0c!ANC=;kjGi2Aw2amWlc+I%VcswZL__lxx8*X3^ zWZ)*xO#E961Yg@R!_jN?+;2C2_XT4Uqm{B&j^8qM+;MMuUwKYzOKVA9Jd5A;>(!r< z+Va|wy{AzEzEh`{Gq~NL;D{`&!zJEDl;@N4#~hcjn+IvV6kG;RecJ=<1&1f8j-&+j zfU2yfz9yG*kE`owJV_2)m+0f8=E3&+Bem5E^@a#LpEj05`VHF!z9`Qxw^1kRuZFk% zS@dI-#;E>8U_Kc)w>`AeiHQE7n0DZpr;w-8`ScZFgk{cL{OyEZfavn~W6)ji-s+?P z+iST8;PGNz-_NJ+I_l)mo5G##%wqyCfMaQ`x!nd5bKL$)|GKhwYfAKy|LAVu$?ZmY zsHiBL5<~*hyqr0)nraxZbA`Wvf8V2np#JjBw=>+#4Cc&(2MVkLwSVR%hLgwnI*63Z zSv!PwC$HfkmWU+}b+G>Gsl)Kp0(oa}s^<3O|8QUo9a;b#yN|5E(U8OKrk0TX%{1u4 z7<77WyV z=uoh46!hB%3K|y*?jIToN(vh9|IkX%RR7U|fr1JFK)w5qj@H}p?-u*EzoGwggpCh| zf`2egr*Y| z6eh*r9a>U}{0s^TW(lC80o0I{;WoCjp*J+KGcu)jv$6l%4iv8&_Zw+r3N$2kv$3{y z;&$UB{YQiQjsDAKASM1s1!%=bsv)aDENtg!O3Y5rNY6;hk4Q{R% z$=DHK4+PlR68~-2(8$gi$VW>0x1;~F{X0%mH^6`QWb5=Fv)&A3_$y&xqGx3Izrlb2 zv;PO|ujF6YKX(1w9q-@9xK*7@9fj>|Y)ox|{QvE7-hX=f{|Wzloc{t90B)w%8X|x< zq|=*C{LEa8|3Uq4$^R9p`QJz;R_6bS{2!A4f&6O%x00!oowf5{7pmFqH+4gWGS_Hcd3({(a1ly2J$5RWgjP{o|5qZ{YKI}%jQdR*Qs48x#|4m0xc z@oBzY_2lUq&ER6;+o6`1Tv=HmSSoq9`*b-bFYvf9#{D&q&1yEkHv+5Z`F5>6>V25Q zo9;_uUlblkA<@%1{LZgMHOyjKMmfylIm2%}7Xh(m#sEqF~cCuc6nR1INEhusA{|w-*pkX|mt&ncN>t#R(Q^_pI zaqT3sdfr$Qu`qLQ#|lq^ZddlUW~=I~<_fiKn+i19Ko7tzCg*qATcs**qyFVYH;#RZ zrdY-ufk`KoqU)k*HS^;Jm2=(qD?VAFG(#&mHPFJqCZsOMoc}UamNQ+YB)GnQm=;k|BZ898g#hJ3 z8S0Rc<3I!qFHgY|3j%_qW=n0&pEVto0Kd#;jS)J{Ebiqo zZj46UPiNgc{F|M5SOTy2W0~dHGe8=hzP%f$c*UYFGQ!N0()aa|e_U?f$nEk28l)o| z%z0{M7W#%u>M05_mSxU?#Dg9Td3<(6++!|g{BD>ldG8C17_-K~I8m!YvvIvfd&4E& zS+Y#7co#c6yXNygyjHc|R*@|}ZhUHaXPq~{3u^rJ7*^iYh9nJn{A>v}S!xB}JE={Q zoTPj;i)hnf+-X=;-gP$8bx#iu^cZ&)_4z)dR>Z=ZjyuhDhZe7~&5M$vEN&T=S(o~o zr#Z&JW6s8xheHgq93?rPW3b`iuW9wAzwUI&g6n(EnVV4Ig5)Oz^CgXuVMc27wVZ{1 z7%cuQCQ6?7PXM3&Z50Qt+Q4hxFodnnENU+p&(?x4=63XLwhA1v`@Ic@@jOyf^&f9~ z(K4Q-oQjwB?mWbieJV83sl%-}Bj*c?D6=%C)|nJIY22#+;4{KD_c8r_me<9gc58+J z=IR%jzu~=P>*vt!C7?uJXi}kG<%T*j;EMPKAG1bMD^i0B36oZWJT`>TquBT3l4Bm( zDIHD9t)w1rQoHp+jiEh$V$gYwTyNS8q$oSf`+iuzzEkZ>5*!UuWEGst0WO;QV559- zU1C40*5SOs-Fm>Y)?9pGu`!>yv@#VvB!&DP?~_}8;JaA>D_cB=a^J)Wi@)AK7GV=1 z9Zj>5>RGTm((Ui(#kk~B9WWtoHdWV-au0_UO{dtn|H;E|uobro=%32E0UM(B#;?02 z7+Wsw3UBoCUGwg+?UdRy#EYY9PVvM6+oih4j*3 z-FFaJFzLPWT(^2rA8BiSo|^nqa=#g0NWHrOV@0~A^x+jO+2MODz>J_&g6*R!?hpQN z73rK@BS)6`JR;^n2g7!;V0x9y&o2Y;8ckM@{Q@rzn>Wyv%heX69;*Mw>J#1B4>1uZ zpw9-AE-a+D&wyKKsk@F(!TH+EWBxrHJbdC02{|clDdwqkR>x9JZyzZy$9q0xUyoi$ z+({T@qc0!qzEuPEQk9Y}9JxW7Lex1-jzhPSD_3-YtD^ZEd`GyL^M!N1_@#=YgM6@% z?LI*dp<9DRb+WAf+N*p&;K1(nOTK4{cH;M_azYjE7H>8glQl7LqZAjZ}%A!Q>TF0EryF^iei8Xo4j#>`$N*Q@(%iTVz}u;b5U`V|%F_I;cDbdI?+jE-u>vY&saHa02}tGEaf>xKJhkKfg2iW~$j8E;zC zRJBa3l5U2Bs)F9d%JFH7p!%{a%`&*%YtlBorIC_dxC8!bG75{VA8zG!;*YeJ@^Sc6 z2X(Bqm=PEpP(3m#UJa3xRme4(tCg^5#(7^ds3D*!QZQb-mwYsW)fkfn7n;)VxqPm{J-6eHoQ z!@?X!HICD%A*ygL+xo4+@3Q+yP5u0m-v-R_mblTXpa8iFt2Yb1B`#%)l#V6sJesqa#YNwO~MrMcsqfYFu}DKB|y5JQOkTsbpfJ{9^+p`}?7n=LaHYq`O6 z#Hy(}pX_rrA8MwW$ne5w;S0N>`WC%tyjj8SUB?62p z)E1ch;7cyTyqJLG>XTihjhH@5Gm=_LSE3ERxSxr~a3Zz7My28Iit*pS* zVP&|Et`kTv>K8P(e5>cXASx2M+6)6h2GiPXAd5JMCO!>q-$3$Hb^RVrCP|_7{mNfP zv&{S+q@0^d1L16^jGo}>3zP( zNyk|FXW}usAgNf17&j!5xEsCJrByy_+-f`1@Txolq9Wa#rT$GY>2Reb3-d>;AHzdD z1nTQ~o`b|BGPA_DRB4DNztmk`(niJg&Dlxr)NEL1)aKDw1vmeU>EJCU6txt&gr zgw_3>daG(le=CSZI)w_fx+RkqD>q5}m{6V7jq^{0NcW*)VopHSihpi_9~%T8A)aoY z&fqA_@g>L1NN(9FH_0XVq{uV|#5J+SFK%yMpMjado#1p!j+=O7lWl3~hGCb#Yu7{l zqgL=YbCMvbkmZtSAC2>!ustYKkYUz{Cu7MR$eXKj@J6#rJO9Sg{;5TVE57ICGXd|s zWn6SVMg$?u188xSO8u=X9!l;(S)NJ<+Id7#RpE5M47UzliYZPo>lo-B6g^hD>^|o4 zXd6#75MK6N_1wN#YJi;I!psgV$i}vWp!fO$EiXSe%9#^2bw5lm-CxyIThUhfR@gUa z{>-{MELFwPM>^Yz%jUm8om}kOW*4(-zAf_*H*@w;OgAhIZyka;fSuv)9X-3d$V!EL zyVRTSJ2<;W&38&xo2q5+R{7$Y1jkCcSat={NoqBDb(+#uMzKoR=z?!g!3`jwud4h0 zw~)D!`5Q?*6IHNjfzQu53^rSwu2Yj&(>vs3rf$2K1hFo)s5zO-}ODJ z{-m0^>RZ8}O{+kW+uu30#(C$u)L5eiUY}T6JSYnvg7FN1!ws0xx^8^DZwx5R=iq;i zy$TE{Dja!+g#-tQ7kRF}Rseg3Hd0Qq+pbc=(3Iao_O0X{uQh9F8%pr}dh#F?O}e2R zou1nEvZLQq}vq!FJc{`^~w^#q`vm$K+>Gty9()-@Cib#{L ztLKBjA;Xq62}31$KG0e3<EM&}^7m zXc_TQwY7Q7`0;FWQl((p9_-B;FAy7qo;T+qWh7Fi?NpY~|HW{GpfbTfKj^Ir}%{Q!TPwJ_-ahdXAO$uPYZFi@;5ismVt@dy|L4 z_z4v{wf3Vy_b;6~{#yu(x{fqo22x>bpJ$@-# z|Bo46L?Ltr7N-Z$$vrE5J?xD%Buq>Bmh3e{(xuaMEJj*BRWtNa=RXsZHg5=+m= z%i{pU3~*J={(OIXD$5}+Q0U9v;FPkG^zwL<1VPsSP0@NcHCJT!bejuYFAswtRq^o8 zxK5M+mGAi6_D04y$w6Y2p|7`Tlt+wo?PpW)Q)y8k$iy`WA}!!!5i&u5Dl|pOHVLoi zrg8w7R`$t~yauc|twH!IeQ0@I7kd(=&kjAs1=3H$BtP`iYBf>o-lcF9I?4Y?TD|;D zHkpPDf?&LQRAC@T%w=Zr9k%X`UKL3h;CXD7JjuU4f*=O6nT=o81KpLUqLAizF|*Yh zTVmm`*|Kjt%Unpp#ISaZ8F;w)&IfQH5Xup`2=!asGXUl24WDBMQ3~&3`pZNAZH$}& z5*^P@=>l9)c6!@+a!f(@4WGS=Vk39G+x5kYi=l@~?{r5}jZeD^K&!n(fUm|fA!Lo5 zWT+Au^#Z#C%d?y0Oh@x;WTew^ToF3Z&6iU-yT_qy%F4hf zT2}^dMglfhJ?{H)<4K%ESH6Ec@Ki;H_L5Y_m6(nX!6v z)II3{FAs2G7mIIqH_?5VWFTa={RU%x7U9ic@_T)2t`N1|r0v8ldlHP){5-5G&1%zD z6n1lhgd#sC;ADFV!*a;g{<6Pd>tnDGeAOkdyB1h*`O+kYVvf(2CyAk**RM_wq5>Va z2lw;aXL~x!T8Ba|TWnn<7IlILuV>dVsUYzY@j7T`5DO5-Y6 z%JVn3L`&FUv_eQ(sdgmaSBsGptl~OdH|vM;8|~TOC0g@PN{hvip%emkA!U0RupmHp zOYBg=J+v@zlD4k@c}}-TS;ehEQ)1xvw5@G(-lLG`{<)Cj<9#{)g|x6@U?DBAV@u}c zNcl!~Z6=9NOsXQNcZ;F@z6ZGbgfl`e!o%7q*x^s395&0WXfx2icjiUV-gmGJ@zO zVOoCuTGfj6yB_rMSd#4ChBXTpYZ>S)zICeNuS^ZpI)6R77caDH-P$&k487T^(>co% z@HFx$@oH%;SY^{#qMjS6PmY|m)yb9+bLDgNdFVh|{V~e-5_voWXz13SnBrgY7>$d% z3b@TkdwJ$7x-TCIy~ta$5lFC+U6_jb5x08rM;LjwDrMb4%zKrxQu_2^kwDMtK&>Co zW?nADgj__k&CKaxpx3o%&x`it<60xvY?Xvq5h3A)6I&P?D&p9T^TF@_vMk34+b>XA zLNGK4QE}b+dNquEkFR6I4Zi!_Q_R=9)O{KrS%wA2S>Od4fk&zC$_mAC#`94RO+?wkEogb=}g5_ZF zFWnV~EkfgrC6jejg|lAI_vQ-QU+)8Cb#XLptZ>RQ#(N1X!h$FM41>kOXd`K<$x9hp ztDk3j!EvEEeosVCH+GX{{65ML{*{r6Z%M2|d~&U6Gwx~%FQw(=QVYXK>#Oo1&d|-{ z&PUeZDsBOC#WG~%pnl)l72>7jNWJVVm#);M5i3`rWsR77m$E+sPuH+0A4VGmS^-Tk z5HmY%!@io=U30?C3DjS_WFI2Ux&kz*91t3`pgOwBRnY4J1t1KQ zx{2j!22nxpMAF=+duopj@Dxxe{P`rwsCZ3lbPilx{`l1GgQ81f1QsJf(79{E%cM=Q z+(-z7S##c$H#AWhf|FmaN)>!nb!0Mal$$~+WGDaiS_XlK^Olk3NeW8So1Cb88nLX} zVj6ks8q1x^nS+R^*=d4%_#(P$Im;WQzUq{Qy^Kzv9(C{m^de*>*`A$o8XuWRvz+t4KYZUHRbtsOW9c z>+{oGK@me}(_Q`9{EC6+A)gH?5!bg9w&#SZwYb&CC?0}OHiE{*208IU@Dw>ww7?&7 zLA9IUuJ6n*LfQ@6>W;@@#c;+qHgrL^Y~!6BfBM4WG3lMBBWWzfRAUgM-u|aSJ*W1KhT0{Y<$nQ>nUv5uGG{4BuC9> zHPWumqzW(tgCT;hav6k@zgbM0HDx148U;m90?!?rV8)`qqu5pqK@JNwdE`Obz4OzrOilu5zCE-}9@Rpe@~uuzy0#GbFf<+P?GyfcG&;es5ph- z8#LaZ$9hmcJ?G3;e7Vp}o+rS0d+%X?b<;20Loj+7=sx8oYJS}3y(Zs7M!d%lW6Vt(bUQV1ZnTc^`R!G5K}g$rnS8M@h3x3jAxwcwwZXX9=Kb5cKYrT zS=WyiwaT$1<2sjz4c#;+drSVw`%(8QbDuZ4nGNs3xmVhiUwTjez?mg;=pC{EJ7C*M zJtBsu^Y~A**xKUD^pDwsjr*H5*k61wW7(b-4_Cu$1w2u61q~oB`eWBzVdjTF6#A#r zVC~ts%ciBY5NSwaA|-?NV&QP$1F z?zNmq1sT+V_ORjo?r_cg;$nT??d{a(U*sg{pR7bH3UoBBEAV1K^!$Ia*t@5WZLSyG z23XY6uA{6xT^~aCf54(hXS?^dpiAyn=-+E-HJk0%>}$ZSWv-))gLmkfL-J*My(=lp zx$;t&TN-pF5=acV{h$;b+ zXVDOr=Q%Lv@C-$v=;_p@q&3$|sqKLkUAbgpnc~64=FL!-V+)<&qLi8@gt%|47DJ<#zC$M=4MdpzCQ@ zUh5#QRP^W}k-Qumy7p_LQt9AZN~QdY?vnT8?G26n@^^7Ja8R2YIA6?DF~@2&abA6JMWNeO zFz)VVkPu`phD{snv)N^QwL3f^uD90CjY)>EYG<{PP)55iC+wKGy%l=2yZUJ-DOcfYNv7SD680F|7y{1~ z8->TnFsa-785z+z#Cg8sOU%Y$XEF!T8GBGS_`N!zkeNw{9d$e9YZjY;963A{j<*tr z8b9O*fs+veN}i98y!vyv?&|$=H#+J8vsSm=@5(!#Q(lVmAD`+$jM@2OMfI0jxDhy; zF0%5vT4fNTNW4FN5zpuFM5!;ET>_J7v0_5{FF&&B@EG)3V01@ki5~UETb%5DMjGm7 zySf+%cHEm$cZEHoj#BvDWz&mq#v^Wq_D|S!{|&;86Ia7)9=t~Czyi8 zaiHkmcZUlJbQkABs94I6i=7Q5oPe$L^xzUt`K|fO6t|P0_#GWb5lH3M(O#KExj^}G zX>9gZKHOkU@n+)%6DDTjyOm+o!L@#)C}nVC8f)&t&*k#IC>t{UAu-CWk%VPUoyz38 zNwaLx1IJrd)O$V0m9y&{HMdpvGvT@fY;B}l1VaIC9;By=AkVx;)NpN#A>kgdZ~&as z2?MVC>9pW*lM8v3P)nq>Sp8b78>lPUv0VTeOBFlb2i8(e~x8vG}_loOl=XZ=}z574Iw^& z4?g$O`Wd?nZEbbbpqI0hBBCRomtV~U4jlu2JeH|#XS4mYo@RYQ+0G%#SDf&!>T6|7 z&{83INGBSGKMwFKsZo`2xfxx*#?+lze;KnlE=C(qzGH4S85$ZWCtp&#Gum6a(&!m@ zw}{xla+4Z-n%7b+IbUIwz!Pw*;m+DjDJ$o?_F~Vy)97B((7>EinPIH}4@1$?-vf;@lQofNsK6;iIRral6<7 z-u_&w?cLd3HO+ZKx_6RyiMprtGH>%1;kOuFwAZ1v@(YE#hUiqt1gbLr$;NtJ6)kY} zF)us61mvJvHZVqd-8FdZ^f0Ms^9|`J471pk?TS95gk_3uj#jpoQfAI{aU(_EHF45Y z8@z{^CdC99`wI^A}Mye+ZT{k!P;9*GL= z+KNwNip3_i&>2wO%w%Yp#tC`_u6&W6%9|^fcDf?xL?|grpHNmMjDW-B_0ZsW zLK|s$hGN$SIlg&zQ?K?c-NqtDW}ZWr`?0+K;UBY%{N5wY{4Q|#DJ?mG+BlsN`=0Gf z+1yuh`fb#Gy*%y8sYAF*&FpAi7nd~8o(+Jaxby#1K+TR3O|5JhwP`L2ddi3`e`Qzt=9&b!<_>^qXs zDgo?k6yJUDsK35RfI0P10=O1`7gc`2%Kqn=l}*KQ$H+36wDrI*0x4+s<^>RvpC037 znbtkVjUYhV^L4mA;I8`0l!DeBm!8>blx)w1?0I?fL;ulq9zoT#~0;yD?Fh2SdGR9Y>#{Q~U>|`LYHBdO_ zM)^G-TnVLEp*Dq|OJJr*cH^HFFMo&heq9uF6z(l+#~N$>8{_GcCApy1Ggx30dbv#P zG^O(R7%+s%Bm6|>F1Vy}ue2ffl-bDH)n`a>7`m)?X`CpEN3odxxL{^@O6$Y=urxkP z#88)fW;ajy2&JWIKQ)C`-Jv32O=CGPeN(-?$Z#Fxv(QyCn4W2EbBUB<9P(phWn5bC$~SyJ_g|&&@U*pK-J* zp&aV6`*bLn&@W7t#@zu45d&sJr5`|0%pl9i6nWAQA_V7SRN6M&{ie-}afGuo9-Zt5 z{_V-;v3Wu1VQevI?_NrS%%TNU#o)j*dtA&uM`H--@jEn6=Lq(^+aFu|e&Wj(i9+G` z^LKvZhZ%q_tk=>NvV4{(S4x=;#kYWU7?T!|?2i;tyo!W}M(T{X7sVif>z<}d?1$iT zoyS&)%ewf*3c|iO6+)=oMP{6|FI$(P^{azdwz5UBX;j|;+p=6{B;dl@1{BW8A`n5h<~Ok)<*wk#%$Q@}b++9d22NG80a zRC|{U2B45KA${LQiPArEgHol&5r%Rh^Ig}^!T{4x3uEwDuDONgw|_@x3iD4_t0hI# zKqC&dCD;gRW%fboZkyGx@$c7*G>Z`2Rn;if>)#~2aY)Yyl9AhvhvmgU$?6b7vJ>IE zKxddXB?^;U5GOX-`+-hLV=v@`K=p~he8Vp)n)LaLI(Cmr4P#=v*;&F3?m=%L89yF@rL*iRMv$tKEr#li?pAv2D3a}(Q$j6^eic8V*AesI~aa85FwJ>2z#n-CVisK3kW8r zbbBXh9tkqI8Z@`u-ai=qE%VJy^dlV8K95FE4|KV)D=Cse+(`Ez)*{W@KT7C&7Y(>e z3R_C2&gSx9YI(2o+mF(!uqJzZ{r4^6;c?Fx>28F-n!Xk{7+cNmPoe$eXKuNancc|E8}+aK#epGp-8eyf<1P7-O|X=E;Qe`mOa zU-Kpp*1)P;CcBFuzjD+3DSjPIHW7&TL~XrKc7(2PNEI!^B9|rn6gR>?@9J9vi6 zM9+-a*opI)$@|M4iZ$Qlln zXiutr7~ggS=ywzT6Q?vypo8YN?>iaE3uTSySFD7)r3uA!L)GU;itqXv|9f0~u3xo; z()Vxpe4k}#tB~RuF8hO+($0#-!%4Lu>I%pq-^IPAHNKhCnoLy#%*m~B{dyMA7jQO} z!=J`E60gr~E%rR(x!oS;*b7h#mg2o>Cgv;jiR3S*(mEw7;np0#&+_8H(Zouk!@461 zrauvfy+e0g$`T8^${kLfMN^-}Ni$!C>+i=7{%QZog2++h^Y_S5Ha70$3Vap`l|>bf z>84s<%LstR1dCTpN&3@980VR&OCC(fF=(5Pz;D7`X)|Ji%OlvLM;+49C#=R#!@uy0 zfjuQ=@v~fsCs0;cmFI>Y^rWXF?p5-*}UpEI7z8+iiu zi%0x&qD41&34&peJ*Whw#~UtX;yX~c1XF6U|_GnP?v_-UF8-ldM0)tgiH+Ys|?VsrmC&aOp;eLfOuEZcJpu4v%Oke?3;hH z^BnnA%Mu+^iQ?@Km!e>DG_Hhco}E#1`|tI3~z0a1i8-Gps>$4G#oPHP~rwJzR~QxP*46^Vdy z!NLkvxL*nizn2yQ2F2Kecp|rSxh3SN2^(d(RElV(f&_rRQ+mn*5ZKs3?ZDjjBQpG3 zQ4-Sl>zZXD5)|t)^z4CA$|WNIMZ1IY?s*PZNhp2mpLF$I#fg!qptNq+36V%Q96|8H z?Yi*b7!XGpo}5}s@fa;GkObO~coX(O5SubymT~ifH(5};vQ*Kat9ml=#;}}j z3f>^@6Jhufc2+mpsqnJgP-mpEpE^uwf@Et}zA&1BM~E@s4u+2jqA`=vW~a^ugvc05 zU0s(eq7;*K*R%;L()xfK<}=wAcBC4nS|(U<2Hu!NGb5-Z*H5H>=KB$e@sc44mRGE> zQhp4|a$2;MaQgyCm0EiS|A28tY?N;I%)MWe8Nw z{MQV@chYD3V>gLWImi?TzH||RojS?R3Q{P8b}i`kjEuRA>F|nh3{+`$_3h%(T^#S2 z{f>MiS*oe`W@w^y#%RHRes2o zg%XGL3>bY4{uFA^ui>Rqk>4Gi8L`FWsPf_MeNvQBrJveVFam*B5<{9_f`Z?LR1Q4S z;O8F+)@kc<1P8wFj?1-kR~)|(lCI&pBrU?1%J9g4mn^Cl3)n}b=?o%Uuo;}yQ&4Xm z!CfxjfnOnp9+DulPxMz<;K-Z2I%gCbSeAzgp;}A8Bs_L zd#*IV`-x{AF1!9hM_VF@+Q5Q@_xtx@#T$msfX$-5C9s4 z2nwO`urNVwt`#k6P0qwGJ>gM-L}!vfs+jlFquD_nMX@0QOr*`SL;wLX4QRaj_t?lK z7^OE~@{Tgl#d?x!^fuKoB)`;TsqF>w>(VxQf zk&QsI=X>6D1oBzo%URWe?v>&e}O%|ytGi3uJ5w?X5DzgaT86*skLNZVRPhy zq~UJlu>OnSF>?O{*`o+}0GY5UwH>Hz=+RXf6+#NdP|8D zZ*e4XhJQt0e-Z!SAPYJO#(eM(y2i1-n|RtaKjdoKAJ66yxpiUWEPBnDLcSKCl>XQ7 zg0PJNBb3!;axs-?B8gHGf=GdBzqZJUfEZK+^{|@ksWhg$tPuwJ-8n!I9{A`cU?}Az zh68AUoXuzhxZQMB%kYIW3eGfBDN9hRz&}!vdbc!J%mr_B;MWMSFQ?Hy`wCO*mPlcII8)PjOa@X*Hk;Afw#vVDjp$1&pAPr?Do zbkMcfNO+2eX5ta7?Nbu3kusiWav1$uw)76Nko2U7X)A8oDvo{f7b-Cp5@RFb8BPtV z#mB@WuEwrT>cl7hz;D2o;>3XcRGs4^k`yrE6XO{NSv4Z31s?EH@mB3V(!c>_V&ooy z>DyqiAvA)du%f?$UF0eJiASipp9v=xCIEC25fsT_LS~OXY&=`kfyC7UlaujnFe&XbZ+0L-9vMwr z(PxN{0Pu8j0b9n1EUy;$<4Co~S_lS!pWt+VM1(Z(+Vgact91kkR0Gcj6Bk5Kqw3*F z8BF`u`_jkyu21s^+kfE`D}1zme7d}@9~p$c==$o31w@aKi9jOp@D6d`TOqtq7ukg> z+2Li06mS&VnjMY}%m$9o&HIkNtiRf%py+`gvT(!cAnOxqf&*)BanF|I%z=gO*x3Li zM|4md(qJ>Mr3FjDh`;PZ8$5<39ivJXaI?I?d&(?hqi0RiLdTnFa5m1mU?1a0u;V8@ z7iaZ2K^QcQX8N{8Q~$6E-^hpU!m!8*<7{u16hs-W_OW0^O#gyMDT@<6^s&A?8h{MN z{IRii@mZFKChAHoLd-TmC;d4dWdkp1I2Obs#~5tgt{uo3Bl}!b+-JDu1=)P=D)x1i z5u$r@jQl03u?wEy-RER0ud~ws1n52kQTrZyX%_;57u)!tBmJ-FDOhmbEIrCTK9Ab$ zKhOin`J+Lm4T?C3IO;PIzWB|h8duc_To`m~_)DN65cec#$3t={z&>@Rrj@7Y@PR9E zJH^V0ZX^h5Rm`7_FeO=ZIJKDxBOPd9AZ3631(tZJK5j8kEwEC$*{WlzSYfrUd|@zE z!rPq#*1*Z390Ow7=&5~KTlkDlbgW<`C{5FCh)P>Z$JW-Ri~4R%`wq6>un47(cReBf zv_3a<10l=7uJy_KTQ-T9G(~`aobAFFb|#5mLWV3NBbi;Fx3S16JmF1#U(XMLr4+w)HwmVC}y}kvZEqdT{_*f4A{MiC8RIh*ekS}D5xHVDR(hP$xH$#R1LBAREkmIDNu@eSClr9BK|G;Kf z(g>rn+OBz5Fw+)UC@94rfe;Jba-=(TR>m-lniR6mjL{(+3_1mZ?=$J3?#ec-lu^>tFb-P^GRrY>RDwYC)x>CnA#Dut;nt!+Xm=|t|Utm6+sgT8zd)hI=-M{8lgRSx=uDUPh`gz=q)}jt49%%t&XE}=b?XibR~Qb`>h1B_y=|9_+*Ou?qu>GWU-I7#g5pX53zyFzG}!xN=J?l>204O2WXsBNfP*nn9xR6 z6BF&LkHn}{a_CPrhAS~e=8%VlCQjg6ployOi&R-w=o3c_0EnM>L<<1?8~hEAOz0}T zYrxX?p@e;KIFfjps$I!w`u39&y0$>Depha?)M*BT)HH>P4i5r`)ofqFXov&#^hRp#Sau5*UBM1uPGZ}+h1;Sat1-;VwFy0{T@Gr?oh_<7k zn?rUCghL57HR4K)j-#T((JY=W(FzR;@`tSAjr~~X>e6#x*-&B}xH&;OSOqspQ`fim z-;tg%(D^5nH_Cb+>|UUIg_w@@Yvd~9LtnpzW&LcG?5vgmwteJ$>mq@iVC)aUVrS_A zR_S;+9+@1_Sr-Qbw&b)WJt+36+TCH4s5uMw>sW+n)xWmH0UPmSZP1BH9iI+X@U1@t zK_lQWnzrr)ob}MfB%uj;4kDo8<&y(3lt}>W&O!wriUT`#8DU2-D?Uha_*zAKmMeHE zEIIk0tJ)0#ocQ^yEqHfwe2PD1-=HITR3}QNX}TQiGBz^9#T`7a`52ZH1A6GwOgvc@ z>OxQdV0qoPufxVFG-`ea5!+_OIG3FFoD{5pzguxZ*&oB={-f4D#*wt zWEMX9QF0Q5HdT(X@&o~KL88b1@KvYhOph$)>Eu%Ovn<95{UPsBpXdVL^oi;NUpVr4 zrl30HLr>~8DzW}Lrtes9rh?J~7zxW(dteDA;#Z1GC&j6@g%)1$D9^9~=l%_*bbvql zLkk;VBYYluOO_mS*55Qh%U-7Y)j>{a5&x?5IkFD`=fv{!YJP|;noiYYk86J$x! z3{`x_@bF1MkijSzF9I|=CUA628(1XOIZWn@22Y z3{xjh^Df88URQeQORwv@EnU!ezte$TB{l82QOedv@xAfd!Q z&DoA2nyFfZER)ZE*i!iT#>bL%Xy_g`4I5%!>G(ry5mlF-N$~|Wxn{=iStoRqXNxI?(ZO5AZ9=0JEDULUD3jWrC zU=V-HDLQmo%ZnY<2?Iyoa~s4rr8OZ95>i*2r1;t@$YKs?`1Z@ zdE{hlSP>`09Tm_EDr}k6z~5II3omW?gEt+~;P_8}JbUM*EZbW4v0b%ASJ6R0pX5pI zLd>~J^r?qe$b%>`!p(THqh5?AY#S3GK!jwA(dn70aApt)UwJhhvN043!Mv_P5)h|Q z0{?O4iw@!NhpHKPnkP7T0c-wzn>hg^1@I~NBnhQ-HXDVYzzC|BkVtNxIxR#%&_*ro z)`=bJ0?x+aK>F2n9}u0xfh2=FAk^fus|}2d8X7Cu&+B_Ay|(xEv|on>X~A>W zr$M2h^|ZaAO*;t)J4$8qBmx*{s?eEiV&R%UFo+|+Vx>6ahDWHdKO{R>QFJ6&PAC!7 z&_Q;a+xFD~{84~^Z9Vcd08H>D{0ofaq}Ql$LNG1u+qZ_Hvj@*|W(JoJ$uBTrWo95E zusR7HPP`r_Ar@m=fj!XQ?Sf%zc`ZCRLpqw9 z>MbjBxAI3E$5$}1pM(o{AxHvB#5RWMQj&5T^x3mc*q39~U}I!Z+n`S(_)}E;PaF1E z0gjQ6Ng%r=)-iHILR(@)KDV!+Cs^LJ0WbUyhUr*NXp29iJnhmJu_=Cl=@UFTapE&7 zTxmRrJ5K1+`cooOefg-F2rnkP7f)G%6tct1u2-i3sdAXz?)h@7w{z(hw$CY+=y zfT4~aYDZC@l>w(-e>PBnMbgvzl}uN*IJs{{dc%g>(y;@2JLM>4z2?fFZXBO}+K8Wt zcA!EPC1D~SK67I$5<^ZX$P&%5V^R4caMj=r==(J!GXZ89X~2fGlYC?+pET5{ExIrq zHa^<1qhtF>`-Ww!KPN72k?Y*qOb%~gYP7Qq-h2|U=U|DwIl~{?b zzywE$SkM76C|20n@#p;2Zt5Lt!N4(q^wb5CXwabrt7H2? zdlYJHC*nj0_&=5_*vDT6GbGewEtQzZAF{t?!)|1S%pV@m;zVr^MAD#cQ1V*zEDPd? zob*%e3rAg5aMl>(1XUq7lT}_rmVl~LlEaXNKYS4bCNNZqIMm5qdzR3`5j(nS#zHF0 zd^z4{HP(j60bvkR08N#34QEP+HYEZJTy+S)S^#UoS6XoymqkzDEF?~o2ncF15Lj*M z$1n?6B)64R=V;-WT?|S<%Q%C*9wIgshQ8YAIAYX9WA1F(;07%|IMf6!hWEKwN{tFY zg);1P^>E(c+Vr}Ox250iUmWU>@_kEvR=TL?q_n6u$+8jAu(4irTr!%4P_9U37B zr~^p|;aubk`;zPlZIk@zA}M6A#`vi(Ib;#SloGwqg1cs|zF>m(xYN0o>pPKXwj z3ptWZI3%iwDL5iKwgU)0$QDVa$QnGb2>!)yXd^h{(8?=CAdA`zg*}L4;L#ZY^luw` z3%=T@mLBjddI-^Y`U*TC@u~P>zu+(VX%|m;Q0O=I6Y;M)FL$UPdYQw};ZbCl8C(;$ z&1j!{4xMds|C4Wmsw8)iawL6={bes~7*s-M=O5KHW^P`ame=)WE{x-BEQVqiNh1XI z%}zKT1<;M)@(?LAR<#ANQPnPN3>lq^V^CSok-#$8fG*iHGVs|O;jN(z##IuWC73WG z0Y^}lX`YVz;f+xuIIs+NcUu6}!x{c4?|lbKoZ-uKArd6*0+S&*D0c!Cg-MZpWZ`j*zw0?ReXntt*Gy<<6h>#Tf$V5%k;7c%a1F7gGqx*tqq{TFOtlgs z`eT!!(T?b;y%`kPH;+D`4rxqhUBR={VG&j^UFxw#=I`Nq^M=t(!0ieU$;!zATcJs=M|K56$YSNOx$wL% z@tXYxdgh=u$tIY(ZpCo?S$}LB@mlov6c4{}shvOI*h(&65w|%N5BLS=TW`s$fS{k7 zA+ms_!(xAE(b}b}(Twoix3M#z(3brfnbsaU=a|7uC(lpco3*vaEk*%Ug-(f4EiX(A6G4uE1R&d{Q_VviQ2`IblE6YCs^A|q zQNRY0(jLWS`Zkz)o@#?WMumskEu?D0Xw<8Yz?MPSoYl8j3Fz*0q7u>8%4J=1)91U7 zPmgp>woK5(ttRK7#`M9{{3JIbNcyO?tpp(if}H?BPl5&XQqPWqUwB4A7l>#JT>=I9 z%{dy>P9SGJ^VP=)RPavXnjj7SFG5BqB6p4yPdMKsF@3_212NFexfY~7F({`fBVH*K2h!J*9y z!EiuVb=X+I*MZ>xivENM_Ngp`{Xz~T3)yUk7TTQHyq*h*TyNboU$FcPDLx3|g3tU5 zPb`NHf)$mBS<$7B2bNld?~}TC7>?v582sk}0Msp9wnI>YoOP@%IcL7{U~yf~LFuPc zj!D1jnU^-PNDcG+A#0%!u8R(>>;`4o8Ui@aR)nsCl(i;zQYllMZio4pAOc*NqU*Ug zfuJ*W^UOgT$qW$Yie9bI#d-VJHl}lW z?@!O}dmtS&(EhrP03P~&ur?+A)r1q$RgL{rDSFb^L5BfcFfjH)CIyM_Nm6IRE^4t2 z)MO`%f7nPgfXx9#TdWO8R>{eqKvi%jv_&cF=TRcISnwjmCxi;;oPa>d?RfAiwZ zE~-A$a)wr$X?O}Kn;8~=hmP3S1>Vgz?(t$?4JC9CYzAU_5szsE?XngFYUnyNJ;GcO z2f#{p?9mKx9h<6vtS1Cu$88$ouMvRlVI0MU+H4ISV;_(HL<{~D_!Rw(2rZgOWTI)l z#tpu}nlGIWKXVL+!k;=s6OI^KGyw<&9q?ry1sO;U@Yi3+jeXHq1hmzTWphlSh`}>| z$sY-)s4rP%Z@h+N;KoUbgUnyD8Yd@f)e1)#&=$P;AhY;;gvyBpnLVmgF9#0zU?5*3 zAN80YT0Hh89Q22_a7lEIbMumJAmdYXvt-g9Tf<*`qYeT9C{`BxJUPd}e@ zc)D)FL1G$8z|_tufV#3p7DN!_C8%I*!Uzi-MusWOtN=73zymI&F-n;%FE`j=T|BW~eqd3|E~ zYWFeehuw!Zr(rfCPBKq%!AaJy$dUDtSWY(o5fJhkd$6v)p$Q=c{fP>b?MF)IGf6%`EEvJxUAGj=r6AbO*kLZu)lP) zePgW%7R|UY9LZEVzyo~bwFu^}{qPNSmPmqOxA2W%C9l^P4HvX5vA&!yKoiZ5iO6mF zYn9fIE}wX4x@y9_bbZg<)XS7ij7*I0A{-+U`w&4x02GRm6o~}RzzB$T1QUGV_@!kTbc>r6 z^$F=)Jx8a1>p4`H-JARF>fID=Scl*XBImGzI2BcnVgC}hEh`mol+kiW=?eXJ2A zC9BU?1UZR`vpu~RXwd*48+e$j1JmXf2f+kAhf3^&C7kHga1b)KluVofNz4vF!MOvP z3u0#7EOQ*e)^dW+pMy-b_z{0uFgHTLe5o^@zLD3*z~vJTTnhiDJyb^l4;)Jk4#3(_ zFC??`*;>YqvwP_8&ZG8-14pghrW?EGrn|al>9@;*Q1cXlQ=IA~kd>99 z9=36)%*xP@4r~Qz<5?ROwMCFfEaABlAraod@KL>rgGyUF$A&Wnck(Iy8`B8`%hSn9 zJ}37rNkc;CB~H<3CI{2eSxEZDP`AaonWqC8yV%k2!#0A;((n0j=!(a%4S~-#8%?%yM??<( zBwM_`gCLD0ZL!f4U#pWipoQM#FE|ADdW3lZ8^Iny4Q=F>y6^`U{q2XaF?JA;K5;T@ z%F5^?>tmV0vHhd-U{?{d+@_5YtXqqG)Ir?l4}UwYN)Fp!ae~d!!Tyr}fw%tj4G@iw zj4`zvN>T_-D_h`V<59QhSr1iV2jpU8SYhn%QiAu+01u6 zBP%)z7Wy7-iGD~>d>?W!3Ua~b{0Yx7;TX#U2iE@R)6mez{Mo#bcXWcF7z`pi3 z3I^5DzjeD~y0?2~y0d%Vba&URw6L*Hy0<<}>q`@CCX9>yNm4$`OHq=MM@a~Y;M&Id zLgNEuMUf`NGyCC+Zrhf$7Xv+ROKW{Nwaf(f?_1qF^3 z3{KDP^qP)%M1X={Iz+(5&^UJ*0s@;!e_!dbk#YcFA8hVKmHBhVgQ3pse#M4#FpBLQ z3&IWv;aYKt?vTdrf}yi|s-ta8bA*$VuLC}m2~7xi3N(aY60v=#3m=Im@sST0Xk$0x z!7?IZOaY85y1|}A8oK&KCfg7P(UHRLo(2dw;w{@g^YEIZ+0n73OW{vlv*QWJ%p?;h zQOt>v_(C>1QkK;^3l@L!pm<4k#s|ZrL~yk)bl;EXeLA+1kWa$II5r|FAr}@mhFN+v zWc~ml@(_Q=8n)4tFOrIA(XV8q7`zD)dN7axrtICJq(D0{Ty%*98~kA_@aDH^VQ*@+ zjgup>!hT*OBsTDoWe&O?i`e8Ot*}?C4W)t19Er_I?(A25R_ltJ(}@~AJbleA=}8;z zNfW#fWofqg3)NR>I`>G|RDGtU#r4T)g?_qvRbxt8skalZt@Wghjh?hluP@-a`vGOh z&9Y#Z&Nej}SFTMHq|ro;Y^Lhr(y3aUo;k2S%^KL4W({sgbNkn&xr6J{0sU*!6mA1} z3}uPr{Bh4==|8#-O-s6`$+k)oDmcgi;(gqb-IEoK(Fl}at%e~3AX7h;Bc5~ z?NGJx!Z%er5Lo;#>lYD}oGCb;>rDt*x9DU6?*J7JebKnu@!4J+BJh-mWIKW{z6m(- z4*|p**(8cj2!eGR9b0l!mq)7TA8nZq?M)gaV09oT4Z+D@bl#AY6NN|-=tQNXkuCUE zT3ckmzL7Y5AD7yF6*i9!qJ790n9qUh4n&708KNutfh)4eOs7Wke2asx5+M=%on1mc zU@cyzA#0jH3DX2Gh(xV8F2-ECr~l&oUMM(T?4a3wgoSz7rla zLCd;iviOq{c0qr&=aH|IFYSyx@h_l!S^kg@KH!=q&8El6Otf+g@g6Ehr?v$Nrq~i$ zR10#E3mu$rp()$p=6H>XGa4PS0xw`OogiV( zSbtA?iW1VP8}HYeN(6*u*#o{-)+VN3_8gr4vvF{`se6uX;V+EE8Oj|Q)619&OpIxh zI{0i_cYxMs<}j{D4>+7Gp{?#Ar!HyrVB z4mg5Kf01)6xPp>1U>@l}hd&3QWQUKac)hHQE(Py9>#=#}6SNh3MSkd@pW34%v4h=% zzZ-;I?9YjWGcfQ$6WbvR=9gV;54B}^81--!$gm_P;WnoYBr(B7au%w9up6?Gh%JwF zpq)`N9IbC_=cgUJYs+uhk;ow$@j+5xrXZdO>=TA)t1lvlnL}0dOOYzpHIlD6iWD88kXlLqp86z?|K4u7B=e5^k{B;F_(fJCmpOv(vGb=CnkG~|>zp4EO<^t=$rYAW@C^mUjW!?HC-_qOqWhMN}u^@;=rbK@`eY~nVTL+r)|1F&FWuo zk#?sq)W28vNBvrBT309m-CmpSt6yC*nD4RhRgFBvlpXwo05%{F5Vj2HsRM*K=4|2Q zET^dr=hI||@%V}YQL7-+ zEpkT#9J;0*y1|!%zJAjmolAcXP~_Fe9Z z7jz@|r8)HID1yOz#pEQso^DlmZ2lA7=e4`}{)DiKjDkWZwyx6DKMX-X_ z2}?)tD+$khu$f?~%ko%9k`DBAp@*A!y)Gs{mbF3j=}30*$Itu}ynTvou_ZprCxj3n{9$;t+m;e65(#37F10pC zX~qAl_f4p(%ep$2u!n(xK_AvsW2y}tqfqp(opIqOHG-AWnK(v>JDfpc>Vsi%RxKT( z^_UYkJ(Nz|_;5N_i@|d=P1@CpT#y!a%}BR4=A`SjuztN>(Yjh!z$jiEBzV!Et^O$N zdrD)ws+MS0AT)=+whi#u2}gm)2ct*lx4FS{5eN0*6`4_ zy`js9C^{o9Quo#uolSdky!D_;$rKvp>>Rwa-;e?F=0sqj2j9XI9fs75MxtK(_P^-s z2lnDZ0%v53^fqREJ5iL*O@|k)G72jEJu1s`fn`j1W_h6MK(vlg@9C6uhTPa z!1RZ$Jn9eucPd7ef-^bMjrXrBsMQ|&MMuP*06~Er{A-&?MXN=vK;Ypun8?)8=s3tS zXJ4C=6NUEd1hqpm#|CkN47?^8pZjDl29ZRO0a%#Ag1x9S-P~Ct;YdID5D$h|pQPi0 zVg9Q3Cqm1f_IU9^1%m(ww6D@=i zeMwuAjQNWmb|Kc`EBqo893nwUHT{tk&HpT|5vff|@bY`kcA=0kbyh`j4f7c_=s3EN z+O_aV+bk^-&+lE9j@Y~+9j*sN57m~n8<97i@&4MRwUmX8X-Yi%r2D$GXs!fwSI>TF zgQE;*V-PyD0s_4-2zwYw`})#{W9{KYEk1@Z!Z{=hiVf+248!WybK!);O8^%>Z228H zcLiX;6Dubn2T^enPLzZMo_2lpjI${GZ12ED)_BB54Tx;n>7XPPZGhL`@D8LJ1p%%0 zsfCp6e)U1dLMV1QGg5S><}nQG;f_c%0U8|41)55L=x;H&p-sZOvtdJ;=^#kt4#siB zkS$4P)lQrlk&jP?!DjAU1TIs8ESKp@P#8kf_RJ$qkVVt9RZlV~{5&-iPU)~Bpg%0d zA2AV~lo10$`9eg~UvwNngKz%G8Q3ByIq)yE(Ny)aOLR=ZAvYaRx?#%_7phQEJ4i;v zAIQtG=s?r_WH0*;mhcyS>E(hSk)4q?TjEDsONOBE1*e4<{DZgjmV?a0HY~^RZ_!`y zhJ!u6)7A+IPVf+Je_wC#6)LvV0nh+~Wchu;N&6Ass<#eB4|quSEI+livtIETOowLw->h`)lG%mSh!M)%geO*y-1hX`K)S8 z@{7=X29|J^TY=>fjU0sI!-s0bh-E`1MhcAthaS|SD;-Bcs$=6yJ`Y`U&^UNFTQmH{ z=o*eXC+lq?2ek*s>o) zKr#T2|Ik}xXtPfVW)UKAAqZgM2|vq%*K}qQyk!C2|B^`C&_6l~$-wJS4*H>hGU2R0 z9FU0-5_F1PgIM?nKJm;SqZaW;fAHl$%L$%Kwwd^moP08|ZUWHOx}a3ii-{99qQy9B z&_UQt_Q7ZR!)M3`iC8lM2;DeK!_`&%(<5cm#HQecJ=i)a!&iUSU!x#sg-=Dp$rK#bX@u+CU>o62>Vv=I z&ikRW`#f|VlS-YU$@*343t&>vDPlJGBTvK%F$O+XLMH@wb`p-{!2cnDwh_CIOTl9Q zkQWAAo{`}F`U`k~1>^&OVGQYTZ0H~o1QEtA#et4;jnt=X{gAGf@u^L~3btwpE`bNM zCPf{84glIkD>}7W^1geTWI<6EY{{-|+NA`f5uA?8bc<|_K^eV;GHRp_U2Gt2yeqj) zOFCua6eIc_x^^&{gKH^;o@Hp-1|urS2rU0$3pt}{Y@DEug9G8EKa5U0_4t5f7nkkJ zl!i3}Me=twQJ>BGsuh88W4*666%0bAi0ixKu04UW-2F0F?RZNwbczWqV#eXOtf zcifR*irA0f(sAWSre0Cls+A6!N3#*PBpKvZvp!C~*d6GiAWd{;=wmDFgk1~|r1mM+ zKUcEvFpqv&`b_f;qri)P^kWWG;87Bahv`1xqpBuog0B9XbTi)J>=rpLop6S4U!lMVaju4 zfunko2li6Cv$uAAHbi*ZFs7}Hvp6QhGQEMWf=62$UqYIu@QD^1k{}aq33~15Kjefa zZT%?^(&f;J`B+exl=w4nCx4pCDGV14$LC z6c21`dho~Z@}+2*IShmleDc~B@KgiSg)hXHSiyEgh51W0(S#nh4Gt_7Fm6V-AzvdG z9h#G&@~3{D5BqChwuAzplSw zwKLq^pOB}QTxT-o1KLz?lErt0vrk+Gw6 zHZfup+h&_WOMTh!!efyfyTxmG{3{*^B;|6)CpdyC0ZD*R^i7bX7zCv_MhiS}C8WI% zGpaK~44bcB5J)B_0N-Px?88qRvx-k~FtA2~p`j;Xn?pN0P9_XXinsQ0ObBcIXcKK6 zfsc_ma9}!|vy;H~nL%3&MNms-G_sR)U=<)lL1*!oRNBB7+61`hHQ9iJjm%Q?)PUYu zj-hvcV?WuOk%mX1qT}R?tk9Pe`Gc-HBWHa);E|IYr+KUbnRO)O$;nEvmOL9+hfW#s z+6CE2H1!?}3uco5;2r5rM^&I21E%OI9sF7q8^zoWk6hT;36QlRTg>44%K8h28tX4w z*wOrv&4B@)_RU|NiH=Ibq81o;b|?TP9q}o<-0!6~S4RtfkC5So9Y{*FDgL3S zHaQokxdf22ssfEd{McD2F9!ZN=xrXGq=wPyte|66;Iv=h=~U>0Vf}$H0tpDkcpW9i zunRGS_Tfn|5qwqz0vSh$5YsV+z>x6ASQHsS^*+;bWH^F}`zut`=#dCc6&}+d9BgNB z3@sHLjSfB&a>juUMeTM_90^KNQ>SA-?sFtr=&J%*z+oqnw<-kWQHHiSKV*Q8fwSzU zW}BctN2YfetFN#lFY`OW@#{gI?R_A~-RH&T5B~3$|Abg#BSDc;bc53j_30XTcXXF0JAf zBNQmGANU3VMSs4Zg%FlJ_OCh#ou*8AtrzHu8~a=+mZ}gz5Aio2@h_ux_ZRDE%ZA)J z_CU=>fN6nD^nc7drFewO6PBQB&D;qD%`1&O@EwigQjR`-$p`qYTcG~5FWJ9 z$!)Y3C!&iABd);nkzi2)nmTtXx$=4hW<$sbZ{iwlp%XMSJUrk!jEY*PG_A&yrE4nqPL|+#;}br zqE5<19oj{QrK3{k5tT+O(C3(ug>92@kO3=1jE1gUatAg}4q_pLNlVEhND`ieauT-< zqN4~(ZTgZv{9$GE;XWu0*R-$rBi02&M;3MKg>7RLf-YGfc;PELhu}Ptaa-u%^)-Py zHk&ZO2Mxy=)X+`#SAYg(I-~YN7Zb3o7F&lQzjU)r&`Z2kkF?m;zET?_X=20tKo)%o zDJbotzhI1qZu&4<4&TN}Eog~up0)`pd;)2x&{e^+{}GG|VR0-Tk&Lhn2-r1j%~~tA zH4sfw$R}<_%a9;`M8o~b8mW%>!`2QEfguz0Krl@BLc4)s0mu!i5Jks{=yMWA<~q|X zXCqv-XbfzG*TYSrkVa!xYc{JrC+=L()fOdv{8foPuLP#Kk+n^^I(F@~4U($pu zqKzpOEtZFEX{WQ}QjQ}mqvMl296;K}L!1O6P81JyKnJGvji7_6X<80Bfo2m$u+ z)s~+Uc3|kha`9z3=p?iWH^T-V5@vjLCbtXDYcA54M1`#h9HvI-O`T5?z=pck*&c;Kff6>>wv#mD21LoJ;_m!yuA?p@t2tcPp5*e{V)B5 zi)~_bCI1uq0tj7Y9npjqb)|nWE%6B@tOuunx6fb&e=)Jnl1aOwDBjq<#9y={m*WIn zU=Yr+j{YrjXL&gpSby0nl7(>0N4iQE%cx_hF@1}KfRAMd74r`>`eeYU#?ZE59wi|y zvl-;hANrkRPWJIgSMY9>{Lqg67&^Fr!e6#)(BLzTgtF^#K!la_RUL-4U|@(QIvY98 z65s&ggeJq2UG*P|7(oJ|XofKlFfzZg{(&Lr+)i$0$QOcZ14SK{P91g^P1TikBo-z8 ziw9UF(+3TM5-hH^ZfX`D@_>(VtRrVY;EVn=nhu7FIL6F+?n@p4_9U?8W?00EGP@#n-7L8+b02OUaW z1Z{%U0SiAlQ6|a!72?)U@*oWkCP@L~_|vf&hs|NHx2;1?@*=x@M*@;e_7zMVUxJf7 z*fw-vyodP0B_Xjsqho~PgvOT3^pYIq#UI<_e=LNZC4>;1uN2b|vwTh8C*Ejx3_%O-Y_uPLA_BYsJ*qc?*y(kwPTZD}{zNN%}|FrmV8pdYy}qmQgwl(J}rAuL|=@}mp&l^mcPVn z^gq4r6~6M3PjsRSTAVP#H-w4>^pn+1;|Nmqgq=qL7L+;!BXCt@U~q$2WM6j-+EfT^ z0fnOkiB=A75)S*o6ys~(oy7d(ET$^cj!_7Fn8L-Cwm4hsOoa5Jw49Pr(HdbRbOGBA;>W%_6}&BD=?~V=+ANUC{&3yOP|~7}}9+iJZZs(ZD=NX?I~2 zKbo9+?*&GArpNC2@3?dAms1AV&VT>q#U(A9;+#c1RnLrzNB%ub!b0G0{B@AmO-ke6 z`ImqEcLO@XVO+lOA^r+=`r?;|-nX;FowjU>x`cGYxPh`j>QLaE3m{E$_t3|2?;tTa zLT3CUEuEB6OV$8&w%IUSw$pY2Z0sHsn^v-L+`y9PNSV&ObW|T4d+*3(B8m8uWV#4M z!kD|@gs_C9cb9m{2rQplfxiMN$=A%z$Ae^n@%+ZmX7iBP#jP+Wf+O%HwFmN3yh$-x zMHRMhrv>i~#Mre$q^HQlH@sp9%o2?`{ETy{!V&Dn0cU+*{G*434G=Ks20yOIxm2zk zhGT)DA)fi)u9QsAyq(R(T`2jyhspPjuBd9~K#jm9ANtGhy|GpvEA~zJZurk8e#GRz ziSjsS3kUkXI+XoeP>vfCIh)^cuz_^A*rO}{-HVIoPrsJx&W?$%(CLHI?x&sWCQ)$~ z04w8uTz9^SwbtR|0`9}P$yNL>hKoNxxez@bHc^!?JBsOrgZloUrE42yNJ68i@q}teq?`-Dh+e=Q~jCS9l$!>uySqnn= z906v4xuJ}-K=jIU(-0lG>%JetOheA8>l8%gpBuF;1H$%z6uzuw99L6QK zw8KFs+yJdG(;ZeM_5F>DG2L`Fcxun!@k54Pg)EL?-^*~VuY!Vm-b?gfZADEul6*VL z`mIj!v`H}|lg?ZznJX?G@B!WY@Y|rJBTojTRm4a9&io79@F{Hi{3-}iIFVFbjf2F= z^J?O9l(5Fh?0YA8#kW4T@zbFJvs}~f!-VCg*R62C&EB;R3#^{ybc5@=JevRKPl05P z{nW$ye6FEBgS`%Yu$_N7DF07!oQy}9dzM4Hj$KZ?qTZjh;v)xYDX~nq2&Fft+md(e zOSOEuxsJObgRdOLIiHKo-<5L=O7D&rBb@j*M!rEm-Z=VQqg3RW+k45DiQ(lx6o-qH zYc>k7zdGAx78&^o#PXcT=$wt4;8I%s{i^@z%-Y5O@}@ZeDS+0CjZh@OfEq0);ygZpOP154iIw(&>Aq>`M+ zc1b1)RWYJoVpepKN^D%7%)a$npHkQ(qVWfZUuebGNWaeMZV{t9{=$ zIs*u~B21SJ69Sn*$nbVsxZ5t^;(X4FZyrJRuO zt#+3$a)UpMTxa4ik#;W3<&4xR0GCEOabfpkF!G~crB1BzXZJ9B#*M`(S@n09@O)MQ z8yhsP{yJdl_~3(0`N#PIn1JKsj&L$C4NrD@-uHj<1)jLr61Dgp^`>m=B0|bBpF^W2eEMPyHa2##|0li`s z+*ahI$H1I)3^5Zu0NpMj<<0(>>c6e`Zq{ZSj2pZu1U@h`CqRFD?AK3P&mt0$eE#8F z@nvI4#6)@UHgGVdy}aQckIs|b#6t|ci8{c7IyfGESg?G{{|Q->3h8Wd zVUpYBT{`2+<|Vx17y9Cgmrcsc{qz6$T?!I3L6QCI3_fENdT!M)$ZY*hMgox-t8(p| z;RL%$1lVLu2of2Hn;;MraKPSfEB@syfda0*2=bL~jRx%Pj_5P;X8PW7jkmvQmFO^=9PoWoW5d{xT-c1?o5v3R?% z948}-8-sDP+Isw7Ex!2E|0Xfx``c}9>9OFa` eK3Q(~di)0nZnJ(@Y^T})0000 Date: Sun, 26 Mar 2023 17:31:55 +0200 Subject: [PATCH 08/21] Update docs and rebuild behaviour --- .devcontainer/initialize.sh | 1 + .devcontainer/update.sh | 7 +++---- README.md | 2 +- {docs => doc}/Devcontainer.md | 20 +++++++++++++++++--- {docs => doc}/remote-dev-button.png | Bin 5 files changed, 22 insertions(+), 8 deletions(-) rename {docs => doc}/Devcontainer.md (65%) rename {docs => doc}/remote-dev-button.png (100%) diff --git a/.devcontainer/initialize.sh b/.devcontainer/initialize.sh index 5c74c1c..c817465 100755 --- a/.devcontainer/initialize.sh +++ b/.devcontainer/initialize.sh @@ -11,6 +11,7 @@ then fi if [ -d "app/hitobito" ]; then + echo "Already cloned, skipping…" exit 0 fi diff --git a/.devcontainer/update.sh b/.devcontainer/update.sh index cb91195..55cd4de 100755 --- a/.devcontainer/update.sh +++ b/.devcontainer/update.sh @@ -1,7 +1,7 @@ #!/bin/bash # Set the directory containing git repositories -repositories_dir=app +repositories_dir=. # Loop over the directories in the repositories directory for repository_dir in "$repositories_dir"/*/ @@ -12,9 +12,8 @@ do # Change into the repository directory, discard all local changes, and pull the latest changes cd "$repository_dir" echo "Updating repository: $(basename $repository_dir)" - git reset --hard HEAD - git clean -f -d - git pull + git checkout Gemfile.lock + git pull --ff-only fi done diff --git a/README.md b/README.md index 083e198..92694fb 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ We're glad you want to setup your machine for hitobito development 💃 > For an easy to use quick start solution you can use [devcontainers and codespaces][devcontainers]. -[devcontainers]: docs/Devcontainer.md +[devcontainers]: doc/Devcontainer.md ## System Requirements diff --git a/docs/Devcontainer.md b/doc/Devcontainer.md similarity index 65% rename from docs/Devcontainer.md rename to doc/Devcontainer.md index 33cb052..44e2160 100644 --- a/docs/Devcontainer.md +++ b/doc/Devcontainer.md @@ -4,7 +4,7 @@ This repository has devcontainers available. They are a standard way to run deve This documentation focuses on getting up and running and will not get into details about how devcontainers work. Devcontainers can be run locally or in the cloud with GitHub Codespaces. Each have their advantages and drawbacks. -**Codespaces** are generally instant to start and immediately ready to run. However you need a (somewhat) stable internetconnection to work and they might cost something (for hobby use the free usafe will probably be enough: https://github.com/features/codespaces#pricing). +**Codespaces** are generally instant to start and immediately ready to run. However you need a (somewhat) stable internetconnection to work and they might cost something (for hobby use, the free usage will probably be enough: https://github.com/features/codespaces#pricing). To learn more about codespaces, see [here](https://docs.github.com/en/codespaces). GitHubs documentation is quite thorough. **Locallly** running the devcontainers has the advantage that it's always free and doesn't need an internet connection to work but they need some time to pull all the docker images and ruby gems and to seed the database with initial test data. ## Locally running @@ -24,11 +24,25 @@ _You'll find more detailed requirements [here](https://code.visualstudio.com/doc ## Running on GitHub Codespaces -_TBD_ +In general, see here: https://docs.github.com/en/codespaces/developing-in-codespaces/creating-a-codespace-for-a-repository#creating-a-codespace-for-a-repository + +Some notes for starting a hitobito codespace: + +- Make sure to select "New with options" and then select the desired configuration. Otherwise it launches without any setup and won't be able to run. +- No need to change the branch, as it only changes the branch of the development environment, but not hitobito itself. + +If you want to get familiar with codespaces, check the quickstart guide here: https://docs.github.com/en/codespaces/getting-started/quickstart + ## Rebuilding -_TBD_ +If you change something with the docker setup and/or change the Gemfile, simply rebuild the codespace. In VS Code this can easily be achieved by pressing Shift+Command+P (Mac) or Ctrl+Shift+P and then Entering `Rebuild Container`. + +To also freshly seed your database, type `Full Rebuild Container`. + +With both rebuilds, your changes are kept. To get a totally clean setup, delete your codespace and create a new one. + +If rebuild fails, you probably should update your hitobito repos first… ## A note about committing and pushing diff --git a/docs/remote-dev-button.png b/doc/remote-dev-button.png similarity index 100% rename from docs/remote-dev-button.png rename to doc/remote-dev-button.png From 25bceac8d2aac48574fe60e8a1518c29950626be Mon Sep 17 00:00:00 2001 From: BacLuc Date: Sat, 9 Mar 2024 00:44:15 +0100 Subject: [PATCH 09/21] .devcontainer/update.sh: add github.com to known_hosts Else you need to accept the public key of github.com, which needs interaction. --- .devcontainer/update.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/.devcontainer/update.sh b/.devcontainer/update.sh index fef8612..d9df7b9 100755 --- a/.devcontainer/update.sh +++ b/.devcontainer/update.sh @@ -3,6 +3,7 @@ # Set the directory containing git repositories repositories_dir=. +ssh-keyscan github.com >> /home/$USER/.ssh/known_hosts # Loop over the directories in the repositories directory for repository_dir in "$repositories_dir"/*/ do From 400040fd089b9e611a0fef600543fb6d3ac4861a Mon Sep 17 00:00:00 2001 From: BacLuc Date: Sat, 9 Mar 2024 01:04:28 +0100 Subject: [PATCH 10/21] readd app/* to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 7953cc3..afa86a8 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,5 @@ /dumps docker/home/rails/ /shared/.env.generated +app/* !app/.vscode From 0481ba4699604f38d5f6e1a283d83869f79d2598 Mon Sep 17 00:00:00 2001 From: Nicolas Da Mutten Date: Sat, 9 Mar 2024 03:28:51 +0100 Subject: [PATCH 11/21] WIP: make github host keys static --- .devcontainer/create.sh | 4 ++++ .devcontainer/update.sh | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.devcontainer/create.sh b/.devcontainer/create.sh index 2b06c33..bda00c9 100755 --- a/.devcontainer/create.sh +++ b/.devcontainer/create.sh @@ -2,4 +2,8 @@ sudo gem install debug +echo "github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl +github.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg= +github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk=" >> /home/$USER/.ssh/known_hosts + /usr/local/bin/rails-entrypoint.sh echo "Finished initializing!" diff --git a/.devcontainer/update.sh b/.devcontainer/update.sh index d9df7b9..fef8612 100755 --- a/.devcontainer/update.sh +++ b/.devcontainer/update.sh @@ -3,7 +3,6 @@ # Set the directory containing git repositories repositories_dir=. -ssh-keyscan github.com >> /home/$USER/.ssh/known_hosts # Loop over the directories in the repositories directory for repository_dir in "$repositories_dir"/*/ do From 7c9f653a69baf28f52332168437c32f0489bccf0 Mon Sep 17 00:00:00 2001 From: Nicolas Da Mutten Date: Sat, 9 Mar 2024 18:20:33 +0100 Subject: [PATCH 12/21] fix(compose): replace mysql with mariadb --- docker-compose.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 4c68c38..6b48f72 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -84,8 +84,7 @@ services: - sphinx_indexes:/opt/sphinx/indexes db: - image: mysql:5.7 - platform: linux/amd64 + image: mariadb:10.2 command: - --sort_buffer_size=2M - --character-set-server=utf8mb4 From c3c8d54b1c58ba0f2933d7268ee991404e182801 Mon Sep 17 00:00:00 2001 From: Nicolas Da Mutten Date: Sat, 9 Mar 2024 18:50:25 +0100 Subject: [PATCH 13/21] feat(compose): implement docker healthchecks --- docker-compose.yml | 50 ++++++++++++++++++++++++++++-------- docker/rails-entrypoint.sh | 4 --- docker/rails.dockerfile | 1 - docker/waitfortcp | 9 ------- docker/webpack-entrypoint.sh | 4 --- 5 files changed, 39 insertions(+), 29 deletions(-) delete mode 100755 docker/waitfortcp diff --git a/docker-compose.yml b/docker-compose.yml index 6b48f72..b9df864 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,10 +9,14 @@ services: tty: true stdin_open: true depends_on: - - db - - mailcatcher - - cache - - webpack + db: + condition: service_healthy + mailcatcher: + condition: service_healthy + cache: + condition: service_started + webpack: + condition: service_started env_file: docker/rails.env environment: WEBPACKER_DEV_SERVER_HOST: webpack @@ -28,6 +32,11 @@ services: - ./docker/rails/work_around_docker_fs_bug.rb:/usr/src/app/hitobito/config/initializers/work_around_docker_fs_bug.rb:ro - /etc/timezone:/etc/timezone:ro - /etc/localtime:/etc/localtime:ro + healthcheck: + test: [ "CMD", "curl", "--fail", "http://localhost:3000/healthz" ] + interval: 5s + timeout: 5s + start_period: 30m # `exec` into this to execute the tests of the core rails_test_core: @@ -43,7 +52,8 @@ services: SKIP_SEEDS: 1 SKIP_BUNDLE_INSTALL: 1 depends_on: - - db + db: + condition: service_healthy worker: <<: *rails @@ -54,10 +64,15 @@ services: SKIP_SEEDS: 1 SKIP_BUNDLE_INSTALL: 1 depends_on: - - rails - - db - - mailcatcher - - cache + rails: + condition: service_healthy + db: + condition: service_healthy + mailcatcher: + condition: service_healthy + cache: + condition: service_started + # Dependencies mailcatcher: @@ -67,7 +82,10 @@ services: dockerfile: mailcatcher.dockerfile ports: - "1080:1080" - + healthcheck: + test: [ "CMD", "curl", "--fail", "http://localhost:1080" ] + interval: 5s + timeout: 5s cache: image: memcached:1.6-alpine command: [ memcached, -l, '0.0.0.0', -p, '11211' ] @@ -76,7 +94,10 @@ services: image: macbre/sphinxsearch:3.1.1 command: sphinx-start depends_on: - - db + db: + condition: service_healthy + rails: + condition: service_healthy volumes: - ./docker/sphinx.conf:/opt/sphinx/conf/sphinx.conf:ro - ./docker/sphinx-start:/usr/local/bin/sphinx-start:ro @@ -103,6 +124,10 @@ services: - ./docker/mysql-setup.sql:/docker-entrypoint-initdb.d/mysql-setup.sql:ro - ./docker/test-setup.sql:/docker-entrypoint-initdb.d/test-setup.sql:ro - db:/var/lib/mysql + healthcheck: + test: [ "CMD", "mysqladmin", "ping", "--silent" ] + interval: 5s + timeout: 5s webpack: build: @@ -122,6 +147,9 @@ services: - ./app/:/usr/src/app - hitobito_bundle:/opt/bundle - hitobito_yarn_cache:/home/developer/.cache/yarn + depends_on: + db: + condition: service_healthy volumes: db: diff --git a/docker/rails-entrypoint.sh b/docker/rails-entrypoint.sh index ef5e2b2..10fdf46 100755 --- a/docker/rails-entrypoint.sh +++ b/docker/rails-entrypoint.sh @@ -39,10 +39,6 @@ initialize() { done fi - echo "⚙️ Testing DB connection" - timeout 300s waitfortcp "${RAILS_DB_HOST-db}" "${RAILS_DB_PORT-3306}" - echo "✅ DB server is ready" - if [ -z "$SKIP_RAILS_MIGRATIONS" ]; then echo "⚙️ Performing migrations" bundle exec rails db:migrate wagon:migrate diff --git a/docker/rails.dockerfile b/docker/rails.dockerfile index 7619a31..905ff1b 100644 --- a/docker/rails.dockerfile +++ b/docker/rails.dockerfile @@ -75,7 +75,6 @@ RUN bash -vxc 'gem install cmdparse pastel' COPY ./rails-entrypoint.sh /usr/local/bin COPY ./webpack-entrypoint.sh /usr/local/bin -COPY ./waitfortcp /usr/local/bin RUN mkdir /opt/bundle && chmod 777 /opt/bundle RUN mkdir /seed && chmod 777 /seed diff --git a/docker/waitfortcp b/docker/waitfortcp deleted file mode 100755 index d02a632..0000000 --- a/docker/waitfortcp +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -HOST=$1 -PORT=$2 - -while ! (echo >"/dev/tcp/$HOST/$PORT") &>/dev/null; do - echo "💤 Waiting for $HOST:$PORT to become available." - sleep 1 -done diff --git a/docker/webpack-entrypoint.sh b/docker/webpack-entrypoint.sh index 7addec5..2cac8c1 100755 --- a/docker/webpack-entrypoint.sh +++ b/docker/webpack-entrypoint.sh @@ -17,10 +17,6 @@ done echo "Running yarn install" bundle exec rails webpacker:yarn_install -echo "⚙️ Testing DB connection" -timeout 300s waitfortcp "${RAILS_DB_HOST-db}" "${RAILS_DB_PORT-3306}" -echo "✅ DB server is ready" - echo "➡️ Handing control over to '$*''" echo "⚙️ Executing: $@" From d68f5bc84e704629237f76af1e37d55b30ca068d Mon Sep 17 00:00:00 2001 From: Nicolas Da Mutten Date: Sat, 9 Mar 2024 18:50:38 +0100 Subject: [PATCH 14/21] fix(compose): mount less into home directory --- docker-compose.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index b9df864..d06c0dd 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -27,7 +27,10 @@ services: - ./app/:/usr/src/app - hitobito_bundle:/opt/bundle - seed:/seed - - ./docker/home/rails:/home/developer + - ./docker/home/rails/.gnupg:/home/developer/.gnupg + - ./docker/home/rails/.ssh:/home/developer/.ssh + - ./docker/home/rails/.bashrc:/home/developer/.bashrc + - ./docker/home/rails/.pryrc:/home/developer/.pryrc - /tmp/.X11-unix:/tmp/.X11-unix - ./docker/rails/work_around_docker_fs_bug.rb:/usr/src/app/hitobito/config/initializers/work_around_docker_fs_bug.rb:ro - /etc/timezone:/etc/timezone:ro From 8898b2eb27ed9101b4560a78041d140a72c9eff1 Mon Sep 17 00:00:00 2001 From: Nicolas Da Mutten Date: Sat, 9 Mar 2024 19:31:56 +0100 Subject: [PATCH 15/21] fix: make devcontainer work with healthchecks --- .devcontainer/create.sh | 2 ++ .devcontainer/docker-compose.yml | 19 ++++++++++++++++++- .devcontainer/initialize.sh | 2 ++ .devcontainer/update.sh | 2 ++ 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/.devcontainer/create.sh b/.devcontainer/create.sh index bda00c9..73235e9 100755 --- a/.devcontainer/create.sh +++ b/.devcontainer/create.sh @@ -1,5 +1,7 @@ #!/bin/bash +# This script will be run _inside_ the container everytime you create a devontainer. This happens after the initialize.sh script. + sudo gem install debug echo "github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml index 3e4d1af..40d4236 100644 --- a/.devcontainer/docker-compose.yml +++ b/.devcontainer/docker-compose.yml @@ -7,4 +7,21 @@ services: # Skip entrypoint which would try to migrate on entry entrypoint: [] # Overrides default command so things don't shut down after the process ends. - command: /bin/bash -c "while sleep 1000; do :; done" \ No newline at end of file + command: sleep infinity + healthcheck: {} + worker: + depends_on: + rails: + condition: service_started + db: + condition: service_healthy + mailcatcher: + condition: service_healthy + cache: + condition: service_started + sphinx: + depends_on: + db: + condition: service_healthy + rails: + condition: service_started \ No newline at end of file diff --git a/.devcontainer/initialize.sh b/.devcontainer/initialize.sh index c817465..a6e132e 100755 --- a/.devcontainer/initialize.sh +++ b/.devcontainer/initialize.sh @@ -1,5 +1,7 @@ #!/bin/bash +# This script will be run _outside_ the container everytime you create a devcontainer (locally or in the cloud) + docker volume create hitobito_bundle docker volume create hitobito_yarn_cache diff --git a/.devcontainer/update.sh b/.devcontainer/update.sh index fef8612..a15cee0 100755 --- a/.devcontainer/update.sh +++ b/.devcontainer/update.sh @@ -1,5 +1,7 @@ #!/bin/bash +# This scipt will be run _inside_ the container everytime you create a devontainer (or on a schedule in the cloud). This happens after the initialize.sh and after the create.sh script. + # Set the directory containing git repositories repositories_dir=. From 70743ad77ddb3a05cc9c55922802dbfe6d1e80f2 Mon Sep 17 00:00:00 2001 From: Nicolas Da Mutten Date: Sat, 9 Mar 2024 19:34:00 +0100 Subject: [PATCH 16/21] fix(compose): make it work on apple silicon --- docker-compose.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index d06c0dd..31f8e90 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -31,7 +31,8 @@ services: - ./docker/home/rails/.ssh:/home/developer/.ssh - ./docker/home/rails/.bashrc:/home/developer/.bashrc - ./docker/home/rails/.pryrc:/home/developer/.pryrc - - /tmp/.X11-unix:/tmp/.X11-unix + # Capybara can show the browser window on the host if the X11 socket is mounted… however this can brick on some systems (eg. Apple Silicon Macs) + #- /tmp/.X11-unix:/tmp/.X11-unix - ./docker/rails/work_around_docker_fs_bug.rb:/usr/src/app/hitobito/config/initializers/work_around_docker_fs_bug.rb:ro - /etc/timezone:/etc/timezone:ro - /etc/localtime:/etc/localtime:ro From 9f48c96514b2073a1f3cb63845bad8c95302bac4 Mon Sep 17 00:00:00 2001 From: Nicolas Da Mutten Date: Sat, 9 Mar 2024 19:48:03 +0100 Subject: [PATCH 17/21] fix(compose): make services restart When launching a devcontainer locally, the db is not yet ready and some service crash. This makes them restart until the db is ready. --- docker-compose.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index 31f8e90..acacced 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,6 +5,7 @@ services: context: ./docker dockerfile: rails.dockerfile image: ghcr.io/hitobito/development/rails + restart: unless-stopped user: "${RAILS_UID:-1000}" tty: true stdin_open: true @@ -80,6 +81,7 @@ services: # Dependencies mailcatcher: + restart: unless-stopped image: ghcr.io/hitobito/development/mailcatcher build: context: ./docker @@ -91,10 +93,12 @@ services: interval: 5s timeout: 5s cache: + restart: unless-stopped image: memcached:1.6-alpine command: [ memcached, -l, '0.0.0.0', -p, '11211' ] sphinx: + restart: unless-stopped image: macbre/sphinxsearch:3.1.1 command: sphinx-start depends_on: @@ -109,6 +113,7 @@ services: - sphinx_indexes:/opt/sphinx/indexes db: + restart: unless-stopped image: mariadb:10.2 command: - --sort_buffer_size=2M @@ -134,6 +139,7 @@ services: timeout: 5s webpack: + restart: unless-stopped build: context: ./docker dockerfile: rails.dockerfile From 20b84db18c31c0a704567b383a8ce485f58235b0 Mon Sep 17 00:00:00 2001 From: Nicolas Da Mutten Date: Sun, 10 Mar 2024 11:53:10 +0100 Subject: [PATCH 18/21] feat: allow docker access from within container --- .devcontainer/docker-compose.yml | 1 + docker-compose.yml | 1 + docker/rails.dockerfile | 13 ++++++++++--- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml index 40d4236..e0797c6 100644 --- a/.devcontainer/docker-compose.yml +++ b/.devcontainer/docker-compose.yml @@ -9,6 +9,7 @@ services: # Overrides default command so things don't shut down after the process ends. command: sleep infinity healthcheck: {} + privileged: true worker: depends_on: rails: diff --git a/docker-compose.yml b/docker-compose.yml index acacced..384b852 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -37,6 +37,7 @@ services: - ./docker/rails/work_around_docker_fs_bug.rb:/usr/src/app/hitobito/config/initializers/work_around_docker_fs_bug.rb:ro - /etc/timezone:/etc/timezone:ro - /etc/localtime:/etc/localtime:ro + - /var/run/docker.sock:/var/run/docker.sock healthcheck: test: [ "CMD", "curl", "--fail", "http://localhost:3000/healthz" ] interval: 5s diff --git a/docker/rails.dockerfile b/docker/rails.dockerfile index 905ff1b..6dc8fd6 100644 --- a/docker/rails.dockerfile +++ b/docker/rails.dockerfile @@ -14,7 +14,7 @@ ARG TRANSIFEX_VERSION="1.6.4" # Packages ARG BUILD_PACKAGES="nodejs git sqlite3 libsqlite3-dev imagemagick build-essential default-libmysqlclient-dev" -ARG DEV_PACKAGES="direnv xvfb chromium chromium-driver default-mysql-client pv vim curl less sudo" +ARG DEV_PACKAGES="direnv xvfb chromium chromium-driver default-mysql-client pv vim curl less sudo docker-ce-cli" ################################# # Build Stage # @@ -36,13 +36,20 @@ WORKDIR /usr/src/app/hitobito ARG NODEJS_VERSION RUN export DEBIAN_FRONTEND=noninteractive \ && apt-get update \ - && apt-get install -y ca-certificates curl gnupg \ + && apt-get install -y ca-certificates curl gnupg lsb-release \ && mkdir -p /etc/apt/keyrings \ && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \ && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_${NODEJS_VERSION}.x nodistro main" > /etc/apt/sources.list.d/nodesource.list \ && echo "Package: nodejs" >> /etc/apt/preferences.d/preferences \ && echo "Pin: origin deb.nodesource.com" >> /etc/apt/preferences.d/preferences \ - && echo "Pin-Priority: 1001" >> /etc/apt/preferences.d/preferences + && echo "Pin-Priority: 1001" >> /etc/apt/preferences.d/preferences \ + # Prepare Docker cli install to be able to use it in the devcontainer + && install -m 0755 -d /etc/apt/keyrings \ + && curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc \ + && chmod a+r /etc/apt/keyrings/docker.asc \ + && echo \ + "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \ + $(. /etc/os-release && echo "$VERSION_CODENAME") stable" > /etc/apt/sources.list.d/docker.list ARG BUILD_PACKAGES ARG DEV_PACKAGES From 018860acc10384c372268a9db3d13cd521790c01 Mon Sep 17 00:00:00 2001 From: Nicolas Da Mutten Date: Sun, 10 Mar 2024 11:53:39 +0100 Subject: [PATCH 19/21] fix: better setup dev user --- .devcontainer/create.sh | 4 ---- docker/rails.dockerfile | 13 +++++++++++-- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/.devcontainer/create.sh b/.devcontainer/create.sh index 73235e9..211d523 100755 --- a/.devcontainer/create.sh +++ b/.devcontainer/create.sh @@ -4,8 +4,4 @@ sudo gem install debug -echo "github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl -github.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg= -github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk=" >> /home/$USER/.ssh/known_hosts - /usr/local/bin/rails-entrypoint.sh echo "Finished initializing!" diff --git a/docker/rails.dockerfile b/docker/rails.dockerfile index 6dc8fd6..d497b26 100644 --- a/docker/rails.dockerfile +++ b/docker/rails.dockerfile @@ -71,12 +71,22 @@ RUN bash -vxc "gem install bundler -v ${BUNDLER_VERSION}" # Create the user RUN groupadd --gid $USER_GID $USERNAME \ - && useradd --uid $USER_UID --gid $USER_GID -m $USERNAME -s /bin/bash \ + && useradd --uid $USER_UID --gid $USER_GID -m $USERNAME -s /bin/bash -d /home/developer \ # # [Optional] Add sudo support. Omit if you don't need to install software after connecting. && echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \ && chmod 0440 /etc/sudoers.d/$USERNAME +# Preinstall github.com ssh host keys +# This needs to be in /home/developer, since we have a non-standard home directory for the user $USERNAME +RUN mkdir -p /home/developer/.ssh \ + && echo "github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl" >> /home/developer/.ssh/known_hosts \ + && echo "github.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg=" >> /home/developer/.ssh/known_hosts \ + && echo "github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk=" >> /home/developer/.ssh/known_hosts \ + && chmod 600 /home/developer/.ssh/known_hosts \ + && /usr/bin/ssh-keygen -H -f /home/developer/.ssh/known_hosts \ + && chown -R $USERNAME:$USERNAME /home/developer/.ssh + # for release and version-scripts RUN bash -vxc 'gem install cmdparse pastel' @@ -85,7 +95,6 @@ COPY ./webpack-entrypoint.sh /usr/local/bin RUN mkdir /opt/bundle && chmod 777 /opt/bundle RUN mkdir /seed && chmod 777 /seed -RUN mkdir /home/developer && chmod 777 /home/developer USER $USERNAME From d0683aabd17839a168e680eabed0bf7b4699a949 Mon Sep 17 00:00:00 2001 From: Nicolas Da Mutten Date: Mon, 11 Mar 2024 23:39:47 +0100 Subject: [PATCH 20/21] fix(devcotainers): enhance documentation --- .devcontainer/docker-compose.yml | 3 +++ .gitignore | 3 +++ README.md | 1 + doc/Devcontainer.md | 45 +++++++++++++++++++++++++++----- doc/DevcontainerInDepth.md | 44 +++++++++++++++++++++++++++++++ docker-compose.yml | 2 -- docker/rails.dockerfile | 2 -- 7 files changed, 90 insertions(+), 10 deletions(-) create mode 100644 doc/DevcontainerInDepth.md diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml index e0797c6..de3e39c 100644 --- a/.devcontainer/docker-compose.yml +++ b/.devcontainer/docker-compose.yml @@ -8,8 +8,11 @@ services: entrypoint: [] # Overrides default command so things don't shut down after the process ends. command: sleep infinity + # disable healthcheck, we override the command which would not respond! healthcheck: {} + # Allow accessing docker privileged: true + # redefine dependencies, not waiting for the rails container to be healthy. it will never be, since it's missing the healthcheck… worker: depends_on: rails: diff --git a/.gitignore b/.gitignore index afa86a8..9871738 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,9 @@ .yarnrc /dumps docker/home/rails/ +!docker/home/rails/.pryrc +!docker/home/rails/.bashrc +!docker/home/rails/.gitignore /shared/.env.generated app/* !app/.vscode diff --git a/README.md b/README.md index b138c01..4130007 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ We're glad you want to setup your machine for hitobito development 💃 +> [!IMPORTANT] > For an easy to use quick start solution you can use [devcontainers and codespaces][devcontainers]. [devcontainers]: doc/Devcontainer.md diff --git a/doc/Devcontainer.md b/doc/Devcontainer.md index 44e2160..b2b8ea7 100644 --- a/doc/Devcontainer.md +++ b/doc/Devcontainer.md @@ -1,13 +1,16 @@ # Devcontainers & GitHub Codespaces -This repository has devcontainers available. They are a standard way to run development completely isolated. You find more information about them on https://containers.dev. +This repository has devcontainers available. They are a standard way to run development completely isolated. You find more information about them on https://containers.dev. Essentially, it runs your favorite IDE inside a Docker Container. This documentation focuses on getting up and running and will not get into details about how devcontainers work. Devcontainers can be run locally or in the cloud with GitHub Codespaces. Each have their advantages and drawbacks. -**Codespaces** are generally instant to start and immediately ready to run. However you need a (somewhat) stable internetconnection to work and they might cost something (for hobby use, the free usage will probably be enough: https://github.com/features/codespaces#pricing). To learn more about codespaces, see [here](https://docs.github.com/en/codespaces). GitHubs documentation is quite thorough. -**Locallly** running the devcontainers has the advantage that it's always free and doesn't need an internet connection to work but they need some time to pull all the docker images and ruby gems and to seed the database with initial test data. +**Codespaces** are generally instant to start and immediately ready to run. However you need a (somewhat) stable internet connection to work and they might cost something (for hobby use, the free usage will probably be enough: https://github.com/features/codespaces#pricing). To learn more about codespaces, see [here](https://docs.github.com/en/codespaces). GitHubs documentation is quite thorough. +**Locally** running the devcontainers has the advantage that it's always free and doesn't need an internet connection to work but they need some time to pull all the docker images and ruby gems and to seed the database with initial test data. -## Locally running +## Local Setup + +> [!NOTE] +> devcontainers can be used with many IDEs. This guide only presents VS Code, as it's Free. See https://containers.dev/supporting for more. To get started with locally running the devcontainers, you need the following: - [docker](https://docs.docker.com/get-docker/) and the [docker compose plugin](https://docs.docker.com/compose/install/) @@ -22,7 +25,7 @@ _You'll find more detailed requirements [here](https://code.visualstudio.com/doc 3. Select the variant (wagon) you want to run. 4. Grab a coffee! The dev container will start which takes quite some time (depending on your computer this might take over 15min). It will clone the wagons, install all the ruby gems and migrate as well as seed the database. -## Running on GitHub Codespaces +## GitHub Codespaces Setup In general, see here: https://docs.github.com/en/codespaces/developing-in-codespaces/creating-a-codespace-for-a-repository#creating-a-codespace-for-a-repository @@ -33,6 +36,32 @@ Some notes for starting a hitobito codespace: If you want to get familiar with codespaces, check the quickstart guide here: https://docs.github.com/en/codespaces/getting-started/quickstart +> [!WARNING] +> If you run codespaces in the browser, you will have issues with CORS. Either run locally or just change the file `config/initializers/cors.rb` to the following: +> ```ruby +> … +> allow do +> origins do |origin, env| +> Api::CorsCheck.new(ActionDispatch::Request.new(env)).allowed?(origin) +> end +> resource '*', +> … +> ``` + +## Starting hitobito + +To actually run hitobito you can use regular ruby/rails commands in the Terminal: +```sh +rails server -b 0.0.0.0 +``` + +The shell is already in the context of the ruby bundler. + +### Starting in VS Code + +For VS Code or Github Codespaces Users, you can even use the IDE features like setting breakpoints etc. + +To do so, there is a `.vscode/launch.json` file mounted. This allows you to go to the "Run and Debug" tab in the main navigation, select a Task from the dropdown and click the play button. It will launch hitobito or the specs in a separate panel and attach the debugger. ## Rebuilding @@ -48,4 +77,8 @@ If rebuild fails, you probably should update your hitobito repos first… When running the devcontainer locally, you should be able to commit and push as normal even from inside the container (vs code passes through authentication). Please keep in mind though, that the devcontainer clones the core and wagons via http and from the main repositories, so you probably first need to add your fork as a git remote (`git remote add `) -When running in codespaces, it becomes a bit more tricky. I did not yet fully investigate this scenario, you might find some hints [here](https://docs.github.com/en/codespaces/managing-your-codespaces/managing-repository-access-for-your-codespaces) or [here](https://docs.github.com/en/codespaces/prebuilding-your-codespaces/allowing-a-prebuild-to-access-other-repositories). Please open a PR if you have this working and extend this documentation! \ No newline at end of file +When running in codespaces, it becomes a bit more tricky. I did not yet fully investigate this scenario, you might find some hints [here](https://docs.github.com/en/codespaces/managing-your-codespaces/managing-repository-access-for-your-codespaces) or [here](https://docs.github.com/en/codespaces/prebuilding-your-codespaces/allowing-a-prebuild-to-access-other-repositories). Please open a PR if you have this working and extend this documentation! + +## More + +If you want to dive deeper: [check here](DevcontainerInDepth.md) \ No newline at end of file diff --git a/doc/DevcontainerInDepth.md b/doc/DevcontainerInDepth.md new file mode 100644 index 0000000..49c39e6 --- /dev/null +++ b/doc/DevcontainerInDepth.md @@ -0,0 +1,44 @@ +# Devcontainers & GitHub Codespaces in Depth + +## How do devcontainers work? + +Essentially, there is a `devcontainer.json` in the `.devcontainer` folder which defines the devcontainer setup. + +This consist on a high level of the following: +- Define the docker compose file to use. In this repo, we also have a second `.devcontainer/docker-compose.yml`, which overrides some stuff form the main image. +- Define which service to user to run the IDE in +- Specify the workspace folder that gets opened by default inside the container +- Predefine some port mappings. They are supplemental to the docker compose ports… +- Some devcontainer setup commands + 1. initializeCommand: Runs outside of the container, before the container is being started. + 2. onCreateCommand: Runs inside the container after launching it, but before the IDE is available + 3. updateContentCommand: Runs inside the container after the onCreateCommant, but before the IDE is available. This is also rerun by github to update the prebuilt images. +- Some vscode extensions, that will get preinstalled. + +## What to the Scripts do? + +### initialize.sh + +The initialize.sh script is run outside the container, before it is launched. It clones the app repositories given to it as parameters. This is used to allow for all the variant/wagon setups to use almost the same setup. + +### create.sh + +The create.sh script is run inside the container after launching it, but before the IDE is available. It installs the ruby "debug" gem, which is needed for the ruby debugger to work. It then also runs the rails-entrypoint.sh script, which installs the gems, runs the migrations, seeds the database etc. + +### update.sh + +The update.sh script is run inside the container after the onCreateCommant, but before the IDE is available. This is also rerun by github to update the prebuilt images. It tries to pull all the wagon repositories, if they are not modified/fast forward is possible. It the reruns the rails-entrypoint.sh script, but skipping seeding the database and copying the wagonfiles. + +## Prebuilt Github Codespaces +Not gonna go into detail here. But the prebuilt github codespaces are a feature that allows to prebuild the devcontainer images, so that the first time a user opens a codespace, it is already prebuilt and ready to go. This is done by running all the scripts on a schedule and storing the resulting workspace as template. + +## Docker Access + +To access docker inside from the devcontainer: +- we mount the docker socket into the container +- we run the container as privileged +- we install docker-ce-cli inside the container + +This is a security risk for production, but not really a problem for development. + +The docker group is not available inside the container, so you always have to call docker as root, eg using sudo. If we would create it in the container, it's id would be different from the host, which would cause problems with the mounted socket. \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 384b852..893332f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -28,8 +28,6 @@ services: - ./app/:/usr/src/app - hitobito_bundle:/opt/bundle - seed:/seed - - ./docker/home/rails/.gnupg:/home/developer/.gnupg - - ./docker/home/rails/.ssh:/home/developer/.ssh - ./docker/home/rails/.bashrc:/home/developer/.bashrc - ./docker/home/rails/.pryrc:/home/developer/.pryrc # Capybara can show the browser window on the host if the X11 socket is mounted… however this can brick on some systems (eg. Apple Silicon Macs) diff --git a/docker/rails.dockerfile b/docker/rails.dockerfile index d497b26..1db3aea 100644 --- a/docker/rails.dockerfile +++ b/docker/rails.dockerfile @@ -101,7 +101,5 @@ USER $USERNAME ENV HOME=/home/developer ENV NODE_PATH=/usr/lib/nodejs -USER $USERNAME - ENTRYPOINT ["rails-entrypoint.sh"] CMD [ "rails", "server", "-b", "0.0.0.0" ] From b1b6be262f6866d16aa6a6818bc971285df001c5 Mon Sep 17 00:00:00 2001 From: Nicolas Da Mutten Date: Tue, 12 Mar 2024 00:05:27 +0100 Subject: [PATCH 21/21] fix: remove unnecessary docker/home/rails/.gitignore --- docker/home/rails/.gitignore | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 docker/home/rails/.gitignore diff --git a/docker/home/rails/.gitignore b/docker/home/rails/.gitignore deleted file mode 100644 index bd61e3a..0000000 --- a/docker/home/rails/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -/.bundle -/.cache -/.pki -/.webdrivers \ No newline at end of file