diff --git a/confluent_client/confluent/vnc.py b/confluent_client/confluent/vnc.py index 360e1ebe..44c0f5d5 100644 --- a/confluent_client/confluent/vnc.py +++ b/confluent_client/confluent/vnc.py @@ -202,9 +202,10 @@ class VNCClient: self.receiver = asyncio.create_task(self._receive_loop()) payload.add_number(2, 1) # Set encodings payload.add_number(0, 1) # Padding - payload.add_number(4, 2) # Number of encodings + payload.add_number(5, 2) # Number of encodings payload.add_number(6, 4) # zlib payload.add_number(7, 4) # tight + payload.add_number(-239, 4) # cursor payload.add_number(-223, 4) # desktopsize payload.add_number(-308, 4) # extended desktopsize payload.flush(self.writer) @@ -339,8 +340,22 @@ class VNCClient: img = Image.open(jpgimg) img.load() self.framebuffer.paste(img, (x, y)) + elif encoding_type == -239: # cursor + cursor_pixels = await self.reader.readexactly(width * height * 4) + mask_row_bytes = (width + 7) // 8 + cursor_mask = await self.reader.readexactly(mask_row_bytes * height) + pixels = np.frombuffer(cursor_pixels, dtype=np.uint8).reshape( + (height, width, 4)).copy() + if width and height: + mask = np.unpackbits( + np.frombuffer(cursor_mask, dtype=np.uint8).reshape( + (height, mask_row_bytes)), + axis=1, bitorder='big')[:, :width] + pixels[:, :, 3] = mask * 0xff + self.cursor = Image.fromarray(pixels, 'RGBA') + self.cursor_hotspot = (x, y) else: - raise Exception(f'Unsupported encoding type: {encoding_type}') + raise Exception(f'Unsupported encoding type: {encoding_type}, x: {x}, y: {y}, width: {width}, height: {height}') async def _read_tight_length(self): length = 0 diff --git a/confluent_osdeploy/el10-diskless/profiles/default/scripts/imageboot.sh b/confluent_osdeploy/el10-diskless/profiles/default/scripts/imageboot.sh index aeb6f601..208a4e4c 100644 --- a/confluent_osdeploy/el10-diskless/profiles/default/scripts/imageboot.sh +++ b/confluent_osdeploy/el10-diskless/profiles/default/scripts/imageboot.sh @@ -7,7 +7,10 @@ mkdir -p /mnt/remoteimg /mnt/remote /mnt/overlay /sysroot set_selinux_context system_u:object_r:bin_t:s0 /opt/confluent/bin/urlmount if [ "untethered" = "$(getarg confluent_imagemethod)" -o "uncompressed" = "$(getarg confluent_imagemethod)" ]; then mount -t tmpfs untethered /mnt/remoteimg - curl https://$confluent_whost/confluent-public/os/$confluent_profile/rootimg.sfs -o /mnt/remoteimg/rootimg.sfs + while ! curl -f https://$confluent_whost/confluent-public/os/$confluent_profile/rootimg.sfs -o /mnt/remoteimg/rootimg.sfs; do + echo "Failed downloading image, retrying..." + sleep $((RANDOM%3)).$((RANDOM)) + done else confluent_urls="$confluent_urls https://$confluent_whost/confluent-public/os/$confluent_profile/rootimg.sfs" /opt/confluent/bin/urlmount $confluent_urls /mnt/remoteimg diff --git a/confluent_osdeploy/el7-diskless/profiles/default/scripts/imageboot.sh b/confluent_osdeploy/el7-diskless/profiles/default/scripts/imageboot.sh index 406dc01b..ff254d2c 100644 --- a/confluent_osdeploy/el7-diskless/profiles/default/scripts/imageboot.sh +++ b/confluent_osdeploy/el7-diskless/profiles/default/scripts/imageboot.sh @@ -2,7 +2,10 @@ mkdir -p /mnt/remoteimg /mnt/remote /mnt/overlay if [ "untethered" = "$(getarg confluent_imagemethod)" ]; then mount -t tmpfs untethered /mnt/remoteimg - curl https://$confluent_mgr/confluent-public/os/$confluent_profile/rootimg.sfs -o /mnt/remoteimg/rootimg.sfs + while ! curl -f https://$confluent_mgr/confluent-public/os/$confluent_profile/rootimg.sfs -o /mnt/remoteimg/rootimg.sfs; do + echo "Failed downloading image, retrying..." + sleep $((RANDOM%3)).$((RANDOM)) + done else confluent_urls="$confluent_urls https://$confluent_mgr/confluent-public/os/$confluent_profile/rootimg.sfs" modprobe fuse diff --git a/confluent_osdeploy/el8-diskless/profiles/default/scripts/imageboot.sh b/confluent_osdeploy/el8-diskless/profiles/default/scripts/imageboot.sh index ac9dd67d..322cd988 100644 --- a/confluent_osdeploy/el8-diskless/profiles/default/scripts/imageboot.sh +++ b/confluent_osdeploy/el8-diskless/profiles/default/scripts/imageboot.sh @@ -7,7 +7,10 @@ mkdir -p /mnt/remoteimg /mnt/remote /mnt/overlay TETHERED=0 if [ "untethered" = "$(getarg confluent_imagemethod)" ]; then mount -t tmpfs untethered /mnt/remoteimg - curl https://$confluent_whost/confluent-public/os/$confluent_profile/rootimg.sfs -o /mnt/remoteimg/rootimg.sfs + while ! curl -f https://$confluent_whost/confluent-public/os/$confluent_profile/rootimg.sfs -o /mnt/remoteimg/rootimg.sfs; do + echo "Failed downloading image, retrying..." + sleep $((RANDOM%3)).$((RANDOM)) + done else TETHERED=1 confluent_urls="$confluent_urls https://$confluent_whost/confluent-public/os/$confluent_profile/rootimg.sfs" diff --git a/confluent_osdeploy/el9-diskless/profiles/default/scripts/imageboot.sh b/confluent_osdeploy/el9-diskless/profiles/default/scripts/imageboot.sh index cac45184..7ca1f1e9 100644 --- a/confluent_osdeploy/el9-diskless/profiles/default/scripts/imageboot.sh +++ b/confluent_osdeploy/el9-diskless/profiles/default/scripts/imageboot.sh @@ -6,7 +6,10 @@ fi mkdir -p /mnt/remoteimg /mnt/remote /mnt/overlay /sysroot if [ "untethered" = "$(getarg confluent_imagemethod)" -o "uncompressed" = "$(getarg confluent_imagemethod)" ]; then mount -t tmpfs untethered /mnt/remoteimg - curl https://$confluent_whost/confluent-public/os/$confluent_profile/rootimg.sfs -o /mnt/remoteimg/rootimg.sfs + while ! curl -f https://$confluent_whost/confluent-public/os/$confluent_profile/rootimg.sfs -o /mnt/remoteimg/rootimg.sfs; do + echo "Failed downloading image, retrying..." + sleep $((RANDOM%3)).$((RANDOM)) + done else confluent_urls="$confluent_urls https://$confluent_whost/confluent-public/os/$confluent_profile/rootimg.sfs" /opt/confluent/bin/urlmount $confluent_urls /mnt/remoteimg diff --git a/confluent_osdeploy/suse15-diskless/profiles/default/scripts/imageboot.sh b/confluent_osdeploy/suse15-diskless/profiles/default/scripts/imageboot.sh index 558510e3..79fc55e5 100644 --- a/confluent_osdeploy/suse15-diskless/profiles/default/scripts/imageboot.sh +++ b/confluent_osdeploy/suse15-diskless/profiles/default/scripts/imageboot.sh @@ -2,7 +2,10 @@ mkdir -p /mnt/remoteimg /mnt/remote /mnt/overlay if [ "untethered" = "$(getarg confluent_imagemethod)" ]; then mount -t tmpfs untethered /mnt/remoteimg - curl https://$confluent_mgr/confluent-public/os/$confluent_profile/rootimg.sfs -o /mnt/remoteimg/rootimg.sfs + while ! curl -f https://$confluent_mgr/confluent-public/os/$confluent_profile/rootimg.sfs -o /mnt/remoteimg/rootimg.sfs; do + echo "Failed downloading image, retrying..." + sleep $((RANDOM%3)).$((RANDOM)) + done else confluent_urls="$confluent_urls https://$confluent_mgr/confluent-public/os/$confluent_profile/rootimg.sfs" /opt/confluent/bin/urlmount $confluent_urls /mnt/remoteimg diff --git a/confluent_osdeploy/suse16-diskless/profiles/default/scripts/imageboot.sh b/confluent_osdeploy/suse16-diskless/profiles/default/scripts/imageboot.sh index 876ecef9..7add1718 100644 --- a/confluent_osdeploy/suse16-diskless/profiles/default/scripts/imageboot.sh +++ b/confluent_osdeploy/suse16-diskless/profiles/default/scripts/imageboot.sh @@ -2,7 +2,10 @@ mkdir -p /mnt/remoteimg /mnt/remote /mnt/overlay if [ "untethered" = "$(getarg confluent_imagemethod)" ]; then mount -t tmpfs untethered /mnt/remoteimg - curl https://$confluent_mgr/confluent-public/os/$confluent_profile/rootimg.sfs -o /mnt/remoteimg/rootimg.sfs + while ! curl -f https://$confluent_mgr/confluent-public/os/$confluent_profile/rootimg.sfs -o /mnt/remoteimg/rootimg.sfs; do + echo "Failed downloading image, retrying..." + sleep $((RANDOM%3)).$((RANDOM)) + done else confluent_urls="$confluent_urls https://$confluent_mgr/confluent-public/os/$confluent_profile/rootimg.sfs" /opt/confluent/bin/urlmount $confluent_urls /mnt/remoteimg diff --git a/confluent_osdeploy/ubuntu20.04-diskless/profiles/default/scripts/imageboot.sh b/confluent_osdeploy/ubuntu20.04-diskless/profiles/default/scripts/imageboot.sh index e0e03879..b09a9e9b 100644 --- a/confluent_osdeploy/ubuntu20.04-diskless/profiles/default/scripts/imageboot.sh +++ b/confluent_osdeploy/ubuntu20.04-diskless/profiles/default/scripts/imageboot.sh @@ -23,7 +23,10 @@ TETHERED=1 if grep -q confluent_imagemethod=untethered /proc/cmdline || grep -q confluent_imagemethod=uncompressed /proc/cmdline; then TETHERED=0 mount -t tmpfs untethered /mnt/remoteimg - curl https://$confluent_mgr/confluent-public/os/$confluent_profile/rootimg.sfs -o /mnt/remoteimg/rootimg.sfs + while ! curl -f https://$confluent_mgr/confluent-public/os/$confluent_profile/rootimg.sfs -o /mnt/remoteimg/rootimg.sfs; do + echo "Failed downloading image, retrying..." + sleep $((RANDOM%3)).$((RANDOM)) + done elif [ -n "$rootimg" ]; then ln -s "$rootimg" /mnt/remoteimg/rootimg.sfs else diff --git a/confluent_server/confluent/httpapi.py b/confluent_server/confluent/httpapi.py index 9ecb4395..4852e678 100644 --- a/confluent_server/confluent/httpapi.py +++ b/confluent_server/confluent/httpapi.py @@ -855,7 +855,9 @@ async def resourcehandler_backend(req, make_response): if default: try: loop = asyncio.get_running_loop() - ip_info = await loop.getaddrinfo(targip, 0, 0, socket.SOCK_STREAM) + ip_info = await loop.getaddrinfo( + targip, 0, family=socket.AF_UNSPEC, + type=socket.SOCK_STREAM) except socket.gaierror: rsp = await make_response('text/plain', 404) await rsp.write(b'hardwaremanagement.manager definition could not be resolved') diff --git a/confluent_server/confluent/plugins/hardwaremanagement/proxmox.py b/confluent_server/confluent/plugins/hardwaremanagement/proxmox.py index 03bd1149..fe62ab1a 100644 --- a/confluent_server/confluent/plugins/hardwaremanagement/proxmox.py +++ b/confluent_server/confluent/plugins/hardwaremanagement/proxmox.py @@ -708,6 +708,10 @@ async def create(nodes, element, configmanager, inputdata): return yield msg.ChildCollection(url) return + elif '_console' not in element: + async for rsp in update([node], element, configmanager, inputdata): + yield rsp + return serialdata = await clientsbynode[node].get_vm_serial(node) yield PmxConsole(serialdata, node, configmanager, clientsbynode[node]) return diff --git a/confluent_server/confluent_server.spec.tmpl b/confluent_server/confluent_server.spec.tmpl index 84a9143e..2dcc2a2f 100644 --- a/confluent_server/confluent_server.spec.tmpl +++ b/confluent_server/confluent_server.spec.tmpl @@ -19,6 +19,12 @@ Prefix: %{_prefix} BuildArch: noarch Requires: confluent_vtbufferd Recommends: rsync +%if 0%{?python3_version_nodots} >= 313 +# 3.13 removed crypt from the stdlib, and stored credentials are hashed with +# it. Recommends rather than Requires: some 3.13 distros package no candidate +# at all, where a hard dependency would make the rpm uninstallable. +Recommends: python3-legacycrypt +%endif %if "%{dist}" == ".el9" Requires: python3-asyncssh, python3-cryptography, confluent_client == %{version}, python3-pyparsing, python3-netifaces, python3-pyasn1 >= 0.2.3, python3-pysnmp >= 4.3.4, python3-lxml, python3-setuptools, python3-dateutil, python3-cffi, python3-pyOpenSSL python3-msgpack python3-libarchive-c python3-yaml python3-yarl python3-aiohttp openssl iproute # httpapi drops passkey support without webauthn, and only BIOS settings on