enable nginx config management
This commit is contained in:
parent
686ed543ab
commit
466239d0e6
4 changed files with 55 additions and 20 deletions
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
import { daemon_listen, Runner } from "./src/lib.ts";
|
import { daemon_listen, Runner } from "./src/lib.ts";
|
||||||
import { ContainerConfig } from "./src/lib/config.ts";
|
import { ContainerConfig } from "./src/lib/config.ts";
|
||||||
|
import { NginxController } from "./src/lib/nginx.ts";
|
||||||
import { socket_path, state_path } from "./src/lib/paths.ts";
|
import { socket_path, state_path } from "./src/lib/paths.ts";
|
||||||
import { log_from, sleep } from "./src/lib/utils.ts";
|
import { log_from, sleep } from "./src/lib/utils.ts";
|
||||||
|
|
||||||
|
@ -78,9 +79,11 @@ async function main() {
|
||||||
|
|
||||||
class State {
|
class State {
|
||||||
enabled;
|
enabled;
|
||||||
|
nginx;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.enabled = new Map<string, Runner>();
|
this.enabled = new Map<string, Runner>();
|
||||||
|
this.nginx = new NginxController("barnulf.net", "/etc/nginx/sites-enabled");
|
||||||
}
|
}
|
||||||
|
|
||||||
static async load() {
|
static async load() {
|
||||||
|
@ -104,7 +107,7 @@ class State {
|
||||||
const config = await ContainerConfig.load(name); // TODO
|
const config = await ContainerConfig.load(name); // TODO
|
||||||
if (config === null) throw new Error("can't read config");
|
if (config === null) throw new Error("can't read config");
|
||||||
log("starting container", name);
|
log("starting container", name);
|
||||||
const runner = new Runner(config);
|
const runner = new Runner(config, this.nginx);
|
||||||
runner.start();
|
runner.start();
|
||||||
this.enabled.set(name, runner);
|
this.enabled.set(name, runner);
|
||||||
log("container", name, "started");
|
log("container", name, "started");
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { ContainerConfig } from "./lib/config.ts";
|
||||||
import { container_paths } from "./lib/paths.ts";
|
import { container_paths } from "./lib/paths.ts";
|
||||||
import { container_command } from "./lib/nspawn.ts";
|
import { container_command } from "./lib/nspawn.ts";
|
||||||
import { LoopProcess } from "./lib/utils.ts";
|
import { LoopProcess } from "./lib/utils.ts";
|
||||||
|
import { NginxController } from "./lib/nginx.ts";
|
||||||
|
|
||||||
const log = log_from("lib");
|
const log = log_from("lib");
|
||||||
|
|
||||||
|
@ -70,15 +71,22 @@ export async function daemon_send(sock_path: string, command: Cmd) {
|
||||||
export class Runner {
|
export class Runner {
|
||||||
name;
|
name;
|
||||||
config;
|
config;
|
||||||
loop: LoopProcess | null;
|
nginx;
|
||||||
|
loop;
|
||||||
|
|
||||||
constructor(config: ContainerConfig) {
|
constructor(config: ContainerConfig, nginx: NginxController) {
|
||||||
this.name = config.name;
|
this.name = config.name;
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.loop = null;
|
this.nginx = nginx;
|
||||||
|
this.loop = null as LoopProcess | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
|
this.update_proxies();
|
||||||
|
this.start_process();
|
||||||
|
}
|
||||||
|
|
||||||
|
private start_process() {
|
||||||
const paths = container_paths(name);
|
const paths = container_paths(name);
|
||||||
const command = container_command(name, paths.root, {
|
const command = container_command(name, paths.root, {
|
||||||
boot: true,
|
boot: true,
|
||||||
|
@ -99,4 +107,18 @@ export class Runner {
|
||||||
async stop() {
|
async stop() {
|
||||||
await this.loop?.kill();
|
await this.loop?.kill();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async update_proxies() {
|
||||||
|
const paths = container_paths(name);
|
||||||
|
await Deno.mkdir(paths.sites, { recursive: true });
|
||||||
|
const sites = new Set<string>();
|
||||||
|
for (const redir of this.config.redirections) {
|
||||||
|
if (redir.kind !== "http") continue;
|
||||||
|
await this.nginx.add_proxy(redir.domain, redir.port, paths.sites);
|
||||||
|
sites.add(redir.domain);
|
||||||
|
}
|
||||||
|
for await (const domains of this.nginx.read_all_in_dir(paths.sites)) {
|
||||||
|
if (!sites.has(domains)) this.nginx.remove_proxy(domains, paths.sites);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,41 +1,50 @@
|
||||||
import { run } from "./utils.ts";
|
import { run } from "./utils.ts";
|
||||||
import * as path from "https://deno.land/std@0.214.0/path/mod.ts";
|
import * as path from "https://deno.land/std@0.214.0/path/mod.ts";
|
||||||
|
|
||||||
class NginxController {
|
export class NginxController {
|
||||||
proxy_target_url;
|
private proxy_target_domain;
|
||||||
enabled_conf_dir;
|
private enabled_conf_dir;
|
||||||
|
|
||||||
constructor(proxy_target_url: string, enabled_conf_dir: string) {
|
constructor(proxy_target_domain: string, enabled_conf_dir: string) {
|
||||||
this.proxy_target_url = proxy_target_url;
|
this.proxy_target_domain = proxy_target_domain;
|
||||||
this.enabled_conf_dir = enabled_conf_dir;
|
this.enabled_conf_dir = enabled_conf_dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async add_proxy(url: string, port: number, conf_dir: string) {
|
public async add_proxy(domain: string, port: number, conf_dir: string) {
|
||||||
const conf_file_content = `
|
const conf_file_content = `
|
||||||
server {
|
server {
|
||||||
listen 80;
|
listen 80;
|
||||||
listen [::]:80;
|
listen [::]:80;
|
||||||
server_name ${url};
|
server_name ${domain};
|
||||||
location / {
|
location / {
|
||||||
proxy_pass http://${this.proxy_target_url}:${port};
|
proxy_pass http://${this.proxy_target_domain}:${port};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
const conf_file_path = path.join(conf_dir, url + ".conf");
|
const conf_file_path = path.join(conf_dir, domain + ".conf");
|
||||||
const enabled_conf_file_path = path.join(this.enabled_conf_dir, url + ".conf");
|
const enabled_conf_file_path = path.join(this.enabled_conf_dir, domain + ".conf");
|
||||||
await Deno.writeTextFile(conf_file_path, conf_file_content);
|
await Deno.writeTextFile(conf_file_path, conf_file_content);
|
||||||
await run("ln", "-s", await Deno.realPath(conf_file_path), enabled_conf_file_path);
|
await run("ln", "-s", await Deno.realPath(conf_file_path), enabled_conf_file_path);
|
||||||
await this.reload();
|
await this.reload();
|
||||||
|
return conf_file_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async remove_proxy(url: string, conf_dir: string) {
|
public async remove_proxy(domain: string, conf_dir: string) {
|
||||||
const conf_file_path = path.join(conf_dir, url + ".conf");
|
const conf_file_path = path.join(conf_dir, domain + ".conf");
|
||||||
const enabled_conf_file_path = path.join(this.enabled_conf_dir, url + ".conf");
|
const enabled_conf_file_path = path.join(this.enabled_conf_dir, domain + ".conf");
|
||||||
await Deno.remove(enabled_conf_file_path);
|
await Deno.remove(enabled_conf_file_path, { recursive: true });
|
||||||
await Deno.remove(conf_file_path);
|
await Deno.remove(conf_file_path, { recursive: true });
|
||||||
await this.reload();
|
await this.reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async *read_all_in_dir(conf_dir: string) {
|
||||||
|
for await (const { name } of Deno.readDir(conf_dir)) {
|
||||||
|
const [domain, rest] = name.split(".conf");
|
||||||
|
if (rest !== "") continue;
|
||||||
|
yield domain;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async reload() {
|
private async reload() {
|
||||||
await run("systemctl", "restart", "nginx");
|
await run("systemctl", "restart", "nginx");
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,8 @@ export function container_paths(name: string) {
|
||||||
const base = containers_path() + "/" + name;
|
const base = containers_path() + "/" + name;
|
||||||
const configuration = base + "/config.json";
|
const configuration = base + "/config.json";
|
||||||
const root = base + "/root";
|
const root = base + "/root";
|
||||||
return { base, configuration, root };
|
const sites = base + "/sites";
|
||||||
|
return { base, configuration, root, sites };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function state_path() {
|
export function state_path() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue