A roles/hub.sr.ht/defaults/main.yml => roles/hub.sr.ht/defaults/main.yml +3 -0
@@ 0,0 1,3 @@
+---
+hubsrht_oauth_client_id: ""
+hubsrht_oauth_client_secret: ""
A roles/hub.sr.ht/tasks/config.yml => roles/hub.sr.ht/tasks/config.yml +39 -0
@@ 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
A roles/hub.sr.ht/tasks/db.yml => roles/hub.sr.ht/tasks/db.yml +15 -0
@@ 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
A roles/hub.sr.ht/tasks/main.yml => roles/hub.sr.ht/tasks/main.yml +15 -0
@@ 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
A roles/hub.sr.ht/tasks/nginx.yml => roles/hub.sr.ht/tasks/nginx.yml +13 -0
@@ 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
A roles/hub.sr.ht/templates/nginx.conf => roles/hub.sr.ht/templates/nginx.conf +35 -0
@@ 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;
+ }
+}
A roles/hub.sr.ht/templates/schema.psql => roles/hub.sr.ht/templates/schema.psql +103 -0
@@ 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
+);
M run.yml => run.yml +4 -0
@@ 19,3 19,7 @@
hosts: all
roles:
- role: git.sr.ht
+- name: Setup hub.sr.ht
+ hosts: all
+ roles:
+ - role: hub.sr.ht