Skip to content

sync: merge OpenWrt upstream main through 244d2f67a5 - #145

Open
fwerkor wants to merge 4824 commits into
mainfrom
sync/openwrt-main-2026-10
Open

fwerkor wants to merge 4824 commits into
mainfrom
sync/openwrt-main-2026-10

Conversation

@fwerkor

@fwerkor fwerkor commented Oct 9, 2026 •

Copy link
Copy Markdown
Owner

Merge current OpenWrt main into CapOS while preserving upstream history and authors.

Core upstream:

  • OpenWrt 244d2f6
  • 4,812 upstream commits were missing from CapOS at the start
  • merged as real Git history, not squashed or re-authored

Feeds are also aligned with current upstream main rather than the old openwrt-25.12 branches:

  • packages 607b3dd1b5bb9c4f01f724eb3788fd21517f2250
  • luci 37e6a6bb654984bfaaeff18bcd7cfa8d9c568a52
  • routing 4b9891b9136259f93294a424507ed24c5e8c1cbd
  • telephony 5d68d53c160a325ea9d03fce393e051573bcc736
  • video 8d4551ceb287527f6a2ba99f9e86ded782a937bb

Conflict handling:

  • 781 initial core-tree conflicts
  • stale OpenWrt 25.12 snapshots, old 6.12 patch queues, package/security backports, and temporary ABI pins were resolved in favor of current OpenWrt
  • CapOS product changes were preserved: ArgosFS rootfs/image support, Snap/WebDesktop/OCI integration, CapOS base package framework, NJU/CapOS mirrors, CapOS CI/branding
  • feed refresh preserves CapOS AppArmor/Snap integration, dbus system.d creation, gpgme target gpgrt-config pin, and LuCI dockerman argument escaping
  • obsolete 6.12 AppArmor backport was dropped with the move to the current 6.18 kernel stack

Intentionally not imported from upstream:

  • OpenWrt-only github-release/kernel/packages workflows, which depend on OpenWrt shared CI infrastructure and overlap CapOS workflows
  • upstream removal of the CapOS labeler workflow
  • OpenWrt project branding
  • mirror pruning that would remove the explicit NJU mirrors or repo.capos.top/sources

Validation:

  • no unresolved merge entries or conflict markers
  • make defconfig completes with current feed-main metadata
  • CONFIG_TARGET_ROOTFS_ARGOSFS=y and CONFIG_TARGET_ROOTFS_PERSIST_VAR=y are retained
  • all repository-native CapOS smoke tests pass
  • the original scanner group collision caused by mixing current core with openwrt-25.12 packages feed is eliminated

l0rdg3x and others added 30 commits October 6, 2026 10:09
The next change calls it from otto_l3_route_trap_hw(), which comes
earlier in the file. Move it, unchanged, to just before that function.
No functional change.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Gennaro Cimmino <gcimmino@rayonra.net>
Link: openwrt/openwrt#25651
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
Four places wrote a route's entry the same way: skip a host route that
a local route shadows, take the host slot it holds or a free one, or
place a prefix row when it has none, then write it. Fold that into
otto_l3_route_install(), which returns 0, or -ENOSPC with the errors
they logged, and let each caller keep its own reaction: with no slot,
otto_l3_host_route_trap() and otto_l3_fib_add_v4() free the route,
otto_l3_route_update_hw() returns before the next hop, and
otto_l3_route_trap_new() leaves it. otto_l3_route_trap_hw() now ends in
otto_l3_route_rewrite(), which writes a route where it already is.

The handling stays the same. The one visible difference is that
otto_l3_route_update_hw() logs "Got slot for route" at debug level, as
the other paths did.

Tested on a Hasivo S1100W-8XGT-SE (RTL9303), main against this change,
in the bench rounds on switch addresses that shadow main routes, on IPv4
multipath with a neighbour going away and coming back, on trap rows and
on source-specific IPv6 routes: 17 of 17, 15 of 15, 46 of 46 and 20 of
20 on both.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Gennaro Cimmino <gcimmino@rayonra.net>
Link: openwrt/openwrt#25651
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
cortexa72 enables ext4 for its eMMC and SD card devices, so the UBI
images of the MikroTik RB5009 are built for ext4 as well. An ext4 file
system in a UBI volume can only be used read-only through ubiblock, so
these images are of no use.

