diff --git a/scripts/add-juxt-community.sh b/scripts/add-juxt-community.sh deleted file mode 100755 index 3906f41..0000000 --- a/scripts/add-juxt-community.sh +++ /dev/null @@ -1,23 +0,0 @@ -#! /bin/sh - -set -eu - -git_base=$(git rev-parse --show-toplevel) -create_community_script=$(cat "$git_base/scripts/run-in-container/create-juxt-community.js") - -docker compose up -d juxtaposition-ui - -printf "Enter the community name you want to create: " -read -r community_name -printf "Enter the community description: " -read -r community_description -printf "Enter the title IDs you want to add (comma separated, no spaces): " -read -r community_title_ids -printf "Enter a path for the community icon: " -read -r community_icon_path -docker compose cp "$community_icon_path" juxtaposition-ui:/tmp/icon -printf "Enter a path for the community banner: " -read -r community_banner_path -docker compose cp "$community_banner_path" juxtaposition-ui:/tmp/banner - -docker compose exec juxtaposition-ui node -e "$create_community_script" "$community_name" "$community_description" "$community_title_ids" diff --git a/scripts/compile-custom-inkay.sh b/scripts/compile-custom-inkay.sh index 5da3dc3..6fabc26 100755 --- a/scripts/compile-custom-inkay.sh +++ b/scripts/compile-custom-inkay.sh @@ -3,18 +3,31 @@ set -eu git_base=$(git rev-parse --show-toplevel) + +if [ ! -f "$git_base/environment/system.local.env" ]; then + echo "Missing environment file system.local.env. Did you run setup-environment.sh?" + exit 1 +fi . "$git_base/environment/system.local.env" +if [ -z "${WIIU_IP+x}" ]; then + echo "Missing environment variable WIIU_IP. Did you specify a Wii U IP address when you ran setup-environment.sh?" + echo "Continuing without automatic FTP upload." +fi + cd "$git_base/repos/Inkay" -# Get the current certificate (requires mitmproxy-pretendo to have been run at -# least once) -mitmproxy_cert=$(docker run -it --rm -v pretendo-network_mitmproxy-pretendo-data:/mnt busybox cat /mnt/mitmproxy-ca-cert.pem) -echo "$mitmproxy_cert" | tee ./data/ca.pem +docker compose up -d mitmproxy-pretendo + +# Get the current certificate +docker compose cp mitmproxy-pretendo:/home/mitmproxy/.mitmproxy/mitmproxy-ca-cert.pem ./data/ca.pem # Set up the Inkay build environment and then build the patches docker build . -t inkay-build docker run -it --rm -v .:/app -w /app inkay-build +echo "Inkay patches built successfully at $(pwd)/Inkay-pretendo.wps" -# Finally, upload the new Inkay patches to the Wii U -ftp -u ftp://user:pass@"$WIIU_IP"/fs/vol/external01/wiiu/environments/aroma/plugins/Inkay-pretendo.wps ./Inkay-pretendo.wps -echo "Reboot your Wii U now to apply the new patches." +# Upload the new Inkay patches to the Wii U +if [ -n "${WIIU_IP+x}" ]; then + ftp -u "ftp://user:pass@$WIIU_IP/fs/vol/external01/wiiu/environments/aroma/plugins/Inkay-pretendo.wps" ./Inkay-pretendo.wps + echo "Reboot your Wii U now to apply the new patches." +fi diff --git a/scripts/create-juxt-community.sh b/scripts/create-juxt-community.sh new file mode 100755 index 0000000..2f61446 --- /dev/null +++ b/scripts/create-juxt-community.sh @@ -0,0 +1,29 @@ +#! /bin/sh + +set -eu + +git_base=$(git rev-parse --show-toplevel) +create_community_script=$(cat "$git_base/scripts/run-in-container/create-juxt-community.js") + +if [ "$#" -lt 3 ]; then + echo "Usage: $0 [icon image path] [banner image path]" + exit 1 +fi + +# Clean up title IDs by removing non-alphanumeric characters, but keep commas +title_ids=$(echo "$3" | tr -dc "a-zA-Z0-9,") + +docker compose up -d juxtaposition-ui + +icon_path= +if [ "$#" -ge 4 ]; then + docker compose cp "$4" juxtaposition-ui:/tmp/icon + icon_path="/tmp/icon" +fi +banner_path= +if [ "$#" -eq 5 ]; then + docker compose cp "$5" juxtaposition-ui:/tmp/banner + banner_path="/tmp/banner" +fi + +docker compose exec juxtaposition-ui node -e "$create_community_script" "$1" "$2" "$title_ids" "$icon_path" "$banner_path" diff --git a/scripts/firstrun-mongodb-container.sh b/scripts/firstrun-mongodb-container.sh index 80751e1..d4b3673 100755 --- a/scripts/firstrun-mongodb-container.sh +++ b/scripts/firstrun-mongodb-container.sh @@ -12,9 +12,9 @@ docker compose up -d mongodb # This needs to be run after it initializes. # https://github.com/docker-library/mongo/issues/339 -while ! docker compose exec mongodb mongosh --eval "db.adminCommand('ping')"; do +while ! docker compose exec mongodb mongosh --eval "db.adminCommand('ping')" >/dev/null 2>&1; do echo "Waiting for mongodb to be ready..." - sleep 1 + sleep 2 done docker compose exec mongodb mongosh --eval "$mongodb_init_script" diff --git a/scripts/make-pnid-dev.sh b/scripts/make-pnid-dev.sh new file mode 100755 index 0000000..3f77a84 --- /dev/null +++ b/scripts/make-pnid-dev.sh @@ -0,0 +1,14 @@ +#! /bin/sh + +set -eu + +git_base=$(git rev-parse --show-toplevel) +update_pnid_access_level_script=$(cat "$git_base/scripts/run-in-container/make-pnid-dev.js") + +if [ "$#" -lt 1 ]; then + echo "Usage: $0 " + exit 1 +fi +echo "Giving developer access to PNID $1..." + +docker compose exec account node -e "$update_pnid_access_level_script" "$1" diff --git a/scripts/run-in-container/create-juxt-community.js b/scripts/run-in-container/create-juxt-community.js index ccee5c4..1258e72 100644 --- a/scripts/run-in-container/create-juxt-community.js +++ b/scripts/run-in-container/create-juxt-community.js @@ -1,4 +1,4 @@ -// This should run in the juxtaposition-ui container +// This should be evaled in the juxtaposition-ui container const mongoose = require("mongoose"); const { COMMUNITY } = require("./src/models/communities"); const fs = require("fs").promises; @@ -12,19 +12,22 @@ const s3 = new S3({ }); async function runAsync() { - await connect(); - - if (process.argv.length !== 4) { - console.log(" "); + if (process.argv.length < 4) { + console.log( + "Usage: [icon image path] [banner image path]" + ); + process.exit(1); } + await connect(); + await createMainCommunity( 1, process.argv[1], process.argv[2], process.argv[3].split(","), - "/tmp/icon", - "/tmp/banner" + process.argv[4], + process.argv[5] ); await mongoose.connection.close(); @@ -86,45 +89,55 @@ async function createMainCommunity( async function uploadAssets(community_id, iconPath, bannerPath) { console.log("Uploading assets for community " + community_id); - const sizes = [32, 64, 128]; - const iconBuffer = await fs.readFile(iconPath); - for (const size of sizes) { - const resizedIconBuffer = await sharp(iconBuffer) - .resize(size, size, { - fit: "cover", - position: "center", - }) - .png({ quality: 80 }) - .toBuffer(); + if (iconPath) { + console.log("Uploading icon from " + iconPath); + const sizes = [32, 64, 128]; + const iconBuffer = await fs.readFile(iconPath); + for (const size of sizes) { + const resizedIconBuffer = await sharp(iconBuffer) + .resize(size, size, { + fit: "cover", + position: "center", + }) + .png({ quality: 80 }) + .toBuffer(); - const uploadParams = { - Bucket: "pn-cdn", - Key: `icons/${community_id}/${size}.png`, - Body: resizedIconBuffer, - ACL: "public-read", - ContentType: "image/png", - }; - await s3.putObject(uploadParams).promise(); + const uploadParams = { + Bucket: "pn-cdn", + Key: `icons/${community_id}/${size}.png`, + Body: resizedIconBuffer, + ACL: "public-read", + ContentType: "image/png", + }; + await s3.putObject(uploadParams).promise(); + } + } else { + console.log("No icon path specified, skipping icon upload."); } - const consoles = ["WiiU", "3DS"]; - const bannerBuffer = await fs.readFile(bannerPath); - for (const console of consoles) { - const resizedBannerBuffer = await sharp(bannerBuffer) - .resize(1280, 180, { - fit: "cover", - position: "center", - }) - .png({ quality: 80 }) - .toBuffer(); + if (bannerPath) { + console.log("Uploading banner from " + bannerPath); + const consoles = ["WiiU", "3DS"]; + const bannerBuffer = await fs.readFile(bannerPath); + for (const console of consoles) { + const resizedBannerBuffer = await sharp(bannerBuffer) + .resize(1280, 180, { + fit: "cover", + position: "center", + }) + .png({ quality: 80 }) + .toBuffer(); - const uploadParams = { - Bucket: "pn-cdn", - Key: `headers/${community_id}/${console}.png`, - Body: resizedBannerBuffer, - ACL: "public-read", - ContentType: "image/png", - }; - await s3.putObject(uploadParams).promise(); + const uploadParams = { + Bucket: "pn-cdn", + Key: `headers/${community_id}/${console}.png`, + Body: resizedBannerBuffer, + ACL: "public-read", + ContentType: "image/png", + }; + await s3.putObject(uploadParams).promise(); + } + } else { + console.log("No banner path specified, skipping banner upload."); } } diff --git a/scripts/run-in-container/update-pnid-access-level-in-database.js b/scripts/run-in-container/make-pnid-dev.js similarity index 56% rename from scripts/run-in-container/update-pnid-access-level-in-database.js rename to scripts/run-in-container/make-pnid-dev.js index 8816922..aceb3f7 100644 --- a/scripts/run-in-container/update-pnid-access-level-in-database.js +++ b/scripts/run-in-container/make-pnid-dev.js @@ -1,22 +1,25 @@ -// This should run in the account container +// This should be evaled in the account container const mongoose = require("mongoose"); const { connect } = require("./dist/database"); const { PNID } = require("./dist/models/pnid"); async function runAsync() { + if (process.argv.length < 2) { + console.log("Usage: "); + process.exit(1); + } + await connect(); - if (process.argv[1]) { - const pnid = await PNID.findOne({ - usernameLower: process.argv[1].toLowerCase(), - }); - if (pnid) { - await updatePnidAccessLevel(pnid, 3, "dev"); - } else { - console.log(`No PNID found for username ${process.argv[1]}.`); - } + const pnid = await PNID.findOne({ + usernameLower: process.argv[1].toLowerCase(), + }); + if (pnid) { + await updatePnidAccessLevel(pnid, 3, "dev"); } else { - console.log("No username given, skipping update."); + console.log(`No PNID found for username ${process.argv[1]}.`); + await mongoose.connection.close(); + process.exit(2); } await mongoose.connection.close(); diff --git a/scripts/run-in-container/postgres-init.sh b/scripts/run-in-container/postgres-init.sh index dbfabec..c4ffb9c 100644 --- a/scripts/run-in-container/postgres-init.sh +++ b/scripts/run-in-container/postgres-init.sh @@ -6,7 +6,5 @@ databases="friends" for database in $databases; do echo "Creating database: $database" - psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL - CREATE DATABASE $database; -EOSQL + psql -v ON_ERROR_STOP=1 -U "$POSTGRES_USER" -c "CREATE DATABASE $database;" done diff --git a/scripts/run-in-container/create-server-in-database.js b/scripts/run-in-container/update-account-servers-database.js similarity index 98% rename from scripts/run-in-container/create-server-in-database.js rename to scripts/run-in-container/update-account-servers-database.js index 2272e6f..fa05592 100644 --- a/scripts/run-in-container/create-server-in-database.js +++ b/scripts/run-in-container/update-account-servers-database.js @@ -1,4 +1,4 @@ -// This should run in the account container +// This should be evaled in the account container const mongoose = require("mongoose"); const { connect } = require("./dist/database"); const { Server } = require("./dist/models/server"); diff --git a/scripts/run-in-container/create-endpoint-in-database.js b/scripts/run-in-container/update-miiverse-endpoints.js similarity index 86% rename from scripts/run-in-container/create-endpoint-in-database.js rename to scripts/run-in-container/update-miiverse-endpoints.js index e290554..29f6c74 100644 --- a/scripts/run-in-container/create-endpoint-in-database.js +++ b/scripts/run-in-container/update-miiverse-endpoints.js @@ -1,4 +1,4 @@ -// This should run in the miiverse-api container +// This should be evaled in the miiverse-api container const mongoose = require("mongoose"); const { connect } = require("./dist/database"); const { Endpoint } = require("./dist/models/endpoint"); @@ -7,6 +7,7 @@ async function runAsync() { await connect(); await resetEndpoints(); + // These are static and always use the same domains await createEndpoint( 0, "dev", @@ -41,10 +42,8 @@ async function createEndpoint( const newEndpoint = new Endpoint({ status: status, server_access_level: server_access_level, - // Unused - topics: true, - // Unused - guest_access: true, + topics: true, // Unused + guest_access: true, // Unused host: host, api_host: api_host, portal_host: portal_host, diff --git a/scripts/setup-environment.sh b/scripts/setup-environment.sh index 7f44aa1..f828af9 100755 --- a/scripts/setup-environment.sh +++ b/scripts/setup-environment.sh @@ -2,25 +2,46 @@ set -eu -# Stop all running containers so the new environment variables can be applied -docker compose down - generate_password() { length=$1 - tr -dc 'a-zA-Z0-9' [Wii U IP address]" + exit 1 +fi +server_ip=$1 +wiiu_ip= +if [ "$#" -ge 2 ]; then + wiiu_ip=$2 +fi + echo "Setting up local environment variables..." git_base=$(git rev-parse --show-toplevel) cd "$git_base/environment" -rm ./*.local.env || true +firstrun=true +if ls ./*.local.env 1>/dev/null 2>&1; then + echo "Local environment files already exist. They will be overwritten if you continue." + printf "Continue? [y/N] " + read -r continue + if [ "$continue" != "Y" ] && [ "$continue" != "y" ]; then + echo "Aborting." + exit 1 + fi + + docker compose down + rm ./*.local.env + firstrun=false +fi # Generate an AES-256-CBC key for account server tokens account_aes_key=$(generate_hex 64) @@ -36,7 +57,7 @@ echo "PN_FRIENDS_ACCOUNT_GRPC_API_KEY=$account_grpc_api_key" >>./friends.local.e echo "PN_MIIVERSE_API_CONFIG_GRPC_ACCOUNT_API_KEY=$account_grpc_api_key" >>./miiverse-api.local.env echo "JUXT_CONFIG_GRPC_ACCOUNT_API_KEY=$account_grpc_api_key" >>./juxtaposition-ui.local.env -# Generate secret key for MinIO +# Generate a secret key for MinIO minio_secret_key=$(generate_password 32) echo "MINIO_ROOT_PASSWORD=$minio_secret_key" >>./minio.local.env echo "PN_ACT_CONFIG_S3_ACCESS_SECRET=$minio_secret_key" >>./account.local.env @@ -52,7 +73,8 @@ postgres_password=$(generate_password 32) echo "POSTGRES_PASSWORD=$postgres_password" >>./postgres.local.env echo "PN_FRIENDS_CONFIG_DATABASE_URI=postgres://postgres_pretendo:$postgres_password@postgres/friends?sslmode=disable" >>./friends.local.env -# Generate a Kerberos password and a gRPC API key for the friends server +# Generate a Kerberos password, a gRPC API key, and an AES key for the friends +# server friends_kerberos_password=$(generate_password 32) echo "PN_FRIENDS_CONFIG_KERBEROS_PASSWORD=$friends_kerberos_password" >>./friends.local.env friends_api_key=$(generate_password 32) @@ -72,23 +94,26 @@ miiverse_aes_key=$(generate_hex 64) echo "PN_MIIVERSE_API_CONFIG_AES_KEY=$miiverse_aes_key" >>./miiverse-api.local.env echo "JUXT_CONFIG_AES_KEY=$miiverse_aes_key" >>./juxtaposition-ui.local.env -# Get the computer IP address -printf "What is your server's IP address? It must be accessible to your consoles: " -read -r server_ip +# Set up the server IP address +echo "Using server IP address $server_ip." echo "SERVER_IP=$server_ip" >>./system.local.env echo "PN_FRIENDS_SECURE_SERVER_HOST=$server_ip" >>./friends.local.env echo "PN_WIIU_CHAT_SECURE_SERVER_LOCATION=$server_ip" >>./wiiu-chat.local.env # Get the Wii U IP address -printf "Enter your Wii U's IP address: " -read -r wiiu_ip -echo "WIIU_IP=$wiiu_ip" >>./system.local.env +if [ -n "$wiiu_ip" ]; then + echo "Using Wii U IP address $wiiu_ip." + echo "WIIU_IP=$wiiu_ip" >>./system.local.env +else + echo "Skipping Wii U IP address." +fi echo "Successfully set up environment." # Some things need to be updated with the new environment variables and secrets -echo "Running necessary scripts..." -"$git_base"/scripts/update-postgres-password.sh -"$git_base"/scripts/update-account-servers-database.sh - -docker compose down +if [ "$firstrun" = false ]; then + echo "Running necessary container update scripts..." + "$git_base"/scripts/update-postgres-password.sh + "$git_base"/scripts/update-account-servers-database.sh + docker compose down +fi diff --git a/scripts/setup-submodule-patches.sh b/scripts/setup-submodule-patches.sh index 5e9f504..1413ec0 100755 --- a/scripts/setup-submodule-patches.sh +++ b/scripts/setup-submodule-patches.sh @@ -18,8 +18,8 @@ for dir in "$git_base/patches/"*; do cd "$git_base/repos/$subdir" for patch in "$git_base/patches/$subdir"/*; do - echo "Applying patch $patch..." - git apply "$patch" -v + echo "Applying patch $subdir/$(basename "$patch")..." + git apply "$patch" git add . num_patches=$((num_patches + 1)) done diff --git a/scripts/update-account-servers-database.sh b/scripts/update-account-servers-database.sh index f68121a..f6a4b8d 100755 --- a/scripts/update-account-servers-database.sh +++ b/scripts/update-account-servers-database.sh @@ -2,19 +2,21 @@ set -eu -null_aes_key="" -for _ in $(seq 1 64); do - null_aes_key="${null_aes_key}0" -done - git_base=$(git rev-parse --show-toplevel) -create_server_script=$(cat "$git_base/scripts/run-in-container/create-server-in-database.js") -update_pnid_access_level_script=$(cat "$git_base/scripts/run-in-container/update-pnid-access-level-in-database.js") -create_endpoint_script=$(cat "$git_base/scripts/run-in-container/create-endpoint-in-database.js") +create_server_script=$(cat "$git_base/scripts/run-in-container/update-account-servers-database.js") -necessary_environment="friends miiverse-api wiiu-chat" +if [ ! -f "$git_base/environment/system.local.env" ]; then + echo "Missing environment file system.local.env. Did you run setup-environment.sh?" + exit 1 +fi . "$git_base/environment/system.local.env" -for environment in $necessary_environment; do + +necessary_environment_files="friends miiverse-api wiiu-chat" +for environment in $necessary_environment_files; do + if [ ! -f "$git_base/environment/$environment.local.env" ]; then + echo "Missing environment file $environment.local.env. Did you run setup-environment.sh?" + exit 1 + fi . "$git_base/environment/$environment.env" . "$git_base/environment/$environment.local.env" done @@ -27,11 +29,3 @@ docker compose exec -e SERVER_IP="$SERVER_IP" \ -e MIIVERSE_AES_KEY="$PN_MIIVERSE_API_CONFIG_AES_KEY" \ -e WIIU_CHAT_PORT="$PN_WIIU_CHAT_AUTHENTICATION_SERVER_PORT" \ account node -e "$create_server_script" - -printf "Enter the PNID you want to give dev access to: " -read -r dev_pnid -docker compose exec account node -e "$update_pnid_access_level_script" "$dev_pnid" - -docker compose up -d miiverse-api - -docker compose exec miiverse-api node -e "$create_endpoint_script" diff --git a/scripts/update-miiverse-endpoints.sh b/scripts/update-miiverse-endpoints.sh new file mode 100755 index 0000000..a37d4ec --- /dev/null +++ b/scripts/update-miiverse-endpoints.sh @@ -0,0 +1,10 @@ +#! /bin/sh + +set -eu + +git_base=$(git rev-parse --show-toplevel) +create_endpoint_script=$(cat "$git_base/scripts/run-in-container/update-miiverse-endpoints.js") + +docker compose up -d miiverse-api + +docker compose exec miiverse-api node -e "$create_endpoint_script" diff --git a/scripts/update-postgres-password.sh b/scripts/update-postgres-password.sh index cde4e19..943e16f 100755 --- a/scripts/update-postgres-password.sh +++ b/scripts/update-postgres-password.sh @@ -3,6 +3,10 @@ set -eu git_base=$(git rev-parse --show-toplevel) +if [ ! -f "$git_base/environment/postgres.local.env" ]; then + echo "Missing environment file postgres.local.env. Did you run setup-environment.sh?" + exit 1 +fi . "$git_base/environment/postgres.env" . "$git_base/environment/postgres.local.env"