From 75c714c341f700161ee859602b9c03b5b6f945dd Mon Sep 17 00:00:00 2001 From: Anastasia Lubennikova Date: Wed, 31 May 2023 15:21:57 +0100 Subject: [PATCH] Add Extension Store chapter for Extension loading RFC --- docs/rfcs/024-extension-loading.md | 92 ++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/docs/rfcs/024-extension-loading.md b/docs/rfcs/024-extension-loading.md index b7aeaeb2d3..ecd584d8e3 100644 --- a/docs/rfcs/024-extension-loading.md +++ b/docs/rfcs/024-extension-loading.md @@ -207,3 +207,95 @@ Cons: The extension store does not have to be S3 directly, but could be a Node-local caching service on top of S3. This would reduce the load on the network for popular extensions. + +## Extension Store implementation + +Extension Store in our case is a private S3 bucket. +Extensions are stored as tarballs in the bucket. The tarball contains the extension's control file and all the files that the extension needs to run. + +We may also store the control file separately from the tarball to speed up the extension loading. + +`s3:///extensions/ext-name/sha-256+1234abcd1234abcd1234abcd1234abcd/bundle.tar` + +where `ext-name` is an extension name and `sha-256+1234abcd1234abcd1234abcd1234abcd` is a hash of a specific extension version tarball. + +To ensure security, there is no direct access to the S3 bucket from compute node. + +Control plane forms a list of extensions available to the compute node +and forms a short-lived [pre-signed URL](https://docs.aws.amazon.com/AmazonS3/latest/userguide/ShareObjectPreSignedURL.html) +for each extension that is available to the compute node. + +so, `compute_ctl` receives spec in the following format + +``` +"extensions": [{ + "meta_format": 1, + "extension_name": "postgis", + "link": "https:///extensions/sha-256+1234abcd1234abcd1234abcd1234abcd/bundle.tar?AWSAccessKeyId=1234abcd1234abcd1234abcd1234abcd&Expires=1234567890&Signature=1234abcd1234abcd1234abcd1234abcd", + ... +}] +``` + +`compute_ctl` then downloads the extension from the link and unpacks it to the right place. + +### How do we handle private extensions? + +Private and public extensions are treated equally from the Extension Store perspective. +The only difference is that the private extensions are not listed in the user UI (managed by control plane). + +### How to add new extension to the Extension Store? + +Since we need to verify that the extension is compatible with the compute node and doesn't contain any malicious code, +we need to review the extension before adding it to the Extension Store. + +I do not expect that we will have a lot of extensions to review, so we can do it manually for now. + +Some admin UI may be added later to automate this process. + +The list of extensions available to a compute node is stored in the console database. + +### How is the list of available extensions managed? + +We need to add new tables to the console database to store the list of available extensions, their versions and access rights. + +something like this: + +``` +CREATE TABLE extensions ( + id SERIAL PRIMARY KEY, + name VARCHAR(255) NOT NULL, + version VARCHAR(255) NOT NULL, + hash VARCHAR(255) NOT NULL, // this is the path to the extension in the Extension Store + supported_postgres_versions integer[] NOT NULL, + is_public BOOLEAN NOT NULL, // public extensions are available to all users + is_shared_preload BOOLEAN NOT NULL, // these extensions require postgres restart + is_preload BOOLEAN NOT NULL, + license VARCHAR(255) NOT NULL, +); + +CREATE TABLE user_extensions ( + user_id INTEGER NOT NULL, + extension_id INTEGER NOT NULL, + FOREIGN KEY (user_id) REFERENCES users (id), + FOREIGN KEY (extension_id) REFERENCES extensions (id) +); +``` + +When new extension is added to the Extension Store, we add a new record to the table and set permissions. + +In UI, user may select the extensions that they want to use with their compute node. + +NOTE: Extensions that require postgres restart will not be available until the next compute restart. +Also, currently user cannot force postgres restart. We should add this feature later. + +For other extensions, we must communicate updates to `compute_ctl` and they will be downloaded in the background. + +### How can user update the extension? + +User can update the extension by selecting the new version of the extension in the UI. + +### Alternatives + +For extensions written on trusted languages we can also adopt +`dbdev` PostgreSQL Package Manager based on `pg_tle` by Supabase. +This will increase the amount supported extensions and decrease the amount of work required to support them.