They are broken anyway: the ext4 images are gzipped as a whole, which
moves the metadata of the sysupgrade image into the gzip stream. fwtool
reads the metadata from the end of the file, so sysupgrade rejects the
image with "Image metadata not present".

Build the UBI images for squashfs only.

Link: openwrt/openwrt#25658
Signed-off-by: Paul Spooren <mail@aparcar.org>
gemini enables ext4 for the hard disk image of the D-Link DNS-313, so
the flash images of the DIR-685 are built for ext4 as well. The ext4
root file system is padded to CONFIG_TARGET_ROOTFS_PARTSIZE, which
makes these images about 108 MiB, while the DIR-685 has 32 MiB of
flash.

The ext4 sysupgrade image is broken anyway: the ext4 images are gzipped
as a whole, which moves the image metadata into the gzip stream, so
sysupgrade rejects it with "Image metadata not present".

Build the DIR-685 images for squashfs only, like the StorLink reference
designs.

Link: openwrt/openwrt#25658
Signed-off-by: Paul Spooren <mail@aparcar.org>
Every image is built for all filesystems in FILESYSTEMS. A device that
needs an image only for some of them, e.g. a flash image for squashfs
and a disk image for ext4, can only restrict FILESYSTEMS for the whole
device, which drops its other images as well.

Add FILESYSTEMS/<image> to build an image only for some filesystems of
the device, similar to IMAGE/<image>/<fs> for per filesystem recipes.
Like the recipes, it is not reset between devices, so it should be set
next to the recipe of the image.

