diff --git a/db/knex_init_db.js b/db/knex_init_db.js index fbf8d2b9e..c5ea03972 100644 --- a/db/knex_init_db.js +++ b/db/knex_init_db.js @@ -11,7 +11,6 @@ async function createTables() { log.info("mariadb", "Creating basic tables for MariaDB"); const knex = R.knex; - // Up to `patch-add-google-analytics-status-page-tag.sql` for now // TODO: Should check later if it is really the final patch sql file. // docker_host diff --git a/db/knex_migrations/2023-06-30-1348-http-body-encoding.js b/db/knex_migrations/2023-06-30-1348-http-body-encoding.js new file mode 100644 index 000000000..c4cc7d941 --- /dev/null +++ b/db/knex_migrations/2023-06-30-1348-http-body-encoding.js @@ -0,0 +1,22 @@ +// ALTER TABLE monitor ADD http_body_encoding VARCHAR(25); +// UPDATE monitor SET http_body_encoding = 'json' WHERE (type = 'http' or type = 'keyword') AND http_body_encoding IS NULL; +exports.up = function (knex) { + return knex.schema.table("monitor", function (table) { + table.string("http_body_encoding", 25); + }).then(function () { + knex("monitor") + .where(function () { + this.where("type", "http").orWhere("type", "keyword"); + }) + .whereNull("http_body_encoding") + .update({ + http_body_encoding: "json", + }); + }); +}; + +exports.down = function (knex) { + return knex.schema.table("monitor", function (table) { + table.dropColumn("http_body_encoding"); + }); +}; diff --git a/db/knex_migrations/2023-06-30-1354-add-description-monitor.js b/db/knex_migrations/2023-06-30-1354-add-description-monitor.js new file mode 100644 index 000000000..4b291777d --- /dev/null +++ b/db/knex_migrations/2023-06-30-1354-add-description-monitor.js @@ -0,0 +1,12 @@ +// ALTER TABLE monitor ADD description TEXT default null; +exports.up = function (knex) { + return knex.schema.table("monitor", function (table) { + table.text("description").defaultTo(null); + }); +}; + +exports.down = function (knex) { + return knex.schema.table("monitor", function (table) { + table.dropColumn("description"); + }); +}; diff --git a/db/knex_migrations/2023-06-30-1357-api-key-table.js b/db/knex_migrations/2023-06-30-1357-api-key-table.js new file mode 100644 index 000000000..d22721ed5 --- /dev/null +++ b/db/knex_migrations/2023-06-30-1357-api-key-table.js @@ -0,0 +1,30 @@ +/* +CREATE TABLE [api_key] ( + [id] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + [key] VARCHAR(255) NOT NULL, + [name] VARCHAR(255) NOT NULL, + [user_id] INTEGER NOT NULL, + [created_date] DATETIME DEFAULT (DATETIME('now')) NOT NULL, + [active] BOOLEAN DEFAULT 1 NOT NULL, + [expires] DATETIME DEFAULT NULL, + CONSTRAINT FK_user FOREIGN KEY ([user_id]) REFERENCES [user]([id]) ON DELETE CASCADE ON UPDATE CASCADE +); + */ +exports.up = function (knex) { + return knex.schema.createTable("api_key", function (table) { + table.increments("id").primary(); + table.string("key", 255).notNullable(); + table.string("name", 255).notNullable(); + table.integer("user_id").unsigned().notNullable() + .references("id").inTable("user") + .onDelete("CASCADE") + .onUpdate("CASCADE"); + table.dateTime("created_date").defaultTo(knex.fn.now()).notNullable(); + table.boolean("active").defaultTo(1).notNullable(); + table.dateTime("expires").defaultTo(null); + }); +}; + +exports.down = function (knex) { + return knex.schema.dropTable("api_key"); +}; diff --git a/db/knex_migrations/2023-06-30-1400-monitor-tls.js b/db/knex_migrations/2023-06-30-1400-monitor-tls.js new file mode 100644 index 000000000..95d66bab1 --- /dev/null +++ b/db/knex_migrations/2023-06-30-1400-monitor-tls.js @@ -0,0 +1,25 @@ +/* +ALTER TABLE monitor + ADD tls_ca TEXT default null; + +ALTER TABLE monitor + ADD tls_cert TEXT default null; + +ALTER TABLE monitor + ADD tls_key TEXT default null; + */ +exports.up = function (knex) { + return knex.schema.table("monitor", function (table) { + table.text("tls_ca").defaultTo(null); + table.text("tls_cert").defaultTo(null); + table.text("tls_key").defaultTo(null); + }); +}; + +exports.down = function (knex) { + return knex.schema.table("monitor", function (table) { + table.dropColumn("tls_ca"); + table.dropColumn("tls_cert"); + table.dropColumn("tls_key"); + }); +}; diff --git a/db/knex_migrations/2023-06-30-1401-maintenance-cron.js b/db/knex_migrations/2023-06-30-1401-maintenance-cron.js new file mode 100644 index 000000000..51ae7a9b1 --- /dev/null +++ b/db/knex_migrations/2023-06-30-1401-maintenance-cron.js @@ -0,0 +1,25 @@ +/* +-- 999 characters. https://stackoverflow.com/questions/46134830/maximum-length-for-cron-job +DROP TABLE maintenance_timeslot; +ALTER TABLE maintenance ADD cron TEXT; +ALTER TABLE maintenance ADD timezone VARCHAR(255); +ALTER TABLE maintenance ADD duration INTEGER; + */ +exports.up = function (knex) { + return knex.schema + .dropTableIfExists("maintenance_timeslot") + .table("maintenance", function (table) { + table.text("cron"); + table.string("timezone", 255); + table.integer("duration"); + }); +}; + +exports.down = function (knex) { + return knex.schema + .table("maintenance", function (table) { + table.dropColumn("cron"); + table.dropColumn("timezone"); + table.dropColumn("duration"); + }); +}; diff --git a/db/knex_migrations/2023-06-30-1413-add-parent-monitor.js b/db/knex_migrations/2023-06-30-1413-add-parent-monitor.js new file mode 100644 index 000000000..2d417b8ca --- /dev/null +++ b/db/knex_migrations/2023-06-30-1413-add-parent-monitor.js @@ -0,0 +1,18 @@ +/* +ALTER TABLE monitor + ADD parent INTEGER REFERENCES [monitor] ([id]) ON DELETE SET NULL ON UPDATE CASCADE; + */ +exports.up = function (knex) { + return knex.schema.table("monitor", function (table) { + table.integer("parent").unsigned() + .references("id").inTable("monitor") + .onDelete("SET NULL") + .onUpdate("CASCADE"); + }); +}; + +exports.down = function (knex) { + return knex.schema.table("monitor", function (table) { + table.dropColumn("parent"); + }); +}; diff --git a/db/knex_migrations/README.md b/db/knex_migrations/README.md index bcad04681..5789307b0 100644 --- a/db/knex_migrations/README.md +++ b/db/knex_migrations/README.md @@ -21,7 +21,9 @@ exports.down = function(knex) { ## Example -20230211120000_create_users_products.js +YYYY-MM-DD-HHMM-create-users-products.js + +2023-06-30-1348-create-users-products.js ```js exports.up = function(knex) { @@ -44,3 +46,5 @@ exports.down = function(knex) { .dropTable("users"); }; ``` + +https://knexjs.org/guide/migrations.html#transactions-in-migrations diff --git a/docker/debian-base.dockerfile b/docker/debian-base.dockerfile index 003e3f9ea..cde5cd2fe 100644 --- a/docker/debian-base.dockerfile +++ b/docker/debian-base.dockerfile @@ -1,36 +1,33 @@ -# DON'T UPDATE TO node:14-bullseye-slim, see #372. # If the image changed, the second stage image should be changed too -FROM node:18-buster-slim AS base2-slim +FROM node:18-bullseye-slim AS base2-slim ARG TARGETPLATFORM -# Install Curl -# Install Apprise, add sqlite3 cli for debugging in the future, iputils-ping for ping, util-linux for setpriv -# Stupid python3 and python3-pip actually install a lot of useless things into Debian, specify --no-install-recommends to skip them, make the base even smaller than alpine! -RUN apt-get update && \ - apt-get --yes --no-install-recommends install python3 python3-pip python3-cryptography python3-six python3-yaml python3-click python3-markdown python3-requests python3-requests-oauthlib \ +RUN apt update && \ + apt --yes --no-install-recommends install python3 python3-pip python3-cryptography python3-six python3-yaml python3-click python3-markdown python3-requests python3-requests-oauthlib \ sqlite3 iputils-ping util-linux dumb-init git curl ca-certificates && \ pip3 --no-cache-dir install apprise==1.4.0 && \ rm -rf /var/lib/apt/lists/* && \ apt --yes autoremove # Install cloudflared -RUN set -eux && \ - mkdir -p --mode=0755 /usr/share/keyrings && \ - curl --fail --show-error --silent --location --insecure https://pkg.cloudflare.com/cloudflare-main.gpg --output /usr/share/keyrings/cloudflare-main.gpg && \ - echo 'deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared buster main' | tee /etc/apt/sources.list.d/cloudflared.list && \ - apt-get update && \ - apt-get install --yes --no-install-recommends cloudflared && \ +RUN curl https://pkg.cloudflare.com/cloudflare-main.gpg --output /usr/share/keyrings/cloudflare-main.gpg && \ + echo 'deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared bullseye main' | tee /etc/apt/sources.list.d/cloudflared.list && \ + apt update && \ + apt install --yes --no-install-recommends cloudflared && \ cloudflared version && \ rm -rf /var/lib/apt/lists/* && \ apt --yes autoremove +# Full Base Image +# MariaDB, Chromium and fonts +# Not working for armv7, so use the older version (10.5) of MariaDB from the debian repo +# curl -LsS https://r.mariadb.com/downloads/mariadb_repo_setup | bash -s -- --mariadb-server-version="mariadb-11.1" && \ FROM base2-slim AS base2 RUN apt update && \ - apt --yes --no-install-recommends install curl && \ - curl -LsS https://r.mariadb.com/downloads/mariadb_repo_setup | bash -s -- --mariadb-server-version="mariadb-10.11" && \ - apt --yes --no-install-recommends install mariadb-server && \ + apt --yes --no-install-recommends install chromium fonts-indic fonts-noto fonts-noto-cjk mariadb-server && \ apt --yes remove curl && \ rm -rf /var/lib/apt/lists/* && \ - apt --yes autoremove -RUN chown -R node:node /var/lib/mysql + apt --yes autoremove && \ + chown -R node:node /var/lib/mysql + ENV UPTIME_KUMA_ENABLE_EMBEDDED_MARIADB=1 diff --git a/server/database.js b/server/database.js index e362128f9..6c5d71ee2 100644 --- a/server/database.js +++ b/server/database.js @@ -76,7 +76,7 @@ class Database { "patch-api-key-table.sql": true, "patch-monitor-tls.sql": true, "patch-maintenance-cron.sql": true, - "patch-add-parent-monitor.sql": true, + "patch-add-parent-monitor.sql": true, // The last file so far converted to a knex migration file }; /** @@ -305,16 +305,30 @@ class Database { } static async patch() { + // Still need to keep this for old versions of Uptime Kuma if (Database.dbConfig.type === "sqlite") { await this.patchSqlite(); } - // TODO: Using knex migrations + // Using knex migrations // https://knexjs.org/guide/migrations.html // https://gist.github.com/NigelEarle/70db130cc040cc2868555b29a0278261 - await R.knex.migrate.latest({ - directory: Database.knexMigrationsPath, - }); + try { + await R.knex.migrate.latest({ + directory: Database.knexMigrationsPath, + }); + } catch (e) { + log.error("db", "Database migration failed"); + throw e; + } + } + + /** + * + * @returns {Promise} + */ + static async rollbackLatestPatch() { + } /**