From ca4c6b266dd537c9ad36b89fcb9580c1851f4b67 Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Tue, 31 Oct 2023 15:19:29 +0100 Subject: [PATCH] experimental hub.sr.ht support TODO: documentation --- roles/hub.sr.ht/defaults/main.yml | 3 + roles/hub.sr.ht/tasks/config.yml | 39 ++++++++++ roles/hub.sr.ht/tasks/db.yml | 15 ++++ roles/hub.sr.ht/tasks/main.yml | 15 ++++ roles/hub.sr.ht/tasks/nginx.yml | 13 ++++ roles/hub.sr.ht/templates/nginx.conf | 35 +++++++++ roles/hub.sr.ht/templates/schema.psql | 103 ++++++++++++++++++++++++++ run.yml | 4 + 8 files changed, 227 insertions(+) create mode 100644 roles/hub.sr.ht/defaults/main.yml create mode 100644 roles/hub.sr.ht/tasks/config.yml create mode 100644 roles/hub.sr.ht/tasks/db.yml create mode 100644 roles/hub.sr.ht/tasks/main.yml create mode 100644 roles/hub.sr.ht/tasks/nginx.yml create mode 100644 roles/hub.sr.ht/templates/nginx.conf create mode 100644 roles/hub.sr.ht/templates/schema.psql diff --git a/roles/hub.sr.ht/defaults/main.yml b/roles/hub.sr.ht/defaults/main.yml new file mode 100644 index 0000000..0ad3942 --- /dev/null +++ b/roles/hub.sr.ht/defaults/main.yml @@ -0,0 +1,3 @@ +--- +hubsrht_oauth_client_id: "" +hubsrht_oauth_client_secret: "" diff --git a/roles/hub.sr.ht/tasks/config.yml b/roles/hub.sr.ht/tasks/config.yml new file mode 100644 index 0000000..7d89ad8 --- /dev/null +++ b/roles/hub.sr.ht/tasks/config.yml @@ -0,0 +1,39 @@ +--- +- name: Ensure the hub.sr.ht config is injected + ansible.builtin.blockinfile: + path: /etc/sr.ht/config.ini + marker: "#-- {mark} ANSIBLE hub.sr.ht --#" + block: | + [hub.sr.ht] + # + # URL hub.sr.ht is being served at (protocol://domain) + origin={{ srht_protocol }}://hub.{{ srht_domain }} + # + # Address and port to bind the debug server to + debug-host=0.0.0.0 + debug-port=5014 + # + # Configures the SQLAlchemy connection string for the database. + connection-string=postgresql://postgres@127.0.0.1/hubsrht?sslmode=disable + # + # Set to "yes" to automatically run migrations on package upgrade. + migrate-on-upgrade=yes + # + # hub.sr.ht's OAuth client ID and secret for meta.sr.ht + # Register your client at meta.example.org/oauth + oauth-client-id={{ hubsrht_oauth_client_id }} + oauth-client-secret={{ hubsrht_oauth_client_secret }} + register: conf + +- name: Enable & start hub.sr.ht service + ansible.builtin.service: + name: hub.sr.ht + state: restarted + enabled: true + when: conf.changed +- name: Enable & start hub.sr.ht api service + ansible.builtin.service: + name: hub.sr.ht-api + state: restarted + enabled: true + when: conf.changed diff --git a/roles/hub.sr.ht/tasks/db.yml b/roles/hub.sr.ht/tasks/db.yml new file mode 100644 index 0000000..edafb5d --- /dev/null +++ b/roles/hub.sr.ht/tasks/db.yml @@ -0,0 +1,15 @@ +--- +- name: Copy database schema to host + ansible.builtin.template: + src: schema.psql + dest: /tmp/hubsrht.psql + +- name: Create database + community.postgresql.postgresql_db: + name: hubsrht + +- name: Ensure database layout + community.postgresql.postgresql_db: + name: hubsrht + state: restore + target: /tmp/hubsrht.psql diff --git a/roles/hub.sr.ht/tasks/main.yml b/roles/hub.sr.ht/tasks/main.yml new file mode 100644 index 0000000..3ac1dd4 --- /dev/null +++ b/roles/hub.sr.ht/tasks/main.yml @@ -0,0 +1,15 @@ +--- +- name: Install hub.sr.ht packages + community.general.apk: + name: + - hub.sr.ht + state: latest + +- name: Setup Database + ansible.builtin.import_tasks: db.yml + +- name: Setup config & services + ansible.builtin.import_tasks: config.yml + +- name: Setup nginx + ansible.builtin.import_tasks: nginx.yml diff --git a/roles/hub.sr.ht/tasks/nginx.yml b/roles/hub.sr.ht/tasks/nginx.yml new file mode 100644 index 0000000..2c42dde --- /dev/null +++ b/roles/hub.sr.ht/tasks/nginx.yml @@ -0,0 +1,13 @@ +--- +- name: Copy nginx config file + ansible.builtin.template: + src: nginx.conf + dest: /etc/nginx/http.d/hub.sr.ht.conf + register: nginxconf + +- name: Start & enable nginx + ansible.builtin.service: + name: nginx + state: restarted + enabled: true + when: nginxconf.changed diff --git a/roles/hub.sr.ht/templates/nginx.conf b/roles/hub.sr.ht/templates/nginx.conf new file mode 100644 index 0000000..2ad2abb --- /dev/null +++ b/roles/hub.sr.ht/templates/nginx.conf @@ -0,0 +1,35 @@ +server { + include sourcehut.conf; + server_name hub.{{ srht_domain }}; + + location / { + return 302 {{ srht_protocol }}://{{ srht_domain }}$request_uri; + } +} + +server { + include sourcehut.conf; + server_name {{ srht_domain }}; + + location / { + proxy_pass http://127.0.0.1:5014; + include headers.conf; + add_header Content-Security-Policy "default-src 'none'; style-src 'self' 'unsafe-inline'; img-src * data:; script-src 'self'; frame-ancestors 'none'" always; + include web.conf; + } + + location /query { + proxy_pass http://127.0.0.1:5114; + include graphql.conf; + } + + location /static { + root /usr/lib/$python/site-packages/hubsrht; + expires 30d; + } + + # Redirect for legacy.sr.ht + location ~ ^/[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$ { + return 302 {{ srht_protocol }}://l.{{ srht_domain }}$request_uri; + } +} diff --git a/roles/hub.sr.ht/templates/schema.psql b/roles/hub.sr.ht/templates/schema.psql new file mode 100644 index 0000000..90a7437 --- /dev/null +++ b/roles/hub.sr.ht/templates/schema.psql @@ -0,0 +1,103 @@ +CREATE TYPE visibility AS ENUM ( + 'PUBLIC', + 'PRIVATE', + 'UNLISTED' +); + +CREATE TABLE "user" ( + id serial PRIMARY KEY, + created timestamp without time zone NOT NULL, + updated timestamp without time zone NOT NULL, + username character varying(256), + email character varying(256) NOT NULL, + user_type character varying NOT NULL, + url character varying(256), + location character varying(256), + bio character varying(4096), + suspension_notice character varying(4096), + oauth_token character varying(256), + oauth_token_expires timestamp without time zone, + oauth_token_scopes character varying, + oauth_revocation_token character varying(256) +); + +CREATE UNIQUE INDEX ix_user_username ON "user" USING btree (username); + +CREATE TABLE project ( + id serial PRIMARY KEY, + created timestamp without time zone NOT NULL, + updated timestamp without time zone NOT NULL, + owner_id integer NOT NULL REFERENCES "user"(id) ON DELETE CASCADE, + name character varying(128) NOT NULL, + description character varying(512) NOT NULL, + website character varying, + visibility visibility DEFAULT 'UNLISTED'::visibility NOT NULL, + checklist_complete boolean DEFAULT false NOT NULL, + summary_repo_id integer, + tags character varying(16)[] DEFAULT '{}'::character varying[] NOT NULL +); + +CREATE TABLE features ( + id serial PRIMARY KEY, + created timestamp without time zone NOT NULL, + project_id integer NOT NULL REFERENCES project(id) ON DELETE CASCADE, + summary character varying NOT NULL +); + +CREATE TABLE mailing_list ( + id serial PRIMARY KEY, + remote_id integer NOT NULL, + created timestamp without time zone NOT NULL, + updated timestamp without time zone NOT NULL, + project_id integer NOT NULL REFERENCES project(id) ON DELETE CASCADE, + owner_id integer NOT NULL REFERENCES "user"(id) ON DELETE CASCADE, + name character varying(128) NOT NULL, + description character varying, + visibility visibility DEFAULT 'UNLISTED'::visibility NOT NULL +); + +CREATE TABLE source_repo ( + id serial PRIMARY KEY, + remote_id integer NOT NULL, + created timestamp without time zone NOT NULL, + updated timestamp without time zone NOT NULL, + project_id integer NOT NULL REFERENCES project(id) ON DELETE CASCADE, + owner_id integer NOT NULL REFERENCES "user"(id) ON DELETE CASCADE, + name character varying(128) NOT NULL, + description character varying, + repo_type character varying NOT NULL, + visibility visibility DEFAULT 'UNLISTED'::visibility NOT NULL, + CONSTRAINT project_source_repo_unique UNIQUE (project_id, remote_id, repo_type) +); + +ALTER TABLE project + ADD CONSTRAINT project_summary_repo_id_fkey FOREIGN KEY (summary_repo_id) REFERENCES source_repo(id) ON DELETE CASCADE; + +CREATE TABLE tracker ( + id serial PRIMARY KEY, + remote_id integer NOT NULL, + created timestamp without time zone NOT NULL, + updated timestamp without time zone NOT NULL, + project_id integer NOT NULL REFERENCES project(id) ON DELETE CASCADE, + owner_id integer NOT NULL REFERENCES "user"(id) ON DELETE CASCADE, + name character varying(128) NOT NULL, + description character varying, + visibility visibility DEFAULT 'UNLISTED'::visibility NOT NULL +); + +CREATE TABLE event ( + id serial PRIMARY KEY, + created timestamp without time zone NOT NULL, + project_id integer NOT NULL REFERENCES project(id) ON DELETE CASCADE, + user_id integer REFERENCES "user"(id) ON DELETE CASCADE, + event_type character varying NOT NULL, + source_repo_id integer REFERENCES source_repo(id) ON DELETE CASCADE, + mailing_list_id integer REFERENCES mailing_list(id) ON DELETE CASCADE, + tracker_id integer REFERENCES tracker(id) ON DELETE CASCADE, + external_source character varying, + external_summary character varying, + external_details character varying, + external_summary_plain character varying, + external_details_plain character varying, + external_url character varying +); diff --git a/run.yml b/run.yml index 472f624..f11ce56 100644 --- a/run.yml +++ b/run.yml @@ -19,3 +19,7 @@ hosts: all roles: - role: git.sr.ht +- name: Setup hub.sr.ht + hosts: all + roles: + - role: hub.sr.ht -- 2.38.5