Skip to content

Commit

Permalink
containers/ws: Enable beibooting and install standard cockpit pages
Browse files Browse the repository at this point in the history
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
  • Loading branch information
martinpitt committed Sep 27, 2024
1 parent 6b8ea93 commit b448046
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 13 deletions.
4 changes: 1 addition & 3 deletions containers/ws/cockpit-auth-ssh-key
Original file line number Diff line number Diff line change
Expand Up @@ -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__':
Expand Down
17 changes: 16 additions & 1 deletion containers/ws/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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/*
Expand Down
12 changes: 8 additions & 4 deletions test/ostree.install
Original file line number Diff line number Diff line change
@@ -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 \
Expand Down
28 changes: 23 additions & 5 deletions test/verify/check-ws-bastion
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down Expand Up @@ -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
Expand All @@ -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")

Expand Down

0 comments on commit b448046

Please sign in to comment.