cockpit: 330 -> 331 (#368886)

This commit is contained in:
Gaétan Lepage
2024-12-29 23:48:37 +01:00
committed by GitHub
3 changed files with 51 additions and 226 deletions
+2 -165
View File
@@ -53,171 +53,8 @@ in {
networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ cfg.port ];
# units are in reverse sort order if you ls $out/lib/systemd/system
# all these units are basically verbatim translated from upstream
# Translation from $out/lib/systemd/system/systemd-cockpithttps.slice
systemd.slices.system-cockpithttps = {
description = "Resource limits for all cockpit-ws-https@.service instances";
sliceConfig = {
TasksMax = 200;
MemoryHigh = "75%";
MemoryMax = "90%";
};
};
# Translation from $out/lib/systemd/system/cockpit-wsinstance-https@.socket
systemd.sockets."cockpit-wsinstance-https@" = {
unitConfig = {
Description = "Socket for Cockpit Web Service https instance %I";
BindsTo = [ "cockpit.service" "cockpit-wsinstance-https@%i.service" ];
# clean up the socket after the service exits, to prevent fd leak
# this also effectively prevents a DoS by starting arbitrarily many sockets, as
# the services are resource-limited by system-cockpithttps.slice
Documentation = "man:cockpit-ws(8)";
};
socketConfig = {
ListenStream = "/run/cockpit/wsinstance/https@%i.sock";
SocketUser = "root";
SocketMode = "0600";
};
};
# Translation from $out/lib/systemd/system/cockpit-wsinstance-https@.service
systemd.services."cockpit-wsinstance-https@" = {
description = "Cockpit Web Service https instance %I";
bindsTo = [ "cockpit.service"];
path = [ cfg.package ];
documentation = [ "man:cockpit-ws(8)" ];
serviceConfig = {
Slice = "system-cockpithttps.slice";
ExecStart = "${cfg.package}/libexec/cockpit-ws --for-tls-proxy --port=0";
User = "root";
Group = "";
};
};
# Translation from $out/lib/systemd/system/cockpit-wsinstance-http.socket
systemd.sockets.cockpit-wsinstance-http = {
unitConfig = {
Description = "Socket for Cockpit Web Service http instance";
BindsTo = "cockpit.service";
Documentation = "man:cockpit-ws(8)";
};
socketConfig = {
ListenStream = "/run/cockpit/wsinstance/http.sock";
SocketUser = "root";
SocketMode = "0600";
};
};
# Translation from $out/lib/systemd/system/cockpit-wsinstance-https-factory.socket
systemd.sockets.cockpit-wsinstance-https-factory = {
unitConfig = {
Description = "Socket for Cockpit Web Service https instance factory";
BindsTo = "cockpit.service";
Documentation = "man:cockpit-ws(8)";
};
socketConfig = {
ListenStream = "/run/cockpit/wsinstance/https-factory.sock";
Accept = true;
SocketUser = "root";
SocketMode = "0600";
};
};
# Translation from $out/lib/systemd/system/cockpit-wsinstance-https-factory@.service
systemd.services."cockpit-wsinstance-https-factory@" = {
description = "Cockpit Web Service https instance factory";
documentation = [ "man:cockpit-ws(8)" ];
path = [ cfg.package ];
serviceConfig = {
ExecStart = "${cfg.package}/libexec/cockpit-wsinstance-factory";
User = "root";
};
};
# Translation from $out/lib/systemd/system/cockpit-wsinstance-http.service
systemd.services."cockpit-wsinstance-http" = {
description = "Cockpit Web Service http instance";
bindsTo = [ "cockpit.service" ];
path = [ cfg.package ];
documentation = [ "man:cockpit-ws(8)" ];
serviceConfig = {
ExecStart = "${cfg.package}/libexec/cockpit-ws --no-tls --port=0";
User = "root";
Group = "";
};
};
# Translation from $out/lib/systemd/system/cockpit.socket
systemd.sockets."cockpit" = {
unitConfig = {
Description = "Cockpit Web Service Socket";
Documentation = "man:cockpit-ws(8)";
Wants = "cockpit-motd.service";
};
socketConfig = {
ListenStream = cfg.port;
ExecStartPost = [
"-${cfg.package}/share/cockpit/motd/update-motd \"\" localhost"
"-${pkgs.coreutils}/bin/ln -snf active.motd /run/cockpit/motd"
];
ExecStopPost = "-${pkgs.coreutils}/bin/ln -snf inactive.motd /run/cockpit/motd";
};
wantedBy = [ "sockets.target" ];
};
# Translation from $out/lib/systemd/system/cockpit.service
systemd.services."cockpit" = {
description = "Cockpit Web Service";
documentation = [ "man:cockpit-ws(8)" ];
restartIfChanged = true;
path = with pkgs; [ coreutils cfg.package ];
requires = [ "cockpit.socket" "cockpit-wsinstance-http.socket" "cockpit-wsinstance-https-factory.socket" ];
after = [ "cockpit-wsinstance-http.socket" "cockpit-wsinstance-https-factory.socket" ];
environment = {
G_MESSAGES_DEBUG = "cockpit-ws,cockpit-bridge";
};
serviceConfig = {
RuntimeDirectory="cockpit/tls";
ExecStartPre = [
# cockpit-tls runs in a more constrained environment, these + means that these commands
# will run with full privilege instead of inside that constrained environment
# See https://www.freedesktop.org/software/systemd/man/systemd.service.html#ExecStart= for details
"+${cfg.package}/libexec/cockpit-certificate-ensure --for-cockpit-tls"
];
ExecStart = "${cfg.package}/libexec/cockpit-tls";
User = "root";
Group = "";
NoNewPrivileges = true;
ProtectSystem = "strict";
ProtectHome = true;
PrivateTmp = true;
PrivateDevices = true;
ProtectKernelTunables = true;
RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ];
MemoryDenyWriteExecute = true;
};
};
# Translation from $out/lib/systemd/system/cockpit-motd.service
# This part basically implements a motd state machine:
# - If cockpit.socket is enabled then /run/cockpit/motd points to /run/cockpit/active.motd
# - If cockpit.socket is disabled then /run/cockpit/motd points to /run/cockpit/inactive.motd
# - As cockpit.socket is disabled by default, /run/cockpit/motd points to /run/cockpit/inactive.motd
# /run/cockpit/active.motd is generated dynamically by cockpit-motd.service
systemd.services."cockpit-motd" = {
path = with pkgs; [ nettools ];
serviceConfig = {
Type = "oneshot";
ExecStart = "${cfg.package}/share/cockpit/motd/update-motd";
};
description = "Cockpit motd updater service";
documentation = [ "man:cockpit-ws(8)" ];
wants = [ "network.target" ];
after = [ "network.target" "cockpit.socket" ];
};
systemd.packages = [ cfg.package ];
systemd.sockets.cockpit.wantedBy = [ "multi-user.target" ];
systemd.tmpfiles.rules = [ # From $out/lib/tmpfiles.d/cockpit-tmpfiles.conf
"C /run/cockpit/inactive.motd 0640 root root - ${cfg.package}/share/cockpit/motd/inactive.motd"
+11 -9
View File
@@ -67,14 +67,14 @@ import ./make-test-python.nix (
log("Opening homepage")
driver.get("https://server:9090")
wait = WebDriverWait(driver, 60)
def wait_elem(by, query):
def wait_elem(by, query, timeout=10):
wait = WebDriverWait(driver, timeout)
wait.until(EC.presence_of_element_located((by, query)))
def wait_title_contains(title):
def wait_title_contains(title, timeout=10):
wait = WebDriverWait(driver, timeout)
wait.until(EC.title_contains(title))
@@ -121,6 +121,12 @@ import ./make-test-python.nix (
assert "Web console is running in limited access mode" in driver.page_source
log("Clicking the sudo button")
driver.switch_to.default_content()
driver.find_element(By.CSS_SELECTOR, 'button.ct-locked').click()
log("Checking that /nonexistent is not a thing")
assert '/nonexistent' not in driver.page_source
driver.close()
'';
in
@@ -136,12 +142,8 @@ import ./make-test-python.nix (
testScript = ''
start_all()
server.wait_for_unit("sockets.target")
server.wait_for_open_port(9090)
server.wait_for_unit("network.target")
server.wait_for_unit("multi-user.target")
server.systemctl("start", "polkit")
client.wait_for_unit("multi-user.target")
client.succeed("curl -k https://server:9090 -o /dev/stderr")
print(client.succeed("whoami"))
+38 -52
View File
@@ -14,7 +14,6 @@
git,
glib,
glib-networking,
gnused,
gnutls,
json-glib,
krb5,
@@ -31,21 +30,20 @@
pkg-config,
polkit,
python3Packages,
runtimeShell,
systemd,
udev,
xmlto,
}:
stdenv.mkDerivation rec {
stdenv.mkDerivation (finalAttrs: {
pname = "cockpit";
version = "330";
version = "331";
src = fetchFromGitHub {
owner = "cockpit-project";
repo = "cockpit";
rev = "refs/tags/${version}";
hash = "sha256-tPoFa9/22WUO+N3Pc/7jdWIOsoImeru6/F+2yUi92iI=";
tag = finalAttrs.version;
hash = "sha256-G0L1ZcvjUCSNkDvYoyConymZ4bsEye03t5K15EyI008=";
fetchSubmodules = true;
};
@@ -87,29 +85,30 @@ stdenv.mkDerivation rec {
echo "#!/bin/sh" > test/node_modules
substituteInPlace src/tls/cockpit-certificate-helper.in \
--replace 'COCKPIT_CONFIG="@sysconfdir@/cockpit"' 'COCKPIT_CONFIG=/etc/cockpit'
--replace-fail 'COCKPIT_CONFIG="@sysconfdir@/cockpit"' 'COCKPIT_CONFIG=/etc/cockpit'
substituteInPlace src/tls/cockpit-certificate-ensure.c \
--replace '#define COCKPIT_SELFSIGNED_PATH PACKAGE_SYSCONF_DIR COCKPIT_SELFSIGNED_FILENAME' '#define COCKPIT_SELFSIGNED_PATH "/etc" COCKPIT_SELFSIGNED_FILENAME'
--replace-fail '#define COCKPIT_SELFSIGNED_PATH PACKAGE_SYSCONF_DIR COCKPIT_SELFSIGNED_FILENAME' '#define COCKPIT_SELFSIGNED_PATH "/etc" COCKPIT_SELFSIGNED_FILENAME'
substituteInPlace src/common/cockpitconf.c \
--replace 'const char *cockpit_config_dirs[] = { PACKAGE_SYSCONF_DIR' 'const char *cockpit_config_dirs[] = { "/etc"'
--replace-fail 'const char *cockpit_config_dirs[] = { PACKAGE_SYSCONF_DIR' 'const char *cockpit_config_dirs[] = { "/etc"'
# instruct users with problems to create a nixpkgs issue instead of nagging upstream directly
substituteInPlace configure.ac \
--replace 'devel@lists.cockpit-project.org' 'https://github.com/NixOS/nixpkgs/issues/new?assignees=&labels=0.kind%3A+bug&template=bug_report.md&title=cockpit%25'
--replace-fail 'devel@lists.cockpit-project.org' 'https://github.com/NixOS/nixpkgs/issues/new?assignees=&labels=0.kind%3A+bug&template=bug_report.md&title=cockpit%25'
patchShebangs \
build.js \
test/common/pixel-tests \
test/common/run-tests \
test/common/tap-cdp \
test/static-code \
tools/escape-to-c \
tools/make-compile-commands \
tools/node-modules \
tools/termschutz \
tools/webpack-make.js
tools/webpack-make.js \
tools/test-driver \
test/common/static-code
for f in node_modules/.bin/*; do
patchShebangs $(realpath $f)
@@ -122,17 +121,23 @@ stdenv.mkDerivation rec {
for f in pkg/**/*.js pkg/**/*.jsx test/**/* src/**/*; do
# some files substituteInPlace report as missing and it's safe to ignore them
substituteInPlace "$(realpath "$f")" \
--replace '"/usr/bin/' '"' \
--replace '"/bin/' '"' || true
--replace-quiet '"/usr/bin/' '"' \
--replace-quiet '"/bin/' '"' || true
done
substituteInPlace src/common/Makefile-common.am \
--replace 'TEST_PROGRAM += test-pipe' "" # skip test-pipe because it hangs the build
--replace-warn 'TEST_PROGRAM += test-pipe' "" # skip test-pipe because it hangs the build
substituteInPlace src/ws/Makefile-ws.am \
--replace-warn 'TEST_PROGRAM += test-compat' ""
substituteInPlace test/pytest/*.py \
--replace "'bash" "'${bashInteractive}/bin/bash"
--replace-quiet "'bash" "'${bashInteractive}/bin/bash"
echo "m4_define(VERSION_NUMBER, [${version}])" > version.m4
echo "m4_define(VERSION_NUMBER, [${finalAttrs.version}])" > version.m4
# hardcode libexecdir, I am assuming that cockpit only use it to find it's binaries
printf 'def get_libexecdir() -> str:\n\treturn "%s"' "$out/libexec" >> src/cockpit/packages.py
'';
configureFlags = [
@@ -140,34 +145,15 @@ stdenv.mkDerivation rec {
"--disable-pcp" # TODO: figure out how to package its dependency
"--with-default-session-path=/run/wrappers/bin:/run/current-system/sw/bin"
"--with-admin-group=root" # TODO: really? Maybe "wheel"?
"--enable-old-bridge=yes"
];
enableParallelBuilding = true;
preBuild = ''
patchShebangs \
tools/test-driver
'';
postBuild = ''
chmod +x \
src/systemd/update-motd \
src/tls/cockpit-certificate-helper \
src/ws/cockpit-desktop
patchShebangs \
src/systemd/update-motd \
src/tls/cockpit-certificate-helper \
src/ws/cockpit-desktop
substituteInPlace src/ws/cockpit-desktop \
--replace ' /bin/bash' ' ${runtimeShell}'
'';
fixupPhase = ''
runHook preFixup
patchShebangs $out/libexec/*
wrapProgram $out/libexec/cockpit-certificate-helper \
--prefix PATH : ${
lib.makeBinPath [
@@ -177,41 +163,40 @@ stdenv.mkDerivation rec {
} \
--run 'cd $(mktemp -d)'
wrapProgram $out/share/cockpit/motd/update-motd \
--prefix PATH : ${lib.makeBinPath [ gnused ]}
wrapProgram $out/bin/cockpit-bridge \
--prefix PYTHONPATH : $out/${python3Packages.python.sitePackages}
substituteInPlace $out/${python3Packages.python.sitePackages}/cockpit/_vendor/systemd_ctypes/libsystemd.py \
--replace-fail libsystemd.so.0 ${systemd}/lib/libsystemd.so.0
--replace-warn libsystemd.so.0 ${systemd}/lib/libsystemd.so.0
substituteInPlace $out/share/polkit-1/actions/org.cockpit-project.cockpit-bridge.policy \
--replace-fail /usr $out
substituteInPlace $out/lib/systemd/*/* \
--replace-warn /bin /run/current-system/sw/bin
runHook postFixup
'';
doCheck = true;
nativeCheckInputs = [ python3Packages.pytestCheckHook ];
checkInputs = [
bashInteractive
cacert
dbus
glib-networking
openssh
python3Packages.pytest
];
checkPhase = ''
preCheck = ''
export GIO_EXTRA_MODULES=$GIO_EXTRA_MODULES:${glib-networking}/lib/gio/modules
export G_DEBUG=fatal-criticals
export G_MESSAGES_DEBUG=cockpit-ws,cockpit-wrapper,cockpit-bridge
export PATH=$PATH:$(pwd)
make pytest -j$NIX_BUILD_CORES || true
make check -j$NIX_BUILD_CORES || true
test/static-code
npm run eslint
npm run stylelint || true
npm run stylelint
'';
passthru = {
@@ -219,11 +204,12 @@ stdenv.mkDerivation rec {
updateScript = nix-update-script { };
};
meta = with lib; {
meta = {
description = "Web-based graphical interface for servers";
mainProgram = "cockpit-bridge";
homepage = "https://cockpit-project.org/";
license = licenses.lgpl21;
maintainers = with maintainers; [ lucasew ];
changelog = "https://cockpit-project.org/blog/cockpit-${finalAttrs.version}.html";
license = lib.licenses.lgpl21;
maintainers = [ lib.maintainers.lucasew ];
};
}
})