Compare commits
47 commits
feat-nginx
...
master
Author | SHA1 | Date | |
---|---|---|---|
8f766ae883 | |||
a49b6eda71 | |||
61e1a04a74 | |||
|
2951e6108b | ||
|
5be1af71f1 | ||
|
496a1015bd | ||
97714408bc | |||
845d7b623b | |||
44bb60b819 | |||
6fd98159f8 | |||
|
e9f1c04040 | ||
|
86e6b37baa | ||
|
449f946c1a | ||
|
12326f8b22 | ||
dcf93427a7 | |||
8770086354 | |||
43827923d8 | |||
372fcd6688 | |||
867375673e | |||
|
374cec6eb5 | ||
|
200df429b8 | ||
|
8c75edaec6 | ||
|
e6fafdd9f1 | ||
|
00d1b90538 | ||
43b0226746 | |||
859c947db3 | |||
f580c49a97 | |||
b1d3c3e4a1 | |||
|
9748936a72 | ||
|
3f05a42fa6 | ||
|
09756b6301 | ||
|
7c038bae36 | ||
6aa3c4ffba | |||
|
6377333b84 | ||
a63d251f59 | |||
|
4ac2b04efd | ||
5932a3e96d | |||
fdc7b10a6e | |||
d25a4e9808 | |||
|
15b58dab9f | ||
b0d94f91dc | |||
d40e8642de | |||
5851b686b4 | |||
db9115b90b | |||
b15c72ef30 | |||
cd0589fb2e | |||
58eef6b3fa |
24 changed files with 711 additions and 1818 deletions
|
@ -1,23 +1,19 @@
|
||||||
pipeline:
|
steps:
|
||||||
backend:
|
test:
|
||||||
image: rust
|
image: rust
|
||||||
|
# environment:
|
||||||
|
# - DATABASE_URL=postgres://postgres:password@database:5432/postgres
|
||||||
commands:
|
commands:
|
||||||
- apt update
|
# - make migrate
|
||||||
- apt-get install -y --no-install-recommends nginx sudo
|
|
||||||
- mkdir -p /etc/librepages/nginx/sites-available
|
|
||||||
- mkdir -p /etc/librepages/nginx/sites-enabled/
|
|
||||||
- sed -i "s%include \/etc\/nginx\/sites-enabled%include \/etc\/librepages\/nginx\/sites-enabled%" /etc/nginx/nginx.conf
|
|
||||||
- mkdir /var/www/website/ && echo "Hello Librepages" > /var/www/website/index.html
|
|
||||||
# nginx_le_bind runs this command.
|
|
||||||
# Testing beforehand to ensure it is setup properly
|
|
||||||
- sudo nginx -t
|
|
||||||
- make
|
- make
|
||||||
- make test
|
- make test
|
||||||
- make release
|
- make release
|
||||||
|
|
||||||
publish_bins:
|
publish_bins:
|
||||||
image: rust
|
image: rust
|
||||||
|
when:
|
||||||
|
event: [push, tag, deployment]
|
||||||
|
branch: master
|
||||||
commands:
|
commands:
|
||||||
- apt update
|
- apt update
|
||||||
- apt-get -y --no-install-recommends install gpg tar curl wget
|
- apt-get -y --no-install-recommends install gpg tar curl wget
|
||||||
|
@ -28,7 +24,7 @@ pipeline:
|
||||||
publish:
|
publish:
|
||||||
image: plugins/docker
|
image: plugins/docker
|
||||||
when:
|
when:
|
||||||
event: push
|
event: [push, tag, deployment]
|
||||||
branch: master
|
branch: master
|
||||||
settings:
|
settings:
|
||||||
username: realaravinth
|
username: realaravinth
|
||||||
|
@ -36,3 +32,9 @@ pipeline:
|
||||||
from_secret: DOCKER_TOKEN
|
from_secret: DOCKER_TOKEN
|
||||||
repo: realaravinth/librepages-conductor
|
repo: realaravinth/librepages-conductor
|
||||||
tags: latest
|
tags: latest
|
||||||
|
|
||||||
|
#services:
|
||||||
|
# database:
|
||||||
|
# image: postgres
|
||||||
|
# environment:
|
||||||
|
# - POSTGRES_PASSWORD=password
|
||||||
|
|
663
Cargo.lock
generated
663
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
11
Cargo.toml
11
Cargo.toml
|
@ -12,22 +12,23 @@ build = "build.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix-web = "4"
|
actix-web = "4"
|
||||||
|
actix-web-prom = "0.8.0"
|
||||||
futures-util = { version = "0.3.17", default-features = false, features = ["std"] }
|
futures-util = { version = "0.3.17", default-features = false, features = ["std"] }
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
log = "0.4.17"
|
log = "0.4.17"
|
||||||
pretty_env_logger = "0.4.0"
|
pretty_env_logger = "0.5.0"
|
||||||
serde = { version = "1", features=["derive"]}
|
serde = { version = "1", features=["derive"]}
|
||||||
actix-web-codegen-const-routes = { version = "0.1.0", tag = "0.1.0", git = "https://github.com/realaravinth/actix-web-codegen-const-routes" }
|
actix-web-codegen-const-routes = { version = "0.1.0", tag = "0.1.0", git = "https://github.com/realaravinth/actix-web-codegen-const-routes" }
|
||||||
libconfig = { version = "0.1.0", git = "https://git.batsense.net/librepages/libconfig" }
|
libconfig = { version = "0.1.0", git = "https://git.batsense.net/librepages/libconfig" }
|
||||||
derive_builder = "0.11.2"
|
derive_builder = "0.20.0"
|
||||||
config = "0.13"
|
config = "0.14"
|
||||||
derive_more = "0.99.17"
|
derive_more = "0.99.17"
|
||||||
url = { version = "2.2.2", features = ["serde"]}
|
url = { version = "2.2.2", features = ["serde"]}
|
||||||
serde_json = { version ="1", features = ["raw_value"]}
|
serde_json = { version ="1", features = ["raw_value"]}
|
||||||
clap = { vesrion = "3.2.20", features = ["derive"]}
|
clap = { vesrion = "3.2.20", features = ["derive"]}
|
||||||
actix-web-httpauth = "0.8.0"
|
actix-web-httpauth = "0.8.0"
|
||||||
mime_guess = "2.0.4"
|
mime_guess = "2.0.4"
|
||||||
rust-embed = "6.4.2"
|
rust-embed = "8.0.0"
|
||||||
|
|
||||||
[dependencies.libconductor]
|
[dependencies.libconductor]
|
||||||
path = "./env/libconductor"
|
path = "./env/libconductor"
|
||||||
|
@ -41,4 +42,4 @@ sqlx = { version = "0.6.1", features = [ "runtime-actix-rustls", "postgres", "ti
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
actix-rt = "2.7.0"
|
actix-rt = "2.7.0"
|
||||||
base64 = "0.13.0"
|
base64 = "0.22.0"
|
||||||
|
|
|
@ -19,7 +19,7 @@ RUN cargo --version
|
||||||
#RUN make cache-bust
|
#RUN make cache-bust
|
||||||
RUN cargo build --release
|
RUN cargo build --release
|
||||||
|
|
||||||
FROM debian:bullseye as conductor
|
FROM debian:bookworm as conductor
|
||||||
LABEL org.opencontainers.image.source https://git.batsense.net/librepages/conductor
|
LABEL org.opencontainers.image.source https://git.batsense.net/librepages/conductor
|
||||||
RUN apt-get update && apt-get install -y ca-certificates
|
RUN apt-get update && apt-get install -y ca-certificates
|
||||||
RUN useradd -ms /bin/bash -u 1001 conductor
|
RUN useradd -ms /bin/bash -u 1001 conductor
|
||||||
|
|
|
@ -3,8 +3,7 @@ source_code = "https://git.batsense.net/librepages/conductor"
|
||||||
conductor = "dummy"
|
conductor = "dummy"
|
||||||
|
|
||||||
[creds]
|
[creds]
|
||||||
username = "librepages_api"
|
token="longrandomlygeneratedpassword"
|
||||||
password="longrandomlygeneratedpassword"
|
|
||||||
|
|
||||||
[server]
|
[server]
|
||||||
# Please set a unique value, your mCaptcha instance's security depends on this being
|
# Please set a unique value, your mCaptcha instance's security depends on this being
|
||||||
|
|
24
contrib/librepages-conductor.service
Normal file
24
contrib/librepages-conductor.service
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
[Unit]
|
||||||
|
Description=LibrePages Conductor: Easiest way to deploy websites. Conductor component
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=root
|
||||||
|
ExecStart=/usr/bin/conductor serve
|
||||||
|
Restart=on-failure
|
||||||
|
RestartSec=1
|
||||||
|
SuccessExitStatus=3 4
|
||||||
|
RestartForceExitStatus=3 4
|
||||||
|
SystemCallArchitectures=native
|
||||||
|
MemoryDenyWriteExecute=true
|
||||||
|
NoNewPrivileges=true
|
||||||
|
Environment="RUST_LOG=info"
|
||||||
|
|
||||||
|
[Unit]
|
||||||
|
Wants=network-online.target
|
||||||
|
Wants=network-online.target
|
||||||
|
Requires=postgresql.service
|
||||||
|
After=syslog.target
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
205
env/dummy_conductor/Cargo.lock
generated
vendored
205
env/dummy_conductor/Cargo.lock
generated
vendored
|
@ -3,21 +3,57 @@
|
||||||
version = 3
|
version = 3
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-trait"
|
name = "addr2line"
|
||||||
version = "0.1.57"
|
version = "0.22.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "76464446b8bc32758d7e88ee1a804d9914cd9b1cb264c029899680b0be29826f"
|
checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"gimli",
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "adler"
|
||||||
version = "1.1.0"
|
version = "1.0.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-trait"
|
||||||
|
version = "0.1.80"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.66",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "backtrace"
|
||||||
|
version = "0.3.72"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "17c6a35df3749d2e8bb1b7b21a976d82b15548788d2735b9d82f329268f71a11"
|
||||||
|
dependencies = [
|
||||||
|
"addr2line",
|
||||||
|
"cc",
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"miniz_oxide",
|
||||||
|
"object",
|
||||||
|
"rustc-demangle",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cc"
|
||||||
|
version = "1.0.99"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dummy_conductor"
|
name = "dummy_conductor"
|
||||||
|
@ -30,6 +66,12 @@ dependencies = [
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gimli"
|
||||||
|
version = "0.29.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hermit-abi"
|
name = "hermit-abi"
|
||||||
version = "0.1.19"
|
version = "0.1.19"
|
||||||
|
@ -47,9 +89,9 @@ checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.138"
|
version = "0.2.155"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8"
|
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libconductor"
|
name = "libconductor"
|
||||||
|
@ -69,6 +111,21 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "2.7.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "miniz_oxide"
|
||||||
|
version = "0.7.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae"
|
||||||
|
dependencies = [
|
||||||
|
"adler",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num_cpus"
|
name = "num_cpus"
|
||||||
version = "1.14.0"
|
version = "1.14.0"
|
||||||
|
@ -80,29 +137,44 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project-lite"
|
name = "object"
|
||||||
version = "0.2.9"
|
version = "0.35.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
|
checksum = "b8ec7ab813848ba4522158d5517a6093db1ded27575b070f4177b8d12b41db5e"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pin-project-lite"
|
||||||
|
version = "0.2.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.46"
|
version = "1.0.85"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "94e2ef8dbfc347b10c094890f778ee2e36ca9bb4262e86dc99cd217e35f3470b"
|
checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.21"
|
version = "1.0.36"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
|
checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc-demangle"
|
||||||
|
version = "0.1.24"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ryu"
|
name = "ryu"
|
||||||
version = "1.0.11"
|
version = "1.0.11"
|
||||||
|
@ -111,29 +183,29 @@ checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.145"
|
version = "1.0.203"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "728eb6351430bccb993660dfffc5a72f91ccc1295abaa8ce19b27ebe4f75568b"
|
checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.145"
|
version = "1.0.203"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "81fa1584d3d1bcacd84c277a0dfe21f5b0f6accf4a23d04d4c6d61f1af522b4c"
|
checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn 2.0.66",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.85"
|
version = "1.0.117"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44"
|
checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa",
|
"itoa",
|
||||||
"ryu",
|
"ryu",
|
||||||
|
@ -152,27 +224,37 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "syn"
|
||||||
version = "1.23.0"
|
version = "2.0.66"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "eab6d665857cc6ca78d6e80303a02cea7a7851e85dfbd77cbdc09bd129f1ef46"
|
checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio"
|
||||||
|
version = "1.38.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a"
|
||||||
|
dependencies = [
|
||||||
|
"backtrace",
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"tokio-macros",
|
"tokio-macros",
|
||||||
"windows-sys",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-macros"
|
name = "tokio-macros"
|
||||||
version = "1.8.2"
|
version = "2.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8"
|
checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn 2.0.66",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -180,60 +262,3 @@ name = "unicode-ident"
|
||||||
version = "1.0.4"
|
version = "1.0.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd"
|
checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-sys"
|
|
||||||
version = "0.42.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
|
|
||||||
dependencies = [
|
|
||||||
"windows_aarch64_gnullvm",
|
|
||||||
"windows_aarch64_msvc",
|
|
||||||
"windows_i686_gnu",
|
|
||||||
"windows_i686_msvc",
|
|
||||||
"windows_x86_64_gnu",
|
|
||||||
"windows_x86_64_gnullvm",
|
|
||||||
"windows_x86_64_msvc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_aarch64_gnullvm"
|
|
||||||
version = "0.42.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_aarch64_msvc"
|
|
||||||
version = "0.42.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_i686_gnu"
|
|
||||||
version = "0.42.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_i686_msvc"
|
|
||||||
version = "0.42.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_gnu"
|
|
||||||
version = "0.42.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_gnullvm"
|
|
||||||
version = "0.42.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_msvc"
|
|
||||||
version = "0.42.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5"
|
|
||||||
|
|
28
env/libconductor/Cargo.lock
generated
vendored
28
env/libconductor/Cargo.lock
generated
vendored
|
@ -4,9 +4,9 @@ version = 3
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-trait"
|
name = "async-trait"
|
||||||
version = "0.1.57"
|
version = "0.1.80"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "76464446b8bc32758d7e88ee1a804d9914cd9b1cb264c029899680b0be29826f"
|
checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -39,18 +39,18 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.46"
|
version = "1.0.85"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "94e2ef8dbfc347b10c094890f778ee2e36ca9bb4262e86dc99cd217e35f3470b"
|
checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.21"
|
version = "1.0.36"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
|
checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
@ -63,18 +63,18 @@ checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.145"
|
version = "1.0.203"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "728eb6351430bccb993660dfffc5a72f91ccc1295abaa8ce19b27ebe4f75568b"
|
checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.145"
|
version = "1.0.203"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "81fa1584d3d1bcacd84c277a0dfe21f5b0f6accf4a23d04d4c6d61f1af522b4c"
|
checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -83,9 +83,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.85"
|
version = "1.0.117"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44"
|
checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa",
|
"itoa",
|
||||||
"ryu",
|
"ryu",
|
||||||
|
@ -94,9 +94,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.101"
|
version = "2.0.66"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e90cde112c4b9690b8cbe810cba9ddd8bc1d7472e2cae317b69e9438c1cba7d2"
|
checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
1
env/libconductor/src/event_types.rs
vendored
1
env/libconductor/src/event_types.rs
vendored
|
@ -30,7 +30,6 @@ pub enum EventType {
|
||||||
},
|
},
|
||||||
|
|
||||||
Config {
|
Config {
|
||||||
hostname: String,
|
|
||||||
data: LibConfig,
|
data: LibConfig,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
1
env/nginx_bind_le/.gitignore
vendored
1
env/nginx_bind_le/.gitignore
vendored
|
@ -1 +0,0 @@
|
||||||
target/
|
|
1118
env/nginx_bind_le/Cargo.lock
generated
vendored
1118
env/nginx_bind_le/Cargo.lock
generated
vendored
File diff suppressed because it is too large
Load diff
24
env/nginx_bind_le/Cargo.toml
vendored
24
env/nginx_bind_le/Cargo.toml
vendored
|
@ -1,24 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "nginx_bind_le"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
include = ["/templates"]
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
serde = { version = "1", features=["derive"]}
|
|
||||||
serde_json = { version ="1", features = ["raw_value"]}
|
|
||||||
async-trait = "0.1.57"
|
|
||||||
tokio = { version = "1.23.0", features = ["process", "fs", "io-util"] }
|
|
||||||
tera = "1.17.1"
|
|
||||||
rust-embed = "6.4.2"
|
|
||||||
lazy_static = "1.4.0"
|
|
||||||
libconfig = { version = "0.1.0", git = "https://git.batsense.net/librepages/libconfig" }
|
|
||||||
|
|
||||||
[dependencies.libconductor]
|
|
||||||
path = "../libconductor"
|
|
||||||
|
|
||||||
|
|
||||||
[dev-dependencies]
|
|
||||||
tokio = { version = "1.23.0", features = ["rt-multi-thread", "macros", "rt"] }
|
|
102
env/nginx_bind_le/src/lib.rs
vendored
102
env/nginx_bind_le/src/lib.rs
vendored
|
@ -1,102 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2022 Aravinth Manivannan <realaravinth@batsense.net>
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as
|
|
||||||
* published by the Free Software Foundation, either version 3 of the
|
|
||||||
* License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
use async_trait::async_trait;
|
|
||||||
use tokio::process::Command;
|
|
||||||
|
|
||||||
use libconductor::*;
|
|
||||||
|
|
||||||
mod nginx;
|
|
||||||
mod templates;
|
|
||||||
|
|
||||||
use nginx::Nginx;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
|
||||||
pub struct NginxBindLEConductor;
|
|
||||||
|
|
||||||
const CONDUCTOR_NAME: &str = "NGINX_BIND_LE_CONDUCTOR";
|
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl Conductor for NginxBindLEConductor {
|
|
||||||
async fn process(&self, event: EventType) {
|
|
||||||
match event {
|
|
||||||
EventType::NewSite {
|
|
||||||
hostname,
|
|
||||||
path,
|
|
||||||
branch: _branch,
|
|
||||||
} => {
|
|
||||||
Nginx::new_site(&hostname, &path, None).await.unwrap();
|
|
||||||
}
|
|
||||||
EventType::Config { hostname, data } => {
|
|
||||||
unimplemented!();
|
|
||||||
// Nginx::new_site(&hostname, &path, Some(data)).await.unwrap();
|
|
||||||
}
|
|
||||||
EventType::DeleteSite { hostname } => {
|
|
||||||
Nginx::rm_site(&hostname).await.unwrap();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
fn name(&self) -> &'static str {
|
|
||||||
CONDUCTOR_NAME
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn health(&self) -> bool {
|
|
||||||
nginx::Nginx::env_exists() && nginx::Nginx::status().await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use std::process::Stdio;
|
|
||||||
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[tokio::test]
|
|
||||||
async fn all_good() {
|
|
||||||
const HOSTNAME: &str = "lab.batsense.net";
|
|
||||||
let c = NginxBindLEConductor {};
|
|
||||||
assert_eq!(c.name(), CONDUCTOR_NAME);
|
|
||||||
assert!(c.health().await);
|
|
||||||
if Nginx::site_exists(HOSTNAME) {
|
|
||||||
c.process(EventType::DeleteSite {
|
|
||||||
hostname: HOSTNAME.into(),
|
|
||||||
})
|
|
||||||
.await;
|
|
||||||
}
|
|
||||||
|
|
||||||
c.process(EventType::NewSite {
|
|
||||||
hostname: HOSTNAME.into(),
|
|
||||||
branch: "librepages".into(),
|
|
||||||
path: "/var/www/website/".into(),
|
|
||||||
})
|
|
||||||
.await;
|
|
||||||
|
|
||||||
let out = tokio::process::Command::new("sudo")
|
|
||||||
.arg("nginx")
|
|
||||||
.arg("-T")
|
|
||||||
.stdout(Stdio::piped())
|
|
||||||
.output()
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let expected = format!("server_name {HOSTNAME}");
|
|
||||||
let out = String::from_utf8(out.stdout).unwrap();
|
|
||||||
assert!(out.contains(&expected));
|
|
||||||
c.process(EventType::DeleteSite {
|
|
||||||
hostname: HOSTNAME.into(),
|
|
||||||
})
|
|
||||||
.await;
|
|
||||||
}
|
|
||||||
}
|
|
132
env/nginx_bind_le/src/nginx.rs
vendored
132
env/nginx_bind_le/src/nginx.rs
vendored
|
@ -1,132 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2022 Aravinth Manivannan <realaravinth@batsense.net>
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as
|
|
||||||
* published by the Free Software Foundation, either version 3 of the
|
|
||||||
* License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
use std::cell::RefCell;
|
|
||||||
use std::error::Error;
|
|
||||||
use std::path::{Path, PathBuf};
|
|
||||||
|
|
||||||
use tera::*;
|
|
||||||
use tokio::fs;
|
|
||||||
use tokio::io::AsyncWriteExt;
|
|
||||||
use tokio::process::Command;
|
|
||||||
|
|
||||||
use crate::templates::*;
|
|
||||||
|
|
||||||
pub struct Nginx;
|
|
||||||
|
|
||||||
impl Nginx {
|
|
||||||
pub async fn reload() -> MyResult<()> {
|
|
||||||
Command::new("sudo")
|
|
||||||
.arg("nginx")
|
|
||||||
.arg("-s")
|
|
||||||
.arg("reload")
|
|
||||||
.spawn()?
|
|
||||||
.wait()
|
|
||||||
.await?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
pub async fn status() -> bool {
|
|
||||||
async fn run_async_cmd(cmd: &mut Command) -> bool {
|
|
||||||
if let Ok(mut child) = cmd.spawn() {
|
|
||||||
if let Ok(res) = child.wait().await {
|
|
||||||
return res.success();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
run_async_cmd(Command::new("sudo").arg("nginx").arg("-t")).await
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn new_site(
|
|
||||||
hostname: &str,
|
|
||||||
path: &str,
|
|
||||||
config: Option<libconfig::Config>,
|
|
||||||
) -> MyResult<()> {
|
|
||||||
let config = CreateSite::new(hostname, path, config);
|
|
||||||
let contents = config.render();
|
|
||||||
let staging = Self::get_staging(hostname);
|
|
||||||
let prod = Self::get_prod(hostname);
|
|
||||||
|
|
||||||
let mut file = fs::File::create(&staging).await?;
|
|
||||||
file.write_all(contents.as_bytes()).await?;
|
|
||||||
file.sync_all().await?;
|
|
||||||
fs::symlink(&staging, &prod).await?;
|
|
||||||
Self::reload().await
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_staging(hostname: &str) -> PathBuf {
|
|
||||||
Path::new(NGINX_STAGING_CONFIG_PATH).join(hostname)
|
|
||||||
}
|
|
||||||
fn get_prod(hostname: &str) -> PathBuf {
|
|
||||||
Path::new(NGINX_PRODUCTION_CONFIG_PATH).join(hostname)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn site_exists(hostname: &str) -> bool {
|
|
||||||
Self::get_prod(hostname).exists()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn rm_site(hostname: &str) -> MyResult<()> {
|
|
||||||
let staging = Self::get_staging(hostname);
|
|
||||||
let prod = Self::get_prod(hostname);
|
|
||||||
|
|
||||||
fs::remove_file(&prod).await?;
|
|
||||||
fs::remove_file(&staging).await?;
|
|
||||||
Self::reload().await
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn env_exists() -> bool {
|
|
||||||
let prod = Path::new(NGINX_PRODUCTION_CONFIG_PATH);
|
|
||||||
let staging = Path::new(NGINX_STAGING_CONFIG_PATH);
|
|
||||||
prod.exists() && prod.is_dir() && staging.exists() && staging.is_dir()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct CreateSite {
|
|
||||||
ctx: RefCell<Context>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const CREATE_SITE: TemplateFile = TemplateFile::new("create_site", "nginx/create-site.j2");
|
|
||||||
pub const CREATE_SITE_FRAGMENT: TemplateFile =
|
|
||||||
TemplateFile::new("new_site_frag", "nginx/_new_site.fragement.j2");
|
|
||||||
|
|
||||||
pub const HOSTNAME_KEY: &str = "hostname";
|
|
||||||
pub const DOMAINS_KEY: &str = "domains";
|
|
||||||
pub const PATH_KEY: &str = "path";
|
|
||||||
pub const REDIRECTS_KEY: &str = "redirects";
|
|
||||||
|
|
||||||
pub const NGINX_STAGING_CONFIG_PATH: &str = "/etc/librepages/nginx/sites-available/";
|
|
||||||
pub const NGINX_PRODUCTION_CONFIG_PATH: &str = "/etc/librepages/nginx/sites-enabled/";
|
|
||||||
|
|
||||||
type MyResult<T> = std::result::Result<T, Box<dyn Error>>;
|
|
||||||
|
|
||||||
impl CreateSite {
|
|
||||||
fn new(hostname: &str, path: &str, config: Option<libconfig::Config>) -> Self {
|
|
||||||
let ctx = RefCell::new(context());
|
|
||||||
ctx.borrow_mut().insert(HOSTNAME_KEY, hostname);
|
|
||||||
ctx.borrow_mut().insert(PATH_KEY, path);
|
|
||||||
if let Some(config) = config {
|
|
||||||
ctx.borrow_mut().insert(REDIRECTS_KEY, &config.redirects);
|
|
||||||
ctx.borrow_mut().insert(DOMAINS_KEY, &config.domains);
|
|
||||||
}
|
|
||||||
Self { ctx }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render(&self) -> String {
|
|
||||||
TEMPLATES
|
|
||||||
.render(CREATE_SITE.name, &self.ctx.borrow())
|
|
||||||
.unwrap()
|
|
||||||
}
|
|
||||||
}
|
|
73
env/nginx_bind_le/src/templates.rs
vendored
73
env/nginx_bind_le/src/templates.rs
vendored
|
@ -1,73 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2022 Aravinth Manivannan <realaravinth@batsense.net>
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as
|
|
||||||
* published by the Free Software Foundation, either version 3 of the
|
|
||||||
* License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
use lazy_static::lazy_static;
|
|
||||||
use rust_embed::RustEmbed;
|
|
||||||
use tera::*;
|
|
||||||
|
|
||||||
pub const PAYLOAD_KEY: &str = "payload";
|
|
||||||
|
|
||||||
lazy_static! {
|
|
||||||
pub static ref TEMPLATES: Tera = {
|
|
||||||
let mut tera = Tera::default();
|
|
||||||
|
|
||||||
for template in [crate::nginx::CREATE_SITE, crate::nginx::CREATE_SITE_FRAGMENT].iter() {
|
|
||||||
template.register(&mut tera).expect(template.name);
|
|
||||||
}
|
|
||||||
// tera.autoescape_on(vec![".html", ".sql"]);
|
|
||||||
tera
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(RustEmbed)]
|
|
||||||
#[folder = "templates/"]
|
|
||||||
pub struct Templates;
|
|
||||||
|
|
||||||
impl Templates {
|
|
||||||
pub fn get_template(t: &TemplateFile) -> Option<String> {
|
|
||||||
match Self::get(t.path) {
|
|
||||||
Some(file) => Some(String::from_utf8_lossy(&file.data).into_owned()),
|
|
||||||
None => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn context() -> Context {
|
|
||||||
let mut ctx = Context::new();
|
|
||||||
ctx
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct TemplateFile {
|
|
||||||
pub name: &'static str,
|
|
||||||
pub path: &'static str,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TemplateFile {
|
|
||||||
pub const fn new(name: &'static str, path: &'static str) -> Self {
|
|
||||||
Self { name, path }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn register(&self, t: &mut Tera) -> std::result::Result<(), tera::Error> {
|
|
||||||
t.add_raw_template(self.name, &Templates::get_template(self).expect(self.name))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn register_from_file(&self, t: &mut Tera) -> std::result::Result<(), tera::Error> {
|
|
||||||
use std::path::Path;
|
|
||||||
t.add_template_file(Path::new("templates/").join(self.path), Some(self.name))
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
sudo certbot --nginx -d {{ hostname }}
|
|
|
@ -1,29 +0,0 @@
|
||||||
server {
|
|
||||||
# serve website on port 80
|
|
||||||
listen [::]:80;
|
|
||||||
listen 80;
|
|
||||||
|
|
||||||
# write error logs to file
|
|
||||||
error_log /var/log/nginx/{{ hostname }}.error.log;
|
|
||||||
# write access logs to file
|
|
||||||
access_log /var/log/nginx/{{ hostname }}.access.log;
|
|
||||||
|
|
||||||
# serve only on this domain:
|
|
||||||
server_name {{ hostname }};
|
|
||||||
|
|
||||||
# use files from this directory
|
|
||||||
root {{ path }};
|
|
||||||
|
|
||||||
# remove .html from URL; it is cleaner this way
|
|
||||||
rewrite ^(/.*)\.html(\?.*)?$ $1$2 permanent;
|
|
||||||
|
|
||||||
{% if redirects %}
|
|
||||||
{% for redirect in redirects %}
|
|
||||||
rewrite ^/{{redirect.from}}$ /{{ redirect.to }} redirect;
|
|
||||||
{% endfor %}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
# when a request is received, try the index.html in the directory
|
|
||||||
# or $uri.html
|
|
||||||
try_files $uri/index.html $uri.html $uri/ $uri =404;
|
|
||||||
}
|
|
|
@ -1,7 +0,0 @@
|
||||||
{% include "new_site_frag" %}
|
|
||||||
|
|
||||||
{% if domains %}
|
|
||||||
{% for hostname in domains %}
|
|
||||||
{% include "new_site_frag" %}
|
|
||||||
{% endfor %}
|
|
||||||
{% endif %}
|
|
21
renovate.json
Normal file
21
renovate.json
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||||
|
"extends": [
|
||||||
|
"config:recommended",
|
||||||
|
":dependencyDashboard"
|
||||||
|
],
|
||||||
|
"labels": [
|
||||||
|
"renovate-bot"
|
||||||
|
],
|
||||||
|
"prHourlyLimit": 0,
|
||||||
|
"timezone": "Asia/kolkata",
|
||||||
|
"prCreation": "immediate",
|
||||||
|
"vulnerabilityAlerts": {
|
||||||
|
"enabled": true,
|
||||||
|
"labels": [
|
||||||
|
"renovate-bot",
|
||||||
|
"renovate-security",
|
||||||
|
"security"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -38,6 +38,8 @@ DOCKER_IMG="realaravinth/$NAME:$3"
|
||||||
|
|
||||||
get_bin(){
|
get_bin(){
|
||||||
cp target/release/conductor $TARGET_DIR
|
cp target/release/conductor $TARGET_DIR
|
||||||
|
cp -r config/ $TARGET_DIR
|
||||||
|
cp -r contrib/ $TARGET_DIR
|
||||||
}
|
}
|
||||||
|
|
||||||
copy() {
|
copy() {
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
use actix_web::dev::ServiceRequest;
|
use actix_web::dev::ServiceRequest;
|
||||||
use actix_web::web;
|
use actix_web::web;
|
||||||
use actix_web::Error;
|
use actix_web::Error;
|
||||||
use actix_web_httpauth::extractors::basic::BasicAuth;
|
use actix_web_httpauth::extractors::bearer::BearerAuth;
|
||||||
|
|
||||||
use crate::errors::*;
|
use crate::errors::*;
|
||||||
use crate::AppCtx;
|
use crate::AppCtx;
|
||||||
|
@ -26,14 +26,13 @@ use crate::SETTINGS;
|
||||||
pub mod meta;
|
pub mod meta;
|
||||||
pub mod webhook;
|
pub mod webhook;
|
||||||
|
|
||||||
pub async fn httpauth(
|
pub async fn bearerauth(
|
||||||
req: ServiceRequest,
|
req: ServiceRequest,
|
||||||
credentials: BasicAuth,
|
credentials: BearerAuth,
|
||||||
) -> Result<ServiceRequest, (Error, ServiceRequest)> {
|
) -> Result<ServiceRequest, (Error, ServiceRequest)> {
|
||||||
let _ctx: &AppCtx = req.app_data().unwrap();
|
let _ctx: &AppCtx = req.app_data().unwrap();
|
||||||
let username = credentials.user_id();
|
let token = credentials.token();
|
||||||
let password = credentials.password().unwrap();
|
if SETTINGS.authenticate(token) {
|
||||||
if SETTINGS.authenticate(username, password) {
|
|
||||||
Ok(req)
|
Ok(req)
|
||||||
} else {
|
} else {
|
||||||
let e = Error::from(ServiceError::Unauthorized);
|
let e = Error::from(ServiceError::Unauthorized);
|
||||||
|
|
|
@ -24,7 +24,7 @@ use crate::errors::*;
|
||||||
use crate::AppCtx;
|
use crate::AppCtx;
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
use super::httpauth;
|
use super::bearerauth;
|
||||||
|
|
||||||
pub mod routes {
|
pub mod routes {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -47,7 +47,7 @@ pub fn services(cfg: &mut web::ServiceConfig) {
|
||||||
|
|
||||||
#[actix_web_codegen_const_routes::post(
|
#[actix_web_codegen_const_routes::post(
|
||||||
path = "API_V1_ROUTES.webhook.post_event",
|
path = "API_V1_ROUTES.webhook.post_event",
|
||||||
wrap = "HttpAuthentication::basic(httpauth)"
|
wrap = "HttpAuthentication::bearer(bearerauth)"
|
||||||
)]
|
)]
|
||||||
async fn post_event(ctx: AppCtx, payload: web::Json<EventType>) -> ServiceResult<impl Responder> {
|
async fn post_event(ctx: AppCtx, payload: web::Json<EventType>) -> ServiceResult<impl Responder> {
|
||||||
ctx.conductor.process(payload.into_inner()).await;
|
ctx.conductor.process(payload.into_inner()).await;
|
||||||
|
@ -71,10 +71,7 @@ pub mod tests {
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
let creds = settings.creds.clone();
|
let creds = settings.creds.clone();
|
||||||
let auth = format!(
|
let auth = format!("Bearer {}", creds.token,);
|
||||||
"Basic {}",
|
|
||||||
base64::encode(format!("{}:{}", creds.username.clone(), creds.password))
|
|
||||||
);
|
|
||||||
|
|
||||||
let msg = EventType::NewSite {
|
let msg = EventType::NewSite {
|
||||||
hostname: "demo.librepages.org".into(),
|
hostname: "demo.librepages.org".into(),
|
||||||
|
|
|
@ -19,6 +19,7 @@ use std::env;
|
||||||
use actix_web::http::StatusCode;
|
use actix_web::http::StatusCode;
|
||||||
use actix_web::web::JsonConfig;
|
use actix_web::web::JsonConfig;
|
||||||
use actix_web::{error::InternalError, middleware, App, HttpServer};
|
use actix_web::{error::InternalError, middleware, App, HttpServer};
|
||||||
|
use actix_web_prom::PrometheusMetricsBuilder;
|
||||||
use clap::{Parser, Subcommand};
|
use clap::{Parser, Subcommand};
|
||||||
use log::info;
|
use log::info;
|
||||||
|
|
||||||
|
@ -112,6 +113,11 @@ async fn serve(settings: Settings, ctx: AppCtx) -> std::io::Result<()> {
|
||||||
let ip = settings.server.get_ip();
|
let ip = settings.server.get_ip();
|
||||||
println!("Starting server on: http://{ip}");
|
println!("Starting server on: http://{ip}");
|
||||||
|
|
||||||
|
let prometheus = PrometheusMetricsBuilder::new("api")
|
||||||
|
.endpoint("/metrics")
|
||||||
|
.build()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
HttpServer::new(move || {
|
HttpServer::new(move || {
|
||||||
App::new()
|
App::new()
|
||||||
.wrap(middleware::Logger::default())
|
.wrap(middleware::Logger::default())
|
||||||
|
@ -124,6 +130,7 @@ async fn serve(settings: Settings, ctx: AppCtx) -> std::io::Result<()> {
|
||||||
middleware::TrailingSlash::Trim,
|
middleware::TrailingSlash::Trim,
|
||||||
))
|
))
|
||||||
.app_data(get_json_err())
|
.app_data(get_json_err())
|
||||||
|
.wrap(prometheus.clone())
|
||||||
.configure(routes::services)
|
.configure(routes::services)
|
||||||
})
|
})
|
||||||
.bind(ip)?
|
.bind(ip)?
|
||||||
|
|
|
@ -54,8 +54,7 @@ pub enum ConductorType {
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
pub struct Creds {
|
pub struct Creds {
|
||||||
pub username: String,
|
pub token: String,
|
||||||
pub password: String,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
|
@ -69,15 +68,15 @@ pub struct Settings {
|
||||||
|
|
||||||
#[cfg(not(tarpaulin_include))]
|
#[cfg(not(tarpaulin_include))]
|
||||||
impl Settings {
|
impl Settings {
|
||||||
pub fn authenticate(&self, username: &str, password: &str) -> bool {
|
pub fn authenticate(&self, token: &str) -> bool {
|
||||||
self.creds.username == username && self.creds.password == password
|
self.creds.token == token
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new() -> Result<Self, ConfigError> {
|
pub fn new() -> Result<Self, ConfigError> {
|
||||||
let mut s = Config::builder();
|
let mut s = Config::builder();
|
||||||
|
|
||||||
const CURRENT_DIR: &str = "./config/config.toml";
|
const CURRENT_DIR: &str = "./config/config.toml";
|
||||||
const ETC: &str = "/etc/lpconductor/config.toml";
|
const ETC: &str = "/etc/librepages/conductor/config.toml";
|
||||||
|
|
||||||
if let Ok(path) = env::var("LPCONDUCTOR_CONFIG") {
|
if let Ok(path) = env::var("LPCONDUCTOR_CONFIG") {
|
||||||
s = s.add_source(File::with_name(&path));
|
s = s.add_source(File::with_name(&path));
|
||||||
|
@ -138,6 +137,13 @@ fn set_separator_field(mut s: ConfigBuilder<DefaultState>) -> ConfigBuilder<Defa
|
||||||
&format!("{PREFIX}{SEPARATOR}SERVER{SEPARATOR}PROXY_HAS_TLS"),
|
&format!("{PREFIX}{SEPARATOR}SERVER{SEPARATOR}PROXY_HAS_TLS"),
|
||||||
"server.proxy_has_tls",
|
"server.proxy_has_tls",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
s = from_env(
|
||||||
|
s,
|
||||||
|
&format!("{PREFIX}{SEPARATOR}CREDS{SEPARATOR}TOKEN"),
|
||||||
|
"creds.token",
|
||||||
|
);
|
||||||
|
|
||||||
s
|
s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,16 +154,13 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn creds_works() {
|
fn creds_works() {
|
||||||
let settings = Settings::new().unwrap();
|
let settings = Settings::new().unwrap();
|
||||||
let mut creds = settings.creds.clone();
|
let creds = settings.creds.clone();
|
||||||
|
|
||||||
assert!(settings.authenticate(&creds.username, &creds.password));
|
assert!(settings.authenticate(&creds.token));
|
||||||
|
|
||||||
creds.username = "noexist".into();
|
|
||||||
assert!(!settings.authenticate(&creds.username, &creds.password));
|
|
||||||
|
|
||||||
let mut creds = settings.creds.clone();
|
let mut creds = settings.creds.clone();
|
||||||
|
|
||||||
creds.password = "noexist".into();
|
creds.token = "noexist".into();
|
||||||
assert!(!settings.authenticate(&creds.username, &creds.password));
|
assert!(!settings.authenticate(&creds.token))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue