From b448046f041b5377921d9703a903cb0d3a4f5575 Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Mon, 28 Aug 2023 12:21:49 +0200 Subject: [PATCH] containers/ws: Enable beibooting and install standard cockpit pages This provides similar functionality as the Client, so that the ws bastion container can connect to machines which don't have any Cockpit packages installed. Install cockpit-system and cockpit-networkmanager into the container (we'll likely expand this in the future, but let's start small). Take care to only unpack the RPMs, to avoid installing e.g. NetworkManager and other big dependencies into the container -- they are useless there. https://issues.redhat.com/browse/COCKPIT-954 --- containers/ws/cockpit-auth-ssh-key | 4 +--- containers/ws/install.sh | 17 ++++++++++++++++- test/ostree.install | 12 ++++++++---- test/verify/check-ws-bastion | 28 +++++++++++++++++++++++----- 4 files changed, 48 insertions(+), 13 deletions(-) diff --git a/containers/ws/cockpit-auth-ssh-key b/containers/ws/cockpit-auth-ssh-key index 13dbb6dd18bd..d585a478b92f 100755 --- a/containers/ws/cockpit-auth-ssh-key +++ b/containers/ws/cockpit-auth-ssh-key @@ -188,9 +188,7 @@ def main(args): {"password": "denied"}) return - # for the time being, we only support running an installed cockpit-bridge on the remote, - # and leave beibooting to the flatpak - os.execlpe("python3", "python3", "-m", "cockpit.beiboot", "--remote-bridge=always", host, os.environ) + os.execlpe("python3", "python3", "-m", "cockpit.beiboot", host, os.environ) if __name__ == '__main__': diff --git a/containers/ws/install.sh b/containers/ws/install.sh index 9cc9e38b886c..768542dace8d 100755 --- a/containers/ws/install.sh +++ b/containers/ws/install.sh @@ -3,18 +3,33 @@ set -ex OSVER=$(. /etc/os-release && echo "$VERSION_ID") +INSTALLROOT=/build +INSTALL="dnf install -y --installroot=$INSTALLROOT --releasever=$OSVER --setopt=install_weak_deps=False" -INSTALL="dnf install -y --installroot=/build --releasever=$OSVER --setopt=install_weak_deps=False" +dnf install -y 'dnf-command(download)' cpio $INSTALL coreutils-single util-linux-core sed sscg python3 openssh-clients arch=`uname -p` rpm=$(ls /container/rpms/cockpit-ws-*$OSVER.*$arch.rpm /container/rpms/cockpit-bridge-*$OSVER.*$arch.rpm || true) +unpack() { + rpm2cpio "$1" | cpio -i --make-directories --directory=$INSTALLROOT +} + # If there are rpm files in the current directory we'll install those +# -system and -networkmanager are only for beibooting; don't install their dependencies if [ -n "$rpm" ]; then $INSTALL /container/rpms/cockpit-ws-*$OSVER.*$arch.rpm /container/rpms/cockpit-bridge-*$OSVER.*$arch.rpm + for rpm in /container/rpms/cockpit-system-*$OSVER.*$arch.rpm \ + /container/rpms/cockpit-networkmanager-*$OSVER.*$arch.rpm; do + unpack $rpm + done else $INSTALL cockpit-ws cockpit-bridge + dnf download cockpit-networkmanager cockpit-system + for rpm in cockpit-networkmanager*.rpm cockpit-system*.rpm; do + unpack $rpm + done fi rm -rf /build/var/cache/dnf /build/var/lib/dnf /build/var/lib/rpm* /build/var/log/* diff --git a/test/ostree.install b/test/ostree.install index 3f75f664814d..89ad443f1b9a 100644 --- a/test/ostree.install +++ b/test/ostree.install @@ -1,15 +1,19 @@ #!/bin/sh set -eu -# install/upgrade RPMs that apply to OSTree -# Note: cockpit-selinux would be desirable, but needs setroubleshoot-server which isn't installed cd /var/tmp/ +# install/upgrade RPMs that apply to OSTree +# Note: cockpit-selinux would be desirable, but needs setroubleshoot-server which isn't installed rpm-ostree install --cache-only cockpit-bridge-*.rpm \ cockpit-networkmanager-*.rpm cockpit-system-*.rpm cockpit-tests-*.rpm -# update cockpit-ws and install scripts in the container -for rpm in /var/tmp/cockpit-ws-*.rpm /var/tmp/cockpit-bridge-*.rpm; do +# update cockpit packages and install scripts in the container +for rpm in /var/tmp/cockpit-ws-*.rpm \ + /var/tmp/cockpit-bridge-*.rpm \ + /var/tmp/cockpit-networkmanager-*.rpm \ + /var/tmp/cockpit-system-*.rpm \ + /var/tmp/cockpit-tests-*.rpm; do rpm2cpio "$rpm" | cpio -i --make-directories --directory=/var/tmp/install done podman run --name build-cockpit -i \ diff --git a/test/verify/check-ws-bastion b/test/verify/check-ws-bastion index 78c4788fdff5..9de1e3bd7341 100755 --- a/test/verify/check-ws-bastion +++ b/test/verify/check-ws-bastion @@ -70,19 +70,25 @@ class TestWsBastionContainer(testlib.MachineCase): b.wait_visible('#content') b.wait_text('#current-username', 'admin') + # runs the ssh target's bridge (no beiboot) + m.execute("pgrep -f /usr/bin/[c]ockpit-bridge") b.logout() # remembers the last host via URL, server field should be pre-filled self.assertEqual(b.eval_js("window.location.pathname"), f"/={HOST}/system") - # FIXME: login page does not really set this in the DOM? DOM has empty value, but browser shows the value - # b.wait_text("#server-field", host) # this is only for Cockpit Client b.wait_not_visible("#recent-hosts") - b.set_val("#login-user-input", "admin") - b.set_val("#login-password-input", "foobar") # second time SSH key is known - b.click("#login-button") + b.try_login() + b.wait_visible('#content') + b.logout() + + # disable target bridge, should use beiboot + m.execute("mount -o bind /dev/null /usr/bin/cockpit-bridge") + self.addCleanup(m.execute, "umount /usr/bin/cockpit-bridge") + b.try_login() b.wait_visible('#content') + m.execute("pgrep -f '[p]ython3 -ic # cockpit-bridge'") b.logout() def testKnownHosts(self): @@ -203,6 +209,8 @@ class TestWsBastionContainer(testlib.MachineCase): b.set_val("#login-password-input", KEY_PASSWORD) b.click("#login-button") b.wait_visible('#content') + # runs the ssh target's bridge (no beiboot) + m.execute("pgrep -f /usr/bin/[c]ockpit-bridge") b.logout() # now test with current OpenSSH format @@ -213,8 +221,18 @@ class TestWsBastionContainer(testlib.MachineCase): b.set_val("#login-password-input", KEY_PASSWORD) b.click("#login-button") b.wait_visible('#content') + b.logout() + # disable target bridge, should use beiboot + m.execute("mount -o bind /dev/null /usr/bin/cockpit-bridge") + try: + b.try_login(password=KEY_PASSWORD) + b.wait_visible('#content') + m.execute("pgrep -f '[p]ython3 -ic # cockpit-bridge'") + finally: + m.execute("umount /usr/bin/cockpit-bridge") b.logout() + m.execute("podman rm -f -t0 cockpit-bastion") m.execute("rm /home/admin/.ssh/authorized_keys")