Link: openwrt/openwrt#25658
Signed-off-by: Paul Spooren <mail@aparcar.org>
ext4 was added for the SD card images in commit 1b368f1 ("at91: Add
ext4 filesystem"), but root.ubi and factory.bin are built for ext4 as
well. These put the ext4 file system into a UBI volume, which can only
be used read-only through ubiblock, so the images are of no use.

Build root.ubi and factory.bin for squashfs and ubifs only, while the
SD card images are still built for ext4.

Link: openwrt/openwrt#25658
Signed-off-by: Paul Spooren <mail@aparcar.org>
ext4 was added in commit e824864 ("ixp4xx: Add ext4 and rootfs-part
to features") for machines mounting root from an external hard drive.
The ext4 rootfs.bin is only published gzipped, because the build system
implicitly gzips ext4 images.

In preparation for dropping the implicit gzip, build rootfs.bin for
squashfs only and add rootfs.bin.gz for ext4, which is gzipped
explicitly. The published file names stay the same.

Link: openwrt/openwrt#25658
Signed-off-by: Paul Spooren <mail@aparcar.org>
Currently malta defines both `rootfs.img` and `rootfs.img.gz` as IMAGES.
With CONFIG_TARGET_IMAGES_GZIP enabled (the default), the ext4 rootfs.img
is gzipped to the same name, resulting in two recipes for the same file.
Make merges the prerequisites and the `cp` fails, which is hidden by
`.IGNORE`:

    cp: target '...squashfs-rootfs.img.gz': No such file or directory
    make[4]: [Makefile:32: ...squashfs-rootfs.img.gz] Error 1 (ignored)

Since the JSON info is created from $(KDIR)/tmp, the profiles.json lists
images which don't exist on the download server.

Fix this by selecting either the gzipped or plain image based on
CONFIG_TARGET_IMAGES_GZIP, like it's done for armsr and loongarch64.

Link: openwrt/openwrt#25658
Signed-off-by: Paul Spooren <mail@aparcar.org>
Image/Gzip lost its last user with commit df9ffed ("archs38: drop
target") and Image/gzip-ext4-padded-squashfs with commit 8dfa38b
("malta: convert to Device macro image building"). The latter also
calls Image/Build/gzip, which isn't defined anywhere.

Remove both, along with Image/pad-root-squashfs, which was only used by
Image/gzip-ext4-padded-squashfs.

Link: openwrt/openwrt#25658
Signed-off-by: Paul Spooren <mail@aparcar.org>
With CONFIG_TARGET_IMAGES_GZIP enabled, which is the default, ext4
images are gzipped when they are copied to $(BIN_DIR), unless their
name ends with .gz or .dtb. This causes several problems:

- The JSON info contains the uncompressed name and hash, so
  profiles.json lists images which don't exist on the download server:

    profiles.json: openwrt-at91-sam9x-atmel_at91sam9263ek-ext4-root.ubi
    sha256sums:    openwrt-at91-sam9x-atmel_at91sam9263ek-ext4-root.ubi.gz

- The image is gzipped as a whole, including the metadata and signature
  added by append-metadata. fwtool looks for them at the end of the
  file, so sysupgrade rejects these images. Explicitly gzipped images
  run append-metadata after gzip instead.

- A rule for the gzipped name is defined for every image, which clashes
  with images that are built both plain and gzipped, as it was the case
  for malta.

The previous commits removed the ext4 images which can't be used and
gzip the remaining ones explicitly, so drop the implicit gzip. The file
name in $(BIN_DIR) is now always the one from IMAGES. Targets wanting
gzipped images define them explicitly, e.g. sdcard.img.gz, or select
them via CONFIG_TARGET_IMAGES_GZIP like x86, armsr, loongarch64 and
malta. Limit the option to these targets.

The ext4 kernel.bin and factory.bin of ixp4xx, which only contain the
kernel, and the optional ext4 VM images of x86 and armsr are now stored
uncompressed, like their squashfs counterparts.

Link: openwrt/openwrt#25658
Signed-off-by: Paul Spooren <mail@aparcar.org>
zlib-ng decides whether to build its POWER8 and POWER9 sources from a
probe that compiles getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_2_07 and
nothing else, so it accepts any target whose libc has getauxval. On
mpc85xx that offers POWER8 to an e500v2 and the build fails:

  adler32_power8.c:126:13: error: '__builtin_vsx_lxvw4x_v16qi' requires
  the '-mvsx' option

POWER8 is ISA 2.07 and POWER9 is ISA 3.0, 64-bit server ISAs that no
32-bit PowerPC in the tree implements, so turn both off for
ARCH=powerpc. powerpc64 keeps them, where they build and zlib-ng gates
them on HWCAP2 at runtime.

Fixes: b6ab568 ("zlib: switch to zlib-ng 2.3.3 in zlib-compatible mode")
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Current GL-E750 units (V2, sold as "Mudi V2") ship a QCA9887 without
calibration data in its EEPROM, so the 5 GHz radio never comes up:

  ath10k_pci 0000:00:00.0: failed to read device EEPROM at 0000
  ath10k_pci 0000:00:00.0: failed to read calibration data from EEPROM: -22

On V2 the calibration is stored in art at 0x5000 (0x844 bytes, starting
with its length 0x0844). On V1 the radio has calibration in EEPROM and
art is empty at that offset (0xff apart from a MAC address), so the
block cannot simply be wired up as an nvmem cell: doing that on a V1
makes the firmware fail to boot ("wmi unified ready event not
received") and the 5 GHz radio disappears.

Extract the block as the ath10k cal file only when it carries the
expected length header, otherwise leave ath10k to read its EEPROM.

Tested with this script installed on 24.10.8 (kernel 6.6) and on a
main snapshot r36812-13f1e1c66d (kernel 6.18), same results on both:
- GL-E750 V1: the block is discarded, ath10k reports "cal eeprom";
  5 GHz AP on ch 36, VHT80, 23 dBm.
- GL-E750 V2: without the script ath10k fails ("could not probe fw");
  with it the block is used, ath10k reports "cal file" and the 5 GHz
  AP comes up on ch 36, VHT80, 23 dBm with the MAC from art.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Serv Pol <tureens_balsa_7g@icloud.com>
Link: openwrt/openwrt#25606
Signed-off-by: Robert Marko <robimarko@gmail.com>
px5g uses a 512 bit RSA key by default, for rsakey without a size and
for selfsigned without -newkey. mbedtls 3.6 refuses to generate RSA
keys smaller than MBEDTLS_RSA_GEN_KEY_MIN_BITS, which is 1024 bits, so
both commands fail with "error: key generation failed". OpenWrt uses
mbedtls 3.6 since 24.10.

Use 2048 bits as the default RSA key size, like px5g-wolfssl and
OpenSSL do.

Signed-off-by: Josef Schlehofer <pepe.schlehofer@gmail.com>
Link: openwrt/openwrt#25629
Signed-off-by: Robert Marko <robimarko@gmail.com>
Now that we expose the UBI volumes in DTS anyway and have NVMEM support
for ath11k, load the caldata directly via NVMEM.

Signed-off-by: Robert Marko <robimarko@gmail.com>
libdeflate-gzip provides a better compression ratio while beeing fully
compatible with deflate algorithms.

It reduces the kernel size enough for Asrock G10 image to build again.

Signed-off-by: Robert Marko <robimarko@gmail.com>
On RTL838x and RTL839x, SPCL_TRAP_IGMP_CTRL traps IGMP and MLD to the
CPU, and the receive path hands trapped frames to the bridge unmarked,
so the bridge sees every report and forwards it itself. The RTL93xx
setup aims at the same but does neither:

- rteth_930x/931x_hw_init() write VLAN_APP_PKT_CTRL = 0x12, which puts
  2 in IGMP_ACT and MLD_ACT. The action encoding in dal_longan_trap.c
  of the Zyxel XMG1915 GPL U-Boot is 0 forward, 1 trap, 2 copy, 3 trap
  to master, 4 copy to master, so 2 is a copy.
- The actions only apply in a VLAN whose GROUP_MASK selects them, and
  the VLAN writers leave that mask at 0 (RTL930x) or at whatever the
  entry held (RTL931x).

On an RTL9303, VLAN_APP_PKT_CTRL reads back 0x12, every VLAN write the
driver makes carries GROUP_MASK 0, and IGMPv3 and MLDv2 reports reach
the CPU as normal forwarding (reason 63). Forcing one group mask bit at
a time shows bit 2 selecting IGMP and bit 3 MLD.

Trap both (0x9), set bits 2 and 3 in every VLAN entry, and count reason
55 (IGMP_MLD) as trapped, so that the reports reach the bridge unmarked,
as on RTL83xx, and are forwarded by the CPU rather than flooded by the
switch. RTL931x has the same IGMP_ACT and MLD_ACT fields
(rtk_mango_regField_list.c in the D-Link DMS-1250 GPL SDK), and its
VLAN entry carries the 16-bit GROUP_MASK in multicast_grp_mask; that
bits 2 and 3 select IGMP and MLD there as well is taken from RTL930x.

Tested on an RTL9303 (Hasivo S1100W-8XGT-SE), main against this change,
with a bench-only print of the CPU reason and of the DSA mark. On main:
VLAN_APP_PKT_CTRL 0x12, GROUP_MASK 0 in all 21 VLAN writes, 16 IGMPv3
reports with reason 63 and 8 MLDv2 reports with reason 36 (IPv6
hop-by-hop option), all forwarded by the switch and marked. With this
change: 0x9, GROUP_MASK 0x0c in all 21 writes, and the 16 IGMP and 8
MLD reports all arrive with reason 55, trapped and unmarked; tcpdump on
the user port still sees them. RTL931x was not tested.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Gennaro Cimmino <gcimmino@rayonra.net>
Link: openwrt/openwrt#25660
Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
This commit adds a new realtek subtarget rtl960x and some initial
support for rtl960x, or more specifically, the rtl9607c and rtl8198d
based machines. It doesn't add support for Lexra nor ARM architecture
based SoCs in the rtl960x family.

The MIPS Kconfig file was patched to add RTL960X config option.
It relies on MACH_REALTEK_RTL config and rtl-otto platform code.

RTL9607C / RTL8198D are SoCs based on MIPS InterAptiv with 2 cores.
Former SoC is found in many XPON routers while latter is found in
typical wireless routers.

Enable the drivers that are already in the kernel for rtl9607c with their
compatibles in the subtarget device tree. That includes support for I2C,
thermal sensor, internal MDIO, PCIe, CPU NIC, GPIO, SPI-NAND and more.

Flashing however is not supported yet, so only initramfs image booting
is supported. The bootloader on these machines have tftp capabilities
which makes booting the initramfs easier.

Intructions to boot initramfs from bootloader:
1. Connect to UART on the board and power it on.
2. Press a key in the first 2 seconds to interrupt the boot.
3. Enable tftp server with an ip specified by env variable.
4. Run the command "tftp ${freeAddr} initramfs-kernel.bin".
5. After it is loaded, type "bootm" to boot into initramfs.

Signed-off-by: Rustam Adilov <adilov@tutamail.com>
Link: openwrt/openwrt#20064
Signed-off-by: John Crispin <john@phrozen.org>
The BT-PON BT-G711AX is a fiber modem (ONT) based on RTL9607C.

Specifications:

- SoC : Realtek RTL9607C
- RAM : DDR3 256 MiB
- Flash : SPI-NAND 128 MiB (Windbond)
- Ethernet : 4 port GbE Switch
- Fiber : 1x XPON SC/UPC (Semtech GN25L95)
- Phone : 1x RJ11 (Si32192)
- WIFI : RTL8192XBR + RTL8832BR
- LED : 12x (Power, PON, LOS, LAN1-4, TEL, USB, WPS, Wifi 2.4, Wifi 5)
- UART : 4 pin holes on PCB, 115200 8N1
- Button : 3x (WPS, WLAN, Reset)
- USB : 1x USB 2.0
- Power : 12V DC, 1.5A

This device, and many other devices of this platform, use a
dual-image layout inside a single ubi_device partition.

Intructions to boot initramfs can be found in the previous
commit message.

The networking on this device is not supported yet due to lack of DSA
driver support and thus no MAC addresses interfaces to assign in its
device tree file. But the mdio and cpu gmac are supported so the 4
PHYs and 3 GMAC are described along with 4 switch ports in preperation
for upcoming DSA.

Signed-off-by: Rustam Adilov <adilov@tutamail.com>
Link: openwrt/openwrt#20064
Signed-off-by: John Crispin <john@phrozen.org>
Legacy fbdev carries the boot framebuffer on armsr today, through efifb
and the PL111 driver, and armv8 guests on Hyper-V go through hyperv_fb.
A DRM driver can claim the firmware framebuffer on its own, so those
hardware drivers only add size to every image.

Mark the firmware framebuffer as a generic system framebuffer so sysfb
registers it as simple-framebuffer, and let simpledrm bind to it. sysfb
builds that device from the screen_info the EFI stub hands over, so
SystemReady hardware and EDK2 or U-Boot virtual platforms keep their
display. DRM fbdev emulation and fbcon stay, so the boot log and the
console prompt still reach the screen; the emulation serves fbcon, as
generic leaves FB_DEVICE off and no /dev/fb node appears.

armv8 gains hyperv_drm as its Hyper-V driver's help text asks, and loses
the backlight class and the videomode helpers, which a machine with no
panel has no use for. DRM_BOCHS, DRM_QXL and DRM_VIRTIO_GPU are
untouched.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
efifb, the simple-framebuffer fbdev driver, hyperv_fb and xen-fbfront
carry the display on these two subtargets, with fbcon and DRM fbdev
emulation on top. A DRM driver can claim the firmware framebuffer on its
own, so the legacy hardware drivers only add size to every image.

Mark the firmware framebuffer as a generic system framebuffer so sysfb
registers it as simple-framebuffer for simpledrm, and enable hyperv_drm
for Hyper-V guests as its help text asks. DRM fbdev emulation and fbcon
stay, so the boot log and the console prompt still reach the screen; the
emulation serves fbcon, as generic leaves FB_DEVICE off and no /dev/fb
node appears. VGA_CONSOLE and VT stay as well: a BIOS boot through GRUB
pc leaves the machine in VGA text mode, where the firmware offers no
framebuffer for simpledrm to drive, so vgacon is the only console there.
A Xen PV or PVH guest has neither, and keeps its console on hvc0. The
shared x86 config and the legacy and geode subtargets are untouched.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
The fragment carries "# CONFIG_EXPERT is not set" while every other
target inherits CONFIG_EXPERT=y from target/linux/generic. That looks
like an artefact of an imported defconfig, and it has a consequence: a
symbol whose prompt is conditional on EXPERT stops being settable with
EXPERT off and silently takes its own default, so the generic fragment
cannot control it.

CONFIG_VT is one of those, declared bool "Virtual terminal" if EXPERT
with default y, which is why the "# CONFIG_VT is not set" in generic has
no effect on this target today. Drop the override so gemini resolves such
symbols the same way as everything else.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
The TVE200 DRM driver drives the display here; the legacy fbdev stack
only added the framebuffer console on top of it, through DRM fbdev
emulation. Drop it, with the fonts and the boot logo that depend on
fbdev core, and the virtual terminal layer that had nothing left to bind
to. kmscon in the video feed provides a terminal on the KMS device for
anyone who wants one back.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
The fragment builds fbdev core, the framebuffer console, the fonts and
the boot logo for one driver: xen-fbfront, which gives a Xen guest a
display through the vfb protocol. It also builds the backlight class with
nothing to light. No fbdev or DRM display driver is enabled and no module
package provides one, so on bare metal none of it draws anything.

Drop the lot, including the virtual terminal layer. A Xen guest keeps its
console on hvc0.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
The Loongson DRM driver drives the display here; efifb, the
simple-framebuffer fbdev driver and the framebuffer console on top of DRM
fbdev emulation are legacy weight on both kernels. Drop them, the
compiled-in font set and the virtual terminal layer that had nothing left
to bind to; EFI_EARLYCON keeps the 8x16 font it needs. kmscon in the
video feed provides a terminal on the KMS device for anyone who wants one
back.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
The Mediatek DRM driver drives the display here; fbdev core, the
framebuffer console, the fonts and the boot logo rode along on DRM fbdev
emulation. Drop them, and the virtual terminal layer that had nothing
left to bind to. kmscon in the video feed provides a terminal on the KMS
device for anyone who wants one back.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
The fragment enables fbdev core with the Xilinx fbdev driver explicitly
turned off, and the DRM core with its bridge, panel and HDMI helpers and
no display driver at all. No module package provides one either, so none
of it can drive a screen; it is kernel size every image pays for.

Drop it, along with the virtual terminal layer that had nothing to bind
to. A board that drives a panel selects the DRM modules it needs, which
bring the core with them.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
The Atmel HLCDC DRM driver drives the display here. CONFIG_VT is off on
this subtarget and generic leaves FB_DEVICE off, so DRM fbdev emulation
added helper code with neither a console nor a /dev/fb node to show for
it. Drop it.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
The MXSFB DRM driver drives the display here; fbdev, the framebuffer
console and the fonts came in through DRM fbdev emulation. Drop them,
the virtual terminal layer that had nothing left to bind to, and
HW_CONSOLE, which no kernel in the tree defines. kmscon in the video
feed provides a terminal on the KMS device for anyone who wants one
back.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
The Tegra DRM driver drives the display here. CONFIG_VT is off on this
target and generic leaves FB_DEVICE off, so DRM fbdev emulation added
helper code with neither a console nor a /dev/fb node to show for it.
Drop it.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
The tool opens /dev/fb0 and mmaps it. Legacy fbdev and DRM fbdev
emulation are gone from every target except the exempt ones, so the
device node it needs is absent there. Nothing depends on the package.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
packages 607b3dd1b5bb9c4f01f724eb3788fd21517f2250
luci 37e6a6bb654984bfaaeff18bcd7cfa8d9c568a52
routing 4b9891b9136259f93294a424507ed24c5e8c1cbd
telephony 5d68d53c160a325ea9d03fce393e051573bcc736
video 8d4551ceb287527f6a2ba99f9e86ded782a937bb

Retain CapOS AppArmor/Snap integration, the dbus system.d setup,
the target gpgrt-config pin, and the LuCI dockerman argument escaping.
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

Deploying capos with  Cloudflare Pages  Cloudflare Pages

Latest commit: 7697ce1
Status: ✅  Deploy successful!
Preview URL: https://7b46c23a.capos.pages.dev
Branch Preview URL: https://sync-openwrt-main-2026-10.capos.pages.dev

View logs

@chatgpt-codex-connector

Copy link
Copy Markdown

💡 Codex Review

if: github.repository_owner == 'openwrt'

P2 Badge Run the LLM review jobs for the CapOS owner

In this CapOS repository, github.repository_owner is not openwrt, so both this job and the nightly job's identical owner check at line 68 evaluate false for every scheduled or manually dispatched run. The newly added workflow therefore always skips all work; remove these upstream-only guards or change them to the CapOS repository owner.


uses: openwrt/actions-shared-workflows/.github/workflows/build-pr-profile.yml@main

P2 Badge Install CapOS host dependencies before profile builds

For every requested profile build, the referenced reusable workflow generates a fresh target config without disabling TARGET_ROOTFS_ARGOSFS, which defaults to enabled and selects argosfs; its host build resolves Fuse3 through host pkg-config (package/utils/argosfs/Makefile:19-30). I checked the invoked workflow's setup step: unlike CapOS's real-boot workflow, it does not install fuse3 or libfuse3-dev, and the current Ubuntu runner inventory does not provide those development files. As a result, profile builds reach the ArgosFS host build without its native Fuse3 dependency and fail; use a CapOS-specific setup or add these packages to the reusable workflow.


if [ -s "$backup" ]; then
cat "$image" "$backup" > "$bundle"
else
cp "$image" "$bundle"
fi

P1 Badge Verify the ONIE bundle before changing boot state

When the root partition is full or encounters an I/O error, either cat or cp can leave a truncated installer here, but the function ignores that failure, makes the partial file executable, and proceeds to set both GRUB environments for an ONIE reinstall. The subsequent reboot then enters ONIE install mode with an unusable payload instead of retaining a bootable upgrade path; write to a temporary file and verify the command succeeded before updating either grubenv.


grep -q PARTNAME=ONIE-BOOT /sys/class/block/*/uevent 2>/dev/null || return 1
grep -q PARTNAME=OPENWRT-ROOT /sys/class/block/*/uevent 2>/dev/null || return 1

P1 Badge Scope ONIE detection to the active boot disk

On a multi-disk x86 system with ONIE-BOOT and OPENWRT-ROOT labels on an attached or stale disk, these independent repository-wide scans classify the current installation as ONIE even when the running system booted from another disk. find_partname_dev() then independently selects the first matching partitions, so image validation and upgrade staging can be redirected to the wrong device; resolve the active boot disk first and require both labelled partitions to belong to that disk.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@chatgpt-codex-connector

Copy link
Copy Markdown

💡 Codex Review

OPENWRT_VOLUME_LABEL="OPENWRT-ROOT"
OPENWRT_PART_SIZE=512 # MiB -- OpenWrt x86 default is 104; 512 gives headroom

P1 Badge Size the ONIE partition for the configured root filesystem

Replace the fixed 512 MiB size with the configured rootfs size or validate the extracted payload before modifying the disk. When TARGET_ROOTFS_PARTSIZE is set above 512 MiB—or a selected package set simply expands beyond 512 MiB—the artifact still builds, but the installer deletes the existing OPENWRT-ROOT partition, recreates it at only 512 MiB, and then fails partway through extraction, potentially leaving the switch unbootable.


- name: Post build progress
if: steps.request.outputs.requested == 'true'
id: progress
uses: peter-evans/create-or-update-comment@v5

P2 Badge Let fork PR builds proceed without a write token

Do not make the progress-comment write a prerequisite for checkout and build. For pull_request runs from public forks, GitHub restricts GITHUB_TOKEN to read-only despite the requested pull-requests: write permission, so this action fails before the requested profile is built; GitHub documents this restriction for untrusted pull-request workflows in its Actions security guidance. Skip or tolerate the comment step for fork PRs, or separate trusted commenting from the untrusted build.


- name: Post build progress
if: steps.request.outputs.requested == 'true'
id: progress
uses: peter-evans/create-or-update-comment@v5

P2 Badge Let fork PR builds proceed without a write token

Do not make the progress-comment write a prerequisite for checkout and build. For pull_request runs from public forks, GitHub restricts GITHUB_TOKEN to read-only despite the requested pull-requests: write permission, so this action fails before the requested profile is built; GitHub documents this restriction for untrusted pull-request workflows in its Actions security guidance. Skip or tolerate the comment step for fork PRs, or separate trusted commenting from the untrusted build.


# Install on the same disk that holds ONIE-BOOT (demo-installer idiom)
blk_dev=$(blkid | awk -F: '/ONIE-BOOT/ {print $1; exit}' \
| sed -e 's/[0-9]*$//' -e 's/p$//')

P1 Badge Scope ONIE installation to the disk that booted ONIE

Do not select the first globally reported ONIE-BOOT label. When more than one ONIE-capable disk is attached, blkid ordering is not a boot-disk guarantee, so the installer can select a foreign disk and subsequently delete its OPENWRT-ROOT partition even though sysupgrade correctly staged the bundle on the active disk. Resolve the block device backing the running ONIE environment, or otherwise carry the selected disk identity into the installer.


CapOS/include/toplevel.mk

Lines 271 to 272 in 6d45688

[ -f $(CONFIG_CHECK_STAMP) ] && [ -z "$$(find $(CONFIG_CHECK_FILES) -newer $(CONFIG_CHECK_STAMP) \
\( -name .config -o -name conf -o -name '*.in' -o -name 'Config.*' \) -print -quit 2>/dev/null)" ] && exit 0; \

P2 Badge Invalidate the config cache when Kconfig files are deleted

Include relevant directories or another deletion-sensitive input in this freshness check. If a Kconfig file such as config/Config-devel.in is deleted or renamed after the stamp is written, find cannot see the removed file and the changed parent directory does not match any of these name predicates, so subsequent top-level builds incorrectly skip the configuration synchronization check until some surviving watched file changes; the analogous diffconfig cache in the root Makefile has the same problem and can also leave config.buildinfo stale.


ARTIFACT/onie-installer.bin := onie-installer

P1 Badge Sign ONIE installers when firmware signing is enabled

Add an authentication step that is compatible with the self-extracting format instead of publishing the raw onie-installer artifact. Unlike the adjacent combined images, this pipeline never invokes append-metadata, so CONFIG_SIGN_FIRMWARE=y does not append a certificate or signature; on x86, REQUIRE_IMAGE_SIGNATURE is unset and fwtool_check_signature() accepts an absent signature, while platform_check_image() only checks the shebang and PAYLOAD_OFFSET header. Consequently an ONIE sysupgrade silently accepts an unauthenticated installer even in builds configured to sign firmware.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@chatgpt-codex-connector

Copy link
Copy Markdown

💡 Codex Review

if [[ "$PR_BODY" =~ (^|[[:space:]])build[[:space:]]+([a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+) ]]; then

P2 Badge Allow dots in requested device profiles

Valid profiles such as ath79/generic/tplink_tl-wr710n-v2.1 (declared in target/linux/ath79/image/generic-tp-link.mk) cannot be requested because the profile component excludes .. Since the regex also lacks a trailing boundary, that request is accepted as the nonexistent profile tplink_tl-wr710n-v2, so make defconfig drops the device selection and the workflow may build the target's defaults instead of the requested image. Include the characters supported by TARGET_DEVICES and require the match to end at a token boundary.


if: github.repository_owner == 'openwrt'

P2 Badge Run the LLM review workflow for the CapOS repository

This repository is fwerkor/capos (as linked from README.md), so github.repository_owner is not openwrt. This condition skips detect-kernels on every scheduled and manually dispatched run, and the identical owner check on nightly skips the consumer job as well, making the newly added workflow a permanent no-op in CapOS.


needed=$(( (root_kib * 5 / 4 + kernel_kib + 65536 + 1023) / 1024 ))

P2 Badge Reserve space for the complete staged ONIE installer

For larger or poorly compressible images, reserving only 25% of the installed root plus 64 MiB does not leave enough room for platform_do_upgrade_onie() to copy the complete installer—which itself contains a compressed copy of that root—onto OPENWRT-ROOT. Once the installer exceeds this headroom, every sysupgrade fails at the staging cp; size the partition for the installed tree plus the actual installer bundle, backup, and filesystem overhead rather than assuming the bundle fits in 25%.


search --no-floppy --label --set=root $OPENWRT_VOLUME_LABEL

P2 Badge Select the installed root by a unique identifier

When another attached disk also contains an OPENWRT-ROOT filesystem, this label search can select that disk, even though the installer deliberately scoped partitioning to the disk containing the mounted ONIE-BOOT. GRUB's search --label searches devices by filesystem label rather than disk identity (GNU GRUB manual), so the system may load the other installation's kernel or grubenv; use the newly read partition/filesystem UUID to select the root unambiguously.


grub-editenv "$root_mnt/boot/grub/grubenv" set next_entry=ONIE || {

P2 Badge Set ONIE mode before arming the one-shot reboot

If mounting ONIE-BOOT or updating its grubenv fails after this command, next_entry=ONIE remains persisted while onie_mode=install was never set. The generic do_stage2 caller ignores platform_do_upgrade()'s return value and reboots unconditionally, so this failure path boots into ONIE in its previous mode instead of applying the staged installer; update the ONIE mode first or roll back next_entry on every later failure.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment