forked from fediversity/fediversity
Compare commits
10 commits
69579fea1c
...
350245c097
Author | SHA1 | Date | |
---|---|---|---|
350245c097 | |||
631ce8a92d | |||
09119803e8 | |||
4dd1491e71 | |||
2f55e1512a | |||
b59f8a4183 | |||
56b953526b | |||
1f8677e83d | |||
2fae356d0a | |||
046f7c5998 |
11 changed files with 85 additions and 48 deletions
|
@ -79,10 +79,16 @@ in
|
|||
## and check that they are working properly.
|
||||
|
||||
extraTestScript = ''
|
||||
with subtest("Check the status of the services - there should be none"):
|
||||
garage.fail("systemctl status garage.service")
|
||||
mastodon.fail("systemctl status mastodon-web.service")
|
||||
peertube.fail("systemctl status peertube.service")
|
||||
pixelfed.fail("systemctl status phpfpm-pixelfed.service")
|
||||
|
||||
with subtest("Run deployment with no services enabled"):
|
||||
deployer.succeed("nixops4 apply check-deployment-cli-nothing --show-trace --no-interactive 1>&2")
|
||||
|
||||
with subtest("Check the status of the services - there should be none"):
|
||||
with subtest("Check the status of the services - there should still be none"):
|
||||
garage.fail("systemctl status garage.service")
|
||||
mastodon.fail("systemctl status mastodon-web.service")
|
||||
peertube.fail("systemctl status peertube.service")
|
||||
|
|
|
@ -53,6 +53,7 @@ in
|
|||
};
|
||||
|
||||
config = {
|
||||
acmeNodeIP = config.nodes.acme.networking.primaryIPAddress;
|
||||
|
||||
nodes =
|
||||
{
|
||||
|
|
|
@ -50,13 +50,16 @@ in
|
|||
};
|
||||
|
||||
security.pki.certificateFiles = [
|
||||
## NOTE: This certificate is the one used by the Pebble HTTPS server.
|
||||
## This is NOT the root CA of the Pebble server. We do add it here so
|
||||
## that Pebble clients can talk to its API, but this will not allow
|
||||
## those machines to verify generated certificates.
|
||||
testCerts.ca.cert
|
||||
];
|
||||
|
||||
## FIXME: it is a bit sad that all this logistics is necessary. look into
|
||||
## better DNS stuff
|
||||
networking.extraHosts = "${config.acmeNodeIP} acme.test";
|
||||
|
||||
})
|
||||
];
|
||||
}
|
||||
|
|
|
@ -33,11 +33,25 @@
|
|||
## information coming from the FediPanel.
|
||||
##
|
||||
## FIXME: lock step the interface with the definitions in the FediPanel
|
||||
panelConfig:
|
||||
panelConfigNullable:
|
||||
|
||||
let
|
||||
inherit (lib) mkIf;
|
||||
|
||||
nonNull = x: v: if x == null then v else x;
|
||||
|
||||
panelConfig = {
|
||||
domain = nonNull panelConfigNullable.domain "fediversity.net";
|
||||
initialUser = nonNull panelConfigNullable.initialUser {
|
||||
displayName = "Testy McTestface";
|
||||
username = "test";
|
||||
password = "testtest";
|
||||
email = "test@test.com";
|
||||
};
|
||||
mastodon = nonNull panelConfigNullable.mastodon { enable = false; };
|
||||
peertube = nonNull panelConfigNullable.peertube { enable = false; };
|
||||
pixelfed = nonNull panelConfigNullable.pixelfed { enable = false; };
|
||||
};
|
||||
in
|
||||
|
||||
## Regular arguments of a NixOps4 deployment module.
|
||||
|
@ -122,7 +136,7 @@ in
|
|||
{ pkgs, ... }:
|
||||
mkIf (cfg.mastodon.enable || cfg.peertube.enable || cfg.pixelfed.enable) {
|
||||
fediversity = {
|
||||
inherit (panelConfig) domain;
|
||||
inherit (cfg) domain;
|
||||
garage.enable = true;
|
||||
pixelfed = pixelfedS3KeyConfig { inherit pkgs; };
|
||||
mastodon = mastodonS3KeyConfig { inherit pkgs; };
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
{
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-24.11"; # consumed by flake-parts
|
||||
flake-parts.url = "github:hercules-ci/flake-parts";
|
||||
git-hooks.url = "github:cachix/git-hooks.nix";
|
||||
nixops4.follows = "nixops4-nixos/nixops4";
|
||||
|
@ -11,9 +10,11 @@
|
|||
inputs@{ flake-parts, ... }:
|
||||
let
|
||||
sources = import ./npins;
|
||||
inherit (import "${flake-inputs}/lib.nix") import-flake;
|
||||
inherit (sources) git-hooks agenix;
|
||||
nixpkgs = import-flake sources.nixpkgs;
|
||||
in
|
||||
flake-parts.lib.mkFlake { inherit inputs; } {
|
||||
flake-parts.lib.mkFlake { inputs = inputs // { inherit nixpkgs; }; } {
|
||||
systems = [
|
||||
"x86_64-linux"
|
||||
"aarch64-linux"
|
||||
|
|
|
@ -25,6 +25,22 @@
|
|||
"url": null,
|
||||
"hash": "1w2gsy6qwxa5abkv8clb435237iifndcxq0s79wihqw11a5yb938"
|
||||
},
|
||||
"flake-inputs": {
|
||||
"type": "GitRelease",
|
||||
"repository": {
|
||||
"type": "GitHub",
|
||||
"owner": "fricklerhandwerk",
|
||||
"repo": "flake-inputs"
|
||||
},
|
||||
"pre_releases": false,
|
||||
"version_upper_bound": null,
|
||||
"release_prefix": null,
|
||||
"submodules": false,
|
||||
"version": "1.1",
|
||||
"revision": "6461d0b56e790bf289af07c5e5261abbf4f536af",
|
||||
"url": "https://api.github.com/repos/fricklerhandwerk/flake-inputs/tarball/1.1",
|
||||
"hash": "03mwisvr1mc3nd33nvg4bvcyxjxpm4lwhwym39r0768cm1007ixl"
|
||||
},
|
||||
"flake-parts": {
|
||||
"type": "Git",
|
||||
"repository": {
|
||||
|
|
|
@ -9,10 +9,4 @@ in
|
|||
{
|
||||
REPO_DIR = toString ../.;
|
||||
# explicitly use nix, as e.g. lix does not have configurable-impure-env
|
||||
BIN_PATH = lib.makeBinPath [
|
||||
# explicitly use nix, as e.g. lix does not have configurable-impure-env
|
||||
pkgs.nix
|
||||
# nixops error maybe due to our flake git hook: executing 'git': No such file or directory
|
||||
pkgs.git
|
||||
];
|
||||
}
|
||||
|
|
|
@ -146,7 +146,19 @@ in
|
|||
${cfg.domain} =
|
||||
{
|
||||
locations = {
|
||||
"/".proxyPass = "http://localhost:${toString cfg.port}";
|
||||
"/" = {
|
||||
proxyPass = "http://localhost:${toString cfg.port}";
|
||||
extraConfig = ''
|
||||
## FIXME: The following is necessary because /deployment/status
|
||||
## can take aaaaages to respond. I think this is horrendous
|
||||
## design from the panel and should be changed there, but in the
|
||||
## meantime we bump nginx's timeouts to one hour.
|
||||
proxy_connect_timeout 3600;
|
||||
proxy_send_timeout 3600;
|
||||
proxy_read_timeout 3600;
|
||||
send_timeout 3600;
|
||||
'';
|
||||
};
|
||||
"/static/".alias = "/var/lib/${name}/static/";
|
||||
};
|
||||
}
|
||||
|
@ -166,10 +178,18 @@ in
|
|||
description = "${name} ASGI server";
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
path = [
|
||||
python-environment
|
||||
manage-service
|
||||
];
|
||||
path =
|
||||
[
|
||||
python-environment
|
||||
manage-service
|
||||
]
|
||||
++ (
|
||||
with pkgs;
|
||||
lib.mkBinPath [
|
||||
nix
|
||||
git
|
||||
]
|
||||
);
|
||||
preStart = ''
|
||||
# Auto-migrate on first run or if the package has changed
|
||||
versionFile="/var/lib/${name}/package-version"
|
||||
|
|
|
@ -240,8 +240,6 @@ if user_settings_file is not None:
|
|||
# The correct thing to do here would be using a helper function such as with `get_secret()` that will catch the exception and explain what's wrong and where to put the right values.
|
||||
# Replacing the `USER_SETTINGS_FILE` mechanism following the comment there would probably be a good thing.
|
||||
|
||||
# PATH to expose to launch button
|
||||
bin_path=env['BIN_PATH']
|
||||
# path of the root flake to trigger nixops from, see #94.
|
||||
# to deploy this should be specified, for dev just use a relative path.
|
||||
repo_dir = env["REPO_DIR"]
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
from django.test import TestCase
|
||||
from django.urls import reverse
|
||||
from django.contrib.auth.models import User
|
||||
from django.template import Template, Context
|
||||
from urllib.parse import unquote
|
||||
|
||||
from panel.templatetags.custom_tags import auth_url
|
||||
|
||||
class Login(TestCase):
|
||||
def setUp(self):
|
||||
self.username = 'testuser'
|
||||
|
@ -27,8 +28,7 @@ class Login(TestCase):
|
|||
|
||||
# check that the expected login URL is in the response
|
||||
context = response.context[0]
|
||||
template = Template("{% load custom_tags %}{% auth_url 'login' %}")
|
||||
login_url = template.render(context)
|
||||
login_url = auth_url(context, 'login')
|
||||
self.assertIn(login_url, response.content.decode('utf-8'))
|
||||
|
||||
# log in
|
||||
|
@ -49,8 +49,7 @@ class Login(TestCase):
|
|||
|
||||
# check that the expected logout URL is present
|
||||
context = response.context[0]
|
||||
template = Template("{% load custom_tags %}{% auth_url 'logout' %}")
|
||||
logout_url = template.render(context)
|
||||
logout_url = auth_url(context, 'logout')
|
||||
self.assertIn(logout_url, response.content.decode('utf-8'))
|
||||
|
||||
# log out again
|
||||
|
@ -88,8 +87,7 @@ class Login(TestCase):
|
|||
|
||||
# check that the expected logout URL is present
|
||||
context = response.context[0]
|
||||
template = Template("{% load custom_tags %}{% auth_url 'logout' %}")
|
||||
logout_url = template.render(context)
|
||||
logout_url = auth_url(context, 'logout')
|
||||
self.assertIn(logout_url, response.content.decode('utf-8'))
|
||||
|
||||
# log out
|
||||
|
@ -97,8 +95,7 @@ class Login(TestCase):
|
|||
|
||||
# check that we're at the expected location, logged out
|
||||
self.assertEqual(response.status_code, 200)
|
||||
template = Template("{% load custom_tags %}{% auth_url 'login' %}")
|
||||
login_url = template.render(context)
|
||||
login_url = auth_url(context, 'login')
|
||||
location, status = response.redirect_chain[-1]
|
||||
self.assertEqual(location, unquote(login_url))
|
||||
self.assertFalse(response.context['user'].is_authenticated)
|
||||
|
|
|
@ -65,9 +65,6 @@ class ConfigurationForm(LoginRequiredMixin, APIView):
|
|||
config.save()
|
||||
return redirect(self.success_url)
|
||||
|
||||
# TODO(@fricklerhandwerk):
|
||||
# this is broken after changing the form view.
|
||||
# but if there's no test for it, how do we know it ever worked in the first place?
|
||||
class DeploymentStatus(ConfigurationForm):
|
||||
|
||||
def post(self, request):
|
||||
|
@ -84,28 +81,15 @@ class DeploymentStatus(ConfigurationForm):
|
|||
config.save()
|
||||
|
||||
deployment_result, deployment_params = self.deployment(config.parsed_value)
|
||||
if deployment_result.returncode == 0:
|
||||
deployment_status = "Deployment Succeeded"
|
||||
else:
|
||||
deployment_status = "Deployment Failed"
|
||||
|
||||
return render(self.request, "partials/deployment_result.html", {
|
||||
"deployment_status": deployment_status,
|
||||
"deployment_succeeded": (deployment_result.returncode == 0),
|
||||
"services": deployment_params.json(),
|
||||
})
|
||||
|
||||
def deployment(self, config: BaseModel):
|
||||
# FIXME: let the user specify these from the form (#190)
|
||||
dummy_user = {
|
||||
"initialUser": {
|
||||
"displayName": "Testy McTestface",
|
||||
"username": "test",
|
||||
"password": "testtest",
|
||||
"email": "test@test.com",
|
||||
},
|
||||
}
|
||||
env = {
|
||||
"PATH": settings.bin_path,
|
||||
"PATH": os.environ.get("PATH"),
|
||||
# pass in form info to our deployment
|
||||
"DEPLOYMENT": config.json()
|
||||
}
|
||||
|
@ -118,10 +102,13 @@ class DeploymentStatus(ConfigurationForm):
|
|||
"nixops4",
|
||||
"apply",
|
||||
"test",
|
||||
"--show-trace",
|
||||
"--no-interactive",
|
||||
]
|
||||
deployment_result = subprocess.run(
|
||||
cmd,
|
||||
cwd=settings.repo_dir,
|
||||
env=env,
|
||||
cwd = settings.repo_dir,
|
||||
env = env,
|
||||
stderr = subprocess.STDOUT,
|
||||
)
|
||||
return deployment_result, config
|
||||
|
|
Loading…
Add table
Reference in a new issue