Browse Source
* add devcontainers for `server` * run db migrations automatically in dev environment * remove curl * remove trailing comma; causes parsing with `jq` * use existing .env * add initializeCommand * use better search string * restructure common files * chmod +x scripts * remove problematic env config scripts * add mention of var that is needed for devcontainer * remove ref to deleted script * Update .devcontainer/community_dev/devcontainer.json Co-authored-by: Justin Baur <19896123+justindbaur@users.noreply.github.com> * Update .devcontainer/internal_dev/devcontainer.json Co-authored-by: Justin Baur <19896123+justindbaur@users.noreply.github.com> * use dev image for `6.0.416` SDK * revert to manual DB migrations * reuse SQL connection string var --------- Co-authored-by: Justin Baur <19896123+justindbaur@users.noreply.github.com>pull/3415/head
7 changed files with 223 additions and 0 deletions
@ -0,0 +1,32 @@ |
|||||||
|
version: '3' |
||||||
|
|
||||||
|
services: |
||||||
|
bitwarden_server: |
||||||
|
image: mcr.microsoft.com/devcontainers/dotnet:dev-6.0 |
||||||
|
volumes: |
||||||
|
- ../../:/workspace:cached |
||||||
|
# Overrides default command so things don't shut down after the process ends. |
||||||
|
command: sleep infinity |
||||||
|
|
||||||
|
bitwarden_mssql: |
||||||
|
image: mcr.microsoft.com/azure-sql-edge:latest |
||||||
|
restart: unless-stopped |
||||||
|
env_file: |
||||||
|
../../dev/.env |
||||||
|
environment: |
||||||
|
ACCEPT_EULA: "Y" |
||||||
|
MSSQL_PID: Developer |
||||||
|
volumes: |
||||||
|
- edgesql_dev_data:/var/opt/mssql |
||||||
|
- ../../util/Migrator:/mnt/migrator/ |
||||||
|
- ../../dev/helpers/mssql:/mnt/helpers |
||||||
|
- ../../dev/.data/mssql:/mnt/data |
||||||
|
network_mode: service:bitwarden_server |
||||||
|
|
||||||
|
bitwarden_mail: |
||||||
|
image: sj26/mailcatcher:latest |
||||||
|
restart: unless-stopped |
||||||
|
network_mode: service:bitwarden_server |
||||||
|
|
||||||
|
volumes: |
||||||
|
edgesql_dev_data: |
||||||
@ -0,0 +1,14 @@ |
|||||||
|
{ |
||||||
|
"name": "Bitwarden Community Dev", |
||||||
|
"dockerComposeFile": "../../.devcontainer/bitwarden_common/docker-compose.yml", |
||||||
|
"service": "bitwarden_server", |
||||||
|
"workspaceFolder": "/workspace", |
||||||
|
"customizations": { |
||||||
|
"vscode": { |
||||||
|
"settings": {}, |
||||||
|
"features": {}, |
||||||
|
"extensions": ["ms-dotnettools.csdevkit"] |
||||||
|
} |
||||||
|
}, |
||||||
|
"postCreateCommand": "bash .devcontainer/community_dev/postCreateCommand.sh" |
||||||
|
} |
||||||
@ -0,0 +1,63 @@ |
|||||||
|
#!/usr/bin/env bash |
||||||
|
export DEV_DIR=/workspace/dev |
||||||
|
export CONTAINER_CONFIG=/workspace/.devcontainer/community_dev |
||||||
|
git config --global --add safe.directory /workspace |
||||||
|
|
||||||
|
get_installation_id_and_key() { |
||||||
|
pushd ./dev >/dev/null || exit |
||||||
|
echo "Please enter your installation id and key from https://bitwarden.com/host:" |
||||||
|
read -r -p "Installation id: " INSTALLATION_ID |
||||||
|
read -r -p "Installation key: " INSTALLATION_KEY |
||||||
|
jq ".globalSettings.installation.id = \"$INSTALLATION_ID\" | |
||||||
|
.globalSettings.installation.key = \"$INSTALLATION_KEY\"" \ |
||||||
|
secrets.json.example >secrets.json # create/overwrite secrets.json |
||||||
|
popd >/dev/null || exit |
||||||
|
} |
||||||
|
|
||||||
|
configure_other_vars() { |
||||||
|
pushd ./dev >/dev/null || exit |
||||||
|
cp secrets.json .secrets.json.tmp |
||||||
|
# set DB_PASSWORD equal to .services.mssql.environment.MSSQL_SA_PASSWORD, accounting for quotes |
||||||
|
DB_PASSWORD="$(grep -oP 'MSSQL_SA_PASSWORD=["'"'"']?\K[^"'"'"'\s]+' $DEV_DIR/.env)" |
||||||
|
CERT_OUTPUT="$(./create_certificates_linux.sh)" |
||||||
|
#shellcheck disable=SC2086 |
||||||
|
IDENTITY_SERVER_FINGERPRINT="$(echo $CERT_OUTPUT | awk -F 'Identity Server Dev: ' '{match($2, /[[:alnum:]]+/); print substr($2, RSTART, RLENGTH)}')" |
||||||
|
#shellcheck disable=SC2086 |
||||||
|
DATA_PROTECTION_FINGERPRINT="$(echo $CERT_OUTPUT | awk -F 'Data Protection Dev: ' '{match($2, /[[:alnum:]]+/); print substr($2, RSTART, RLENGTH)}')" |
||||||
|
SQL_CONNECTION_STRING="Server=localhost;Database=vault_dev;User Id=SA;Password=$DB_PASSWORD;Encrypt=True;TrustServerCertificate=True" |
||||||
|
echo "Identity Server Dev: $IDENTITY_SERVER_FINGERPRINT" |
||||||
|
echo "Data Protection Dev: $DATA_PROTECTION_FINGERPRINT" |
||||||
|
jq \ |
||||||
|
".globalSettings.sqlServer.connectionString = \"$SQL_CONNECTION_STRING\" | |
||||||
|
.globalSettings.postgreSql.connectionString = \"Host=localhost;Username=postgres;Password=$DB_PASSWORD;Database=vault_dev;Include Error Detail=true\" | |
||||||
|
.globalSettings.mySql.connectionString = \"server=localhost;uid=root;pwd=$DB_PASSWORD;database=vault_dev\" | |
||||||
|
.globalSettings.identityServer.certificateThumbprint = \"$IDENTITY_SERVER_FINGERPRINT\" | |
||||||
|
.globalSettings.dataProtection.certificateThumbprint = \"$DATA_PROTECTION_FINGERPRINT\"" \ |
||||||
|
.secrets.json.tmp >secrets.json |
||||||
|
rm -f .secrets.json.tmp |
||||||
|
popd >/dev/null || exit |
||||||
|
} |
||||||
|
|
||||||
|
one_time_setup() { |
||||||
|
read -r -p \ |
||||||
|
"Would you like to configure your secrets and certificates for the first time? |
||||||
|
WARNING: This will overwrite any existing secrets.json and certificate files. |
||||||
|
Proceed? [y/N] " response |
||||||
|
if [[ "$response" =~ ^([yY][eE][sS]|[yY])+$ ]]; then |
||||||
|
echo "Running one-time setup script..." |
||||||
|
sleep 1 |
||||||
|
get_installation_id_and_key |
||||||
|
configure_other_vars |
||||||
|
pushd ./dev >/dev/null || exit |
||||||
|
pwsh ./setup_secrets.ps1 || true |
||||||
|
popd >/dev/null || exit |
||||||
|
|
||||||
|
echo "Running migrations..." |
||||||
|
sleep 5 # wait for DB container to start |
||||||
|
dotnet run --project ./util/MsSqlMigratorUtility "$SQL_CONNECTION_STRING" |
||||||
|
|
||||||
|
fi |
||||||
|
} |
||||||
|
|
||||||
|
# main |
||||||
|
one_time_setup |
||||||
@ -0,0 +1,16 @@ |
|||||||
|
{ |
||||||
|
"name": "Bitwarden Dev", |
||||||
|
"dockerComposeFile": [ |
||||||
|
"../../.devcontainer/bitwarden_common/docker-compose.yml", |
||||||
|
"../../.devcontainer/internal_dev/docker-compose.override.yml" |
||||||
|
], "service": "bitwarden_server", |
||||||
|
"workspaceFolder": "/workspace", |
||||||
|
"customizations": { |
||||||
|
"vscode": { |
||||||
|
"settings": {}, |
||||||
|
"features": {}, |
||||||
|
"extensions": ["ms-dotnettools.csdevkit"] |
||||||
|
} |
||||||
|
}, |
||||||
|
"postCreateCommand": "bash .devcontainer/internal_dev/postCreateCommand.sh" |
||||||
|
} |
||||||
@ -0,0 +1,9 @@ |
|||||||
|
version: '3' |
||||||
|
|
||||||
|
services: |
||||||
|
bitwarden_storage: |
||||||
|
image: mcr.microsoft.com/azure-storage/azurite:latest |
||||||
|
restart: unless-stopped |
||||||
|
volumes: |
||||||
|
- ../../dev/.data/azurite:/data |
||||||
|
network_mode: service:bitwarden_server |
||||||
@ -0,0 +1,85 @@ |
|||||||
|
#!/usr/bin/env bash |
||||||
|
export DEV_DIR=/workspace/dev |
||||||
|
export CONTAINER_CONFIG=/workspace/.devcontainer/internal_dev |
||||||
|
git config --global --add safe.directory /workspace |
||||||
|
|
||||||
|
get_installation_id_and_key() { |
||||||
|
pushd ./dev >/dev/null || exit |
||||||
|
echo "Please enter your installation id and key from https://bitwarden.com/host:" |
||||||
|
read -r -p "Installation id: " INSTALLATION_ID |
||||||
|
read -r -p "Installation key: " INSTALLATION_KEY |
||||||
|
jq ".globalSettings.installation.id = \"$INSTALLATION_ID\" | |
||||||
|
.globalSettings.installation.key = \"$INSTALLATION_KEY\"" \ |
||||||
|
secrets.json.example >secrets.json # create/overwrite secrets.json |
||||||
|
popd >/dev/null || exit |
||||||
|
} |
||||||
|
|
||||||
|
remove_comments() { |
||||||
|
# jq will not parse files with comments |
||||||
|
file="$1" |
||||||
|
|
||||||
|
if [[ -f "$file" ]]; then |
||||||
|
sed -e '/^\/\//d' -e 's@[[:blank:]]\{1,\}//.*@@' "$file" >"$file.tmp" |
||||||
|
mv "$file.tmp" "$file" |
||||||
|
fi |
||||||
|
} |
||||||
|
|
||||||
|
configure_other_vars() { |
||||||
|
pushd ./dev >/dev/null || exit |
||||||
|
cp secrets.json .secrets.json.tmp |
||||||
|
# set DB_PASSWORD equal to .services.mssql.environment.MSSQL_SA_PASSWORD, accounting for quotes |
||||||
|
DB_PASSWORD="$(grep -oP 'MSSQL_SA_PASSWORD=["'"'"']?\K[^"'"'"'\s]+' $DEV_DIR/.env)" |
||||||
|
CERT_OUTPUT="$(./create_certificates_linux.sh)" |
||||||
|
#shellcheck disable=SC2086 |
||||||
|
IDENTITY_SERVER_FINGERPRINT="$(echo $CERT_OUTPUT | awk -F 'Identity Server Dev: ' '{match($2, /[[:alnum:]]+/); print substr($2, RSTART, RLENGTH)}')" |
||||||
|
#shellcheck disable=SC2086 |
||||||
|
DATA_PROTECTION_FINGERPRINT="$(echo $CERT_OUTPUT | awk -F 'Data Protection Dev: ' '{match($2, /[[:alnum:]]+/); print substr($2, RSTART, RLENGTH)}')" |
||||||
|
SQL_CONNECTION_STRING="Server=localhost;Database=vault_dev;User Id=SA;Password=$DB_PASSWORD;Encrypt=True;TrustServerCertificate=True" |
||||||
|
echo "Identity Server Dev: $IDENTITY_SERVER_FINGERPRINT" |
||||||
|
echo "Data Protection Dev: $DATA_PROTECTION_FINGERPRINT" |
||||||
|
jq \ |
||||||
|
".globalSettings.sqlServer.connectionString = \"$SQL_CONNECTION_STRING\" | |
||||||
|
.globalSettings.postgreSql.connectionString = \"Host=localhost;Username=postgres;Password=$DB_PASSWORD;Database=vault_dev;Include Error Detail=true\" | |
||||||
|
.globalSettings.mySql.connectionString = \"server=localhost;uid=root;pwd=$DB_PASSWORD;database=vault_dev\" | |
||||||
|
.globalSettings.identityServer.certificateThumbprint = \"$IDENTITY_SERVER_FINGERPRINT\" | |
||||||
|
.globalSettings.dataProtection.certificateThumbprint = \"$DATA_PROTECTION_FINGERPRINT\"" \ |
||||||
|
.secrets.json.tmp >secrets.json |
||||||
|
rm .secrets.json.tmp |
||||||
|
popd >/dev/null || exit |
||||||
|
} |
||||||
|
|
||||||
|
one_time_setup() { |
||||||
|
read -r -p \ |
||||||
|
"Would you like to configure your secrets and certificates for the first time? |
||||||
|
WARNING: This will overwrite any existing secrets.json and certificate files. |
||||||
|
Proceed? [y/N] " response |
||||||
|
if [[ "$response" =~ ^([yY][eE][sS]|[yY])+$ ]]; then |
||||||
|
echo "Running one-time setup script..." |
||||||
|
sleep 1 |
||||||
|
read -r -p \ |
||||||
|
"Place the secrets.json and dev.pfx files from our shared Collection in the ./dev directory. |
||||||
|
Press <Enter> to continue." |
||||||
|
remove_comments ./dev/secrets.json |
||||||
|
configure_other_vars |
||||||
|
echo "Installing Az module. This will take ~a minute..." |
||||||
|
pwsh -Command "Install-Module -Name Az -Scope CurrentUser -Repository PSGallery -Force" |
||||||
|
pwsh ./dev/setup_azurite.ps1 |
||||||
|
|
||||||
|
dotnet tool install dotnet-certificate-tool -g >/dev/null |
||||||
|
|
||||||
|
read -r -s -p "Paste the \"Licensing Certificate - Dev\" password: " CERT_PASSWORD |
||||||
|
echo |
||||||
|
pushd ./dev >/dev/null || exit |
||||||
|
certificate-tool add --file ./dev.pfx --password "$CERT_PASSWORD" |
||||||
|
echo "Injecting dotnet secrets..." |
||||||
|
pwsh ./setup_secrets.ps1 || true |
||||||
|
popd >/dev/null || exit |
||||||
|
|
||||||
|
echo "Running migrations..." |
||||||
|
sleep 5 # wait for DB container to start |
||||||
|
dotnet run --project ./util/MsSqlMigratorUtility "$SQL_CONNECTION_STRING" |
||||||
|
fi |
||||||
|
} |
||||||
|
|
||||||
|
# main |
||||||
|
one_time_setup |
||||||
Loading…
Reference in new issue