From da77d0d939c124e2fb1d9bc8a8bc9b195621f7c4 Mon Sep 17 00:00:00 2001 From: Brad House Date: Sat, 13 Jun 2026 22:47:20 +0000 Subject: [PATCH 1/6] stacked PR #1118 Signed-off-by: Brad House --- .github/onie-build/Dockerfile | 103 + .github/workflows/build-onie.yml | 389 + .gitignore | 3 +- README.rst | 7 + README.sbom | 128 + build-config/Makefile | 23 +- build-config/conf/busybox.config | 832 +- build-config/conf/sbom/cpe-overrides.json | 26 + build-config/conf/sbom/license-overrides.json | 11 + build-config/make/acpica-tools.make | 7 +- build-config/make/btrfs-progs.make | 17 +- build-config/make/busybox.make | 2 +- build-config/make/dmidecode.make | 2 +- build-config/make/dosfstools.make | 45 +- build-config/make/dropbear.make | 2 +- build-config/make/efibootmgr.make | 9 +- build-config/make/efivar.make | 28 +- build-config/make/ethtool.make | 9 +- build-config/make/gptfdisk.make | 2 +- build-config/make/grub.make | 13 +- build-config/make/i2ctools.make | 10 +- build-config/make/ipmitool.make | 15 +- build-config/make/kexec-tools.make | 2 +- build-config/make/keyutils.make | 11 +- build-config/make/libaio.make | 90 + build-config/make/libmnl.make | 102 + build-config/make/libpcap.make | 2 +- build-config/make/lvm2.make | 20 +- build-config/make/lzo.make | 2 +- build-config/make/mokutil.make | 2 +- build-config/make/mtdutils.make | 91 +- build-config/make/openssl.make | 17 +- build-config/make/pciutils.make | 6 +- build-config/make/popt.make | 8 +- build-config/make/sbom.make | 84 + build-config/make/tcpdump.make | 2 +- build-config/make/zlib.make | 7 +- build-config/scripts/gen-sbom.py | 366 + build-config/scripts/install-sbom-tools.sh | 129 + build-config/scripts/mk-grub-efi-image | 2 - build-config/scripts/mk-part-table.py | 8 +- build-config/scripts/onie-mk-iso.sh | 6 +- build-config/scripts/sbom-vuln-scan.py | 395 + contrib/git-stats/README.md | 55 - contrib/git-stats/gitdm-config/aliases | 9 - contrib/git-stats/gitdm-config/domain-map | 332 - contrib/git-stats/gitdm-config/filetypes.txt | 362 - contrib/git-stats/gitdm/.gitignore | 2 - contrib/git-stats/gitdm/COPYING | 2 - contrib/git-stats/gitdm/ConfigFile.py | 195 - contrib/git-stats/gitdm/README | 213 - contrib/git-stats/gitdm/changelogs | 131 - contrib/git-stats/gitdm/committags | 101 - contrib/git-stats/gitdm/csvdump.py | 92 - contrib/git-stats/gitdm/database.py | 322 - contrib/git-stats/gitdm/findoldfiles | 35 - contrib/git-stats/gitdm/firstlast | 194 - contrib/git-stats/gitdm/gitdm | 571 - contrib/git-stats/gitdm/gitdm.config | 27 - contrib/git-stats/gitdm/gitlog.py | 204 - contrib/git-stats/gitdm/grabdates | 22 - contrib/git-stats/gitdm/inittags | 82 - contrib/git-stats/gitdm/linetags | 85 - contrib/git-stats/gitdm/logparser.py | 90 - contrib/git-stats/gitdm/patterns.py | 53 - contrib/git-stats/gitdm/reports.py | 463 - contrib/git-stats/gitdm/sample-config/aliases | 5 - .../git-stats/gitdm/sample-config/domain-map | 308 - .../gitdm/sample-config/filetypes.txt | 362 - .../sample-config/xorg/gitdm.config-xserver | 23 - .../gitdm/sample-config/xorg/group-map-apple | 1 - .../gitdm/sample-config/xorg/group-map-intel | 4 - .../gitdm/sample-config/xorg/group-map-redhat | 1 - contrib/git-stats/gitdm/tests/expected-datelc | 2 - .../gitdm/tests/expected-results.txt | 46 - contrib/git-stats/gitdm/tests/gitdm-tests.py | 129 - contrib/git-stats/gitdm/tests/testrepo/HEAD | 1 - contrib/git-stats/gitdm/tests/testrepo/config | 6 - .../git-stats/gitdm/tests/testrepo/info/refs | 1 - .../gitdm/tests/testrepo/objects/info/packs | 2 - ...2fb949b32db1bccdc300fc13de20bca92b4c01.idx | Bin 1912 -> 0 bytes ...fb949b32db1bccdc300fc13de20bca92b4c01.pack | Bin 2883 -> 0 bytes .../gitdm/tests/testrepo/packed-refs | 2 - contrib/git-stats/gitdm/treeplot | 333 - contrib/git-stats/gitdm/utils.py | 37 - contrib/git-stats/onie-git-stats | 94 - contrib/oce/build-onie.py | 20 +- contrib/oce/eyes.py | 6 +- contrib/oce/modules/dnsmasq.py | 16 +- contrib/oce/modules/iscdhcp.py | 12 +- contrib/oce/test-onie.py | 46 +- contrib/onie-server/dhcp-server.py | 88 +- contrib/onie-server/onie-server.py | 64 +- contrib/onie-server/proxy-server.py | 78 +- contrib/onie-server/web-server.py | 8 +- emulation/ci-boot-test.sh | 228 + emulation/ci-install-test.sh | 177 + emulation/ci-oce-test.sh | 240 + .../mellanox/mlnx_x86/test/mlnx_x86_dut.py | 2 +- .../test/fsl_p2020rdbpca_dut.py | 2 +- patches/busybox/dhcp-additional-options.patch | 131 - .../busybox/feature-flash-erase-command.patch | 593 +- patches/busybox/feature-iorw-command.patch | 56 +- .../feature-onie-syseeprom-command.patch | 43 +- .../busybox/feature-onie-syseeprom-disk.patch | 25 +- .../feature-onie-syseeprom-sysfs.patch | 23 +- ...fw_env-modify-crc-size-in-getenvsize.patch | 4 +- patches/busybox/series | 3 +- patches/busybox/u-boot-env-tools.patch | 59 +- .../dmidecode-onie-cross-compile.patch | 31 +- patches/dmidecode/series | 2 +- patches/dosfstools/remove-local-support.patch | 37 - patches/dosfstools/series | 12 +- ..._t-and-char32_t-definitions-for-ONIE.patch | 36 - .../efivar/30/makefile-changes-for-onie.patch | 86 - patches/efivar/30/series | 3 - ...error-path-in-set_disk_and_part_name.patch | 74 - ...ke-all-the-sys-block-link-parsers-wo.patch | 92 - ...to-find-disk-device-symlinks-in-sysf.patch | 209 - ...es-virtual-nvme-fabrics-nvme-subsyst.patch | 309 - ...-Fix-variable-sz-uninitialized-error.patch | 38 - ...x-parsing-for-nvme-subsystem-devices.patch | 91 - ...e-any-variable-we-use-with-sscanf-s-.patch | 76 - ..._t-and-char32_t-definitions-for-ONIE.patch | 1 - .../37/include-search-one-directory-up.patch | 30 - .../efivar/37/makefile-changes-for-onie.patch | 86 - patches/efivar/37/remove-arrows.patch | 357 - patches/efivar/37/series | 12 - .../gptfdisk/add-onie-partition-types.patch | 30 - .../gptfdisk-onie-cross-compile.patch | 47 +- patches/gptfdisk/series | 7 +- .../2.02/bootp_new_net_bootp6_command.patch | 1117 - .../bootp_process_dhcpack_http_boot.patch | 129 - patches/grub/2.02/core_in_fs.patch | 45 - .../2.02/disable-build-of-documentation.patch | 18 - .../grub/2.02/dont-fail-efi-warnings.patch | 47 - .../2.02/efinet_set_dns_from_uefi_proto.patch | 339 - ...efinet_set_network_from_uefi_devpath.patch | 388 - .../2.02/efinet_uefi_ipv6_pxe_support.patch | 126 - patches/grub/2.02/ext4_feature_encrypt.patch | 143 - patches/grub/2.02/gcc7.patch | 23 - patches/grub/2.02/gcc8.patch | 64 - patches/grub/2.02/gettext_quiet.patch | 30 - .../2.02/grub-install-efibootmgr-check.patch | 178 - .../2.02/grub-install-extra-removable.patch | 220 - .../2.02/include-compatible-unifont-bdf.patch | 22543 ---------------- patches/grub/2.02/install_signed.patch | 295 - patches/grub/2.02/linuxefi.patch | 484 - .../linuxefi_add_sb_to_efi_chainload.patch | 816 - .../linuxefi_cleanup_errors_in_loader.patch | 103 - patches/grub/2.02/linuxefi_debug.patch | 99 - .../linuxefi_fix_efi_validation_race.patch | 99 - .../2.02/linuxefi_handle_multiarch_boot.patch | 264 - .../grub/2.02/linuxefi_honor_sb_mode.patch | 534 - .../grub/2.02/linuxefi_load_arm_with_sb.patch | 445 - .../grub/2.02/linuxefi_minor_cleanups.patch | 92 - .../grub/2.02/linuxefi_move_fdt_helper.patch | 95 - .../grub/2.02/linuxefi_no_insmod_on_sb.patch | 121 - .../grub/2.02/linuxefi_non_sb_fallback.patch | 96 - .../2.02/linuxefi_re-enable_linux_cmd.patch | 43 - .../2.02/linuxefi_rework_linux16_cmd.patch | 104 - .../grub/2.02/linuxefi_rework_linux_cmd.patch | 110 - ...linuxefi_rework_non-sb_efi_chainload.patch | 385 - .../2.02/linuxefi_rework_pe_loading.patch | 356 - .../linuxefi_use_dev_chainloader_target.patch | 40 - patches/grub/2.02/maybe_quiet.patch | 380 - .../2.02/misc-fix-invalid-char-strtol.patch | 34 - patches/grub/2.02/mkconfig_loopback.patch | 96 - patches/grub/2.02/mkconfig_mid_upgrade.patch | 39 - .../2.02/mkconfig_nonexistent_loopback.patch | 55 - patches/grub/2.02/mkconfig_other_inits.patch | 90 - .../grub/2.02/mkconfig_recovery_title.patch | 130 - .../grub/2.02/mkconfig_signed_kernel.patch | 48 - patches/grub/2.02/mkrescue_efi_modules.patch | 35 - .../2.02/net_read_bracketed_ipv6_addr.patch | 254 - patches/grub/2.02/probe_fusionio.patch | 76 - patches/grub/2.02/restore_mkdevicemap.patch | 1320 - patches/grub/2.02/series | 34 - .../set-default-graphics-mode-to-text.patch | 27 - patches/grub/2.02/sleep_shift.patch | 95 - .../disable-build-of-documentation.patch | 17 - .../gcc6-use-no-pie-compiler-flag.patch | 62 - .../include-compatible-unifont-bdf.patch | 22543 ---------------- patches/grub/2.02~beta3/series | 5 - .../set-default-graphics-mode-to-text.patch | 27 - patches/grub/2.04/CVE-2020-10713.patch | 68 - .../grub/2.04/at_keyboard-module-init.patch | 44 - .../bash-completion-drop-have-checks.patch | 143 - patches/grub/2.04/blacklist-1440x900x32.patch | 34 - patches/grub/2.04/bootp-alloc.patch | 29 - .../2.04/bootp-new-net_bootp6-command.patch | 1117 - .../bootp-process-dhcpack-http-boot.patch | 122 - patches/grub/2.04/btrfs-raid1c34.patch | 57 - patches/grub/2.04/core-in-fs.patch | 45 - patches/grub/2.04/default-grub-d.patch | 195 - patches/grub/2.04/dejavu-font-path.patch | 23 - patches/grub/2.04/deviceiter-overflow.patch | 51 - patches/grub/2.04/disable-floppies.patch | 37 - .../grub/2.04/dpkg-version-comparison.patch | 38 - .../2.04/efi-halt-reboot-use-after-free.patch | 177 - .../2.04/efi-malformed-device-path-2.patch | 86 - .../grub/2.04/efi-malformed-device-path.patch | 249 - ...efi-variable-storage-minimise-writes.patch | 895 - .../2.04/efinet-set-dns-from-uefi-proto.patch | 339 - ...efinet-set-network-from-uefi-devpath.patch | 388 - .../2.04/efinet-uefi-ipv6-pxe-support.patch | 126 - patches/grub/2.04/emu-free-null.patch | 32 - patches/grub/2.04/fix-lockdown.patch | 45 - patches/grub/2.04/font-name-leak.patch | 36 - patches/grub/2.04/gettext-quiet.patch | 30 - .../2.04/gfxmenu-load-image-double-free.patch | 34 - patches/grub/2.04/gfxpayload-dynamic.patch | 290 - .../grub/2.04/gfxpayload-keep-default.patch | 39 - .../2.04/grub-install-extra-removable.patch | 202 - .../grub/2.04/grub-install-pvxen-paths.patch | 71 - .../2.04/grub-install-removable-shim.patch | 193 - .../2.04/grub-legacy-0-based-partitions.patch | 39 - patches/grub/2.04/grub.cfg-400.patch | 25 - patches/grub/2.04/hfsplus-overflow.patch | 55 - patches/grub/2.04/ieee1275-clear-reset.patch | 32 - .../2.04/ignore-grub_func_test-failures.patch | 29 - .../2.04/insmod-xzio-and-lzopio-on-xen.patch | 33 - .../2.04/install-efi-adjust-distributor.patch | 34 - patches/grub/2.04/install-efi-fallback.patch | 91 - .../grub/2.04/install-locale-langpack.patch | 116 - .../grub/2.04/install-powerpc-machtypes.patch | 220 - patches/grub/2.04/install-signed.patch | 311 - .../grub/2.04/install-stage2-confusion.patch | 46 - patches/grub/2.04/is_sb_enabled_command.patch | 94 - patches/grub/2.04/iso9660-realloc-leak.patch | 67 - patches/grub/2.04/linux-initrd-overflow.patch | 167 - patches/grub/2.04/linux-loader-overflow.patch | 27 - patches/grub/2.04/linuxefi.patch | 550 - patches/grub/2.04/lvm-overflow.patch | 109 - patches/grub/2.04/lzma-overflow.patch | 50 - patches/grub/2.04/maybe-quiet.patch | 386 - patches/grub/2.04/mdraid1x-linux-gcc-10.patch | 53 - patches/grub/2.04/mkconfig-loopback.patch | 96 - .../2.04/mkconfig-nonexistent-loopback.patch | 55 - patches/grub/2.04/mkconfig-other-inits.patch | 90 - .../grub/2.04/mkconfig-recovery-title.patch | 130 - .../grub/2.04/mkconfig-signed-kernel.patch | 48 - .../2.04/mkconfig-ubuntu-distributor.patch | 37 - .../grub/2.04/mkconfig-ubuntu-recovery.patch | 107 - patches/grub/2.04/mkrescue-efi-modules.patch | 35 - patches/grub/2.04/multiboot2-leak.patch | 32 - .../2.04/net-read-bracketed-ipv6-addr.patch | 254 - .../2.04/no-devicetree-if-secure-boot.patch | 67 - patches/grub/2.04/no-insmod-on-sb.patch | 99 - patches/grub/2.04/olpc-prefix-hack.patch | 51 - ...onie-disable-udevadm-in-grub-install.patch | 44 - patches/grub/2.04/ppc64el-disable-vsx.patch | 52 - patches/grub/2.04/probe-fusionio.patch | 76 - patches/grub/2.04/quick-boot-lvm.patch | 77 - patches/grub/2.04/quick-boot.patch | 358 - .../2.04/relocator-chunk-addr-overflow.patch | 148 - .../2.04/relocator-chunk-align-fix-top.patch | 44 - .../relocator-chunk-align-underflow.patch | 336 - patches/grub/2.04/restore-mkdevicemap.patch | 1320 - patches/grub/2.04/safe-alloc-1.patch | 122 - patches/grub/2.04/safe-alloc-2.patch | 241 - patches/grub/2.04/safe-alloc-3.patch | 1821 -- patches/grub/2.04/safe-alloc-4.patch | 1321 - patches/grub/2.04/safe-alloc-5.patch | 149 - .../2.04/script-remove-unused-fields.patch | 31 - patches/grub/2.04/script-use-after-free.patch | 108 - patches/grub/2.04/series | 99 - .../grub/2.04/skip-grub_cmd_set_date.patch | 27 - patches/grub/2.04/sleep-shift.patch | 95 - ...rc64-fix-bios-boot-partition-support.patch | 49 - patches/grub/2.04/term-overflow.patch | 64 - .../grub/2.04/tftp-no-priority-queue.patch | 281 - patches/grub/2.04/udf-leak.patch | 54 - patches/grub/2.04/uefi-firmware-setup.patch | 84 - .../2.04/uefi-secure-boot-cryptomount.patch | 48 - patches/grub/2.04/unix-config-overflow.patch | 84 - .../2.04/verifiers-blocklist-fallout.patch | 41 - .../grub/2.04/vsnprintf-upper-case-hex.patch | 65 - patches/grub/2.04/vt-handoff.patch | 101 - patches/grub/2.04/wubi-no-windows.patch | 57 - .../xen-ignore-xenpolicy-and-config.patch | 52 - ...xen-no-xsm-policy-in-non-xsm-options.patch | 35 - patches/grub/2.04/xen-support-xsm.patch | 72 - patches/grub/2.04/xnu-double-free.patch | 53 - patches/grub/2.04/zfs-gcc-10.patch | 89 - .../grub/2.04/zpool-full-device-name.patch | 33 - patches/i2ctools/gitignore.patch | 18 +- .../i2ctools-onie-cross-compile.patch | 48 +- patches/i2ctools/i2ctools-sys-eeprom.patch | 36 +- patches/i2ctools/series | 2 +- ...mprove-device-tree-directory-sorting.patch | 84 - ...5-25-kexec-tools-add-aarch64-support.patch | 828 - patches/kexec-tools/series | 15 +- .../0001-add-sysmacros.h-to-filter-sysfs.c | 10 - patches/lvm2/series | 9 +- .../0000-Makefile-changes-for-ONIE.patch | 19 +- patches/pciutils/series | 2 +- patches/popt/aarch64_support.patch | 733 - ...opt-workaround-uclibc-glob-pattern-p.patch | 31 - patches/popt/series | 7 +- rootconf/default/etc/init.d/networking.sh | 7 +- rootconf/default/lib/onie/udhcp4_net | 15 + rootconf/default/lib/onie/udhcp4_sd | 56 +- upstream/18.tar.gz.sha1 | 1 + upstream/39.tar.gz.sha1 | 1 + upstream/IPMITOOL_1_8_19.tar.gz.sha1 | 1 + upstream/LVM2.2.03.41.tgz.sha1 | 1 + upstream/acpica-unix-20260408.tar.gz.sha1 | 1 + upstream/btrfs-progs-v7.0.tar.xz.sha1 | 1 + upstream/busybox-1.38.0.tar.bz2.sha1 | 1 + upstream/dmidecode-3.7.tar.xz.sha1 | 1 + upstream/dosfstools-3.0.26.tar.xz.sha1 | 1 - upstream/dosfstools-4.2.tar.gz.sha1 | 1 + upstream/dropbear-2026.91.tar.bz2.sha1 | 1 + upstream/efibootmgr-16.tar.bz2.sha1 | 1 - upstream/efivar-37.tar.bz2.sha1 | 1 - upstream/ethtool-6.15.tar.xz.sha1 | 1 + upstream/gptfdisk-1.0.10.tar.gz.sha1 | 1 + upstream/grub-2.04.tar.xz.sha1 | 1 - upstream/grub-2.14.tar.xz.sha1 | 1 + upstream/i2c-tools-3.1.1.tar.bz2.sha1 | 1 - upstream/i2c-tools-4.4.tar.gz.sha1 | 1 + upstream/kexec-tools-2.0.32.tar.xz.sha1 | 1 + upstream/keyutils-1.6.3.tar.gz.sha1 | 1 + upstream/libaio-0.3.113.tar.gz.sha1 | 1 + upstream/libmnl-1.0.5.tar.bz2.sha1 | 1 + upstream/libpcap-1.10.6.tar.gz.sha1 | 1 + upstream/lzo-2.10.tar.gz.sha1 | 1 + upstream/mtd-utils-2.3.1.tar.bz2.sha1 | 1 + upstream/mtd-utils-e4c8885.tar.gz.sha1 | 1 - upstream/openssl-1.0.2l.tar.gz.sha1 | 1 - upstream/openssl-1.1.1g.tar.gz.sha1 | 1 - upstream/openssl-3.4.0.tar.gz.sha1 | 1 - upstream/openssl-3.5.7.tar.gz.sha1 | 1 + upstream/pciutils-3.15.0.tar.xz.sha1 | 1 + upstream/pciutils-3.2.1.tar.xz.sha1 | 1 - upstream/popt-1.19.tar.gz.sha1 | 1 + upstream/tcpdump-4.99.6.tar.gz.sha1 | 1 + upstream/zlib-1.3.2.tar.xz.sha1 | 1 + 339 files changed, 3784 insertions(+), 81755 deletions(-) create mode 100644 .github/onie-build/Dockerfile create mode 100644 .github/workflows/build-onie.yml create mode 100644 README.sbom create mode 100644 build-config/conf/sbom/cpe-overrides.json create mode 100644 build-config/conf/sbom/license-overrides.json create mode 100644 build-config/make/libaio.make create mode 100644 build-config/make/libmnl.make create mode 100644 build-config/make/sbom.make create mode 100644 build-config/scripts/gen-sbom.py create mode 100755 build-config/scripts/install-sbom-tools.sh create mode 100755 build-config/scripts/sbom-vuln-scan.py delete mode 100644 contrib/git-stats/README.md delete mode 100644 contrib/git-stats/gitdm-config/aliases delete mode 100644 contrib/git-stats/gitdm-config/domain-map delete mode 100644 contrib/git-stats/gitdm-config/filetypes.txt delete mode 100644 contrib/git-stats/gitdm/.gitignore delete mode 100644 contrib/git-stats/gitdm/COPYING delete mode 100644 contrib/git-stats/gitdm/ConfigFile.py delete mode 100644 contrib/git-stats/gitdm/README delete mode 100755 contrib/git-stats/gitdm/changelogs delete mode 100755 contrib/git-stats/gitdm/committags delete mode 100644 contrib/git-stats/gitdm/csvdump.py delete mode 100644 contrib/git-stats/gitdm/database.py delete mode 100755 contrib/git-stats/gitdm/findoldfiles delete mode 100755 contrib/git-stats/gitdm/firstlast delete mode 100755 contrib/git-stats/gitdm/gitdm delete mode 100644 contrib/git-stats/gitdm/gitdm.config delete mode 100644 contrib/git-stats/gitdm/gitlog.py delete mode 100755 contrib/git-stats/gitdm/grabdates delete mode 100755 contrib/git-stats/gitdm/inittags delete mode 100755 contrib/git-stats/gitdm/linetags delete mode 100644 contrib/git-stats/gitdm/logparser.py delete mode 100644 contrib/git-stats/gitdm/patterns.py delete mode 100644 contrib/git-stats/gitdm/reports.py delete mode 100644 contrib/git-stats/gitdm/sample-config/aliases delete mode 100644 contrib/git-stats/gitdm/sample-config/domain-map delete mode 100644 contrib/git-stats/gitdm/sample-config/filetypes.txt delete mode 100644 contrib/git-stats/gitdm/sample-config/xorg/gitdm.config-xserver delete mode 100644 contrib/git-stats/gitdm/sample-config/xorg/group-map-apple delete mode 100644 contrib/git-stats/gitdm/sample-config/xorg/group-map-intel delete mode 100644 contrib/git-stats/gitdm/sample-config/xorg/group-map-redhat delete mode 100644 contrib/git-stats/gitdm/tests/expected-datelc delete mode 100644 contrib/git-stats/gitdm/tests/expected-results.txt delete mode 100755 contrib/git-stats/gitdm/tests/gitdm-tests.py delete mode 100644 contrib/git-stats/gitdm/tests/testrepo/HEAD delete mode 100644 contrib/git-stats/gitdm/tests/testrepo/config delete mode 100644 contrib/git-stats/gitdm/tests/testrepo/info/refs delete mode 100644 contrib/git-stats/gitdm/tests/testrepo/objects/info/packs delete mode 100644 contrib/git-stats/gitdm/tests/testrepo/objects/pack/pack-f62fb949b32db1bccdc300fc13de20bca92b4c01.idx delete mode 100644 contrib/git-stats/gitdm/tests/testrepo/objects/pack/pack-f62fb949b32db1bccdc300fc13de20bca92b4c01.pack delete mode 100644 contrib/git-stats/gitdm/tests/testrepo/packed-refs delete mode 100755 contrib/git-stats/gitdm/treeplot delete mode 100644 contrib/git-stats/gitdm/utils.py delete mode 100755 contrib/git-stats/onie-git-stats create mode 100755 emulation/ci-boot-test.sh create mode 100755 emulation/ci-install-test.sh create mode 100755 emulation/ci-oce-test.sh delete mode 100644 patches/busybox/dhcp-additional-options.patch delete mode 100644 patches/dosfstools/remove-local-support.patch delete mode 100644 patches/efivar/30/XX-Provide-char16_t-and-char32_t-definitions-for-ONIE.patch delete mode 100644 patches/efivar/30/makefile-changes-for-onie.patch delete mode 100644 patches/efivar/30/series delete mode 100644 patches/efivar/37/0001-Fix-the-error-path-in-set_disk_and_part_name.patch delete mode 100644 patches/efivar/37/0002-sysfs-parsers-make-all-the-sys-block-link-parsers-wo.patch delete mode 100644 patches/efivar/37/0003-Try-even-harder-to-find-disk-device-symlinks-in-sysf.patch delete mode 100644 patches/efivar/37/0004-Handle-sys-devices-virtual-nvme-fabrics-nvme-subsyst.patch delete mode 100644 patches/efivar/37/0005-Fix-variable-sz-uninitialized-error.patch delete mode 100644 patches/efivar/37/0006-Fix-parsing-for-nvme-subsystem-devices.patch delete mode 100644 patches/efivar/37/Always-initialize-any-variable-we-use-with-sscanf-s-.patch delete mode 120000 patches/efivar/37/XX-Provide-char16_t-and-char32_t-definitions-for-ONIE.patch delete mode 100644 patches/efivar/37/include-search-one-directory-up.patch delete mode 100644 patches/efivar/37/makefile-changes-for-onie.patch delete mode 100644 patches/efivar/37/remove-arrows.patch delete mode 100644 patches/efivar/37/series delete mode 100644 patches/gptfdisk/add-onie-partition-types.patch delete mode 100644 patches/grub/2.02/bootp_new_net_bootp6_command.patch delete mode 100644 patches/grub/2.02/bootp_process_dhcpack_http_boot.patch delete mode 100644 patches/grub/2.02/core_in_fs.patch delete mode 100644 patches/grub/2.02/disable-build-of-documentation.patch delete mode 100644 patches/grub/2.02/dont-fail-efi-warnings.patch delete mode 100644 patches/grub/2.02/efinet_set_dns_from_uefi_proto.patch delete mode 100644 patches/grub/2.02/efinet_set_network_from_uefi_devpath.patch delete mode 100644 patches/grub/2.02/efinet_uefi_ipv6_pxe_support.patch delete mode 100644 patches/grub/2.02/ext4_feature_encrypt.patch delete mode 100644 patches/grub/2.02/gcc7.patch delete mode 100644 patches/grub/2.02/gcc8.patch delete mode 100644 patches/grub/2.02/gettext_quiet.patch delete mode 100644 patches/grub/2.02/grub-install-efibootmgr-check.patch delete mode 100644 patches/grub/2.02/grub-install-extra-removable.patch delete mode 100644 patches/grub/2.02/include-compatible-unifont-bdf.patch delete mode 100644 patches/grub/2.02/install_signed.patch delete mode 100644 patches/grub/2.02/linuxefi.patch delete mode 100644 patches/grub/2.02/linuxefi_add_sb_to_efi_chainload.patch delete mode 100644 patches/grub/2.02/linuxefi_cleanup_errors_in_loader.patch delete mode 100644 patches/grub/2.02/linuxefi_debug.patch delete mode 100644 patches/grub/2.02/linuxefi_fix_efi_validation_race.patch delete mode 100644 patches/grub/2.02/linuxefi_handle_multiarch_boot.patch delete mode 100644 patches/grub/2.02/linuxefi_honor_sb_mode.patch delete mode 100644 patches/grub/2.02/linuxefi_load_arm_with_sb.patch delete mode 100644 patches/grub/2.02/linuxefi_minor_cleanups.patch delete mode 100644 patches/grub/2.02/linuxefi_move_fdt_helper.patch delete mode 100644 patches/grub/2.02/linuxefi_no_insmod_on_sb.patch delete mode 100644 patches/grub/2.02/linuxefi_non_sb_fallback.patch delete mode 100644 patches/grub/2.02/linuxefi_re-enable_linux_cmd.patch delete mode 100644 patches/grub/2.02/linuxefi_rework_linux16_cmd.patch delete mode 100644 patches/grub/2.02/linuxefi_rework_linux_cmd.patch delete mode 100644 patches/grub/2.02/linuxefi_rework_non-sb_efi_chainload.patch delete mode 100644 patches/grub/2.02/linuxefi_rework_pe_loading.patch delete mode 100644 patches/grub/2.02/linuxefi_use_dev_chainloader_target.patch delete mode 100644 patches/grub/2.02/maybe_quiet.patch delete mode 100644 patches/grub/2.02/misc-fix-invalid-char-strtol.patch delete mode 100644 patches/grub/2.02/mkconfig_loopback.patch delete mode 100644 patches/grub/2.02/mkconfig_mid_upgrade.patch delete mode 100644 patches/grub/2.02/mkconfig_nonexistent_loopback.patch delete mode 100644 patches/grub/2.02/mkconfig_other_inits.patch delete mode 100644 patches/grub/2.02/mkconfig_recovery_title.patch delete mode 100644 patches/grub/2.02/mkconfig_signed_kernel.patch delete mode 100644 patches/grub/2.02/mkrescue_efi_modules.patch delete mode 100644 patches/grub/2.02/net_read_bracketed_ipv6_addr.patch delete mode 100644 patches/grub/2.02/probe_fusionio.patch delete mode 100644 patches/grub/2.02/restore_mkdevicemap.patch delete mode 100644 patches/grub/2.02/series delete mode 100644 patches/grub/2.02/set-default-graphics-mode-to-text.patch delete mode 100644 patches/grub/2.02/sleep_shift.patch delete mode 100644 patches/grub/2.02~beta3/disable-build-of-documentation.patch delete mode 100644 patches/grub/2.02~beta3/gcc6-use-no-pie-compiler-flag.patch delete mode 100644 patches/grub/2.02~beta3/include-compatible-unifont-bdf.patch delete mode 100644 patches/grub/2.02~beta3/series delete mode 100644 patches/grub/2.02~beta3/set-default-graphics-mode-to-text.patch delete mode 100644 patches/grub/2.04/CVE-2020-10713.patch delete mode 100644 patches/grub/2.04/at_keyboard-module-init.patch delete mode 100644 patches/grub/2.04/bash-completion-drop-have-checks.patch delete mode 100644 patches/grub/2.04/blacklist-1440x900x32.patch delete mode 100644 patches/grub/2.04/bootp-alloc.patch delete mode 100644 patches/grub/2.04/bootp-new-net_bootp6-command.patch delete mode 100644 patches/grub/2.04/bootp-process-dhcpack-http-boot.patch delete mode 100644 patches/grub/2.04/btrfs-raid1c34.patch delete mode 100644 patches/grub/2.04/core-in-fs.patch delete mode 100644 patches/grub/2.04/default-grub-d.patch delete mode 100644 patches/grub/2.04/dejavu-font-path.patch delete mode 100644 patches/grub/2.04/deviceiter-overflow.patch delete mode 100644 patches/grub/2.04/disable-floppies.patch delete mode 100644 patches/grub/2.04/dpkg-version-comparison.patch delete mode 100644 patches/grub/2.04/efi-halt-reboot-use-after-free.patch delete mode 100644 patches/grub/2.04/efi-malformed-device-path-2.patch delete mode 100644 patches/grub/2.04/efi-malformed-device-path.patch delete mode 100644 patches/grub/2.04/efi-variable-storage-minimise-writes.patch delete mode 100644 patches/grub/2.04/efinet-set-dns-from-uefi-proto.patch delete mode 100644 patches/grub/2.04/efinet-set-network-from-uefi-devpath.patch delete mode 100644 patches/grub/2.04/efinet-uefi-ipv6-pxe-support.patch delete mode 100644 patches/grub/2.04/emu-free-null.patch delete mode 100644 patches/grub/2.04/fix-lockdown.patch delete mode 100644 patches/grub/2.04/font-name-leak.patch delete mode 100644 patches/grub/2.04/gettext-quiet.patch delete mode 100644 patches/grub/2.04/gfxmenu-load-image-double-free.patch delete mode 100644 patches/grub/2.04/gfxpayload-dynamic.patch delete mode 100644 patches/grub/2.04/gfxpayload-keep-default.patch delete mode 100644 patches/grub/2.04/grub-install-extra-removable.patch delete mode 100644 patches/grub/2.04/grub-install-pvxen-paths.patch delete mode 100644 patches/grub/2.04/grub-install-removable-shim.patch delete mode 100644 patches/grub/2.04/grub-legacy-0-based-partitions.patch delete mode 100644 patches/grub/2.04/grub.cfg-400.patch delete mode 100644 patches/grub/2.04/hfsplus-overflow.patch delete mode 100644 patches/grub/2.04/ieee1275-clear-reset.patch delete mode 100644 patches/grub/2.04/ignore-grub_func_test-failures.patch delete mode 100644 patches/grub/2.04/insmod-xzio-and-lzopio-on-xen.patch delete mode 100644 patches/grub/2.04/install-efi-adjust-distributor.patch delete mode 100644 patches/grub/2.04/install-efi-fallback.patch delete mode 100644 patches/grub/2.04/install-locale-langpack.patch delete mode 100644 patches/grub/2.04/install-powerpc-machtypes.patch delete mode 100644 patches/grub/2.04/install-signed.patch delete mode 100644 patches/grub/2.04/install-stage2-confusion.patch delete mode 100644 patches/grub/2.04/is_sb_enabled_command.patch delete mode 100644 patches/grub/2.04/iso9660-realloc-leak.patch delete mode 100644 patches/grub/2.04/linux-initrd-overflow.patch delete mode 100644 patches/grub/2.04/linux-loader-overflow.patch delete mode 100644 patches/grub/2.04/linuxefi.patch delete mode 100644 patches/grub/2.04/lvm-overflow.patch delete mode 100644 patches/grub/2.04/lzma-overflow.patch delete mode 100644 patches/grub/2.04/maybe-quiet.patch delete mode 100644 patches/grub/2.04/mdraid1x-linux-gcc-10.patch delete mode 100644 patches/grub/2.04/mkconfig-loopback.patch delete mode 100644 patches/grub/2.04/mkconfig-nonexistent-loopback.patch delete mode 100644 patches/grub/2.04/mkconfig-other-inits.patch delete mode 100644 patches/grub/2.04/mkconfig-recovery-title.patch delete mode 100644 patches/grub/2.04/mkconfig-signed-kernel.patch delete mode 100644 patches/grub/2.04/mkconfig-ubuntu-distributor.patch delete mode 100644 patches/grub/2.04/mkconfig-ubuntu-recovery.patch delete mode 100644 patches/grub/2.04/mkrescue-efi-modules.patch delete mode 100644 patches/grub/2.04/multiboot2-leak.patch delete mode 100644 patches/grub/2.04/net-read-bracketed-ipv6-addr.patch delete mode 100644 patches/grub/2.04/no-devicetree-if-secure-boot.patch delete mode 100644 patches/grub/2.04/no-insmod-on-sb.patch delete mode 100644 patches/grub/2.04/olpc-prefix-hack.patch delete mode 100644 patches/grub/2.04/onie-disable-udevadm-in-grub-install.patch delete mode 100644 patches/grub/2.04/ppc64el-disable-vsx.patch delete mode 100644 patches/grub/2.04/probe-fusionio.patch delete mode 100644 patches/grub/2.04/quick-boot-lvm.patch delete mode 100644 patches/grub/2.04/quick-boot.patch delete mode 100644 patches/grub/2.04/relocator-chunk-addr-overflow.patch delete mode 100644 patches/grub/2.04/relocator-chunk-align-fix-top.patch delete mode 100644 patches/grub/2.04/relocator-chunk-align-underflow.patch delete mode 100644 patches/grub/2.04/restore-mkdevicemap.patch delete mode 100644 patches/grub/2.04/safe-alloc-1.patch delete mode 100644 patches/grub/2.04/safe-alloc-2.patch delete mode 100644 patches/grub/2.04/safe-alloc-3.patch delete mode 100644 patches/grub/2.04/safe-alloc-4.patch delete mode 100644 patches/grub/2.04/safe-alloc-5.patch delete mode 100644 patches/grub/2.04/script-remove-unused-fields.patch delete mode 100644 patches/grub/2.04/script-use-after-free.patch delete mode 100644 patches/grub/2.04/series delete mode 100644 patches/grub/2.04/skip-grub_cmd_set_date.patch delete mode 100644 patches/grub/2.04/sleep-shift.patch delete mode 100644 patches/grub/2.04/sparc64-fix-bios-boot-partition-support.patch delete mode 100644 patches/grub/2.04/term-overflow.patch delete mode 100644 patches/grub/2.04/tftp-no-priority-queue.patch delete mode 100644 patches/grub/2.04/udf-leak.patch delete mode 100644 patches/grub/2.04/uefi-firmware-setup.patch delete mode 100644 patches/grub/2.04/uefi-secure-boot-cryptomount.patch delete mode 100644 patches/grub/2.04/unix-config-overflow.patch delete mode 100644 patches/grub/2.04/verifiers-blocklist-fallout.patch delete mode 100644 patches/grub/2.04/vsnprintf-upper-case-hex.patch delete mode 100644 patches/grub/2.04/vt-handoff.patch delete mode 100644 patches/grub/2.04/wubi-no-windows.patch delete mode 100644 patches/grub/2.04/xen-ignore-xenpolicy-and-config.patch delete mode 100644 patches/grub/2.04/xen-no-xsm-policy-in-non-xsm-options.patch delete mode 100644 patches/grub/2.04/xen-support-xsm.patch delete mode 100644 patches/grub/2.04/xnu-double-free.patch delete mode 100644 patches/grub/2.04/zfs-gcc-10.patch delete mode 100644 patches/grub/2.04/zpool-full-device-name.patch delete mode 100644 patches/kexec-tools/0001-Improve-device-tree-directory-sorting.patch delete mode 100644 patches/kexec-tools/15-25-kexec-tools-add-aarch64-support.patch delete mode 100644 patches/lvm2/0001-add-sysmacros.h-to-filter-sysfs.c delete mode 100644 patches/popt/aarch64_support.patch delete mode 100644 patches/popt/popt-workaround-uclibc-glob-pattern-p.patch create mode 100644 upstream/18.tar.gz.sha1 create mode 100644 upstream/39.tar.gz.sha1 create mode 100644 upstream/IPMITOOL_1_8_19.tar.gz.sha1 create mode 100644 upstream/LVM2.2.03.41.tgz.sha1 create mode 100644 upstream/acpica-unix-20260408.tar.gz.sha1 create mode 100644 upstream/btrfs-progs-v7.0.tar.xz.sha1 create mode 100644 upstream/busybox-1.38.0.tar.bz2.sha1 create mode 100644 upstream/dmidecode-3.7.tar.xz.sha1 delete mode 100644 upstream/dosfstools-3.0.26.tar.xz.sha1 create mode 100644 upstream/dosfstools-4.2.tar.gz.sha1 create mode 100644 upstream/dropbear-2026.91.tar.bz2.sha1 delete mode 100644 upstream/efibootmgr-16.tar.bz2.sha1 delete mode 100644 upstream/efivar-37.tar.bz2.sha1 create mode 100644 upstream/ethtool-6.15.tar.xz.sha1 create mode 100644 upstream/gptfdisk-1.0.10.tar.gz.sha1 delete mode 100644 upstream/grub-2.04.tar.xz.sha1 create mode 100644 upstream/grub-2.14.tar.xz.sha1 delete mode 100644 upstream/i2c-tools-3.1.1.tar.bz2.sha1 create mode 100644 upstream/i2c-tools-4.4.tar.gz.sha1 create mode 100644 upstream/kexec-tools-2.0.32.tar.xz.sha1 create mode 100644 upstream/keyutils-1.6.3.tar.gz.sha1 create mode 100644 upstream/libaio-0.3.113.tar.gz.sha1 create mode 100644 upstream/libmnl-1.0.5.tar.bz2.sha1 create mode 100644 upstream/libpcap-1.10.6.tar.gz.sha1 create mode 100644 upstream/lzo-2.10.tar.gz.sha1 create mode 100644 upstream/mtd-utils-2.3.1.tar.bz2.sha1 delete mode 100644 upstream/mtd-utils-e4c8885.tar.gz.sha1 delete mode 100644 upstream/openssl-1.0.2l.tar.gz.sha1 delete mode 100644 upstream/openssl-1.1.1g.tar.gz.sha1 delete mode 100644 upstream/openssl-3.4.0.tar.gz.sha1 create mode 100644 upstream/openssl-3.5.7.tar.gz.sha1 create mode 100644 upstream/pciutils-3.15.0.tar.xz.sha1 delete mode 100644 upstream/pciutils-3.2.1.tar.xz.sha1 create mode 100644 upstream/popt-1.19.tar.gz.sha1 create mode 100644 upstream/tcpdump-4.99.6.tar.gz.sha1 create mode 100644 upstream/zlib-1.3.2.tar.xz.sha1 diff --git a/.github/onie-build/Dockerfile b/.github/onie-build/Dockerfile new file mode 100644 index 000000000..500e8aedf --- /dev/null +++ b/.github/onie-build/Dockerfile @@ -0,0 +1,103 @@ +# ONIE build environment for CI. +# +# Debian 11 is required: onie/build-config/Makefile still pulls in +# python2-era tooling (python-all-dev) that is unavailable on newer +# Debian releases. +# +# This image builds the generic kvm_x86_64 target with secure boot +# enabled. It includes the secure-boot key-generation and EFI signing +# tooling (gnupg2, efitools, sbsigntool), the NSS command-line tools the +# shim signing step shells out to (libnss3-tools: pk12util/certutil), and +# the build dependencies for the pesign that ONIE compiles from source +# (NSS/NSPR dev packages). +FROM debian:11 +WORKDIR /onie + +# Tolerate transient Debian mirror hiccups (connection resets mid-fetch). +RUN echo 'Acquire::Retries "5";' > /etc/apt/apt.conf.d/80-retries + +# Build dependencies for crosstool-NG and the ONIE image. +RUN apt-get update && apt-get install -y \ + autoconf \ + autoconf-archive \ + automake \ + autopoint \ + bc \ + bison \ + bsdmainutils \ + build-essential \ + coreutils \ + cpio \ + curl \ + device-tree-compiler \ + dosfstools \ + efitools \ + fakeroot \ + flex \ + gawk \ + git \ + gnupg2 \ + gperf \ + help2man \ + libefivar-dev \ + libelf-dev \ + libexpat1 \ + libexpat1-dev \ + libncurses5 \ + libncurses5-dev \ + libnspr4-dev \ + libnss3-dev \ + libnss3-tools \ + libpopt-dev \ + libssl-dev \ + libtool \ + libtool-bin \ + locales \ + mtools \ + pkgconf \ + python-all-dev \ + python3-all-dev \ + python3-sphinx \ + python3-venv \ + rst2pdf \ + rsync \ + sbsigntool \ + stgit \ + texinfo \ + tree \ + u-boot-tools \ + unzip \ + util-linux \ + uuid-dev \ + uuid-runtime \ + wget \ + zip \ + xorriso \ + && rm -rf /var/lib/apt/lists/* + +# Generate UTF-8 locale (needed for the uclibc / crosstool-NG build). +RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \ + locale-gen + +# Create the build user with the same UID/GID as the host invoker so +# build artifacts are not left owned by root. Override at build time +# with --build-arg UID=$(id -u) --build-arg GID=$(id -g). +# +# NOTE: -l avoids docker layer-export hangs for large UIDs. +# (https://github.com/moby/moby/issues/5419#issuecomment-41478290) +ARG UID=1000 +ARG GID=1000 +RUN groupadd -g $GID build && \ + useradd -l -m -u $UID -g $GID -s /bin/bash build && \ + chown -R build:build /onie + +USER build + +# /sbin and /usr/sbin hold tools the build invokes. +RUN echo 'export PATH="/sbin:/usr/sbin:$PATH"' >> ~/.bashrc + +# The build runs git commands; give it a default identity. +RUN git config --global user.email "build@example.com" && \ + git config --global user.name "Build User" + +CMD ["/bin/bash", "--login"] diff --git a/.github/workflows/build-onie.yml b/.github/workflows/build-onie.yml new file mode 100644 index 000000000..1c976fd9a --- /dev/null +++ b/.github/workflows/build-onie.yml @@ -0,0 +1,389 @@ +name: Build ONIE (kvm_x86_64) + +# Builds the generic amd64 ONIE image for the kvm_x86_64 target, intended +# to run as a VM under KVM/QEMU. The build follows the upstream-recommended +# containerized flow (see contrib/build-env and machine/kvm_x86_64/INSTALL), +# with secure boot enabled: the workflow generates demonstration signing +# keys and self-signs the shim before building. + +# Run on every push and pull request: the point of this workflow is to +# confirm the change still builds, and the kvm_x86_64 image depends on far +# more than the build files (installer/, rootconf/, patches/, ...), so path +# filtering would risk skipping validation on build-affecting changes. +on: + workflow_dispatch: + inputs: + oce_scope: + description: >- + OCE compliance test scope: "default" (a fast representative + subset, also what push/PR runs) or "full" (the entire OCE + installer+updater sweep, tests 3-121 -- slow, many VM boots). + type: choice + default: default + options: + - default + - full + push: + pull_request: + +# Cancel an in-progress run when a newer commit is pushed to the same ref, +# so stacked pushes don't pile up concurrent builds. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + name: Build kvm_x86_64 + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0 + + - name: Determine host UID/GID + id: ids + run: | + echo "uid=$(id -u)" >> "$GITHUB_OUTPUT" + echo "gid=$(id -g)" >> "$GITHUB_OUTPUT" + + - name: Build the ONIE build-environment image + uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0 + with: + context: .github/onie-build + tags: onie-build-env:latest + build-args: | + UID=${{ steps.ids.outputs.uid }} + GID=${{ steps.ids.outputs.gid }} + load: true + cache-from: type=gha + cache-to: type=gha,mode=max + + # Cache the crosstool-NG cross toolchain -- the long pole of a cold + # build. We cache the whole stamp chain (so make does not rebuild on a + # missing root stamp) but only the parts the warm, no-op path actually + # needs -- NOT the multi-GB crosstool-NG build scratch or ct-ng source + # tree, which are only used while building the toolchain. On a cache + # hit "make xtools" is a no-op and the real build only uses the + # installed toolchain, so dropping the scratch keeps the cache blob + # small and fast/reliable to restore. + # + # build/stamp-project -- top-of-chain project stamp + # build/download -- toolchain tarballs + download stamps + # build/crosstool-ng/stamp -- crosstool-NG build stamps + # build/x-tools/*/stamp -- xtools build stamps + # build/x-tools/*/install -- the installed cross toolchain + # build/x-tools/*/build/.config -- xtools config (an xtools-build prereq) + # + # The key is tied to every input that can change the toolchain -- + # including the Dockerfile, since it defines the compiler/host + # environment the toolchain is built in. No loose restore-keys: any + # input change forces a clean rebuild rather than restoring a + # mismatched toolchain. + - name: Restore cross-toolchain cache + id: xtools-cache + uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 + with: + path: | + build/stamp-project + build/download + build/crosstool-ng/stamp + build/x-tools/*/stamp + build/x-tools/*/install + build/x-tools/*/build/.config + key: onie-xtools-kvm_x86_64-${{ hashFiles('build-config/make/xtools.make', 'build-config/make/crosstool-ng.make', 'build-config/make/compiler.make', 'build-config/conf/crosstool/**', 'patches/crosstool-NG/**', '.github/onie-build/Dockerfile') }} + + # ONIE drives its build with stamp files compared by mtime. A fresh + # checkout gives every repo source file a current mtime, which is newer + # than the restored stamps -- so make would consider the toolchain + # stale and rebuild it (e.g. build/.../.config depends on the + # checked-out conf/crosstool config). A cache hit means the key + # matched, i.e. every toolchain input is unchanged and the restored + # toolchain is valid, so bump the restored artifacts ahead of the + # checkout to make "make xtools" a genuine no-op. + - name: Mark restored toolchain up to date + if: steps.xtools-cache.outputs.cache-hit == 'true' + # Restoring build/stamp-project makes make skip the project-stamp + # recipe, which is what normally creates the project output dirs -- + # so recreate them (build/images is an output, not part of the + # cache, and the kernel install copies vmlinuz into it). + # + # Then touch only the files make compares -- the stamp files and the + # toolchain .config. Do NOT touch the toolchain tree itself: it + # contains read-only binaries and symlinks to host tools (bash, + # make, ...) that touch would follow and fail to update. + # + # Touch them all to ONE identical timestamp (-t), not "now" per file. + # The xtools build stamp depends on .config (xtools.make), and a bare + # `find -exec touch {} +` batches files across calls that can straddle a + # one-second boundary -- leaving .config (touched last) newer than the + # build stamp. make then re-runs `ct-ng build`, which fails because the + # ct-ng binary is intentionally not in the cache. Equal mtimes mean no + # cached target is ever "newer-than" a cached prerequisite, so `make + # xtools` is a reliable no-op; the timestamp is "now" (after checkout), + # so it's also newer than the just-checked-out toolchain config sources. + run: | + mkdir -p build build/images build/download + ts="$(date +%Y%m%d%H%M.%S)" + find build/stamp-project build/download \ + build/crosstool-ng/stamp \ + build/x-tools/*/stamp \ + build/x-tools/*/build/.config \ + -type f -exec touch -t "$ts" {} + + + - name: Build cross toolchain + run: | + docker run --rm --privileged \ + -v "${PWD}:/onie" \ + onie-build-env \ + bash -lc 'cd build-config && make -j"$(nproc)" \ + MACHINE=kvm_x86_64 \ + xtools' + + # Save only on a cache miss, and only after the toolchain build above + # succeeded (default if: success()), so a broken toolchain is never + # cached. Running before the full build means a later-stage failure + # still preserves the toolchain for the next run. + - name: Save cross-toolchain cache + if: steps.xtools-cache.outputs.cache-hit != 'true' + uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5 + with: + path: | + build/stamp-project + build/download + build/crosstool-ng/stamp + build/x-tools/*/stamp + build/x-tools/*/install + build/x-tools/*/build/.config + key: ${{ steps.xtools-cache.outputs.cache-primary-key }} + + - name: Build ONIE + run: | + docker run --rm --privileged \ + -v "${PWD}:/onie" \ + onie-build-env \ + bash -lc 'cd build-config && \ + make MACHINE=kvm_x86_64 signing-keys-generate && \ + make MACHINE=kvm_x86_64 shim-self-sign && \ + make -j"$(nproc)" MACHINE=kvm_x86_64 all recovery-iso demo' + + # Scan the SBOM (produced by `make all`) for known vulnerabilities and + # publish the table to the job log and the run summary. This is a + # report, not a gate: sbom-vuln-scan.py always exits 0 (CVEs already + # fixed by ONIE patches are suppressed via OpenVEX), so it never fails + # the build. The SBOM tools (incl. grype) were provisioned by the SBOM + # step of `make all`. + - name: SBOM vulnerability scan + run: | + docker run --rm \ + -v "${PWD}:/onie" \ + onie-build-env \ + bash -lc 'cd build-config && make MACHINE=kvm_x86_64 sbom-vuln-scan' + for f in build/images/*.sbom.vulns.md; do + [ -f "$f" ] || continue + cat "$f" >> "$GITHUB_STEP_SUMMARY" + done + - name: Upload kvm recovery image + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + with: + name: onie-kvm-recovery-iso + path: build/images/onie-recovery-x86_64-kvm_x86_64-r0.iso + retention-days: 7 + + # The demonstration PK/KEK/db that signed this build's shim/grub/kernel. + # The boot-test job enrolls them into an OVMF varstore to validate the + # secure-boot signature chain. These are the SAME keys this run signed + # with, so the enrolled db matches the shipped image (regenerating would + # not). Demo keys only -- non-sensitive (see machine-security.make). + - name: Upload secure-boot demo keys + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + with: + name: onie-kvm-sb-keys + # Exclude the gpg-agent sockets that signing-keys-generate leaves in + # the gpg-keys dirs -- upload-artifact can't zip sockets and warns + # ENTRYNOTSUPPORTED; only the .pem/.der key material is needed. + path: | + encryption/machines/kvm_x86_64/keys + !encryption/machines/kvm_x86_64/keys/**/S.gpg-agent* + retention-days: 7 + + # Artifacts for the install-test job: the recovery kernel/initrd (booted + # directly in install mode), the ONIE updater (to embed ONIE on a blank + # disk first), and the demo OS installer (the NOS discovery installs). + - name: Upload install-test images + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + with: + name: onie-kvm-install-images + path: | + build/images/kvm_x86_64-r0.vmlinuz + build/images/kvm_x86_64-r0.initrd + build/images/onie-updater-x86_64-kvm_x86_64-r0 + build/images/demo-installer-x86_64-kvm_x86_64-r0.bin + retention-days: 7 + + # Boot the built recovery ISO headlessly under QEMU+OVMF and assert ONIE gets + # past GRUB into the OS (serial-console milestones, no kernel panic). ONIE is + # serial end-to-end (GRUB+kernel+userspace on ttyS0) so a serial capture + # suffices -- no screen scraping/OCR. See emulation/ci-boot-test.sh. + boot-test: + name: Boot test kvm_x86_64 + needs: build + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - name: Enable KVM (grant /dev/kvm access) + run: | + echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' \ + | sudo tee /etc/udev/rules.d/99-kvm4all.rules + sudo udevadm control --reload-rules + sudo udevadm trigger --name-match=kvm + - name: Install QEMU + OVMF + run: | + sudo apt-get update + sudo apt-get install -y --no-install-recommends \ + qemu-system-x86 qemu-utils ovmf python3-virt-firmware + - name: Download kvm recovery image + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 + with: + name: onie-kvm-recovery-iso + path: build/images + - name: Download secure-boot demo keys + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 + with: + name: onie-kvm-sb-keys + path: encryption/machines/kvm_x86_64/keys + # SB-relaxed smoke: plain OVMF on the default 'pc' machine -- proves the + # image boots past GRUB into the OS independent of the SB signature chain. + - name: Boot ONIE (SB-relaxed) and assert it reaches the OS + run: | + SERIAL_LOG="$PWD/onie-boot-serial.log" BOOT_MODE=relaxed \ + emulation/ci-boot-test.sh \ + build/images/onie-recovery-x86_64-kvm_x86_64-r0.iso 300 + # SB-enforced: enroll the demo PK/KEK/db, boot the secboot OVMF on + # q35,smm=on, and assert the shim/grub/kernel chain verifies (plus a + # negative control with db omitted that MUST be rejected). This is the + # signal that catches a broken signing chain in the grub/shim/kernel + # modernization PRs even when the image otherwise builds and boots. + - name: Boot ONIE (SB-enforced) and assert the signing chain verifies + run: | + SERIAL_LOG="$PWD/onie-boot-serial-secureboot.log" BOOT_MODE=secureboot \ + KEYS_DIR="$PWD/encryption/machines/kvm_x86_64/keys" \ + emulation/ci-boot-test.sh \ + build/images/onie-recovery-x86_64-kvm_x86_64-r0.iso 300 + - name: Upload serial logs + if: always() + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + with: + name: onie-boot-serial-log + path: onie-boot-serial*.log + retention-days: 7 + + # Functional discovery-install: prove ONIE actually installs an OS and boots + # it, not just that it reaches rescue. Embed ONIE onto a blank disk, then in + # install mode point discovery (install_url=) at the locally-served demo + # installer, install it, and boot the resulting demo OS -- all headless via + # the serial console. This exercises the real installer path (download, + # exec_installer, the NOS writing GRUB + the OS to disk, the OS booting) that + # the boot-smoke jobs do not. Runs Secure-Boot-relaxed (legacy BIOS) -- the + # signing chain is covered by boot-test. See emulation/ci-install-test.sh. + install-test: + name: Install test kvm_x86_64 + # Chained after boot-test (not parallel) so only one VM-heavy job runs at a + # time, keeping CI resource use low. + needs: boot-test + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - name: Enable KVM (grant /dev/kvm access) + run: | + echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' \ + | sudo tee /etc/udev/rules.d/99-kvm4all.rules + sudo udevadm control --reload-rules + sudo udevadm trigger --name-match=kvm + - name: Install QEMU + run: | + sudo apt-get update + sudo apt-get install -y --no-install-recommends qemu-system-x86 qemu-utils + - name: Download install-test images + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 + with: + name: onie-kvm-install-images + path: build/images + - name: Install demo OS via discovery and boot it + run: | + SERIAL_PREFIX="$PWD/onie-install" \ + emulation/ci-install-test.sh \ + build/images/kvm_x86_64-r0.vmlinuz \ + build/images/kvm_x86_64-r0.initrd \ + build/images/demo-installer-x86_64-kvm_x86_64-r0.bin 600 + - name: Upload install serial logs + if: always() + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + with: + name: onie-install-serial-log + path: onie-install-*.log + retention-days: 7 + + # Run ONIE's own OCE (ONIE Compliance Environment, contrib/oce) compliance + # suite against the image. Where install-test hands ONIE the installer URL + # directly (install_url=), OCE exercises the REAL OCP discovery path: it + # stands up isc-dhcp-server advertising the ONIE VIVSO vendor option (DHCP + # option 125) plus an nginx HTTP server, and ONIE must DHCP, read the VIVSO + # installer URL, and fetch+install the image itself. OCE needs L2 to the DUT + # (it validates the DUT shares the host interface's subnet), so the VM is on a + # tap interface rather than user-mode SLIRP. contrib/oce is python3 (it was + # ported in the python2-to-3 PR this is stacked on). See + # emulation/ci-oce-test.sh. + oce-test: + name: OCE compliance kvm_x86_64 + # Chained after install-test (not parallel) so only one VM-heavy job runs + # at a time, keeping CI resource use low. + needs: install-test + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - name: Enable KVM (grant /dev/kvm access) + run: | + echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' \ + | sudo tee /etc/udev/rules.d/99-kvm4all.rules + sudo udevadm control --reload-rules + sudo udevadm trigger --name-match=kvm + - name: Install QEMU + OCE service backends + python deps + run: | + sudo apt-get update + sudo apt-get install -y --no-install-recommends \ + qemu-system-x86 qemu-utils isc-dhcp-server nginx-light tftpd-hpa \ + dnsmasq dosfstools python3-venv + python3 -m venv /tmp/oce-venv + /tmp/oce-venv/bin/pip install --quiet jinja2 netifaces psutil + - name: Download install-test images + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4 + with: + name: onie-kvm-install-images + path: build/images + - name: Run OCE compliance test (full install/update via OCP discovery) + run: | + # On push/PR (no dispatch input) run the fast "default" subset; a + # human can manually dispatch this workflow with oce_scope=full to + # run the entire OCE installer+updater sweep. + SCOPE="${{ inputs.oce_scope }}" + [ -z "$SCOPE" ] && SCOPE=default + OCE_PYTHON=/tmp/oce-venv/bin/python SERIAL_PREFIX="$PWD/onie-oce" \ + emulation/ci-oce-test.sh \ + build/images/kvm_x86_64-r0.vmlinuz \ + build/images/kvm_x86_64-r0.initrd \ + build/images/demo-installer-x86_64-kvm_x86_64-r0.bin \ + build/images/onie-updater-x86_64-kvm_x86_64-r0 \ + "$SCOPE" + - name: Upload OCE serial logs + if: always() + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + with: + name: onie-oce-serial-log + path: onie-oce-*.log + retention-days: 7 diff --git a/.gitignore b/.gitignore index 1d16db09d..c4cbcecba 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ /cscope.out.po build local.make -onie-installer \ No newline at end of file +onie-installer +encryption/machines/ diff --git a/README.rst b/README.rst index 8d20f7e64..98d7fd193 100644 --- a/README.rst +++ b/README.rst @@ -15,6 +15,13 @@ Building ONIE The recommended way to set up an ONIE build environment is to use a Docker image, as described in the ONIE Documentation under `Preparing An ONIE Build Environment `_. +Software Bill of Materials +========================== + +Every build emits a Software Bill of Materials (CycloneDX 1.6 and SPDX 2.3) +describing the third-party software shipped in the image. See `README.sbom +`_ for details. + ****************************** Mailing List and Collaboration ****************************** diff --git a/README.sbom b/README.sbom new file mode 100644 index 000000000..0a644c10f --- /dev/null +++ b/README.sbom @@ -0,0 +1,128 @@ +============================================ +Software Bill of Materials (SBOM) for ONIE +============================================ + +Every ONIE image is built with a Software Bill of Materials describing the +third-party software it ships. The SBOM is generated automatically as part of +``make all`` and written next to the image, so a fresh build always produces a +matching SBOM. + +What the SBOM describes +======================= + +The SBOM lists the third-party software that is **compiled from source and +installed into that machine's image** -- nothing that is merely a build-time +host tool. Concretely, for the machine being built it covers: + +- every package whose make fragment installs into the image sysroot + (``$(SYSROOTDIR)``) -- e.g. busybox, e2fsprogs, lvm2, util-linux, dropbear, + ... ; and +- the boot / runtime components that are not ordinary sysroot packages: the + Linux kernel, the uClibc-ng C library, the GCC runtime, and the bootloader + (shim / U-Boot). + +Build-only tooling (the crosstool-NG cross compiler, binutils, gdb, autoconf, +ncurses, the SBOM tools themselves, ...) is intentionally **excluded** -- it is +not present in the shipped image. + +For each component the SBOM records the name, the exact version actually built, +the upstream (canonical, non-mirror) source URL, the source tarball's SHA-256, +the list of ONIE patches applied (as CycloneDX *pedigree*), and the SPDX +license. + +Output +====== + +Two files are written to ``build/images/`` per machine:: + + .sbom.cdx.json CycloneDX 1.6 (source of truth) + .sbom.spdx.json SPDX 2.3 (derived via cyclonedx-cli) + +CycloneDX 1.6 is the authoritative document; the SPDX 2.3 file is converted +from it. This matches the formats published by the SONiC project. + +How it is invoked +================= + +The SBOM is part of the default ``all`` target, so an ordinary build emits it:: + + make -j$(nproc) MACHINE=kvm_x86_64 all + +To (re)generate just the SBOM for an already-built image:: + + make MACHINE=kvm_x86_64 sbom + +To remove the SBOM artifacts:: + + make MACHINE=kvm_x86_64 sbom-clean + +The generator is ``build-config/scripts/gen-sbom.py``. It is fully +machine-agnostic: it introspects the build system to discover the enabled +packages and their final versions, and detects licenses from the package +sources, which are already extracted on disk by the time the sysroot is +assembled. There is nothing machine-specific to maintain. + +Tooling +======= + +``gen-sbom.py`` uses three external tools: + +============== ============================================= ========== +Tool Purpose Required? +============== ============================================= ========== +askalono SPDX license detection from package sources for licenses +cyclonedx-cli CycloneDX -> SPDX 2.3 conversion for SPDX output +grype vulnerability scan (optional helper, below) optional +============== ============================================= ========== + +If these tools are not already on ``PATH``, the build provisions them +automatically -- pinned to specific versions and verified against hard-coded +SHA-256 hashes -- into a build-local prefix (``build/sbom-tools/bin``). This +requires no root and works in any build environment, so a full-fidelity SBOM is +produced whether you build in the ONIE Docker environment, natively, or in CI. + +The provisioning is performed by ``build-config/scripts/install-sbom-tools.sh``, +which you can also run by hand to pre-populate the tools, optionally choosing +the install directory:: + + # system-wide (needs root) + sudo build-config/scripts/install-sbom-tools.sh + + # or into a chosen prefix, no root required + build-config/scripts/install-sbom-tools.sh /path/to/bin + +**Offline / air-gapped builds:** the tools are fetched over the network the +first time they are needed. Pre-install them with the script above (while +online) so the build finds them on ``PATH`` and downloads nothing. + +**Graceful degradation:** if the tools are unavailable and cannot be +provisioned (e.g. no network), the build still succeeds and still emits a +CycloneDX SBOM -- but license fields fall back to ``NOASSERTION`` and the SPDX +file is skipped. A warning is printed in that case. + +License detection and overrides +=============================== + +Licenses are detected automatically by askalono scanning the +``COPYING`` / ``LICENSE`` / ``COPYRIGHT`` files in each extracted source tree. +A handful of components are genuinely multi-licensed or have no single +top-level license file where automatic detection is ambiguous; those carry a +declared SPDX expression in:: + + build-config/conf/sbom/license-overrides.json + +The override is keyed by make-fragment name and always wins over detection. +Add an entry there if a component reports ``NOASSERTION`` but its license is +known. + +Vulnerability scanning (optional) +================================= + +An optional helper scans the generated SBOM against the grype vulnerability +database, suppressing CVEs that ONIE has already fixed by patch (recorded as +OpenVEX):: + + make MACHINE=kvm_x86_64 sbom-vuln-scan + +This writes ``.sbom.vulns.json`` to ``build/images/``. It is +not part of ``all`` -- run it explicitly when you want a vulnerability report. diff --git a/build-config/Makefile b/build-config/Makefile index 57c90c9d1..380477658 100644 --- a/build-config/Makefile +++ b/build-config/Makefile @@ -398,6 +398,8 @@ ifeq ($(GPT_ENABLE),yes) include make/gptfdisk.make endif ifeq ($(LVM2_ENABLE),yes) + # lvm2 >= 2.03 requires libaio for its bcache I/O engine. + include make/libaio.make include make/lvm2.make endif ifeq ($(PARTED_ENABLE),yes) @@ -420,6 +422,8 @@ ifeq ($(DMIDECODE_ENABLE),yes) include make/dmidecode.make endif ifeq ($(ETHTOOL_ENABLE),yes) + # ethtool's netlink interface needs libmnl. + include make/libmnl.make include make/ethtool.make endif ifeq ($(MTREE_ENABLE),yes) @@ -508,6 +512,7 @@ endif include make/images.make include make/demo.make +include make/sbom.make # By default do not enable building firmware updates FIRMWARE_UPDATE_ENABLE ?= no @@ -515,13 +520,11 @@ ifeq ($(FIRMWARE_UPDATE_ENABLE),yes) include make/firmware-update.make endif -# Pre Debian 11 environments just had /usr/bin/python -# Now the environment distinguishes between python2 and python3 -# If 'python' is not present, default to python2 -ifeq (, $(shell which python )) - export PYTHON=python2 -endif - +# Some sub-package build scripts (notably grub's autogen.sh) invoke the +# interpreter as "${PYTHON:-python}". A bare "python" no longer exists on +# modern systems now that python2 is gone, so point $(PYTHON) at python3. +# (grub's build scripts -- gentpl.py, import_gcry.py -- are python3-safe.) +export PYTHON ?= python3 #------------------------------------------------------------------------------- # @@ -537,7 +540,7 @@ download: $(DOWNLOAD) $(Q) echo "=== Finished making $@ ===" PHONY += all -all: $(KERNEL) $(UBOOT) $(SYSROOT) $(IMAGE) +all: $(KERNEL) $(UBOOT) $(SYSROOT) $(IMAGE) $(SBOM_STAMP) $(Q) echo "=== Finished making onie-$(PLATFORM) $(LSB_RELEASE_TAG) ===" PHONY += demo @@ -594,11 +597,11 @@ machine-prefix: # The onie/build-config/scripts/onie-build-targets.json file lists # platforms and known working build environments. DEBIAN_BUILD_HOST_PACKAGES = build-essential stgit u-boot-tools util-linux \ - gperf device-tree-compiler python-all-dev xorriso \ + gperf device-tree-compiler python3-all-dev xorriso \ autoconf automake bison flex texinfo libtool libtool-bin \ gawk libncurses5 libncurses5-dev bc \ dosfstools mtools pkg-config git wget help2man libexpat1 \ - libexpat1-dev fakeroot python-sphinx rst2pdf \ + libexpat1-dev fakeroot python3-sphinx rst2pdf \ libefivar-dev libnss3-tools libnss3-dev libpopt-dev \ libssl-dev sbsigntool uuid-runtime uuid-dev cpio \ bsdmainutils unzip diff --git a/build-config/conf/busybox.config b/build-config/conf/busybox.config index 3cb98e71d..24eaf4131 100644 --- a/build-config/conf/busybox.config +++ b/build-config/conf/busybox.config @@ -1,59 +1,43 @@ # # Automatically generated make config: don't edit -# Busybox version: 1.25.1 -# Mon Feb 6 14:00:48 2017 +# Busybox version: 1.38.0 +# Wed Jun 3 03:36:56 2026 # CONFIG_HAVE_DOT_CONFIG=y # -# Busybox Settings -# - -# -# General Configuration +# Settings # # CONFIG_DESKTOP is not set # CONFIG_EXTRA_COMPAT is not set +# CONFIG_FEDORA_COMPAT is not set # CONFIG_INCLUDE_SUSv2 is not set -# CONFIG_USE_PORTABLE_CODE is not set -CONFIG_PLATFORM_LINUX=y -CONFIG_FEATURE_BUFFERS_USE_MALLOC=y -# CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set -# CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set +CONFIG_LONG_OPTS=y CONFIG_SHOW_USAGE=y CONFIG_FEATURE_VERBOSE_USAGE=y CONFIG_FEATURE_COMPRESS_USAGE=y -CONFIG_BUSYBOX=y -# CONFIG_FEATURE_INSTALLER is not set -# CONFIG_INSTALL_NO_USR is not set -# CONFIG_LOCALE_SUPPORT is not set -# CONFIG_UNICODE_SUPPORT is not set -# CONFIG_UNICODE_USING_LOCALE is not set -# CONFIG_FEATURE_CHECK_UNICODE_IN_ENV is not set -CONFIG_SUBST_WCHAR=0 -CONFIG_LAST_SUPPORTED_WCHAR=0 -# CONFIG_UNICODE_COMBINING_WCHARS is not set -# CONFIG_UNICODE_WIDE_WCHARS is not set -# CONFIG_UNICODE_BIDI_SUPPORT is not set -# CONFIG_UNICODE_NEUTRAL_TABLE is not set -# CONFIG_UNICODE_PRESERVE_BROKEN is not set +CONFIG_LFS=y +CONFIG_TIME64=y # CONFIG_PAM is not set -# CONFIG_FEATURE_USE_SENDFILE is not set -CONFIG_LONG_OPTS=y CONFIG_FEATURE_DEVPTS=y -# CONFIG_FEATURE_CLEAN_UP is not set # CONFIG_FEATURE_UTMP is not set # CONFIG_FEATURE_WTMP is not set CONFIG_FEATURE_PIDFILE=y CONFIG_PID_FILE_PATH="/var/run" +CONFIG_BUSYBOX=y +CONFIG_FEATURE_SHOW_SCRIPT=y +# CONFIG_FEATURE_INSTALLER is not set +CONFIG_FEATURE_VERSION=y +# CONFIG_INSTALL_NO_USR is not set CONFIG_FEATURE_SUID=y CONFIG_FEATURE_SUID_CONFIG=y CONFIG_FEATURE_SUID_CONFIG_QUIET=y -# CONFIG_SELINUX is not set # CONFIG_FEATURE_PREFER_APPLETS is not set CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe" +# CONFIG_SELINUX is not set +# CONFIG_FEATURE_CLEAN_UP is not set +CONFIG_FEATURE_SYSLOG_INFO=y CONFIG_FEATURE_SYSLOG=y -# CONFIG_FEATURE_HAVE_RPC is not set # # Build Options @@ -62,26 +46,17 @@ CONFIG_FEATURE_SYSLOG=y # CONFIG_PIE is not set # CONFIG_NOMMU is not set # CONFIG_BUILD_LIBBUSYBOX is not set +# CONFIG_FEATURE_LIBBUSYBOX_STATIC is not set # CONFIG_FEATURE_INDIVIDUAL is not set # CONFIG_FEATURE_SHARED_BUSYBOX is not set -CONFIG_LFS=y CONFIG_CROSS_COMPILER_PREFIX="" CONFIG_SYSROOT="" CONFIG_EXTRA_CFLAGS="" CONFIG_EXTRA_LDFLAGS="" CONFIG_EXTRA_LDLIBS="" - -# -# Debugging Options -# -# CONFIG_DEBUG is not set -# CONFIG_DEBUG_PESSIMIZE is not set -# CONFIG_DEBUG_SANITIZE is not set -# CONFIG_UNIT_TEST is not set -# CONFIG_WERROR is not set -CONFIG_NO_DEBUG_LIB=y -# CONFIG_DMALLOC is not set -# CONFIG_EFENCE is not set +# CONFIG_USE_PORTABLE_CODE is not set +CONFIG_STACK_OPTIMIZATION_386=y +CONFIG_STATIC_LIBGCC=y # # Installation Options ("make install" behavior) @@ -96,16 +71,40 @@ CONFIG_INSTALL_APPLET_SYMLINKS=y CONFIG_PREFIX="./_install" # -# Busybox Library Tuning +# Debugging Options +# +# CONFIG_DEBUG is not set +# CONFIG_DEBUG_PESSIMIZE is not set +# CONFIG_DEBUG_SANITIZE is not set +# CONFIG_UNIT_TEST is not set +# CONFIG_WERROR is not set +# CONFIG_WARN_SIMPLE_MSG is not set +CONFIG_NO_DEBUG_LIB=y +# CONFIG_DMALLOC is not set +# CONFIG_EFENCE is not set + +# +# Library Tuning # # CONFIG_FEATURE_USE_BSS_TAIL is not set +CONFIG_FLOAT_DURATION=y CONFIG_FEATURE_RTMINMAX=y +CONFIG_FEATURE_RTMINMAX_USE_LIBC_DEFINITIONS=y +CONFIG_FEATURE_BUFFERS_USE_MALLOC=y +# CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set +# CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set CONFIG_PASSWORD_MINLEN=6 CONFIG_MD5_SMALL=1 +CONFIG_SHA1_SMALL=3 +CONFIG_SHA1_HWACCEL=y +CONFIG_SHA256_HWACCEL=y CONFIG_SHA3_SMALL=1 -CONFIG_FEATURE_FAST_TOP=y -# CONFIG_FEATURE_ETC_NETWORKS is not set -CONFIG_FEATURE_USE_TERMIOS=y +CONFIG_FEATURE_NON_POSIX_CP=y +# CONFIG_FEATURE_VERBOSE_CP_MESSAGE is not set +# CONFIG_FEATURE_USE_SENDFILE is not set +CONFIG_FEATURE_COPYBUF_KB=4 +# CONFIG_MONOTONIC_SYSCALL is not set +CONFIG_IOCTL_HEX2STR_ERROR=y CONFIG_FEATURE_EDITING=y CONFIG_FEATURE_EDITING_MAX_LEN=1024 # CONFIG_FEATURE_EDITING_VI is not set @@ -116,14 +115,22 @@ CONFIG_FEATURE_REVERSE_SEARCH=y CONFIG_FEATURE_TAB_COMPLETION=y # CONFIG_FEATURE_USERNAME_COMPLETION is not set CONFIG_FEATURE_EDITING_FANCY_PROMPT=y +CONFIG_FEATURE_EDITING_WINCH=y # CONFIG_FEATURE_EDITING_ASK_TERMINAL is not set -CONFIG_FEATURE_NON_POSIX_CP=y -# CONFIG_FEATURE_VERBOSE_CP_MESSAGE is not set -CONFIG_FEATURE_COPYBUF_KB=4 -CONFIG_FEATURE_SKIP_ROOTFS=y -# CONFIG_MONOTONIC_SYSCALL is not set -CONFIG_IOCTL_HEX2STR_ERROR=y -# CONFIG_FEATURE_HWIB is not set +# CONFIG_LOCALE_SUPPORT is not set +# CONFIG_UNICODE_SUPPORT is not set +# CONFIG_UNICODE_USING_LOCALE is not set +# CONFIG_FEATURE_CHECK_UNICODE_IN_ENV is not set +CONFIG_SUBST_WCHAR=0 +CONFIG_LAST_SUPPORTED_WCHAR=0 +# CONFIG_UNICODE_COMBINING_WCHARS is not set +# CONFIG_UNICODE_WIDE_WCHARS is not set +# CONFIG_UNICODE_BIDI_SUPPORT is not set +# CONFIG_UNICODE_NEUTRAL_TABLE is not set +# CONFIG_UNICODE_PRESERVE_BROKEN is not set +# CONFIG_LOOP_CONFIGURE is not set +# CONFIG_NO_LOOP_CONFIGURE is not set +CONFIG_TRY_LOOP_CONFIGURE=y # # Applets @@ -142,92 +149,105 @@ CONFIG_FEATURE_AR_LONG_FILENAMES=y CONFIG_FEATURE_AR_CREATE=y # CONFIG_UNCOMPRESS is not set CONFIG_GUNZIP=y +CONFIG_ZCAT=y # CONFIG_FEATURE_GUNZIP_LONG_OPTIONS is not set CONFIG_BUNZIP2=y +CONFIG_BZCAT=y # CONFIG_UNLZMA is not set -# CONFIG_FEATURE_LZMA_FAST is not set +CONFIG_LZCAT=y # CONFIG_LZMA is not set CONFIG_UNXZ=y +CONFIG_XZCAT=y CONFIG_XZ=y CONFIG_BZIP2=y +CONFIG_BZIP2_SMALL=8 +CONFIG_FEATURE_BZIP2_DECOMPRESS=y CONFIG_CPIO=y CONFIG_FEATURE_CPIO_O=y CONFIG_FEATURE_CPIO_P=y +CONFIG_FEATURE_CPIO_IGNORE_DEVNO=y +CONFIG_FEATURE_CPIO_RENUMBER_INODES=y CONFIG_DPKG=y CONFIG_DPKG_DEB=y -# CONFIG_FEATURE_DPKG_DEB_EXTRACT_ONLY is not set CONFIG_GZIP=y CONFIG_FEATURE_GZIP_LONG_OPTIONS=y CONFIG_GZIP_FAST=0 # CONFIG_FEATURE_GZIP_LEVELS is not set +CONFIG_FEATURE_GZIP_DECOMPRESS=y CONFIG_LZOP=y +# CONFIG_UNLZOP is not set +# CONFIG_LZOPCAT is not set # CONFIG_LZOP_COMPR_HIGH is not set -# CONFIG_RPM2CPIO is not set # CONFIG_RPM is not set +# CONFIG_RPM2CPIO is not set CONFIG_TAR=y +CONFIG_FEATURE_TAR_LONG_OPTIONS=y CONFIG_FEATURE_TAR_CREATE=y CONFIG_FEATURE_TAR_AUTODETECT=y CONFIG_FEATURE_TAR_FROM=y CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY=y CONFIG_FEATURE_TAR_OLDSUN_COMPATIBILITY=y CONFIG_FEATURE_TAR_GNU_EXTENSIONS=y -CONFIG_FEATURE_TAR_LONG_OPTIONS=y CONFIG_FEATURE_TAR_TO_COMMAND=y CONFIG_FEATURE_TAR_UNAME_GNAME=y CONFIG_FEATURE_TAR_NOPRESERVE_TIME=y # CONFIG_FEATURE_TAR_SELINUX is not set CONFIG_UNZIP=y +CONFIG_FEATURE_UNZIP_CDF=y +# CONFIG_FEATURE_UNZIP_BZIP2 is not set +# CONFIG_FEATURE_UNZIP_LZMA is not set +# CONFIG_FEATURE_UNZIP_XZ is not set +# CONFIG_FEATURE_LZMA_FAST is not set +# CONFIG_FEATURE_PATH_TRAVERSAL_PROTECTION is not set # # Coreutils # +# CONFIG_FEATURE_VERBOSE is not set + +# +# Common options for date and touch +# +# CONFIG_FEATURE_TIMEZONE is not set + +# +# Common options for cp and mv +# +CONFIG_FEATURE_PRESERVE_HARDLINKS=y + +# +# Common options for df, du, ls +# +CONFIG_FEATURE_HUMAN_READABLE=y CONFIG_BASENAME=y CONFIG_CAT=y -CONFIG_DATE=y -CONFIG_FEATURE_DATE_ISOFMT=y -# CONFIG_FEATURE_DATE_NANO is not set -CONFIG_FEATURE_DATE_COMPAT=y -CONFIG_DD=y -CONFIG_FEATURE_DD_SIGNAL_HANDLING=y -CONFIG_FEATURE_DD_THIRD_STATUS_LINE=y -CONFIG_FEATURE_DD_IBS_OBS=y -# CONFIG_FEATURE_DD_STATUS is not set -CONFIG_HOSTID=y -CONFIG_ID=y -CONFIG_GROUPS=y -# CONFIG_SHUF is not set -CONFIG_STAT=y -CONFIG_FEATURE_STAT_FORMAT=y -CONFIG_FEATURE_STAT_FILESYSTEM=y -CONFIG_SYNC=y -# CONFIG_FEATURE_SYNC_FANCY is not set -CONFIG_TEST=y -CONFIG_FEATURE_TEST_64=y -CONFIG_TOUCH=y -# CONFIG_FEATURE_TOUCH_NODEREF is not set -CONFIG_FEATURE_TOUCH_SUSV3=y -CONFIG_TR=y -CONFIG_FEATURE_TR_CLASSES=y -CONFIG_FEATURE_TR_EQUIV=y -# CONFIG_TRUNCATE is not set -# CONFIG_UNLINK is not set -CONFIG_BASE64=y -# CONFIG_WHO is not set -# CONFIG_USERS is not set -CONFIG_CAL=y -CONFIG_CATV=y +CONFIG_FEATURE_CATN=y +CONFIG_FEATURE_CATV=y CONFIG_CHGRP=y CONFIG_CHMOD=y CONFIG_CHOWN=y CONFIG_FEATURE_CHOWN_LONG_OPTIONS=y CONFIG_CHROOT=y CONFIG_CKSUM=y +CONFIG_CRC32=y CONFIG_COMM=y CONFIG_CP=y CONFIG_FEATURE_CP_LONG_OPTIONS=y +CONFIG_FEATURE_CP_REFLINK=y CONFIG_CUT=y +CONFIG_FEATURE_CUT_REGEX=y +CONFIG_DATE=y +CONFIG_FEATURE_DATE_ISOFMT=y +# CONFIG_FEATURE_DATE_NANO is not set +CONFIG_FEATURE_DATE_COMPAT=y +CONFIG_DD=y +CONFIG_FEATURE_DD_SIGNAL_HANDLING=y +CONFIG_FEATURE_DD_THIRD_STATUS_LINE=y +CONFIG_FEATURE_DD_IBS_OBS=y +# CONFIG_FEATURE_DD_STATUS is not set CONFIG_DF=y CONFIG_FEATURE_DF_FANCY=y +CONFIG_FEATURE_SKIP_ROOTFS=y CONFIG_DIRNAME=y CONFIG_DOS2UNIX=y CONFIG_UNIX2DOS=y @@ -236,39 +256,55 @@ CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K=y CONFIG_ECHO=y CONFIG_FEATURE_FANCY_ECHO=y CONFIG_ENV=y -CONFIG_FEATURE_ENV_LONG_OPTIONS=y CONFIG_EXPAND=y -CONFIG_FEATURE_EXPAND_LONG_OPTIONS=y +CONFIG_UNEXPAND=y CONFIG_EXPR=y CONFIG_EXPR_MATH_SUPPORT_64=y +CONFIG_FACTOR=y CONFIG_FALSE=y CONFIG_FOLD=y -CONFIG_FSYNC=y CONFIG_HEAD=y CONFIG_FEATURE_FANCY_HEAD=y +CONFIG_HOSTID=y +CONFIG_ID=y +CONFIG_GROUPS=y CONFIG_INSTALL=y CONFIG_FEATURE_INSTALL_LONG_OPTIONS=y +CONFIG_LINK=y CONFIG_LN=y CONFIG_LOGNAME=y CONFIG_LS=y CONFIG_FEATURE_LS_FILETYPES=y CONFIG_FEATURE_LS_FOLLOWLINKS=y CONFIG_FEATURE_LS_RECURSIVE=y +CONFIG_FEATURE_LS_WIDTH=y CONFIG_FEATURE_LS_SORTFILES=y CONFIG_FEATURE_LS_TIMESTAMPS=y CONFIG_FEATURE_LS_USERNAME=y CONFIG_FEATURE_LS_COLOR=y CONFIG_FEATURE_LS_COLOR_IS_DEFAULT=y CONFIG_MD5SUM=y +CONFIG_SHA1SUM=y +CONFIG_SHA256SUM=y +CONFIG_SHA384SUM=y +CONFIG_SHA512SUM=y +# CONFIG_SHA3SUM is not set + +# +# Common options for md5sum, sha1sum, sha256sum, ..., sha3sum +# +CONFIG_FEATURE_MD5_SHA1_SUM_CHECK=y CONFIG_MKDIR=y -CONFIG_FEATURE_MKDIR_LONG_OPTIONS=y CONFIG_MKFIFO=y CONFIG_MKNOD=y +CONFIG_MKTEMP=y CONFIG_MV=y -CONFIG_FEATURE_MV_LONG_OPTIONS=y CONFIG_NICE=y +CONFIG_NL=y CONFIG_NOHUP=y +CONFIG_NPROC=y CONFIG_OD=y +CONFIG_PASTE=y CONFIG_PRINTENV=y CONFIG_PRINTF=y CONFIG_PWD=y @@ -277,76 +313,76 @@ CONFIG_FEATURE_READLINK_FOLLOW=y CONFIG_REALPATH=y CONFIG_RM=y CONFIG_RMDIR=y -CONFIG_FEATURE_RMDIR_LONG_OPTIONS=y CONFIG_SEQ=y -CONFIG_SHA1SUM=y -CONFIG_SHA256SUM=y -CONFIG_SHA512SUM=y -# CONFIG_SHA3SUM is not set +CONFIG_SHRED=y +# CONFIG_SHUF is not set CONFIG_SLEEP=y CONFIG_FEATURE_FANCY_SLEEP=y -CONFIG_FEATURE_FLOAT_SLEEP=y CONFIG_SORT=y CONFIG_FEATURE_SORT_BIG=y +# CONFIG_FEATURE_SORT_OPTIMIZE_MEMORY is not set CONFIG_SPLIT=y CONFIG_FEATURE_SPLIT_FANCY=y +CONFIG_STAT=y +CONFIG_FEATURE_STAT_FORMAT=y +CONFIG_FEATURE_STAT_FILESYSTEM=y CONFIG_STTY=y CONFIG_SUM=y +CONFIG_SYNC=y +# CONFIG_FEATURE_SYNC_FANCY is not set +CONFIG_FSYNC=y CONFIG_TAC=y CONFIG_TAIL=y CONFIG_FEATURE_FANCY_TAIL=y CONFIG_TEE=y CONFIG_FEATURE_TEE_USE_BLOCK_IO=y +CONFIG_TEST=y +CONFIG_TEST1=y +CONFIG_TEST2=y +CONFIG_FEATURE_TEST_64=y +CONFIG_TIMEOUT=y +CONFIG_TOUCH=y +CONFIG_FEATURE_TOUCH_SUSV3=y +CONFIG_TR=y +CONFIG_FEATURE_TR_CLASSES=y +CONFIG_FEATURE_TR_EQUIV=y CONFIG_TRUE=y +# CONFIG_TRUNCATE is not set +CONFIG_TSORT=y CONFIG_TTY=y CONFIG_UNAME=y CONFIG_UNAME_OSNAME="" -CONFIG_UNEXPAND=y -CONFIG_FEATURE_UNEXPAND_LONG_OPTIONS=y +CONFIG_BB_ARCH=y CONFIG_UNIQ=y +# CONFIG_UNLINK is not set CONFIG_USLEEP=y CONFIG_UUDECODE=y +CONFIG_BASE32=y +CONFIG_BASE64=y CONFIG_UUENCODE=y CONFIG_WC=y CONFIG_FEATURE_WC_LARGE=y +# CONFIG_WHO is not set +# CONFIG_W is not set +# CONFIG_USERS is not set CONFIG_WHOAMI=y CONFIG_YES=y -# -# Common options -# -# CONFIG_FEATURE_VERBOSE is not set - -# -# Common options for cp and mv -# -CONFIG_FEATURE_PRESERVE_HARDLINKS=y - -# -# Common options for ls, more and telnet -# -CONFIG_FEATURE_AUTOWIDTH=y - -# -# Common options for df, du, ls -# -CONFIG_FEATURE_HUMAN_READABLE=y - -# -# Common options for md5sum, sha1sum, sha256sum, sha512sum, sha3sum -# -CONFIG_FEATURE_MD5_SHA1_SUM_CHECK=y - # # Console Utilities # # CONFIG_CHVT is not set -# CONFIG_FGCONSOLE is not set CONFIG_CLEAR=y # CONFIG_DEALLOCVT is not set # CONFIG_DUMPKMAP is not set +# CONFIG_FGCONSOLE is not set # CONFIG_KBD_MODE is not set # CONFIG_LOADFONT is not set +# CONFIG_SETFONT is not set +# CONFIG_FEATURE_SETFONT_TEXTUAL_MAP is not set +CONFIG_DEFAULT_SETFONT_DIR="" +# CONFIG_FEATURE_LOADFONT_PSF2 is not set +# CONFIG_FEATURE_LOADFONT_RAW is not set # CONFIG_LOADKMAP is not set # CONFIG_OPENVT is not set CONFIG_RESET=y @@ -354,28 +390,30 @@ CONFIG_RESET=y # CONFIG_FEATURE_RESIZE_PRINT is not set # CONFIG_SETCONSOLE is not set # CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS is not set -# CONFIG_SETFONT is not set -# CONFIG_FEATURE_SETFONT_TEXTUAL_MAP is not set -CONFIG_DEFAULT_SETFONT_DIR="" # CONFIG_SETKEYCODES is not set # CONFIG_SETLOGCONS is not set # CONFIG_SHOWKEY is not set -# CONFIG_FEATURE_LOADFONT_PSF2 is not set -# CONFIG_FEATURE_LOADFONT_RAW is not set # # Debian Utilities # -CONFIG_MKTEMP=y CONFIG_PIPE_PROGRESS=y CONFIG_RUN_PARTS=y CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS=y CONFIG_FEATURE_RUN_PARTS_FANCY=y CONFIG_START_STOP_DAEMON=y -CONFIG_FEATURE_START_STOP_DAEMON_FANCY=y CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS=y +CONFIG_FEATURE_START_STOP_DAEMON_FANCY=y CONFIG_WHICH=y +# +# klibc-utils +# +# CONFIG_MINIPS is not set +# CONFIG_NUKE is not set +CONFIG_RESUME=y +CONFIG_RUN_INIT=y + # # Editors # @@ -393,6 +431,7 @@ CONFIG_VI=y CONFIG_FEATURE_VI_MAX_LEN=4096 # CONFIG_FEATURE_VI_8BIT is not set CONFIG_FEATURE_VI_COLON=y +CONFIG_FEATURE_VI_COLON_EXPAND=y CONFIG_FEATURE_VI_YANKMARK=y CONFIG_FEATURE_VI_SEARCH=y # CONFIG_FEATURE_VI_REGEX_SEARCH is not set @@ -406,6 +445,7 @@ CONFIG_FEATURE_VI_ASK_TERMINAL=y CONFIG_FEATURE_VI_UNDO=y CONFIG_FEATURE_VI_UNDO_QUEUE=y CONFIG_FEATURE_VI_UNDO_QUEUE_MAX=256 +CONFIG_FEATURE_VI_VERBOSE_STATUS=y CONFIG_FEATURE_ALLOW_EXEC=y # @@ -414,15 +454,22 @@ CONFIG_FEATURE_ALLOW_EXEC=y CONFIG_FIND=y CONFIG_FEATURE_FIND_PRINT0=y CONFIG_FEATURE_FIND_MTIME=y +CONFIG_FEATURE_FIND_ATIME=y +CONFIG_FEATURE_FIND_CTIME=y CONFIG_FEATURE_FIND_MMIN=y +CONFIG_FEATURE_FIND_AMIN=y +CONFIG_FEATURE_FIND_CMIN=y CONFIG_FEATURE_FIND_PERM=y CONFIG_FEATURE_FIND_TYPE=y +CONFIG_FEATURE_FIND_EXECUTABLE=y CONFIG_FEATURE_FIND_XDEV=y CONFIG_FEATURE_FIND_MAXDEPTH=y CONFIG_FEATURE_FIND_NEWER=y CONFIG_FEATURE_FIND_INUM=y +CONFIG_FEATURE_FIND_SAMEFILE=y CONFIG_FEATURE_FIND_EXEC=y # CONFIG_FEATURE_FIND_EXEC_PLUS is not set +CONFIG_FEATURE_FIND_EXEC_OK=y CONFIG_FEATURE_FIND_USER=y CONFIG_FEATURE_FIND_GROUP=y CONFIG_FEATURE_FIND_NOT=y @@ -430,14 +477,16 @@ CONFIG_FEATURE_FIND_DEPTH=y CONFIG_FEATURE_FIND_PAREN=y CONFIG_FEATURE_FIND_SIZE=y CONFIG_FEATURE_FIND_PRUNE=y +CONFIG_FEATURE_FIND_QUIT=y CONFIG_FEATURE_FIND_DELETE=y +CONFIG_FEATURE_FIND_EMPTY=y CONFIG_FEATURE_FIND_PATH=y CONFIG_FEATURE_FIND_REGEX=y # CONFIG_FEATURE_FIND_CONTEXT is not set CONFIG_FEATURE_FIND_LINKS=y CONFIG_GREP=y -CONFIG_FEATURE_GREP_EGREP_ALIAS=y -CONFIG_FEATURE_GREP_FGREP_ALIAS=y +CONFIG_EGREP=y +CONFIG_FGREP=y CONFIG_FEATURE_GREP_CONTEXT=y CONFIG_XARGS=y CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION=y @@ -445,6 +494,8 @@ CONFIG_FEATURE_XARGS_SUPPORT_QUOTES=y CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT=y CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM=y # CONFIG_FEATURE_XARGS_SUPPORT_REPL_STR is not set +CONFIG_FEATURE_XARGS_SUPPORT_PARALLEL=y +CONFIG_FEATURE_XARGS_SUPPORT_ARGS_FILE=y # # Init Utilities @@ -453,6 +504,9 @@ CONFIG_BOOTCHARTD=y CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER=y CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE=y CONFIG_HALT=y +CONFIG_POWEROFF=y +CONFIG_REBOOT=y +CONFIG_FEATURE_WAIT_FOR_INIT=y # CONFIG_FEATURE_CALL_TELINIT is not set CONFIG_TELINIT_PATH="" CONFIG_INIT=y @@ -462,12 +516,10 @@ CONFIG_FEATURE_USE_INITTAB=y CONFIG_FEATURE_KILL_DELAY=0 CONFIG_FEATURE_INIT_SCTTY=y CONFIG_FEATURE_INIT_SYSLOG=y -CONFIG_FEATURE_EXTRA_QUIET=y +CONFIG_FEATURE_INIT_QUIET=y CONFIG_FEATURE_INIT_COREDUMPS=y CONFIG_INIT_TERMINAL_TYPE="linux" # CONFIG_FEATURE_INIT_MODIFY_CMDLINE is not set -# CONFIG_MESG is not set -# CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP is not set # # Login/Password Management Utilities @@ -477,13 +529,12 @@ CONFIG_USE_BB_PWD_GRP=y CONFIG_USE_BB_SHADOW=y # CONFIG_USE_BB_CRYPT is not set # CONFIG_USE_BB_CRYPT_SHA is not set -CONFIG_ADDGROUP=y -CONFIG_FEATURE_ADDGROUP_LONG_OPTIONS=y -CONFIG_FEATURE_ADDUSER_TO_GROUP=y +# CONFIG_USE_BB_CRYPT_YES is not set # CONFIG_ADD_SHELL is not set # CONFIG_REMOVE_SHELL is not set +CONFIG_ADDGROUP=y +CONFIG_FEATURE_ADDUSER_TO_GROUP=y CONFIG_ADDUSER=y -CONFIG_FEATURE_ADDUSER_LONG_OPTIONS=y # CONFIG_FEATURE_CHECK_NAMES is not set CONFIG_LAST_ID=60000 CONFIG_FIRST_SYSTEM_ID=100 @@ -506,6 +557,7 @@ CONFIG_FEATURE_PASSWD_WEAK_CHECK=y CONFIG_SU=y CONFIG_FEATURE_SU_SYSLOG=y CONFIG_FEATURE_SU_CHECKS_SHELLS=y +# CONFIG_FEATURE_SU_BLANK_PW_NEEDS_SECURE_TTY is not set CONFIG_SULOGIN=y CONFIG_VLOCK=y @@ -520,29 +572,29 @@ CONFIG_TUNE2FS=y # # Linux Module Utilities # -CONFIG_MODINFO=y CONFIG_MODPROBE_SMALL=y -CONFIG_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE=y -CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED=y +# CONFIG_DEPMOD is not set # CONFIG_INSMOD is not set -# CONFIG_RMMOD is not set # CONFIG_LSMOD is not set # CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT is not set +CONFIG_MODINFO=y # CONFIG_MODPROBE is not set # CONFIG_FEATURE_MODPROBE_BLACKLIST is not set -# CONFIG_DEPMOD is not set +# CONFIG_RMMOD is not set # # Options common to multiple modutils # +# CONFIG_FEATURE_CMDLINE_MODULE_OPTIONS is not set +# CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED is not set # CONFIG_FEATURE_2_4_MODULES is not set -# CONFIG_FEATURE_INSMOD_TRY_MMAP is not set # CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set # CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set # CONFIG_FEATURE_INSMOD_LOADINKMEM is not set # CONFIG_FEATURE_INSMOD_LOAD_MAP is not set # CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set # CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set +# CONFIG_FEATURE_INSMOD_TRY_MMAP is not set # CONFIG_FEATURE_MODUTILS_ALIAS is not set # CONFIG_FEATURE_MODUTILS_SYMBOLS is not set CONFIG_DEFAULT_MODULES_DIR="/lib/modules" @@ -551,45 +603,27 @@ CONFIG_DEFAULT_DEPMOD_FILE="modules.dep" # # Linux System Utilities # +CONFIG_ACPID=y +CONFIG_FEATURE_ACPID_COMPAT=y # CONFIG_BLKDISCARD is not set +CONFIG_BLKID=y +# CONFIG_FEATURE_BLKID_TYPE is not set CONFIG_BLOCKDEV=y +CONFIG_CAL=y +CONFIG_CHRT=y +CONFIG_DMESG=y +CONFIG_FEATURE_DMESG_PRETTY=y +# CONFIG_EJECT is not set +# CONFIG_FEATURE_EJECT_SCSI is not set +CONFIG_FALLOCATE=y # CONFIG_FATATTR is not set -# CONFIG_FSTRIM is not set -CONFIG_MDEV=y -CONFIG_FEATURE_MDEV_CONF=y -CONFIG_FEATURE_MDEV_RENAME=y -CONFIG_FEATURE_MDEV_RENAME_REGEXP=y -CONFIG_FEATURE_MDEV_EXEC=y -CONFIG_FEATURE_MDEV_LOAD_FIRMWARE=y -CONFIG_MOUNT=y -CONFIG_FEATURE_MOUNT_FAKE=y -CONFIG_FEATURE_MOUNT_VERBOSE=y -# CONFIG_FEATURE_MOUNT_HELPERS is not set -CONFIG_FEATURE_MOUNT_LABEL=y -# CONFIG_FEATURE_MOUNT_NFS is not set -CONFIG_FEATURE_MOUNT_CIFS=y -CONFIG_FEATURE_MOUNT_FLAGS=y -CONFIG_FEATURE_MOUNT_FSTAB=y -# CONFIG_FEATURE_MOUNT_OTHERTAB is not set -# CONFIG_NSENTER is not set -# CONFIG_FEATURE_NSENTER_LONG_OPTS is not set -CONFIG_REV=y -CONFIG_SETARCH=y -# CONFIG_UEVENT is not set -# CONFIG_UNSHARE is not set -CONFIG_ACPID=y -CONFIG_FEATURE_ACPID_COMPAT=y -CONFIG_BLKID=y -# CONFIG_FEATURE_BLKID_TYPE is not set -CONFIG_DMESG=y -CONFIG_FEATURE_DMESG_PRETTY=y # CONFIG_FBSET is not set # CONFIG_FEATURE_FBSET_FANCY is not set # CONFIG_FEATURE_FBSET_READMODE is not set -# CONFIG_FDFLUSH is not set # CONFIG_FDFORMAT is not set CONFIG_FDISK=y # CONFIG_FDISK_SUPPORT_LARGE_DISKS is not set +CONFIG_FEATURE_FDISK_BLKSIZE=y CONFIG_FEATURE_FDISK_WRITABLE=y # CONFIG_FEATURE_AIX_LABEL is not set # CONFIG_FEATURE_SGI_LABEL is not set @@ -599,42 +633,92 @@ CONFIG_FEATURE_FDISK_WRITABLE=y CONFIG_FEATURE_FDISK_ADVANCED=y CONFIG_FINDFS=y CONFIG_FLOCK=y +# CONFIG_FDFLUSH is not set CONFIG_FREERAMDISK=y # CONFIG_FSCK_MINIX is not set -CONFIG_MKFS_EXT2=y -# CONFIG_MKFS_MINIX is not set -# CONFIG_FEATURE_MINIX2 is not set -# CONFIG_MKFS_REISER is not set -CONFIG_MKFS_VFAT=y +CONFIG_FSFREEZE=y +# CONFIG_FSTRIM is not set CONFIG_GETOPT=y CONFIG_FEATURE_GETOPT_LONG=y CONFIG_HEXDUMP=y -CONFIG_FEATURE_HEXDUMP_REVERSE=y CONFIG_HD=y +CONFIG_XXD=y CONFIG_HWCLOCK=y -CONFIG_FEATURE_HWCLOCK_LONG_OPTIONS=y # CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS is not set +CONFIG_IONICE=y CONFIG_IPCRM=y CONFIG_IPCS=y +# CONFIG_LAST is not set +# CONFIG_FEATURE_LAST_FANCY is not set CONFIG_LOSETUP=y +CONFIG_LSBLK=y CONFIG_LSPCI=y CONFIG_LSUSB=y +CONFIG_MDEV=y +CONFIG_FEATURE_MDEV_CONF=y +CONFIG_FEATURE_MDEV_RENAME=y +CONFIG_FEATURE_MDEV_RENAME_REGEXP=y +CONFIG_FEATURE_MDEV_EXEC=y +CONFIG_FEATURE_MDEV_LOAD_FIRMWARE=y +CONFIG_FEATURE_MDEV_DAEMON=y +# CONFIG_MESG is not set +# CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP is not set +CONFIG_MKE2FS=y +CONFIG_MKFS_EXT2=y +# CONFIG_MKFS_MINIX is not set +# CONFIG_FEATURE_MINIX2 is not set +# CONFIG_MKFS_REISER is not set +CONFIG_MKDOSFS=y +CONFIG_MKFS_VFAT=y CONFIG_MKSWAP=y CONFIG_FEATURE_MKSWAP_UUID=y CONFIG_MORE=y +CONFIG_MOUNT=y +CONFIG_FEATURE_MOUNT_FAKE=y +CONFIG_FEATURE_MOUNT_VERBOSE=y +# CONFIG_FEATURE_MOUNT_HELPERS is not set +CONFIG_FEATURE_MOUNT_LABEL=y +# CONFIG_FEATURE_MOUNT_NFS is not set +CONFIG_FEATURE_MOUNT_CIFS=y +CONFIG_FEATURE_MOUNT_FLAGS=y +CONFIG_FEATURE_MOUNT_FSTAB=y +# CONFIG_FEATURE_MOUNT_OTHERTAB is not set +CONFIG_MOUNTPOINT=y +CONFIG_NOLOGIN=y +# CONFIG_NOLOGIN_DEPENDENCIES is not set +# CONFIG_NSENTER is not set CONFIG_PIVOT_ROOT=y CONFIG_RDATE=y CONFIG_RDEV=y CONFIG_READPROFILE=y +CONFIG_RENICE=y +CONFIG_REV=y CONFIG_RTCWAKE=y CONFIG_SCRIPT=y CONFIG_SCRIPTREPLAY=y -CONFIG_SWAPONOFF=y +CONFIG_SETARCH=y +CONFIG_LINUX32=y +CONFIG_LINUX64=y +CONFIG_SETPRIV=y +CONFIG_FEATURE_SETPRIV_DUMP=y +CONFIG_FEATURE_SETPRIV_CAPABILITIES=y +CONFIG_FEATURE_SETPRIV_CAPABILITY_NAMES=y +CONFIG_SETSID=y +CONFIG_SWAPON=y # CONFIG_FEATURE_SWAPON_DISCARD is not set CONFIG_FEATURE_SWAPON_PRI=y +CONFIG_SWAPOFF=y +CONFIG_FEATURE_SWAPONOFF_LABEL=y CONFIG_SWITCH_ROOT=y +# CONFIG_TASKSET is not set +# CONFIG_FEATURE_TASKSET_FANCY is not set +# CONFIG_FEATURE_TASKSET_CPULIST is not set +# CONFIG_UEVENT is not set CONFIG_UMOUNT=y CONFIG_FEATURE_UMOUNT_ALL=y +# CONFIG_UNSHARE is not set +CONFIG_UUIDGEN=y +# CONFIG_WALL is not set # # Common options for mount/umount @@ -650,6 +734,7 @@ CONFIG_VOLUMEID=y # CONFIG_FEATURE_VOLUMEID_BCACHE is not set CONFIG_FEATURE_VOLUMEID_BTRFS=y CONFIG_FEATURE_VOLUMEID_CRAMFS=y +CONFIG_FEATURE_VOLUMEID_EROFS=y # CONFIG_FEATURE_VOLUMEID_EXFAT is not set CONFIG_FEATURE_VOLUMEID_EXT=y # CONFIG_FEATURE_VOLUMEID_F2FS is not set @@ -657,9 +742,11 @@ CONFIG_FEATURE_VOLUMEID_FAT=y CONFIG_FEATURE_VOLUMEID_HFS=y CONFIG_FEATURE_VOLUMEID_ISO9660=y CONFIG_FEATURE_VOLUMEID_JFS=y +# CONFIG_FEATURE_VOLUMEID_LFS is not set CONFIG_FEATURE_VOLUMEID_LINUXRAID=y CONFIG_FEATURE_VOLUMEID_LINUXSWAP=y CONFIG_FEATURE_VOLUMEID_LUKS=y +CONFIG_FEATURE_VOLUMEID_MINIX=y # CONFIG_FEATURE_VOLUMEID_NILFS is not set CONFIG_FEATURE_VOLUMEID_NTFS=y CONFIG_FEATURE_VOLUMEID_OCFS2=y @@ -667,49 +754,23 @@ CONFIG_FEATURE_VOLUMEID_REISERFS=y CONFIG_FEATURE_VOLUMEID_ROMFS=y # CONFIG_FEATURE_VOLUMEID_SQUASHFS is not set CONFIG_FEATURE_VOLUMEID_SYSV=y +CONFIG_FEATURE_VOLUMEID_UBIFS=y CONFIG_FEATURE_VOLUMEID_UDF=y CONFIG_FEATURE_VOLUMEID_XFS=y # # Miscellaneous Utilities # -# CONFIG_CONSPY is not set -# CONFIG_CROND is not set -# CONFIG_FEATURE_CROND_D is not set -# CONFIG_FEATURE_CROND_CALL_SENDMAIL is not set -CONFIG_FEATURE_CROND_DIR="" -# CONFIG_I2CGET is not set -# CONFIG_I2CSET is not set -# CONFIG_I2CDUMP is not set -# CONFIG_I2CDETECT is not set -CONFIG_LESS=y -CONFIG_FEATURE_LESS_MAXLINES=9999999 -CONFIG_FEATURE_LESS_BRACKETS=y -CONFIG_FEATURE_LESS_FLAGS=y -# CONFIG_FEATURE_LESS_TRUNCATE is not set -CONFIG_FEATURE_LESS_MARKS=y -CONFIG_FEATURE_LESS_REGEXP=y -CONFIG_FEATURE_LESS_WINCH=y -CONFIG_FEATURE_LESS_ASK_TERMINAL=y -CONFIG_FEATURE_LESS_DASHCMD=y -CONFIG_FEATURE_LESS_LINENUMS=y -CONFIG_NANDWRITE=y -CONFIG_NANDDUMP=y -# CONFIG_RFKILL is not set -CONFIG_SETSERIAL=y -# CONFIG_TASKSET is not set -# CONFIG_FEATURE_TASKSET_FANCY is not set -# CONFIG_UBIRENAME is not set -CONFIG_UBIATTACH=y -CONFIG_UBIDETACH=y -CONFIG_UBIMKVOL=y -CONFIG_UBIRMVOL=y -CONFIG_UBIRSVOL=y -CONFIG_UBIUPDATEVOL=y -# CONFIG_WALL is not set CONFIG_ADJTIMEX=y +CONFIG_ASCII=y # CONFIG_BBCONFIG is not set # CONFIG_FEATURE_COMPRESS_BBCONFIG is not set +CONFIG_BC=y +# CONFIG_DC is not set +CONFIG_FEATURE_DC_BIG=y +# CONFIG_FEATURE_DC_LIBM is not set +CONFIG_FEATURE_BC_INTERACTIVE=y +CONFIG_FEATURE_BC_LONG_OPTIONS=y CONFIG_BEEP=y CONFIG_FEATURE_BEEP_FREQ=4000 CONFIG_FEATURE_BEEP_LENGTH_MS=30 @@ -721,27 +782,26 @@ CONFIG_FEATURE_BEEP_LENGTH_MS=30 # CONFIG_FEATURE_CHAT_SEND_ESCAPES is not set # CONFIG_FEATURE_CHAT_VAR_ABORT_LEN is not set # CONFIG_FEATURE_CHAT_CLR_ABORT is not set -CONFIG_CHRT=y +# CONFIG_CONSPY is not set +# CONFIG_CROND is not set +# CONFIG_FEATURE_CROND_D is not set +# CONFIG_FEATURE_CROND_CALL_SENDMAIL is not set +# CONFIG_FEATURE_CROND_SPECIAL_TIMES is not set +CONFIG_FEATURE_CROND_DIR="" # CONFIG_CRONTAB is not set -# CONFIG_DC is not set -# CONFIG_FEATURE_DC_LIBM is not set # CONFIG_DEVFSD is not set # CONFIG_DEVFSD_MODLOAD is not set # CONFIG_DEVFSD_FG_NP is not set # CONFIG_DEVFSD_VERBOSE is not set # CONFIG_FEATURE_DEVFS is not set CONFIG_DEVMEM=y -# CONFIG_EJECT is not set -# CONFIG_FEATURE_EJECT_SCSI is not set # CONFIG_FBSPLASH is not set -CONFIG_FLASHCP=y +CONFIG_FLASH_ERASE=y CONFIG_FLASH_LOCK=y CONFIG_FLASH_UNLOCK=y -CONFIG_FLASH_ERASE=y -CONFIG_IONICE=y -# CONFIG_INOTIFYD is not set -# CONFIG_LAST is not set -# CONFIG_FEATURE_LAST_FANCY is not set +CONFIG_FLASHCP=y +CONFIG_UBOOT_ENV=y +CONFIG_GETFATTR=y # CONFIG_HDPARM is not set # CONFIG_FEATURE_HDPARM_GET_IDENTITY is not set # CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF is not set @@ -749,26 +809,61 @@ CONFIG_IONICE=y # CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET is not set # CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF is not set # CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA is not set +CONFIG_HEXEDIT=y +# CONFIG_I2CGET is not set +# CONFIG_I2CSET is not set +# CONFIG_I2CDUMP is not set +# CONFIG_I2CDETECT is not set +CONFIG_I2CTRANSFER=y +# CONFIG_INOTIFYD is not set CONFIG_IORW=y +CONFIG_LESS=y +CONFIG_FEATURE_LESS_MAXLINES=9999999 +CONFIG_FEATURE_LESS_BRACKETS=y +CONFIG_FEATURE_LESS_FLAGS=y +# CONFIG_FEATURE_LESS_TRUNCATE is not set +CONFIG_FEATURE_LESS_MARKS=y +CONFIG_FEATURE_LESS_REGEXP=y +CONFIG_FEATURE_LESS_WINCH=y +CONFIG_FEATURE_LESS_ASK_TERMINAL=y +CONFIG_FEATURE_LESS_DASHCMD=y +CONFIG_FEATURE_LESS_LINENUMS=y +CONFIG_FEATURE_LESS_RAW=y +CONFIG_FEATURE_LESS_ENV=y +CONFIG_LSSCSI=y # CONFIG_MAKEDEVS is not set # CONFIG_FEATURE_MAKEDEVS_LEAF is not set # CONFIG_FEATURE_MAKEDEVS_TABLE is not set # CONFIG_MAN is not set # CONFIG_MICROCOM is not set -CONFIG_MOUNTPOINT=y +CONFIG_MIM=y # CONFIG_MT is not set +CONFIG_NANDWRITE=y +CONFIG_NANDDUMP=y +# CONFIG_PARTPROBE is not set # CONFIG_RAIDAUTORUN is not set CONFIG_READAHEAD=y +# CONFIG_RFKILL is not set # CONFIG_RUNLEVEL is not set # CONFIG_RX is not set -CONFIG_SETSID=y +CONFIG_SEEDRNG=y +CONFIG_SETFATTR=y +CONFIG_SETSERIAL=y # CONFIG_STRINGS is not set CONFIG_TIME=y -CONFIG_TIMEOUT=y +CONFIG_TREE=y +CONFIG_TS=y # CONFIG_TTYSIZE is not set -CONFIG_UBOOT_ENV=y +CONFIG_UBIATTACH=y +CONFIG_UBIDETACH=y +CONFIG_UBIMKVOL=y +CONFIG_UBIRMVOL=y +CONFIG_UBIRSVOL=y +CONFIG_UBIUPDATEVOL=y +# CONFIG_UBIRENAME is not set # CONFIG_VOLNAME is not set CONFIG_WATCHDOG=y +# CONFIG_FEATURE_WATCHDOG_OPEN_TWICE is not set # CONFIG_SYS_EEPROM is not set # CONFIG_SYS_EEPROM_DEVICE_I2C is not set # CONFIG_SYS_EEPROM_DEVICE_MTD is not set @@ -776,10 +871,10 @@ CONFIG_WATCHDOG=y # CONFIG_SYS_EEPROM_SYSFS_FILE is not set CONFIG_SYS_EEPROM_I2C_DEVICE="" CONFIG_SYS_EEPROM_I2C_ADDR= -CONFIG_SYS_EEPROM_I2C_MEM_ADDR_BITS=8 -CONFIG_SYS_EEPROM_I2C_WRITE_1B_DELAY=10 -CONFIG_SYS_EEPROM_I2C_WRITE_2B_DELAY=1000 -CONFIG_SYS_EEPROM_I2C_WRITE_3B_DELAY=10 +CONFIG_SYS_EEPROM_I2C_MEM_ADDR_BITS=0 +CONFIG_SYS_EEPROM_I2C_WRITE_1B_DELAY=0 +CONFIG_SYS_EEPROM_I2C_WRITE_2B_DELAY=0 +CONFIG_SYS_EEPROM_I2C_WRITE_3B_DELAY=0 CONFIG_SYS_EEPROM_MTD_DEVICE="" CONFIG_SYS_EEPROM_DISK_DEVICE="" CONFIG_SYS_EEPROM_SYSFS_FILE_PATH="" @@ -790,28 +885,14 @@ CONFIG_SYS_EEPROM_MAX_SIZE=0 # # Networking Utilities # -CONFIG_NAMEIF=y -CONFIG_FEATURE_NAMEIF_EXTENDED=y -CONFIG_NBDCLIENT=y -CONFIG_NC=y -CONFIG_NC_SERVER=y -CONFIG_NC_EXTRA=y -# CONFIG_NC_110_COMPAT is not set -CONFIG_PING=y -CONFIG_PING6=y -CONFIG_FEATURE_FANCY_PING=y -CONFIG_WGET=y -CONFIG_FEATURE_WGET_STATUSBAR=y -CONFIG_FEATURE_WGET_AUTHENTICATION=y -CONFIG_FEATURE_WGET_LONG_OPTIONS=y -CONFIG_FEATURE_WGET_TIMEOUT=y -# CONFIG_FEATURE_WGET_OPENSSL is not set -# CONFIG_FEATURE_WGET_SSL_HELPER is not set -CONFIG_WHOIS=y CONFIG_FEATURE_IPV6=y # CONFIG_FEATURE_UNIX_LOCAL is not set CONFIG_FEATURE_PREFER_IPV4_ADDRESS=y CONFIG_VERBOSE_RESOLUTION_ERRORS=y +# CONFIG_FEATURE_ETC_NETWORKS is not set +# CONFIG_FEATURE_ETC_SERVICES is not set +# CONFIG_FEATURE_HWIB is not set +# CONFIG_FEATURE_TLS_SHA1 is not set CONFIG_ARP=y CONFIG_ARPING=y CONFIG_BRCTL=y @@ -819,16 +900,17 @@ CONFIG_FEATURE_BRCTL_FANCY=y CONFIG_FEATURE_BRCTL_SHOW=y # CONFIG_DNSD is not set CONFIG_ETHER_WAKE=y -CONFIG_FAKEIDENTD=y # CONFIG_FTPD is not set -# CONFIG_FEATURE_FTP_WRITE is not set +# CONFIG_FEATURE_FTPD_WRITE is not set # CONFIG_FEATURE_FTPD_ACCEPT_BROKEN_LIST is not set -# CONFIG_FEATURE_FTP_AUTHENTICATION is not set +# CONFIG_FEATURE_FTPD_AUTHENTICATION is not set CONFIG_FTPGET=y CONFIG_FTPPUT=y CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS=y CONFIG_HOSTNAME=y +CONFIG_DNSDOMAINNAME=y # CONFIG_HTTPD is not set +CONFIG_FEATURE_HTTPD_PORT_DEFAULT=0 # CONFIG_FEATURE_HTTPD_RANGES is not set # CONFIG_FEATURE_HTTPD_SETUID is not set # CONFIG_FEATURE_HTTPD_BASIC_AUTH is not set @@ -840,6 +922,10 @@ CONFIG_HOSTNAME=y # CONFIG_FEATURE_HTTPD_ERROR_PAGES is not set # CONFIG_FEATURE_HTTPD_PROXY is not set # CONFIG_FEATURE_HTTPD_GZIP is not set +# CONFIG_FEATURE_HTTPD_ETAG is not set +# CONFIG_FEATURE_HTTPD_LAST_MODIFIED is not set +# CONFIG_FEATURE_HTTPD_DATE is not set +# CONFIG_FEATURE_HTTPD_ACL_IP is not set CONFIG_IFCONFIG=y CONFIG_FEATURE_IFCONFIG_STATUS=y CONFIG_FEATURE_IFCONFIG_SLIP=y @@ -848,11 +934,10 @@ CONFIG_FEATURE_IFCONFIG_HW=y CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS=y CONFIG_IFENSLAVE=y CONFIG_IFPLUGD=y -CONFIG_IFUPDOWN=y +CONFIG_IFUP=y +CONFIG_IFDOWN=y CONFIG_IFUPDOWN_IFSTATE_PATH="/var/run/ifstate" CONFIG_FEATURE_IFUPDOWN_IP=y -CONFIG_FEATURE_IFUPDOWN_IP_BUILTIN=y -# CONFIG_FEATURE_IFUPDOWN_IFCONFIG_BUILTIN is not set CONFIG_FEATURE_IFUPDOWN_IPV4=y CONFIG_FEATURE_IFUPDOWN_IPV6=y CONFIG_FEATURE_IFUPDOWN_MAPPING=y @@ -865,79 +950,118 @@ CONFIG_FEATURE_IFUPDOWN_MAPPING=y # CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN is not set # CONFIG_FEATURE_INETD_RPC is not set CONFIG_IP=y +CONFIG_IPADDR=y +CONFIG_IPLINK=y +CONFIG_IPROUTE=y +CONFIG_IPTUNNEL=y +CONFIG_IPRULE=y +CONFIG_IPNEIGH=y CONFIG_FEATURE_IP_ADDRESS=y CONFIG_FEATURE_IP_LINK=y +CONFIG_FEATURE_IP_LINK_CAN=y CONFIG_FEATURE_IP_ROUTE=y CONFIG_FEATURE_IP_ROUTE_DIR="" CONFIG_FEATURE_IP_TUNNEL=y CONFIG_FEATURE_IP_RULE=y CONFIG_FEATURE_IP_NEIGH=y -CONFIG_FEATURE_IP_SHORT_FORMS=y # CONFIG_FEATURE_IP_RARE_PROTOCOLS is not set -CONFIG_IPADDR=y -CONFIG_IPLINK=y -CONFIG_IPROUTE=y -CONFIG_IPTUNNEL=y -CONFIG_IPRULE=y -CONFIG_IPNEIGH=y CONFIG_IPCALC=y -CONFIG_FEATURE_IPCALC_FANCY=y CONFIG_FEATURE_IPCALC_LONG_OPTIONS=y +CONFIG_FEATURE_IPCALC_FANCY=y +CONFIG_FAKEIDENTD=y +CONFIG_NAMEIF=y +CONFIG_FEATURE_NAMEIF_EXTENDED=y +CONFIG_NBDCLIENT=y +CONFIG_NC=y +# CONFIG_NETCAT is not set +CONFIG_NC_SERVER=y +CONFIG_NC_EXTRA=y +# CONFIG_NC_110_COMPAT is not set CONFIG_NETSTAT=y CONFIG_FEATURE_NETSTAT_WIDE=y CONFIG_FEATURE_NETSTAT_PRG=y CONFIG_NSLOOKUP=y +CONFIG_FEATURE_NSLOOKUP_BIG=y +CONFIG_FEATURE_NSLOOKUP_LONG_OPTIONS=y # CONFIG_NTPD is not set # CONFIG_FEATURE_NTPD_SERVER is not set # CONFIG_FEATURE_NTPD_CONF is not set +# CONFIG_FEATURE_NTP_AUTH is not set +CONFIG_PING=y +CONFIG_PING6=y +CONFIG_FEATURE_FANCY_PING=y CONFIG_PSCAN=y CONFIG_ROUTE=y CONFIG_SLATTACH=y +CONFIG_SSL_CLIENT=y +CONFIG_SSL_SERVER=y +# CONFIG_TC is not set +# CONFIG_FEATURE_TC_INGRESS is not set # CONFIG_TCPSVD is not set +# CONFIG_UDPSVD is not set CONFIG_TELNET=y CONFIG_FEATURE_TELNET_TTYPE=y CONFIG_FEATURE_TELNET_AUTOLOGIN=y +CONFIG_FEATURE_TELNET_WIDTH=y CONFIG_TELNETD=y +# CONFIG_FEATURE_TELNETD_SELFTEST_DEBUG is not set CONFIG_FEATURE_TELNETD_STANDALONE=y +CONFIG_FEATURE_TELNETD_PORT_DEFAULT=23 # CONFIG_FEATURE_TELNETD_INETD_WAIT is not set CONFIG_TFTP=y +CONFIG_FEATURE_TFTP_PROGRESS_BAR=y +CONFIG_FEATURE_TFTP_HPA_COMPAT=y # CONFIG_TFTPD is not set - -# -# Common options for tftp/tftpd -# CONFIG_FEATURE_TFTP_GET=y CONFIG_FEATURE_TFTP_PUT=y CONFIG_FEATURE_TFTP_BLOCKSIZE=y -CONFIG_FEATURE_TFTP_PROGRESS_BAR=y # CONFIG_TFTP_DEBUG is not set +CONFIG_TLS=y CONFIG_TRACEROUTE=y CONFIG_TRACEROUTE6=y CONFIG_FEATURE_TRACEROUTE_VERBOSE=y -# CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE is not set # CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set CONFIG_TUNCTL=y CONFIG_FEATURE_TUNCTL_UG=y -CONFIG_UDHCPC6=y +# CONFIG_VCONFIG is not set +CONFIG_WGET=y +CONFIG_FEATURE_WGET_LONG_OPTIONS=y +CONFIG_FEATURE_WGET_STATUSBAR=y +CONFIG_FEATURE_WGET_FTP=y +CONFIG_FEATURE_WGET_AUTHENTICATION=y +CONFIG_FEATURE_WGET_TIMEOUT=y +CONFIG_FEATURE_WGET_HTTPS=y +# CONFIG_FEATURE_WGET_OPENSSL is not set +CONFIG_WHOIS=y +CONFIG_ZCIP=y # CONFIG_UDHCPD is not set -# CONFIG_DHCPRELAY is not set -# CONFIG_DUMPLEASES is not set -# CONFIG_FEATURE_UDHCPD_WRITE_LEASES_EARLY is not set +# CONFIG_FEATURE_UDHCPD_BOOTP is not set # CONFIG_FEATURE_UDHCPD_BASE_IP_ON_MAC is not set +# CONFIG_FEATURE_UDHCPD_WRITE_LEASES_EARLY is not set CONFIG_DHCPD_LEASES_FILE="" +# CONFIG_DUMPLEASES is not set +# CONFIG_DHCPRELAY is not set CONFIG_UDHCPC=y CONFIG_FEATURE_UDHCPC_ARPING=y # CONFIG_FEATURE_UDHCPC_SANITIZEOPT is not set +CONFIG_UDHCPC_DEFAULT_SCRIPT="/usr/share/udhcpc/default.script" +CONFIG_UDHCPC6_DEFAULT_SCRIPT="/usr/share/udhcpc/default6.script" +CONFIG_UDHCPC6=y +CONFIG_FEATURE_UDHCPC6_RFC3646=y +CONFIG_FEATURE_UDHCPC6_RFC4704=y +CONFIG_FEATURE_UDHCPC6_RFC4833=y +CONFIG_FEATURE_UDHCPC6_RFC5970=y + +# +# Common options for DHCP applets +# +CONFIG_UDHCPC_DEFAULT_INTERFACE="eth0" # CONFIG_FEATURE_UDHCP_PORT is not set CONFIG_UDHCP_DEBUG=9 +CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=80 CONFIG_FEATURE_UDHCP_RFC3397=y CONFIG_FEATURE_UDHCP_8021Q=y -CONFIG_UDHCPC_DEFAULT_SCRIPT="/usr/share/udhcpc/default.script" -CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=80 CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="-R -n" -# CONFIG_UDPSVD is not set -# CONFIG_VCONFIG is not set -CONFIG_ZCIP=y # # Print Utilities @@ -949,8 +1073,8 @@ CONFIG_ZCIP=y # # Mail Utilities # -# CONFIG_MAKEMIME is not set CONFIG_FEATURE_MIME_CHARSET="" +# CONFIG_MAKEMIME is not set # CONFIG_POPMAILDIR is not set # CONFIG_FEATURE_POPMAILDIR_DELIVERY is not set # CONFIG_REFORMIME is not set @@ -960,16 +1084,37 @@ CONFIG_FEATURE_MIME_CHARSET="" # # Process Utilities # +CONFIG_FEATURE_FAST_TOP=y +CONFIG_FEATURE_SHOW_THREADS=y +CONFIG_FREE=y +CONFIG_FUSER=y CONFIG_IOSTAT=y +CONFIG_KILL=y +CONFIG_KILLALL=y +CONFIG_KILLALL5=y CONFIG_LSOF=y CONFIG_MPSTAT=y CONFIG_NMETER=y +CONFIG_PGREP=y +CONFIG_PKILL=y +CONFIG_PIDOF=y +CONFIG_FEATURE_PIDOF_SINGLE=y +CONFIG_FEATURE_PIDOF_OMIT=y CONFIG_PMAP=y CONFIG_POWERTOP=y +CONFIG_FEATURE_POWERTOP_INTERACTIVE=y +CONFIG_PS=y +CONFIG_FEATURE_PS_WIDE=y +CONFIG_FEATURE_PS_LONG=y +# CONFIG_FEATURE_PS_TIME is not set +# CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set +# CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS is not set CONFIG_PSTREE=y CONFIG_PWDX=y CONFIG_SMEMCAP=y +CONFIG_BB_SYSCTL=y CONFIG_TOP=y +CONFIG_FEATURE_TOP_INTERACTIVE=y CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE=y CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS=y CONFIG_FEATURE_TOP_SMP_CPU=y @@ -978,25 +1123,7 @@ CONFIG_FEATURE_TOP_SMP_PROCESS=y CONFIG_FEATURE_TOPMEM=y CONFIG_UPTIME=y # CONFIG_FEATURE_UPTIME_UTMP_SUPPORT is not set -CONFIG_FREE=y -CONFIG_FUSER=y -CONFIG_KILL=y -CONFIG_KILLALL=y -CONFIG_KILLALL5=y -CONFIG_PGREP=y -CONFIG_PIDOF=y -CONFIG_FEATURE_PIDOF_SINGLE=y -CONFIG_FEATURE_PIDOF_OMIT=y -CONFIG_PKILL=y -CONFIG_PS=y -CONFIG_FEATURE_PS_WIDE=y -CONFIG_FEATURE_PS_LONG=y -# CONFIG_FEATURE_PS_TIME is not set -# CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS is not set -# CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set -CONFIG_RENICE=y -CONFIG_BB_SYSCTL=y -CONFIG_FEATURE_SHOW_THREADS=y +CONFIG_VMSTAT=y CONFIG_WATCH=y # @@ -1012,46 +1139,59 @@ CONFIG_RUNSVDIR=y # CONFIG_FEATURE_RUNSVDIR_LOG is not set CONFIG_SV=y CONFIG_SV_DEFAULT_SERVICE_DIR="/var/service" +CONFIG_SVC=y +CONFIG_SVOK=y CONFIG_SVLOGD=y # CONFIG_CHCON is not set -# CONFIG_FEATURE_CHCON_LONG_OPTIONS is not set # CONFIG_GETENFORCE is not set # CONFIG_GETSEBOOL is not set # CONFIG_LOAD_POLICY is not set # CONFIG_MATCHPATHCON is not set -# CONFIG_RESTORECON is not set # CONFIG_RUNCON is not set -# CONFIG_FEATURE_RUNCON_LONG_OPTIONS is not set # CONFIG_SELINUXENABLED is not set +# CONFIG_SESTATUS is not set # CONFIG_SETENFORCE is not set # CONFIG_SETFILES is not set # CONFIG_FEATURE_SETFILES_CHECK_OPTION is not set +# CONFIG_RESTORECON is not set # CONFIG_SETSEBOOL is not set -# CONFIG_SESTATUS is not set # # Shells # +CONFIG_SH_IS_ASH=y +# CONFIG_SH_IS_HUSH is not set +# CONFIG_SH_IS_NONE is not set +# CONFIG_BASH_IS_ASH is not set +# CONFIG_BASH_IS_HUSH is not set +CONFIG_BASH_IS_NONE=y +CONFIG_SHELL_ASH=y CONFIG_ASH=y +CONFIG_ASH_OPTIMIZE_FOR_SIZE=y +CONFIG_ASH_INTERNAL_GLOB=y CONFIG_ASH_BASH_COMPAT=y -# CONFIG_ASH_IDLE_TIMEOUT is not set +# CONFIG_ASH_BASH_SOURCE_CURDIR is not set +CONFIG_ASH_BASH_NOT_FOUND_HOOK=y CONFIG_ASH_JOB_CONTROL=y CONFIG_ASH_ALIAS=y -CONFIG_ASH_GETOPTS=y -CONFIG_ASH_BUILTIN_ECHO=y -CONFIG_ASH_BUILTIN_PRINTF=y -CONFIG_ASH_BUILTIN_TEST=y -# CONFIG_ASH_HELP is not set -CONFIG_ASH_CMDCMD=y -# CONFIG_ASH_MAIL is not set -CONFIG_ASH_OPTIMIZE_FOR_SIZE=y CONFIG_ASH_RANDOM_SUPPORT=y CONFIG_ASH_EXPAND_PRMT=y +# CONFIG_ASH_IDLE_TIMEOUT is not set +# CONFIG_ASH_MAIL is not set +CONFIG_ASH_ECHO=y +CONFIG_ASH_PRINTF=y +CONFIG_ASH_TEST=y +# CONFIG_ASH_HELP is not set +CONFIG_ASH_GETOPTS=y +CONFIG_ASH_CMDCMD=y CONFIG_CTTYHACK=y # CONFIG_HUSH is not set +# CONFIG_SHELL_HUSH is not set +# CONFIG_HUSH_NEED_FOR_SPEED is not set # CONFIG_HUSH_BASH_COMPAT is not set # CONFIG_HUSH_BRACE_EXPANSION is not set -# CONFIG_HUSH_HELP is not set +# CONFIG_HUSH_BASH_SOURCE_CURDIR is not set +# CONFIG_HUSH_LINENO_VAR is not set # CONFIG_HUSH_INTERACTIVE is not set # CONFIG_HUSH_SAVEHISTORY is not set # CONFIG_HUSH_JOB is not set @@ -1059,24 +1199,45 @@ CONFIG_CTTYHACK=y # CONFIG_HUSH_IF is not set # CONFIG_HUSH_LOOPS is not set # CONFIG_HUSH_CASE is not set +# CONFIG_HUSH_ALIAS is not set # CONFIG_HUSH_FUNCTIONS is not set +# CONFIG_HUSH_FUNCTION_KEYWORD is not set # CONFIG_HUSH_LOCAL is not set # CONFIG_HUSH_RANDOM_SUPPORT is not set -# CONFIG_HUSH_EXPORT_N is not set # CONFIG_HUSH_MODE_X is not set -# CONFIG_MSH is not set -CONFIG_FEATURE_SH_IS_ASH=y -# CONFIG_FEATURE_SH_IS_HUSH is not set -# CONFIG_FEATURE_SH_IS_NONE is not set -# CONFIG_FEATURE_BASH_IS_ASH is not set -# CONFIG_FEATURE_BASH_IS_HUSH is not set -CONFIG_FEATURE_BASH_IS_NONE=y -CONFIG_SH_MATH_SUPPORT=y -CONFIG_SH_MATH_SUPPORT_64=y +# CONFIG_HUSH_ECHO is not set +# CONFIG_HUSH_PRINTF is not set +# CONFIG_HUSH_TEST is not set +# CONFIG_HUSH_HELP is not set +# CONFIG_HUSH_EXPORT is not set +# CONFIG_HUSH_EXPORT_N is not set +# CONFIG_HUSH_READONLY is not set +# CONFIG_HUSH_KILL is not set +# CONFIG_HUSH_WAIT is not set +# CONFIG_HUSH_COMMAND is not set +# CONFIG_HUSH_TRAP is not set +# CONFIG_HUSH_TYPE is not set +# CONFIG_HUSH_TIMES is not set +# CONFIG_HUSH_READ is not set +# CONFIG_HUSH_SET is not set +# CONFIG_HUSH_UNSET is not set +# CONFIG_HUSH_ULIMIT is not set +# CONFIG_HUSH_UMASK is not set +# CONFIG_HUSH_GETOPTS is not set +# CONFIG_HUSH_MEMLEAK is not set + +# +# Options common to all shells +# +CONFIG_FEATURE_SH_MATH=y +CONFIG_FEATURE_SH_MATH_64=y +CONFIG_FEATURE_SH_MATH_BASE=y CONFIG_FEATURE_SH_EXTRA_QUIET=y # CONFIG_FEATURE_SH_STANDALONE is not set # CONFIG_FEATURE_SH_NOFORK is not set +CONFIG_FEATURE_SH_READ_FRAC=y CONFIG_FEATURE_SH_HISTFILESIZE=y +CONFIG_FEATURE_SH_EMBEDDED_SCRIPTS=y # # System Logging Utilities @@ -1091,6 +1252,7 @@ CONFIG_FEATURE_ROTATE_LOGFILE=y CONFIG_FEATURE_REMOTE_LOG=y CONFIG_FEATURE_SYSLOGD_DUP=y CONFIG_FEATURE_SYSLOGD_CFG=y +# CONFIG_FEATURE_SYSLOGD_PRECISE_TIMESTAMPS is not set CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=256 CONFIG_FEATURE_IPC_SYSLOG=y CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=16 diff --git a/build-config/conf/sbom/cpe-overrides.json b/build-config/conf/sbom/cpe-overrides.json new file mode 100644 index 000000000..e835d8c9c --- /dev/null +++ b/build-config/conf/sbom/cpe-overrides.json @@ -0,0 +1,26 @@ +{ + "_comment": [ + "Maps an ONIE SBOM component name (lowercased, as emitted by gen-sbom.py) to", + "the NVD CPE 2.3 'part:vendor:product' that grype must match on. ONIE builds", + "from upstream source and carries only pkg:generic PURLs, so grype matches", + "components to CVEs solely via CPE against NVD. The NVD vendor:product rarely", + "equals the package name, so the wrong/absent CPE silently yields a false-clean", + "(zero-finding) scan. Components NOT listed here default to 'a::'.", + "Mappings were derived from the grype vulnerability DB (highest-CVE canonical", + "vendor:product per product). The CPE version is filled in per build." + ], + "linux": "o:linux:linux_kernel", + "util-linux": "a:kernel:util-linux", + "grub": "a:gnu:grub2", + "parted": "a:gnu:parted", + "gcc-runtime": "a:gnu:gcc", + "dropbear": "a:dropbear_ssh_project:dropbear_ssh", + "e2fsprogs": "a:e2fsprogs_project:e2fsprogs", + "uclibc-ng": "a:uclibc-ng_project:uclibc-ng", + "dosfstools": "a:dosfstools_project:dosfstools", + "kexec-tools": "a:kexec-tools_project:kexec-tools", + "shim": "a:redhat:shim", + "lvm2": "a:redhat:lvm2", + "dmidecode": "a:nongnu:dmidecode", + "lzo": "a:oberhumer:lzo2" +} diff --git a/build-config/conf/sbom/license-overrides.json b/build-config/conf/sbom/license-overrides.json new file mode 100644 index 000000000..75cf0c7c8 --- /dev/null +++ b/build-config/conf/sbom/license-overrides.json @@ -0,0 +1,11 @@ +{ + "_comment": "Declared SPDX license (or expression) for components whose source is genuinely multi-license or has no single top-level license file, where automatic detection is ambiguous. Keyed by make-fragment name.", + "e2fsprogs": "GPL-2.0-or-later AND LGPL-2.0-or-later AND BSD-3-Clause AND MIT", + "lvm2": "GPL-2.0-only AND LGPL-2.1-only", + "util-linux": "GPL-2.0-or-later AND LGPL-2.1-or-later AND BSD-3-Clause AND BSD-4-Clause-UC AND MIT", + "gcc-runtime": "GPL-3.0-or-later WITH GCC-exception-3.1", + "uclibc-ng": "LGPL-2.1-or-later", + "dropbear": "MIT", + "kernel": "GPL-2.0-only WITH Linux-syscall-note", + "shim": "BSD-2-Clause-Patent" +} diff --git a/build-config/make/acpica-tools.make b/build-config/make/acpica-tools.make index f7ba9fc0a..9a445de5d 100644 --- a/build-config/make/acpica-tools.make +++ b/build-config/make/acpica-tools.make @@ -10,9 +10,12 @@ # This is a makefile fragment that defines the build of acpica-tools # -ACPICA_TOOLS_VERSION = 20150410 +ACPICA_TOOLS_VERSION = 20260408 +# acpica.org's old download area was retired (it redirects to an Intel +# page). The ACPICA project now publishes the official acpica-unix +# tarball as a GitHub release asset. ACPICA_TOOLS_TARBALL = acpica-unix-$(ACPICA_TOOLS_VERSION).tar.gz -ACPICA_TOOLS_TARBALL_URLS += $(ONIE_MIRROR) https://acpica.org/sites/acpica/files/ +ACPICA_TOOLS_TARBALL_URLS += $(ONIE_MIRROR) https://github.com/acpica/acpica/releases/download/$(ACPICA_TOOLS_VERSION) ACPICA_TOOLS_BUILD_DIR = $(USER_BUILDDIR)/acpica-tools ACPICA_TOOLS_DIR = $(ACPICA_TOOLS_BUILD_DIR)/acpica-unix-$(ACPICA_TOOLS_VERSION) diff --git a/build-config/make/btrfs-progs.make b/build-config/make/btrfs-progs.make index 0f5915b84..4dde95841 100644 --- a/build-config/make/btrfs-progs.make +++ b/build-config/make/btrfs-progs.make @@ -9,7 +9,7 @@ # This is a makefile fragment that defines the build of btrfs-progs # -BTRFSPROGS_VERSION = v4.9.1 +BTRFSPROGS_VERSION = v7.0 BTRFSPROGS_TARBALL = btrfs-progs-$(BTRFSPROGS_VERSION).tar.xz BTRFSPROGS_TARBALL_URLS += $(ONIE_MIRROR) \ https://www.kernel.org/pub/linux/kernel/people/kdave/btrfs-progs @@ -37,11 +37,10 @@ PHONY += btrfs-progs btrfs-progs-download btrfs-progs-source \ btrfs-progs-configure btrfs-progs-build btrfs-progs-install \ btrfs-progs-clean btrfs-progs-download-clean -BTRFSPROGS_LIBS = libbtrfs.so libbtrfs.so.0 libbtrfs.so.0.1 -BTRFSPROGS_SBIN = btrfs mkfs.btrfs btrfs-debug-tree btrfs-map-logical \ - btrfs-image btrfs-zero-log btrfs-find-root btrfstune \ - btrfs-show-super btrfs-select-super btrfs-convert \ - btrfsck +BTRFSPROGS_LIBS = libbtrfs.so.0.1.5 libbtrfs.so libbtrfs.so.0 libbtrfs.so.0.1 +BTRFSPROGS_SBIN = btrfs mkfs.btrfs btrfs-map-logical \ + btrfs-image btrfs-find-root btrfstune \ + btrfs-select-super btrfsck btrfs-progs: $(BTRFSPROGS_STAMP) @@ -81,6 +80,12 @@ $(BTRFSPROGS_CONFIGURE_STAMP): $(E2FSPROGS_BUILD_STAMP) \ --disable-documentation \ --disable-backtrace \ --disable-convert \ + --disable-zstd \ + --disable-libudev \ + --disable-python \ + --with-crypto=builtin \ + ac_cv_func_malloc_0_nonnull=yes \ + ac_cv_func_realloc_0_nonnull=yes \ CC=$(CROSSPREFIX)gcc \ CFLAGS="$(ONIE_CFLAGS)" \ $(ONIE_PKG_CONFIG) diff --git a/build-config/make/busybox.make b/build-config/make/busybox.make index 972dfa397..ea7edf2e2 100644 --- a/build-config/make/busybox.make +++ b/build-config/make/busybox.make @@ -14,7 +14,7 @@ # This is a makefile fragment that defines the build of busybox # -BUSYBOX_VERSION = 1.25.1 +BUSYBOX_VERSION = 1.38.0 BUSYBOX_TARBALL = busybox-$(BUSYBOX_VERSION).tar.bz2 BUSYBOX_TARBALL_URLS += $(ONIE_MIRROR) https://www.busybox.net/downloads BUSYBOX_BUILD_DIR = $(MBUILDDIR)/busybox diff --git a/build-config/make/dmidecode.make b/build-config/make/dmidecode.make index 3f106a1aa..c3c92e8c3 100644 --- a/build-config/make/dmidecode.make +++ b/build-config/make/dmidecode.make @@ -9,7 +9,7 @@ # This is a makefile fragment that defines the build of dmidecode # -DMIDECODE_VERSION = 3.1 +DMIDECODE_VERSION = 3.7 DMIDECODE_TARBALL = dmidecode-$(DMIDECODE_VERSION).tar.xz DMIDECODE_TARBALL_URLS += $(ONIE_MIRROR) http://download.savannah.gnu.org/releases/dmidecode/ DMIDECODE_BUILD_DIR = $(USER_BUILDDIR)/dmidecode diff --git a/build-config/make/dosfstools.make b/build-config/make/dosfstools.make index 549720353..acbf6f3d7 100644 --- a/build-config/make/dosfstools.make +++ b/build-config/make/dosfstools.make @@ -9,9 +9,9 @@ # This is a makefile fragment that defines the build of dosfstools # -DOSFSTOOLS_VERSION = 3.0.26 -DOSFSTOOLS_TARBALL = dosfstools-$(DOSFSTOOLS_VERSION).tar.xz -DOSFSTOOLS_TARBALL_URLS += $(ONIE_MIRROR) http://daniel-baumann.ch/files/software/dosfstools +DOSFSTOOLS_VERSION = 4.2 +DOSFSTOOLS_TARBALL = dosfstools-$(DOSFSTOOLS_VERSION).tar.gz +DOSFSTOOLS_TARBALL_URLS += $(ONIE_MIRROR) https://github.com/dosfstools/dosfstools/releases/download/v$(DOSFSTOOLS_VERSION) DOSFSTOOLS_BUILD_DIR = $(USER_BUILDDIR)/dosfstools DOSFSTOOLS_DIR = $(DOSFSTOOLS_BUILD_DIR)/dosfstools-$(DOSFSTOOLS_VERSION) @@ -19,19 +19,25 @@ DOSFSTOOLS_SRCPATCHDIR = $(PATCHDIR)/dosfstools DOSFSTOOLS_DOWNLOAD_STAMP = $(DOWNLOADDIR)/dosfstools-download DOSFSTOOLS_SOURCE_STAMP = $(USER_STAMPDIR)/dosfstools-source DOSFSTOOLS_PATCH_STAMP = $(USER_STAMPDIR)/dosfstools-patch +DOSFSTOOLS_CONFIGURE_STAMP = $(USER_STAMPDIR)/dosfstools-configure DOSFSTOOLS_BUILD_STAMP = $(USER_STAMPDIR)/dosfstools-build DOSFSTOOLS_INSTALL_STAMP = $(STAMPDIR)/dosfstools-install DOSFSTOOLS_STAMP = $(DOSFSTOOLS_SOURCE_STAMP) \ $(DOSFSTOOLS_PATCH_STAMP) \ + $(DOSFSTOOLS_CONFIGURE_STAMP) \ $(DOSFSTOOLS_BUILD_STAMP) \ $(DOSFSTOOLS_INSTALL_STAMP) +# As of 4.x dosfstools installs three programs (mkfs.fat, fsck.fat and +# fatlabel). The legacy program names (dosfsck, mkdosfs, ...) are +# provided as compatibility symlinks via --enable-compat-symlinks. DOSFSTOOLS_PROGRAMS = fsck.fat dosfsck fsck.msdos fsck.vfat \ mkfs.fat mkdosfs mkfs.msdos mkfs.vfat \ fatlabel dosfslabel PHONY += dosfstools dosfstools-download dosfstools-source dosfstools-patch \ - dosfstools-build dosfstools-install dosfstools-clean dosfstools-download-clean + dosfstools-configure dosfstools-build dosfstools-install \ + dosfstools-clean dosfstools-download-clean dosfstools: $(DOSFSTOOLS_STAMP) @@ -59,25 +65,36 @@ $(DOSFSTOOLS_PATCH_STAMP): $(DOSFSTOOLS_SRCPATCHDIR)/* $(DOSFSTOOLS_SOURCE_STAMP $(Q) $(SCRIPTDIR)/apply-patch-series $(DOSFSTOOLS_SRCPATCHDIR)/series $(DOSFSTOOLS_DIR) $(Q) touch $@ +dosfstools-configure: $(DOSFSTOOLS_CONFIGURE_STAMP) +$(DOSFSTOOLS_CONFIGURE_STAMP): $(DOSFSTOOLS_PATCH_STAMP) | $(DEV_SYSROOT_INIT_STAMP) + $(Q) rm -f $@ && eval $(PROFILE_STAMP) + $(Q) echo "==== Configure dosfstools-$(DOSFSTOOLS_VERSION) ====" + $(Q) cd $(DOSFSTOOLS_DIR) && PATH='$(CROSSBIN):$(PATH)' \ + $(DOSFSTOOLS_DIR)/configure \ + --prefix=/usr \ + --host=$(TARGET) \ + --without-iconv \ + --enable-compat-symlinks \ + CC=$(CROSSPREFIX)gcc \ + CFLAGS="$(ONIE_CFLAGS)" \ + LDFLAGS="$(ONIE_LDFLAGS)" \ + $(ONIE_PKG_CONFIG) + $(Q) touch $@ + ifndef MAKE_CLEAN DOSFSTOOLS_NEW_FILES = $(shell test -d $(DOSFSTOOLS_DIR) && test -f $(DOSFSTOOLS_BUILD_STAMP) && \ - find -L $(DOSFSTOOLS_DIR) -newer $(DOSFSTOOLS_BUILD_STAMP) -type f \ + find -L $(DOSFSTOOLS_DIR) -newer $(DOSFSTOOLS_BUILD_STAMP) -type f \ \! -name filelist-rpm -print -quit) endif -DOSFSTOOLS_MAKE_VARS = \ - CC=$(CROSSPREFIX)gcc LD=$(CROSSPREFIX)ld \ - CFLAGS="$(ONIE_CFLAGS)" LDFLAGS="$(ONIE_LDFLAGS)" \ - DESTDIR=$(DEV_SYSROOT) PREFIX=/usr - dosfstools-build: $(DOSFSTOOLS_BUILD_STAMP) -$(DOSFSTOOLS_BUILD_STAMP): $(DOSFSTOOLS_PATCH_STAMP) $(DOSFSTOOLS_NEW_FILES) \ +$(DOSFSTOOLS_BUILD_STAMP): $(DOSFSTOOLS_CONFIGURE_STAMP) $(DOSFSTOOLS_NEW_FILES) \ | $(DEV_SYSROOT_INIT_STAMP) $(Q) rm -f $@ && eval $(PROFILE_STAMP) $(Q) echo "==== Building dosfstools-$(DOSFSTOOLS_VERSION) ====" - $(Q) PATH='$(CROSSBIN):$(PATH)' $(MAKE) -C $(DOSFSTOOLS_DIR) $(DOSFSTOOLS_MAKE_VARS) - $(Q) PATH='$(CROSSBIN):$(PATH)' $(MAKE) -C $(DOSFSTOOLS_DIR) $(DOSFSTOOLS_MAKE_VARS) \ - install-symlinks + $(Q) PATH='$(CROSSBIN):$(PATH)' $(MAKE) -C $(DOSFSTOOLS_DIR) + $(Q) PATH='$(CROSSBIN):$(PATH)' $(MAKE) -C $(DOSFSTOOLS_DIR) \ + DESTDIR=$(DEV_SYSROOT) install $(Q) touch $@ dosfstools-install: $(DOSFSTOOLS_INSTALL_STAMP) diff --git a/build-config/make/dropbear.make b/build-config/make/dropbear.make index d795519e7..2eb027507 100644 --- a/build-config/make/dropbear.make +++ b/build-config/make/dropbear.make @@ -10,7 +10,7 @@ # This is a makefile fragment that defines the build of dropbear # -DROPBEAR_VERSION = 2020.81 +DROPBEAR_VERSION = 2026.91 DROPBEAR_TARBALL = dropbear-$(DROPBEAR_VERSION).tar.bz2 DROPBEAR_TARBALL_URLS += $(ONIE_MIRROR) https://matt.ucc.asn.au/dropbear/releases DROPBEAR_BUILD_DIR = $(USER_BUILDDIR)/dropbear diff --git a/build-config/make/efibootmgr.make b/build-config/make/efibootmgr.make index f5b3ecbbc..e4b34aa18 100644 --- a/build-config/make/efibootmgr.make +++ b/build-config/make/efibootmgr.make @@ -9,10 +9,13 @@ # This is a makefile fragment that defines the build of efibootmgr # -EFIBOOTMGR_VERSION = 16 -EFIBOOTMGR_TARBALL = efibootmgr-$(EFIBOOTMGR_VERSION).tar.bz2 +EFIBOOTMGR_VERSION = 18 +# efibootmgr (like efivar) no longer ships dist tarballs; use the GitHub +# source archive (unpacks to efibootmgr-$(EFIBOOTMGR_VERSION)/). v18 +# matches efivar 39's efidp_format_device_path() signature. +EFIBOOTMGR_TARBALL = $(EFIBOOTMGR_VERSION).tar.gz EFIBOOTMGR_TARBALL_URLS += $(ONIE_MIRROR) \ - https://github.com/rhboot/efibootmgr/releases/download/$(EFIBOOTMGR_VERSION)/$(EFIBOOTMGR_TARBALL) + https://github.com/rhboot/efibootmgr/archive EFIBOOTMGR_BUILD_DIR = $(USER_BUILDDIR)/efibootmgr EFIBOOTMGR_DIR = $(EFIBOOTMGR_BUILD_DIR)/efibootmgr-$(EFIBOOTMGR_VERSION) diff --git a/build-config/make/efivar.make b/build-config/make/efivar.make index c2b0b17e9..ba67b2a98 100644 --- a/build-config/make/efivar.make +++ b/build-config/make/efivar.make @@ -11,26 +11,27 @@ # This is a makefile fragment that defines the build of efivar # -EFIVAR_VERSION = 37 -EFIVAR_TARBALL = efivar-$(EFIVAR_VERSION).tar.bz2 -EFIVAR_TARBALL_URLS += $(ONIE_MIRROR) https://github.com/rhboot/efivar/releases/download/${EFIVAR_VERSION}/${EFIVAR_TARBALL} +EFIVAR_VERSION = 39 +# efivar stopped publishing dist tarballs after v37; use the GitHub source +# archive (unpacks to efivar-$(EFIVAR_VERSION)/). efivar 39's build system +# is fully cross-compile aware (derives CC/AR/HOSTCC from CROSS_COMPILE), so +# none of the old ONIE efivar patches are needed any longer. +EFIVAR_TARBALL = $(EFIVAR_VERSION).tar.gz +EFIVAR_TARBALL_URLS += $(ONIE_MIRROR) https://github.com/rhboot/efivar/archive EFIVAR_BUILD_DIR = $(USER_BUILDDIR)/efivar EFIVAR_DIR = $(EFIVAR_BUILD_DIR)/efivar-$(EFIVAR_VERSION) -EFIVAR_SRCPATCHDIR = $(PATCHDIR)/efivar/$(EFIVAR_VERSION)/ EFIVAR_DOWNLOAD_STAMP = $(DOWNLOADDIR)/efivar-$(EFIVAR_VERSION)-download EFIVAR_SOURCE_STAMP = $(USER_STAMPDIR)/efivar-source -EFIVAR_PATCH_STAMP = $(USER_STAMPDIR)/efivar-patch EFIVAR_BUILD_STAMP = $(USER_STAMPDIR)/efivar-build EFIVAR_INSTALL_STAMP = $(STAMPDIR)/efivar-install EFIVAR_STAMP = $(EFIVAR_SOURCE_STAMP) \ - $(EFIVAR_PATCH_STAMP) \ $(EFIVAR_BUILD_STAMP) \ $(EFIVAR_INSTALL_STAMP) EFIVAR_PROGRAMS = efivar -PHONY += efivar efivar-download efivar-source efivar-patch \ +PHONY += efivar efivar-download efivar-source \ efivar-build efivar-install efivar-clean efivar-download-clean EFIVAR_BINS = efivar @@ -61,26 +62,19 @@ $(EFIVAR_SOURCE_STAMP): $(USER_TREE_STAMP) $(EFIVAR_DOWNLOAD_STAMP) $(Q) $(SCRIPTDIR)/extract-package $(EFIVAR_BUILD_DIR) $(DOWNLOADDIR)/$(EFIVAR_TARBALL) $(Q) touch $@ -efivar-patch: $(EFIVAR_PATCH_STAMP) -$(EFIVAR_PATCH_STAMP): $(EFIVAR_SRCPATCHDIR)/* $(EFIVAR_SOURCE_STAMP) - $(Q) rm -f $@ && eval $(PROFILE_STAMP) - $(Q) echo "==== Patching efivar ====" - $(Q) $(SCRIPTDIR)/apply-patch-series $(EFIVAR_SRCPATCHDIR)/series $(EFIVAR_DIR) - $(Q) touch $@ - ifndef MAKE_CLEAN EFIVAR_NEW_FILES = $(shell test -d $(EFIVAR_DIR) && test -f $(EFIVAR_BUILD_STAMP) && \ find -L $(EFIVAR_DIR) -newer $(EFIVAR_BUILD_STAMP) -type f -print -quit) endif efivar-build: $(EFIVAR_BUILD_STAMP) -$(EFIVAR_BUILD_STAMP): $(EFIVAR_PATCH_STAMP) $(EFIVAR_NEW_FILES) $(POPT_BUILD_STAMP) \ +$(EFIVAR_BUILD_STAMP): $(EFIVAR_SOURCE_STAMP) $(EFIVAR_NEW_FILES) $(POPT_BUILD_STAMP) \ | $(DEV_SYSROOT_INIT_STAMP) $(Q) rm -f $@ && eval $(PROFILE_STAMP) $(Q) echo "==== Building efivar-$(EFIVAR_VERSION) ====" - $(Q) PATH='$(CROSSBIN):$(PATH)' $(MAKE) -C $(EFIVAR_DIR) \ + $(Q) PATH='$(CROSSBIN):$(PATH)' $(MAKE) -C $(EFIVAR_DIR) SUBDIRS=src \ CROSS_COMPILE=$(CROSSPREFIX) PKG_CONFIG=pkg-config $(ONIE_PKG_CONFIG) DESTDIR=$(DEV_SYSROOT) - $(Q) PATH='$(CROSSBIN):$(PATH)' $(MAKE) -C $(EFIVAR_DIR) \ + $(Q) PATH='$(CROSSBIN):$(PATH)' $(MAKE) -C $(EFIVAR_DIR) SUBDIRS=src \ CROSS_COMPILE=$(CROSSPREFIX) PKG_CONFIG=pkg-config $(ONIE_PKG_CONFIG) DESTDIR=$(DEV_SYSROOT) install $(Q) touch $@ diff --git a/build-config/make/ethtool.make b/build-config/make/ethtool.make index 1fdb19e09..026676f5d 100644 --- a/build-config/make/ethtool.make +++ b/build-config/make/ethtool.make @@ -9,7 +9,7 @@ # This is a makefile fragment that defines the build of ethtool # -ETHTOOL_VERSION = 3.14 +ETHTOOL_VERSION = 6.15 ETHTOOL_TARBALL = ethtool-$(ETHTOOL_VERSION).tar.xz ETHTOOL_TARBALL_URLS += $(ONIE_MIRROR) https://www.kernel.org/pub/software/network/ethtool ETHTOOL_BUILD_DIR = $(USER_BUILDDIR)/ethtool @@ -50,7 +50,7 @@ $(ETHTOOL_SOURCE_STAMP): $(USER_TREE_STAMP) | $(ETHTOOL_DOWNLOAD_STAMP) $(Q) touch $@ ethtool-configure: $(ETHTOOL_CONFIGURE_STAMP) -$(ETHTOOL_CONFIGURE_STAMP): $(ETHTOOL_SOURCE_STAMP) | $(DEV_SYSROOT_INIT_STAMP) +$(ETHTOOL_CONFIGURE_STAMP): $(ETHTOOL_SOURCE_STAMP) $(LIBMNL_BUILD_STAMP) | $(DEV_SYSROOT_INIT_STAMP) $(Q) rm -f $@ && eval $(PROFILE_STAMP) $(Q) echo "==== Configure ethtool-$(ETHTOOL_VERSION) ====" $(Q) cd $(ETHTOOL_DIR) && PATH='$(CROSSBIN):$(PATH)' \ @@ -58,7 +58,8 @@ $(ETHTOOL_CONFIGURE_STAMP): $(ETHTOOL_SOURCE_STAMP) | $(DEV_SYSROOT_INIT_STAMP) --prefix=/usr \ --host=$(TARGET) \ CFLAGS="$(ONIE_CFLAGS)" \ - LDFLAGS="$(ONIE_LDFLAGS)" + LDFLAGS="$(ONIE_LDFLAGS)" \ + $(ONIE_PKG_CONFIG) $(Q) touch $@ ethtool-build: $(ETHTOOL_BUILD_STAMP) @@ -70,7 +71,7 @@ $(ETHTOOL_BUILD_STAMP): $(ETHTOOL_CONFIGURE_STAMP) $(Q) touch $@ ethtool-install: $(ETHTOOL_INSTALL_STAMP) -$(ETHTOOL_INSTALL_STAMP): $(SYSROOT_INIT_STAMP) $(ETHTOOL_BUILD_STAMP) +$(ETHTOOL_INSTALL_STAMP): $(SYSROOT_INIT_STAMP) $(ETHTOOL_BUILD_STAMP) $(LIBMNL_INSTALL_STAMP) $(Q) rm -f $@ && eval $(PROFILE_STAMP) $(Q) echo "==== Installing ethtool in $(SYSROOTDIR) ====" $(Q) cp -av $(DEV_SYSROOT)/usr/sbin/$(ETHTOOL_BIN) $(SYSROOTDIR)/usr/sbin diff --git a/build-config/make/gptfdisk.make b/build-config/make/gptfdisk.make index c72024cb8..e50bada33 100644 --- a/build-config/make/gptfdisk.make +++ b/build-config/make/gptfdisk.make @@ -9,7 +9,7 @@ # This is a makefile fragment that defines the build of gptfdisk # -GPTFDISK_VERSION = 0.8.8 +GPTFDISK_VERSION = 1.0.10 GPTFDISK_TARBALL = gptfdisk-$(GPTFDISK_VERSION).tar.gz GPTFDISK_TARBALL_URLS += $(ONIE_MIRROR) http://sourceforge.net/projects/gptfdisk/files/gptfdisk/$(GPTFDISK_VERSION)/ GPTFDISK_BUILD_DIR = $(USER_BUILDDIR)/gptfdisk diff --git a/build-config/make/grub.make b/build-config/make/grub.make index 81d3fb12d..354766542 100644 --- a/build-config/make/grub.make +++ b/build-config/make/grub.make @@ -13,9 +13,9 @@ # This is a makefile fragment that defines the build of grub # -GRUB_VERSION = 2.04 +GRUB_VERSION = 2.14 GRUB_TARBALL = grub-$(GRUB_VERSION).tar.xz -GRUB_TARBALL_URLS += $(ONIE_MIRROR) http://git.savannah.gnu.org/cgit/grub.git/snapshot/ ftp://alpha.gnu.org/gnu/grub/ +GRUB_TARBALL_URLS += $(ONIE_MIRROR) https://ftp.gnu.org/gnu/grub ftp://alpha.gnu.org/gnu/grub/ GRUB_BUILD_DIR = $(USER_BUILDDIR)/grub GRUB_DIR = $(GRUB_BUILD_DIR)/grub-$(GRUB_VERSION) GRUB_I386_DIR = $(GRUB_BUILD_DIR)/grub-i386-pc @@ -123,12 +123,15 @@ $(GRUB_SOURCE_STAMP): $(USER_TREE_STAMP) | $(GRUB_DOWNLOAD_STAMP) $(Q) $(SCRIPTDIR)/extract-package $(GRUB_BUILD_DIR) $(DOWNLOADDIR)/$(GRUB_TARBALL) $(Q) touch $@ +# grub 2.14 needs no ONIE patches and its release tarball ships a generated +# ./configure, so this step applies no patch series and does not run +# autogen.sh. (The i386-pc link fix for binutils >= 2.39 / GCC 14, which +# requires patches + autogen + autoconf-archive, lives with the toolchain +# upgrade, not here.) grub-patch: $(GRUB_PATCH_STAMP) $(GRUB_PATCH_STAMP): $(GRUB_SOURCE_STAMP) $(Q) rm -f $@ && eval $(PROFILE_STAMP) - $(Q) echo "==== Patching grub-$(GRUB_VERSION) ====" - $(Q) $(SCRIPTDIR)/apply-patch-series $(GRUB_SRCPATCHDIR)/series $(GRUB_DIR) - $(Q) cd $(GRUB_DIR) && ./autogen.sh + $(Q) echo "==== grub-$(GRUB_VERSION): no ONIE patches to apply ====" $(Q) touch $@ $(GRUB_CONFIGURE_I386_STAMP): $(GRUB_PATCH_STAMP) $(LVM2_BUILD_STAMP) | $(DEV_SYSROOT_INIT_STAMP) diff --git a/build-config/make/i2ctools.make b/build-config/make/i2ctools.make index 66c75214e..36e94a79e 100644 --- a/build-config/make/i2ctools.make +++ b/build-config/make/i2ctools.make @@ -11,9 +11,9 @@ # This is a makefile fragment that defines the build of i2ctools # -I2CTOOLS_VERSION = 3.1.1 -I2CTOOLS_TARBALL = i2c-tools-$(I2CTOOLS_VERSION).tar.bz2 -I2CTOOLS_TARBALL_URLS += $(ONIE_MIRROR) http://jdelvare.nerim.net/mirror/i2c-tools +I2CTOOLS_VERSION = 4.4 +I2CTOOLS_TARBALL = i2c-tools-$(I2CTOOLS_VERSION).tar.gz +I2CTOOLS_TARBALL_URLS += $(ONIE_MIRROR) https://mirrors.edge.kernel.org/pub/software/utils/i2c-tools I2CTOOLS_BUILD_DIR = $(MBUILDDIR)/i2c-tools I2CTOOLS_DIR = $(I2CTOOLS_BUILD_DIR)/i2c-tools-$(I2CTOOLS_VERSION) @@ -65,8 +65,8 @@ $(I2CTOOLS_PATCH_STAMP): $(I2CTOOLS_SRCPATCHDIR)/* $(MACHINE_I2CTOOLS_PATCHDIR_F $(Q) rm -f $@ && eval $(PROFILE_STAMP) $(Q) echo "==== Patching i2ctools ====" $(Q) mkdir -p $(I2CTOOLS_DIR)/sys_eeprom - $(Q) cp $(I2CTOOLS_DIR)/eepromer/24cXX.c $(I2CTOOLS_DIR)/sys_eeprom/24cXX.c - $(Q) cp $(I2CTOOLS_DIR)/eepromer/24cXX.h $(I2CTOOLS_DIR)/sys_eeprom/24cXX.h + $(Q) cp $(I2CTOOLS_DIR)/eeprog/24cXX.c $(I2CTOOLS_DIR)/sys_eeprom/24cXX.c + $(Q) cp $(I2CTOOLS_DIR)/eeprog/24cXX.h $(I2CTOOLS_DIR)/sys_eeprom/24cXX.h $(Q) mkdir -p $(I2CTOOLS_PATCHDIR) $(Q) cp $(I2CTOOLS_SRCPATCHDIR)/* $(I2CTOOLS_PATCHDIR) ifneq ($(MACHINE_I2CTOOLS_PATCHDIR),) diff --git a/build-config/make/ipmitool.make b/build-config/make/ipmitool.make index d32191faf..57101dc9d 100644 --- a/build-config/make/ipmitool.make +++ b/build-config/make/ipmitool.make @@ -9,9 +9,14 @@ # This is a makefile fragment that defines the build of ipmitool # -IPMITOOL_VERSION = 1.8.18 -IPMITOOL_TARBALL = ipmitool-$(IPMITOOL_VERSION).tar.bz2 -IPMITOOL_TARBALL_URLS += $(ONIE_MIRROR) https://github.com/ipmitool/ipmitool/releases/download/IPMITOOL_$(subst .,_,$(IPMITOOL_VERSION))/ +IPMITOOL_VERSION = 1.8.19 +# 1.8.19 ships no release dist tarball, so use the upstream GitHub source +# tag archive. It unpacks to ipmitool-$(IPMITOOL_TAG)/ and has no +# generated configure, so the source step renames the dir and the +# configure step runs ./bootstrap (autoreconf) first. +IPMITOOL_TAG = IPMITOOL_$(subst .,_,$(IPMITOOL_VERSION)) +IPMITOOL_TARBALL = $(IPMITOOL_TAG).tar.gz +IPMITOOL_TARBALL_URLS += $(ONIE_MIRROR) https://github.com/ipmitool/ipmitool/archive/refs/tags IPMITOOL_BUILD_DIR = $(USER_BUILDDIR)/ipmitool IPMITOOL_DIR = $(IPMITOOL_BUILD_DIR)/ipmitool-$(IPMITOOL_VERSION) @@ -47,12 +52,16 @@ $(IPMITOOL_SOURCE_STAMP): $(USER_TREE_STAMP) | $(IPMITOOL_DOWNLOAD_STAMP) $(Q) rm -f $@ && eval $(PROFILE_STAMP) $(Q) echo "==== Extracting upstream ipmitool ====" $(Q) $(SCRIPTDIR)/extract-package $(IPMITOOL_BUILD_DIR) $(DOWNLOADDIR)/$(IPMITOOL_TARBALL) + $(Q) if [ -d "$(IPMITOOL_BUILD_DIR)/ipmitool-$(IPMITOOL_TAG)" ] ; then \ + mv "$(IPMITOOL_BUILD_DIR)/ipmitool-$(IPMITOOL_TAG)" $(IPMITOOL_DIR) ; \ + fi $(Q) touch $@ ipmitool-configure: $(IPMITOOL_CONFIGURE_STAMP) $(IPMITOOL_CONFIGURE_STAMP): $(IPMITOOL_SOURCE_STAMP) | $(DEV_SYSROOT_INIT_STAMP) $(Q) rm -f $@ && eval $(PROFILE_STAMP) $(Q) echo "==== Configure ipmitool-$(IPMITOOL_VERSION) ====" + $(Q) cd $(IPMITOOL_DIR) && PATH='$(CROSSBIN):$(PATH)' ./bootstrap $(Q) cd $(IPMITOOL_DIR) && PATH='$(CROSSBIN):$(PATH)' \ $(IPMITOOL_DIR)/configure \ --prefix=/usr \ diff --git a/build-config/make/kexec-tools.make b/build-config/make/kexec-tools.make index 4b379c7fb..c061f1df7 100644 --- a/build-config/make/kexec-tools.make +++ b/build-config/make/kexec-tools.make @@ -9,7 +9,7 @@ # This is a makefile fragment that defines the build of kexec-tools # -KEXEC_VERSION = 2.0.22 +KEXEC_VERSION = 2.0.32 KEXEC_TARBALL = kexec-tools-$(KEXEC_VERSION).tar.xz KEXEC_TARBALL_URLS += $(ONIE_MIRROR) \ https://www.kernel.org/pub/linux/utils/kernel/kexec diff --git a/build-config/make/keyutils.make b/build-config/make/keyutils.make index c1aad6b4a..eda105aee 100644 --- a/build-config/make/keyutils.make +++ b/build-config/make/keyutils.make @@ -9,10 +9,13 @@ # This is a makefile fragment that defines the build of keyutils # -KEYUTILS_VERSION = 1.5.10 -KEYUTILS_TARBALL = keyutils-$(KEYUTILS_VERSION).tar.bz2 +KEYUTILS_VERSION = 1.6.3 +KEYUTILS_TARBALL = keyutils-$(KEYUTILS_VERSION).tar.gz +# Upstream tarballs used to live at people.redhat.com/~dhowells, which was +# retired. The maintainer's git tree on kernel.org serves a reproducible +# snapshot tarball (keyutils-.tar.gz) instead. KEYUTILS_TARBALL_URLS += $(ONIE_MIRROR) \ - https://people.redhat.com/~dhowells/keyutils + https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/keyutils.git/snapshot KEYUTILS_BUILD_DIR = $(USER_BUILDDIR)/keyutils KEYUTILS_DIR = $(KEYUTILS_BUILD_DIR)/keyutils-$(KEYUTILS_VERSION) @@ -29,7 +32,7 @@ PHONY += keyutils keyutils-download keyutils-source \ keyutils-download-clean KEYUTILS_BIN = keyctl -KEYUTILS_LIB = libkeyutils.so libkeyutils.so.1 libkeyutils.so.1.6 +KEYUTILS_LIB = libkeyutils.so libkeyutils.so.1 libkeyutils.so.1.10 keyutils: $(KEYUTILS_STAMP) diff --git a/build-config/make/libaio.make b/build-config/make/libaio.make new file mode 100644 index 000000000..5a9b1cd66 --- /dev/null +++ b/build-config/make/libaio.make @@ -0,0 +1,90 @@ +#------------------------------------------------------------------------------- +# +# SPDX-License-Identifier: GPL-2.0 +# +#------------------------------------------------------------------------------- +# +# This is a makefile fragment that defines the build of libaio +# +# libaio provides the Linux asynchronous I/O interface. It is required +# by lvm2 (>= 2.03, which uses it for its bcache I/O engine). + +LIBAIO_VERSION = 0.3.113 +LIBAIO_TARBALL = libaio-$(LIBAIO_VERSION).tar.gz +LIBAIO_TARBALL_URLS += $(ONIE_MIRROR) https://releases.pagure.org/libaio +LIBAIO_BUILD_DIR = $(USER_BUILDDIR)/libaio +LIBAIO_DIR = $(LIBAIO_BUILD_DIR)/libaio-$(LIBAIO_VERSION) + +LIBAIO_DOWNLOAD_STAMP = $(DOWNLOADDIR)/libaio-$(LIBAIO_VERSION)-download +LIBAIO_SOURCE_STAMP = $(USER_STAMPDIR)/libaio-source +LIBAIO_BUILD_STAMP = $(USER_STAMPDIR)/libaio-build +LIBAIO_INSTALL_STAMP = $(STAMPDIR)/libaio-install +LIBAIO_STAMP = $(LIBAIO_SOURCE_STAMP) \ + $(LIBAIO_BUILD_STAMP) \ + $(LIBAIO_INSTALL_STAMP) + +PHONY += libaio libaio-download libaio-source \ + libaio-build libaio-install libaio-clean libaio-download-clean + +# libaio builds via a plain Makefile (no ./configure); soname is +# libaio.so.1, real lib libaio.so.1.$(minor).$(micro) = libaio.so.1.0.2. +LIBAIO_LIBS = libaio.so libaio.so.1 libaio.so.1.0.2 + +libaio: $(LIBAIO_STAMP) + +DOWNLOAD += $(LIBAIO_DOWNLOAD_STAMP) +libaio-download: $(LIBAIO_DOWNLOAD_STAMP) +$(LIBAIO_DOWNLOAD_STAMP): $(PROJECT_STAMP) + $(Q) rm -f $@ && eval $(PROFILE_STAMP) + $(Q) echo "==== Getting upstream libaio ====" + $(Q) $(SCRIPTDIR)/fetch-package $(DOWNLOADDIR) $(UPSTREAMDIR) \ + $(LIBAIO_TARBALL) $(LIBAIO_TARBALL_URLS) + $(Q) touch $@ + +SOURCE += $(LIBAIO_SOURCE_STAMP) +libaio-source: $(LIBAIO_SOURCE_STAMP) +$(LIBAIO_SOURCE_STAMP): $(USER_TREE_STAMP) | $(LIBAIO_DOWNLOAD_STAMP) + $(Q) rm -f $@ && eval $(PROFILE_STAMP) + $(Q) echo "==== Extracting upstream libaio ====" + $(Q) $(SCRIPTDIR)/extract-package $(LIBAIO_BUILD_DIR) $(DOWNLOADDIR)/$(LIBAIO_TARBALL) + $(Q) touch $@ + +ifndef MAKE_CLEAN +LIBAIO_NEW_FILES = $(shell test -d $(LIBAIO_DIR) && test -f $(LIBAIO_BUILD_STAMP) && \ + find -L $(LIBAIO_DIR) -newer $(LIBAIO_BUILD_STAMP) -type f -print -quit) +endif + +libaio-build: $(LIBAIO_BUILD_STAMP) +$(LIBAIO_BUILD_STAMP): $(LIBAIO_SOURCE_STAMP) $(LIBAIO_NEW_FILES) | $(DEV_SYSROOT_INIT_STAMP) + $(Q) rm -f $@ && eval $(PROFILE_STAMP) + $(Q) echo "==== Building libaio-$(LIBAIO_VERSION) ====" + $(Q) PATH='$(CROSSBIN):$(PATH)' $(MAKE) -C $(LIBAIO_DIR) \ + CC=$(CROSSPREFIX)gcc prefix=/usr + $(Q) PATH='$(CROSSBIN):$(PATH)' $(MAKE) -C $(LIBAIO_DIR) \ + CC=$(CROSSPREFIX)gcc prefix=/usr DESTDIR=$(DEV_SYSROOT) install + $(Q) touch $@ + +libaio-install: $(LIBAIO_INSTALL_STAMP) +$(LIBAIO_INSTALL_STAMP): $(SYSROOT_INIT_STAMP) $(LIBAIO_BUILD_STAMP) + $(Q) rm -f $@ && eval $(PROFILE_STAMP) + $(Q) echo "==== Installing libaio in $(SYSROOTDIR) ====" + $(Q) for file in $(LIBAIO_LIBS) ; do \ + cp -a $(DEV_SYSROOT)/usr/lib/$$file $(SYSROOTDIR)/usr/lib/ ; \ + done + $(Q) touch $@ + +USER_CLEAN += libaio-clean +libaio-clean: + $(Q) rm -rf $(LIBAIO_BUILD_DIR) + $(Q) rm -f $(LIBAIO_STAMP) + $(Q) echo "=== Finished making $@ for $(PLATFORM)" + +DOWNLOAD_CLEAN += libaio-download-clean +libaio-download-clean: + $(Q) rm -f $(LIBAIO_DOWNLOAD_STAMP) $(DOWNLOADDIR)/$(LIBAIO_TARBALL) + +#------------------------------------------------------------------------------- +# +# Local Variables: +# mode: makefile-gmake +# End: diff --git a/build-config/make/libmnl.make b/build-config/make/libmnl.make new file mode 100644 index 000000000..bc66ef2a2 --- /dev/null +++ b/build-config/make/libmnl.make @@ -0,0 +1,102 @@ +#------------------------------------------------------------------------------- +# +# SPDX-License-Identifier: GPL-2.0 +# +#------------------------------------------------------------------------------- +# +# This is a makefile fragment that defines the build of libmnl +# +# libmnl is a minimal netlink library (netfilter.org). It is required +# by ethtool's netlink interface (the default since ethtool moved most +# functionality to netlink). + +LIBMNL_VERSION = 1.0.5 +LIBMNL_TARBALL = libmnl-$(LIBMNL_VERSION).tar.bz2 +LIBMNL_TARBALL_URLS += $(ONIE_MIRROR) https://www.netfilter.org/projects/libmnl/files +LIBMNL_BUILD_DIR = $(USER_BUILDDIR)/libmnl +LIBMNL_DIR = $(LIBMNL_BUILD_DIR)/libmnl-$(LIBMNL_VERSION) + +LIBMNL_DOWNLOAD_STAMP = $(DOWNLOADDIR)/libmnl-$(LIBMNL_VERSION)-download +LIBMNL_SOURCE_STAMP = $(USER_STAMPDIR)/libmnl-source +LIBMNL_CONFIGURE_STAMP = $(USER_STAMPDIR)/libmnl-configure +LIBMNL_BUILD_STAMP = $(USER_STAMPDIR)/libmnl-build +LIBMNL_INSTALL_STAMP = $(STAMPDIR)/libmnl-install +LIBMNL_STAMP = $(LIBMNL_SOURCE_STAMP) \ + $(LIBMNL_CONFIGURE_STAMP) \ + $(LIBMNL_BUILD_STAMP) \ + $(LIBMNL_INSTALL_STAMP) + +PHONY += libmnl libmnl-download libmnl-source libmnl-configure \ + libmnl-build libmnl-install libmnl-clean libmnl-download-clean + +LIBMNL_LIBS = libmnl.so libmnl.so.0 libmnl.so.0.2.0 + +libmnl: $(LIBMNL_STAMP) + +DOWNLOAD += $(LIBMNL_DOWNLOAD_STAMP) +libmnl-download: $(LIBMNL_DOWNLOAD_STAMP) +$(LIBMNL_DOWNLOAD_STAMP): $(PROJECT_STAMP) + $(Q) rm -f $@ && eval $(PROFILE_STAMP) + $(Q) echo "==== Getting upstream libmnl ====" + $(Q) $(SCRIPTDIR)/fetch-package $(DOWNLOADDIR) $(UPSTREAMDIR) \ + $(LIBMNL_TARBALL) $(LIBMNL_TARBALL_URLS) + $(Q) touch $@ + +SOURCE += $(LIBMNL_SOURCE_STAMP) +libmnl-source: $(LIBMNL_SOURCE_STAMP) +$(LIBMNL_SOURCE_STAMP): $(USER_TREE_STAMP) | $(LIBMNL_DOWNLOAD_STAMP) + $(Q) rm -f $@ && eval $(PROFILE_STAMP) + $(Q) echo "==== Extracting upstream libmnl ====" + $(Q) $(SCRIPTDIR)/extract-package $(LIBMNL_BUILD_DIR) $(DOWNLOADDIR)/$(LIBMNL_TARBALL) + $(Q) touch $@ + +ifndef MAKE_CLEAN +LIBMNL_NEW_FILES = $(shell test -d $(LIBMNL_DIR) && test -f $(LIBMNL_BUILD_STAMP) && \ + find -L $(LIBMNL_DIR) -newer $(LIBMNL_BUILD_STAMP) -type f -print -quit) +endif + +libmnl-configure: $(LIBMNL_CONFIGURE_STAMP) +$(LIBMNL_CONFIGURE_STAMP): $(LIBMNL_SOURCE_STAMP) | $(DEV_SYSROOT_INIT_STAMP) + $(Q) rm -f $@ && eval $(PROFILE_STAMP) + $(Q) echo "==== Configure libmnl-$(LIBMNL_VERSION) ====" + $(Q) cd $(LIBMNL_DIR) && PATH='$(CROSSBIN):$(PATH)' \ + $(LIBMNL_DIR)/configure \ + --enable-shared \ + --prefix=/usr \ + --host=$(TARGET) \ + CC=$(CROSSPREFIX)gcc \ + CFLAGS="$(ONIE_CFLAGS)" + $(Q) touch $@ + +libmnl-build: $(LIBMNL_BUILD_STAMP) +$(LIBMNL_BUILD_STAMP): $(LIBMNL_CONFIGURE_STAMP) $(LIBMNL_NEW_FILES) + $(Q) rm -f $@ && eval $(PROFILE_STAMP) + $(Q) echo "==== Building libmnl-$(LIBMNL_VERSION) ====" + $(Q) PATH='$(CROSSBIN):$(PATH)' $(MAKE) -C $(LIBMNL_DIR) DESTDIR=$(DEV_SYSROOT) + $(Q) PATH='$(CROSSBIN):$(PATH)' $(MAKE) -C $(LIBMNL_DIR) DESTDIR=$(DEV_SYSROOT) install + $(Q) touch $@ + +libmnl-install: $(LIBMNL_INSTALL_STAMP) +$(LIBMNL_INSTALL_STAMP): $(SYSROOT_INIT_STAMP) $(LIBMNL_BUILD_STAMP) + $(Q) rm -f $@ && eval $(PROFILE_STAMP) + $(Q) echo "==== Installing libmnl in $(SYSROOTDIR) ====" + $(Q) for file in $(LIBMNL_LIBS) ; do \ + cp -a $(DEV_SYSROOT)/usr/lib/$$file $(SYSROOTDIR)/usr/lib/ ; \ + done + $(Q) touch $@ + +USER_CLEAN += libmnl-clean +libmnl-clean: + $(Q) rm -rf $(LIBMNL_BUILD_DIR) + $(Q) rm -f $(LIBMNL_STAMP) + $(Q) echo "=== Finished making $@ for $(PLATFORM)" + +DOWNLOAD_CLEAN += libmnl-download-clean +libmnl-download-clean: + $(Q) rm -f $(LIBMNL_DOWNLOAD_STAMP) $(DOWNLOADDIR)/$(LIBMNL_TARBALL) + +#------------------------------------------------------------------------------- +# +# Local Variables: +# mode: makefile-gmake +# End: diff --git a/build-config/make/libpcap.make b/build-config/make/libpcap.make index 9b0c91994..b1d591b9c 100644 --- a/build-config/make/libpcap.make +++ b/build-config/make/libpcap.make @@ -9,7 +9,7 @@ # This is a makefile fragment that defines the build of libpcap # -LIBPCAP_VERSION = 1.10.4 +LIBPCAP_VERSION = 1.10.6 LIBPCAP_TARBALL = libpcap-$(LIBPCAP_VERSION).tar.gz LIBPCAP_TARBALL_URLS += $(ONIE_MIRROR) \ https://www.tcpdump.org/release diff --git a/build-config/make/lvm2.make b/build-config/make/lvm2.make index 468f6675f..ee3617fbe 100644 --- a/build-config/make/lvm2.make +++ b/build-config/make/lvm2.make @@ -11,11 +11,11 @@ # This is a makefile fragment that defines the build of lvm2 # -LVM2_VERSION ?= 2_02_105 -LVM2_TARBALL = lvm2-$(LVM2_VERSION).tar.xz -LVM2_TARBALL_URLS += $(ONIE_MIRROR) https://git.fedorahosted.org/cgit/lvm2.git/snapshot/ +LVM2_VERSION ?= 2.03.41 +LVM2_TARBALL = LVM2.$(LVM2_VERSION).tgz +LVM2_TARBALL_URLS += $(ONIE_MIRROR) https://sourceware.org/ftp/lvm2 LVM2_BUILD_DIR = $(USER_BUILDDIR)/lvm2 -LVM2_DIR = $(LVM2_BUILD_DIR)/lvm2-$(LVM2_VERSION) +LVM2_DIR = $(LVM2_BUILD_DIR)/LVM2.$(LVM2_VERSION) LVM2_SRCPATCHDIR = $(PATCHDIR)/lvm2 LVM2_DOWNLOAD_STAMP = $(DOWNLOADDIR)/lvm2-$(LVM2_VERSION)-download @@ -45,7 +45,6 @@ LVM2_PROGS = \ sbin/lvcreate \ sbin/lvdisplay \ sbin/lvextend \ - sbin/lvmchange \ sbin/lvmdiskscan \ sbin/lvmsadc \ sbin/lvmsar \ @@ -122,7 +121,7 @@ LVM2_CONFIGURE_OVERRIDES = \ lvm2-configure: $(LVM2_CONFIGURE_STAMP) -$(LVM2_CONFIGURE_STAMP): $(LVM2_SOURCE_STAMP) $(LVM2_PATCH_STAMP)\ +$(LVM2_CONFIGURE_STAMP): $(LVM2_SOURCE_STAMP) $(LVM2_PATCH_STAMP) $(LIBAIO_BUILD_STAMP)\ | $(DEV_SYSROOT_INIT_STAMP) $(Q) rm -f $@ && eval $(PROFILE_STAMP) $(Q) echo "==== Configure lvm2-$(LVM2_VERSION) ====" @@ -131,9 +130,14 @@ $(LVM2_CONFIGURE_STAMP): $(LVM2_SOURCE_STAMP) $(LVM2_PATCH_STAMP)\ $(LVM2_DIR)/configure \ --prefix=/usr \ --host=$(TARGET) \ - --with-clvmd=none \ --disable-nls \ --disable-selinux \ + --disable-readline \ + --disable-systemd-journal \ + --without-systemd \ + --without-udev \ + --disable-use-lvmlockd \ + --disable-use-lvmpolld \ CC=$(CROSSPREFIX)gcc \ CFLAGS="$(ONIE_CFLAGS)" \ LDFLAGS="$(ONIE_LDFLAGS)" @@ -150,7 +154,7 @@ $(LVM2_BUILD_STAMP): $(LVM2_CONFIGURE_STAMP) $(UTILLINUX_BUILD_STAMP) $(Q) touch $@ lvm2-install: $(LVM2_INSTALL_STAMP) -$(LVM2_INSTALL_STAMP): $(SYSROOT_INIT_STAMP) $(LVM2_BUILD_STAMP) $(UTILLINUX_INSTALL_STAMP) +$(LVM2_INSTALL_STAMP): $(SYSROOT_INIT_STAMP) $(LVM2_BUILD_STAMP) $(UTILLINUX_INSTALL_STAMP) $(LIBAIO_INSTALL_STAMP) $(Q) rm -f $@ && eval $(PROFILE_STAMP) $(Q) echo "==== Installing lvm2 programs in $(SYSROOTDIR) ====" $(Q) for file in $(LVM2_PROGS) ; do \ diff --git a/build-config/make/lzo.make b/build-config/make/lzo.make index be4ee0c8a..a16ff886c 100644 --- a/build-config/make/lzo.make +++ b/build-config/make/lzo.make @@ -10,7 +10,7 @@ # This is a makefile fragment that defines the build of lzo # -LZO_VERSION = 2.09 +LZO_VERSION = 2.10 LZO_TARBALL = lzo-$(LZO_VERSION).tar.gz LZO_TARBALL_URLS += $(ONIE_MIRROR) http://www.oberhumer.com/opensource/lzo/download LZO_BUILD_DIR = $(USER_BUILDDIR)/lzo diff --git a/build-config/make/mokutil.make b/build-config/make/mokutil.make index 50f40540b..846cc6b04 100644 --- a/build-config/make/mokutil.make +++ b/build-config/make/mokutil.make @@ -79,7 +79,7 @@ $(MOKUTIL_CONFIGURE_STAMP): $(MOKUTIL_PATCH_STAMP) $(EFIVAR_BUILD_STAMP) | $(DEV --host=$(TARGET) \ EFIVAR_CFLAGS=-I$(DEV_SYSROOT)/usr/include/efivar \ CC=$(CROSSPREFIX)gcc \ - CFLAGS="$(ONIE_CFLAGS)" \ + CFLAGS="$(ONIE_CFLAGS) -Wno-error=deprecated-declarations" \ LDFLAGS="$(ONIE_LDFLAGS)" \ $(ONIE_PKG_CONFIG) $(Q) touch $@ diff --git a/build-config/make/mtdutils.make b/build-config/make/mtdutils.make index be6f3c134..a554407a4 100644 --- a/build-config/make/mtdutils.make +++ b/build-config/make/mtdutils.make @@ -10,26 +10,28 @@ # This is a makefile fragment that defines the build of mtdutils # -MTDUTILS_VERSION = 1.5.2 -MTDUTILS_COMMIT = e4c8885bddac201ba0ef88560d6444f39e1ff870 -MTDUTILS_TARBALL = mtd-utils-$(MTDUTILS_VERSION).tar.gz -MTDUTILS_TARBALL_URLS += $(ONIE_MIRROR) http://git.infradead.org/mtd-utils.git/snapshot +MTDUTILS_VERSION = 2.3.1 +MTDUTILS_TARBALL = mtd-utils-$(MTDUTILS_VERSION).tar.bz2 +MTDUTILS_TARBALL_URLS += $(ONIE_MIRROR) https://infraroot.at/pub/mtd MTDUTILS_BUILD_DIR = $(USER_BUILDDIR)/mtd-utils -MTDUTILS_DIR = $(MTDUTILS_BUILD_DIR)/mtd-utils-e4c8885 +MTDUTILS_DIR = $(MTDUTILS_BUILD_DIR)/mtd-utils-$(MTDUTILS_VERSION) MTDUTILS_DOWNLOAD_STAMP = $(DOWNLOADDIR)/mtdutils-$(MTDUTILS_VERSION)-download MTDUTILS_SOURCE_STAMP = $(USER_STAMPDIR)/mtdutils-source +MTDUTILS_CONFIGURE_STAMP = $(USER_STAMPDIR)/mtdutils-configure MTDUTILS_BUILD_STAMP = $(USER_STAMPDIR)/mtdutils-build MTDUTILS_INSTALL_STAMP = $(STAMPDIR)/mtdutils-install MTDUTILS_STAMP = $(MTDUTILS_SOURCE_STAMP) \ + $(MTDUTILS_CONFIGURE_STAMP) \ $(MTDUTILS_BUILD_STAMP) \ $(MTDUTILS_INSTALL_STAMP) -MTDBINS = mkfs.jffs2 mkfs.ubifs ubinize ubiformat ubinfo mtdinfo +MTDBINS = mkfs.jffs2 mkfs.ubifs ubinize ubiformat ubinfo mtdinfo UBIBINS = ubiattach ubimkvol ubidetach ubirmvol -PHONY += mtdutils mtdutils-download mtdutils-source mtdutils-build \ - mtdutils-install mtdutils-clean mtdutils-download-clean +PHONY += mtdutils mtdutils-download mtdutils-source mtdutils-configure \ + mtdutils-build mtdutils-install mtdutils-clean mtdutils-download-clean \ + mtdutils-configure-help mtdutils: $(MTDUTILS_STAMP) @@ -39,8 +41,7 @@ $(MTDUTILS_DOWNLOAD_STAMP): $(PROJECT_STAMP) $(Q) rm -f $@ && eval $(PROFILE_STAMP) $(Q) echo "==== Getting upstream mtdutils ====" $(Q) $(SCRIPTDIR)/fetch-package $(DOWNLOADDIR) $(UPSTREAMDIR) \ - $(MTDUTILS_COMMIT).tar.gz $(MTDUTILS_TARBALL_URLS) - $(Q) cd $(DOWNLOADDIR) && ln -fs $(MTDUTILS_COMMIT).tar.gz $(MTDUTILS_TARBALL) + $(MTDUTILS_TARBALL) $(MTDUTILS_TARBALL_URLS) $(Q) touch $@ SOURCE += $(MTDUTILS_SOURCE_STAMP) @@ -51,29 +52,66 @@ $(MTDUTILS_SOURCE_STAMP): $(USER_TREE_STAMP) | $(MTDUTILS_DOWNLOAD_STAMP) $(Q) $(SCRIPTDIR)/extract-package $(MTDUTILS_BUILD_DIR) $(DOWNLOADDIR)/$(MTDUTILS_TARBALL) $(Q) touch $@ +mtdutils-configure-help: $(UTILLINUX_BUILD_STAMP) $(LZO_BUILD_STAMP) \ + $(ZLIB_BUILD_STAMP) \ + $(MTDUTILS_SOURCE_STAMP) | $(DEV_SYSROOT_INIT_STAMP) + $(Q) echo "==== Configure help for mtd-utils-$(MTDUTILS_VERSION) ====" + $(Q) cd $(MTDUTILS_DIR) && PATH='$(CROSSBIN):$(PATH)' \ + $(MTDUTILS_DIR)/configure --help + +# mtd-utils 2.x uses an autotools (./configure) build. +# +# Optional dependencies: +# - zlib, lzo, libuuid (util-linux) are provided by ONIE and enabled +# (UBIFS/JFFS2 support). +# - crypto (UBIFS authentication) is disabled: ONIE does not need it and +# the prior 1.5.2 build did not use it. +# - zstd is NOT provided by ONIE, so ZSTD compression is disabled. +# - selinux is NOT provided by ONIE, so SELinux support is disabled. +# - xattr is disabled to match the prior 1.5.2 build (WITHOUT_XATTR=1). +# - The unit/test programs are disabled (--without-tests); they are not +# installed and pull in extra dependencies (pthread, clock_gettime). +mtdutils-configure: $(MTDUTILS_CONFIGURE_STAMP) +$(MTDUTILS_CONFIGURE_STAMP): $(UTILLINUX_BUILD_STAMP) $(LZO_BUILD_STAMP) \ + $(ZLIB_BUILD_STAMP) \ + $(MTDUTILS_SOURCE_STAMP) | $(DEV_SYSROOT_INIT_STAMP) + $(Q) rm -f $@ && eval $(PROFILE_STAMP) + $(Q) echo "==== Configure mtd-utils-$(MTDUTILS_VERSION) ====" + $(Q) cd $(MTDUTILS_DIR) && PATH='$(CROSSBIN):$(PATH)' \ + $(MTDUTILS_DIR)/configure \ + --prefix=/usr \ + --host=$(TARGET) \ + --with-zlib \ + --with-lzo \ + --with-ubifs \ + --with-jffs \ + --without-crypto \ + --without-zstd \ + --without-xattr \ + --without-selinux \ + --without-tests \ + --without-lsmtd \ + --disable-unit-tests \ + --disable-ubihealthd \ + CC=$(CROSSPREFIX)gcc \ + CFLAGS="$(ONIE_CFLAGS)" \ + LDFLAGS="$(ONIE_LDFLAGS)" \ + $(ONIE_PKG_CONFIG) + $(Q) touch $@ + ifndef MAKE_CLEAN MTDUTILS_NEW_FILES = $(shell test -d $(MTDUTILS_DIR) && test -f $(MTDUTILS_BUILD_STAMP) && \ - find -L $(MTDUTILS_DIR) -newer $(MTDUTILS_BUILD_STAMP) -type f -print -quit) + find -L $(MTDUTILS_DIR) -newer $(MTDUTILS_BUILD_STAMP) -type f -print -quit) endif mtdutils-build: $(MTDUTILS_BUILD_STAMP) -$(MTDUTILS_BUILD_STAMP): $(MTDUTILS_NEW_FILES) $(UTILLINUX_BUILD_STAMP) \ - $(LZO_BUILD_STAMP) $(ZLIB_BUILD_STAMP) \ - $(MTDUTILS_SOURCE_STAMP) | $(DEV_SYSROOT_INIT_STAMP) +$(MTDUTILS_BUILD_STAMP): $(MTDUTILS_NEW_FILES) $(MTDUTILS_CONFIGURE_STAMP) $(Q) rm -f $@ && eval $(PROFILE_STAMP) + $(Q) echo "==== Building mtd-utils-$(MTDUTILS_VERSION) ====" $(Q) PATH='$(CROSSBIN):$(PATH)' \ - $(MAKE) -C $(MTDUTILS_DIR) \ - PREFIX=$(DEV_SYSROOT)/usr \ - CROSS=$(CROSSPREFIX) \ - CFLAGS="-g $(ONIE_CFLAGS)" \ - WITHOUT_XATTR=1 + $(MAKE) -C $(MTDUTILS_DIR) DESTDIR=$(DEV_SYSROOT) $(Q) PATH='$(CROSSBIN):$(PATH)' \ - $(MAKE) -C $(MTDUTILS_DIR) \ - PREFIX=$(DEV_SYSROOT)/usr \ - CROSS=$(CROSSPREFIX) \ - CFLAGS="-g $(ONIE_CFLAGS)" \ - WITHOUT_XATTR=1 \ - install + $(MAKE) -C $(MTDUTILS_DIR) DESTDIR=$(DEV_SYSROOT) install $(Q) touch $@ mtdutils-install: $(MTDUTILS_INSTALL_STAMP) @@ -101,8 +139,7 @@ mtdutils-clean: DOWNLOAD_CLEAN += mtdutils-download-clean mtdutils-download-clean: - $(Q) rm -f $(MTDUTILS_DOWNLOAD_STAMP) $(DOWNLOADDIR)/$(MTDUTILS_COMMIT).tar.gz \ - $(DOWNLOADDIR)/$(MTDUTILS_TARBALL) + $(Q) rm -f $(MTDUTILS_DOWNLOAD_STAMP) $(DOWNLOADDIR)/$(MTDUTILS_TARBALL) #------------------------------------------------------------------------------- # diff --git a/build-config/make/openssl.make b/build-config/make/openssl.make index 6591df9fc..64068b8f7 100644 --- a/build-config/make/openssl.make +++ b/build-config/make/openssl.make @@ -10,9 +10,13 @@ # This is a makefile fragment that defines the build of openssl # -OPENSSL_VERSION ?= 1.1.1g +OPENSSL_VERSION ?= 3.5.7 OPENSSL_TARBALL = openssl-$(OPENSSL_VERSION).tar.gz +# openssl.org/source/ only keeps the newest release of each line (older +# ones move to /source/old/), so prefer the stable per-version GitHub +# release asset and keep openssl.org as a fallback. OPENSSL_TARBALL_URLS += $(ONIE_MIRROR) \ + https://github.com/openssl/openssl/releases/download/openssl-$(OPENSSL_VERSION) \ https://www.openssl.org/source OPENSSL_BUILD_DIR = $(USER_BUILDDIR)/openssl OPENSSL_DIR = $(OPENSSL_BUILD_DIR)/openssl-$(OPENSSL_VERSION) @@ -31,13 +35,7 @@ PHONY += openssl openssl-download openssl-source \ openssl-configure openssl-build openssl-install openssl-clean \ openssl-download-clean -ifeq ($(OPENSSL_VERSION),1.1.1g) -OPENSSL_ARCH = -OPENSSL_LIBS = \ - engines-1.1 \ - libcrypto.so libcrypto.so.1.1 \ - libssl.so libssl.so.1.1 -else ifeq ($(OPENSSL_VERSION),3.4.0) +# ONIE standardizes on OpenSSL 3.x (SONAME major 3, "engines" dir). ifeq ($(ARCH),arm64) OPENSSL_ARCH = linux-aarch64 else @@ -48,9 +46,6 @@ OPENSSL_LIBS = \ engines \ libcrypto.so libcrypto.so.3 \ libssl.so libssl.so.3 -else - $(error OPENSSL_LIBS: Unsupported OpenSSL version: $(OPENSSL_VERSION)) -endif OPENSSL_BINS = openssl diff --git a/build-config/make/pciutils.make b/build-config/make/pciutils.make index 39cfedab6..0751b52e1 100644 --- a/build-config/make/pciutils.make +++ b/build-config/make/pciutils.make @@ -9,7 +9,7 @@ # This is a makefile fragment that defines the build of pciutils # -PCIUTILS_VERSION = 3.2.1 +PCIUTILS_VERSION = 3.15.0 PCIUTILS_TARBALL = pciutils-$(PCIUTILS_VERSION).tar.xz PCIUTILS_TARBALL_URLS += $(ONIE_MIRROR) https://www.kernel.org/pub/software/utils/pciutils PCIUTILS_BUILD_DIR = $(USER_BUILDDIR)/pciutils @@ -70,9 +70,9 @@ $(PCIUTILS_BUILD_STAMP): $(PCIUTILS_PATCH_STAMP) $(PCIUTILS_NEW_FILES) $(ZLIB_BU $(Q) rm -f $@ && eval $(PROFILE_STAMP) $(Q) echo "==== Building pciutils-$(PCIUTILS_VERSION) ====" $(Q) PATH='$(CROSSBIN):$(PATH)' $(MAKE) -C $(PCIUTILS_DIR) lib/libpci.so.$(PCIUTILS_VERSION) CROSS_COMPILE=$(CROSSPREFIX) \ - HOST=onie-$(ARCH)-linux ZLIB=yes DNS=no SHARED=yes LIBKMOD=no PREFIX=/usr DESTDIR=$(DEV_SYSROOT) + HOST=$(ARCH)-linux ZLIB=yes DNS=no SHARED=yes LIBKMOD=no PREFIX=/usr DESTDIR=$(DEV_SYSROOT) $(Q) PATH='$(CROSSBIN):$(PATH)' $(MAKE) -C $(PCIUTILS_DIR) install-lib CROSS_COMPILE=$(CROSSPREFIX) \ - HOST=onie-$(ARCH)-linux ZLIB=yes DNS=no SHARED=yes LIBKMOD=no PREFIX=/usr DESTDIR=$(DEV_SYSROOT) + HOST=$(ARCH)-linux ZLIB=yes DNS=no SHARED=yes LIBKMOD=no PREFIX=/usr DESTDIR=$(DEV_SYSROOT) $(Q) touch $@ pciutils-install: $(PCIUTILS_INSTALL_STAMP) diff --git a/build-config/make/popt.make b/build-config/make/popt.make index 59a41f416..80e3119bd 100644 --- a/build-config/make/popt.make +++ b/build-config/make/popt.make @@ -9,9 +9,11 @@ # This is a makefile fragment that defines the build of popt # -POPT_VERSION = 1.16 +POPT_VERSION = 1.19 POPT_TARBALL = popt-$(POPT_VERSION).tar.gz -POPT_TARBALL_URLS += $(ONIE_MIRROR) http://rpm5.org/files/popt/ +# popt's old home rpm5.org is defunct; it is maintained under +# rpm-software-management and released on ftp.rpm.org. +POPT_TARBALL_URLS += $(ONIE_MIRROR) http://ftp.rpm.org/popt/releases/popt-1.x POPT_BUILD_DIR = $(USER_BUILDDIR)/popt POPT_DIR = $(POPT_BUILD_DIR)/popt-$(POPT_VERSION) @@ -32,7 +34,7 @@ PHONY += popt popt-download popt-source popt-patch \ popt-configure popt-build popt-install popt-clean \ popt-download-clean -POPT_LIBS = libpopt.so libpopt.so.0 libpopt.so.0.0.0 +POPT_LIBS = libpopt.so libpopt.so.0 libpopt.so.0.0.2 popt: $(POPT_STAMP) diff --git a/build-config/make/sbom.make b/build-config/make/sbom.make new file mode 100644 index 000000000..0e763e7f5 --- /dev/null +++ b/build-config/make/sbom.make @@ -0,0 +1,84 @@ +#------------------------------------------------------------------------------- +# +# Copyright (C) 2026 Brad House +# +# SPDX-License-Identifier: GPL-2.0 +# +#------------------------------------------------------------------------------- +# +# Generate a Software Bill of Materials (SBOM) for the image. +# +# scripts/gen-sbom.py derives the third-party software COMPILED FROM SOURCE and +# INSTALLED INTO this MACHINE's image (the SYSROOTDIR-installed packages plus the +# kernel / uClibc-ng / GCC runtime / bootloader) from the build system, and emits +# CycloneDX 1.6 (then SPDX 2.3 via cyclonedx-cli). It depends on the assembled +# sysroot so every package source is already extracted (for license detection) +# and every version is final. The SBOM is built as part of `all`, so it is +# always produced alongside the image. +# +# The generator relies on a few external tools (askalono for license +# detection, cyclonedx-cli for the SPDX conversion, grype for the optional +# vulnerability scan). If they are not already on PATH, the build provisions +# them -- pinned + sha256-verified -- into a build-local prefix +# ($(SBOM_TOOLS_DIR)) without needing root, so a full-fidelity SBOM is +# produced in any environment. If provisioning fails (e.g. no network), the +# generator degrades gracefully (NOASSERTION licenses, CycloneDX-only). + +SBOM_CDX = $(IMAGEDIR)/$(MACHINE_PREFIX).sbom.cdx.json +SBOM_SPDX = $(IMAGEDIR)/$(MACHINE_PREFIX).sbom.spdx.json +SBOM_STAMP = $(STAMPDIR)/sbom +SBOM_TOOLS_DIR = $(BUILDDIR)/sbom-tools/bin +SBOM_INSTALL_TOOLS = $(SCRIPTDIR)/install-sbom-tools.sh + +PHONY += sbom sbom-clean sbom-vuln-scan + +sbom: $(SBOM_STAMP) +$(SBOM_STAMP): $(SYSROOT_COMPLETE_STAMP) + $(Q) rm -f $@ && eval $(PROFILE_STAMP) + $(Q) echo "==== Generating SBOM for $(MACHINE) ====" + $(Q) export PATH="$(SBOM_TOOLS_DIR):$$PATH" ; \ + command -v askalono >/dev/null 2>&1 && command -v cyclonedx-cli >/dev/null 2>&1 || { \ + echo "==== Provisioning SBOM tools into $(SBOM_TOOLS_DIR) ====" ; \ + "$(SBOM_INSTALL_TOOLS)" "$(SBOM_TOOLS_DIR)" || \ + echo " WARNING: SBOM tool provisioning failed; SBOM will be degraded (NOASSERTION licenses, CycloneDX only)" ; } ; \ + python3 $(SCRIPTDIR)/gen-sbom.py \ + --machine $(MACHINE) \ + --output $(SBOM_CDX) \ + --spdx-output $(SBOM_SPDX) + $(Q) touch $@ + +# Optional: scan the already-generated SBOM for known vulnerabilities (grype), +# with CVEs already fixed by ONIE patches suppressed via OpenVEX. +# +# This is pure post-processing of the SBOM artifact, so it deliberately does NOT +# depend on $(SBOM_STAMP) (and therefore not on $(SYSROOT_COMPLETE_STAMP)). +# Depending on the stamp made a standalone `make sbom-vuln-scan` re-assemble the +# whole rootfs: the sysroot stamp is invalidated on every parse by the rootconf +# -cnewer guard in images.make, so a second invocation (e.g. the CI scan step, +# run after `make all` already produced the SBOM) rebuilt busybox/e2fsprogs/... +# before scanning. Decoupled, the scan just consumes $(SBOM_CDX); if it is +# missing we fail with a clear message instead of silently rebuilding the image. +sbom-vuln-scan: + $(Q) test -f $(SBOM_CDX) || { \ + echo "ERROR: SBOM not found: $(SBOM_CDX)" >&2 ; \ + echo " Generate it first: make MACHINE=$(MACHINE) sbom (or 'make all')." >&2 ; \ + exit 1 ; } + $(Q) export PATH="$(SBOM_TOOLS_DIR):$$PATH" ; \ + command -v grype >/dev/null 2>&1 || "$(SBOM_INSTALL_TOOLS)" "$(SBOM_TOOLS_DIR)" || true ; \ + python3 $(SCRIPTDIR)/sbom-vuln-scan.py \ + --machine $(MACHINE) \ + --sbom $(SBOM_CDX) \ + --output $(IMAGEDIR)/$(MACHINE_PREFIX).sbom.vulns.json + +sbom-clean: + $(Q) rm -f $(SBOM_STAMP) $(SBOM_CDX) $(SBOM_SPDX) \ + $(IMAGEDIR)/$(MACHINE_PREFIX).sbom.vulns.json \ + $(IMAGEDIR)/$(MACHINE_PREFIX).sbom.vulns.vex.json \ + $(IMAGEDIR)/$(MACHINE_PREFIX).sbom.vulns.md + $(Q) echo "=== Finished making $@ for $(PLATFORM)" + +#------------------------------------------------------------------------------- +# +# Local Variables: +# mode: makefile-gmake +# End: diff --git a/build-config/make/tcpdump.make b/build-config/make/tcpdump.make index 166e77484..871d9686a 100644 --- a/build-config/make/tcpdump.make +++ b/build-config/make/tcpdump.make @@ -12,7 +12,7 @@ include make/libpcap.make include make/openssl.make -TCPDUMP_VERSION = 4.99.4 +TCPDUMP_VERSION = 4.99.6 TCPDUMP_TARBALL = tcpdump-$(TCPDUMP_VERSION).tar.gz TCPDUMP_TARBALL_URLS += $(ONIE_MIRROR) \ https://www.tcpdump.org/release diff --git a/build-config/make/zlib.make b/build-config/make/zlib.make index ffc187797..f1db1e6af 100644 --- a/build-config/make/zlib.make +++ b/build-config/make/zlib.make @@ -9,10 +9,11 @@ # This is a makefile fragment that defines the build of zlib # -ZLIB_VERSION = 1.2.11 +ZLIB_VERSION = 1.3.2 ZLIB_TARBALL = zlib-$(ZLIB_VERSION).tar.xz -ZLIB_TARBALL_URLS += $(ONIE_MIRROR) http://zlib.net \ - http://softlayer-dal.dl.sourceforge.net/project/libpng/zlib/$(ZLIB_VERSION) +ZLIB_TARBALL_URLS += $(ONIE_MIRROR) \ + https://github.com/madler/zlib/releases/download/v$(ZLIB_VERSION) \ + https://zlib.net ZLIB_BUILD_DIR = $(USER_BUILDDIR)/zlib ZLIB_DIR = $(ZLIB_BUILD_DIR)/zlib-$(ZLIB_VERSION) diff --git a/build-config/scripts/gen-sbom.py b/build-config/scripts/gen-sbom.py new file mode 100644 index 000000000..d93b97429 --- /dev/null +++ b/build-config/scripts/gen-sbom.py @@ -0,0 +1,366 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2026 Brad House +# +# SPDX-License-Identifier: GPL-2.0 +# +# Generate a CycloneDX 1.6 SBOM describing the third-party software that is +# COMPILED FROM SOURCE and INSTALLED INTO an ONIE image for a given MACHINE. +# +# ONIE has no package database -- every component is built from an upstream +# source tarball pinned in build-config/make/.make. This tool therefore +# derives the component list and metadata from the build system itself: +# +# * "enabled for this MACHINE" == the *_VERSION make variables that are +# defined, because build-config/Makefile only `include`s a package +# fragment when its *_ENABLE is yes (so undefined => not built). +# * "installed into the image" == the package's fragment writes into +# $(SYSROOTDIR) (the rootfs that becomes the ONIE initramfs). Pure +# build-time tooling (the crosstool-NG toolchain + its companions, the +# host pesign, ...) never touches SYSROOTDIR and is excluded. +# * boot/runtime components that live in the image but install outside +# SYSROOTDIR -- the kernel, uClibc-ng, the GCC runtime libs, and the +# bootloader (shim/grub or u-boot) -- are added explicitly. +# +# Per-component metadata comes from the .make variables (version, tarball, +# source URL), the SHA-256 of the actual downloaded tarball (so the SBOM +# attests the built artifact regardless of the repo's integrity-pin format), +# the applied patch series (patches//series), and the SPDX license +# detected from the already-extracted source tree (askalono) with a curated +# override map for the genuinely multi-license packages. + +import argparse +import json +import hashlib +import os +import re +import shutil +import subprocess +import sys + +HERE = os.path.dirname(os.path.abspath(__file__)) +BUILD_CONFIG = os.path.dirname(HERE) # build-config/ +ONIE_ROOT = os.path.dirname(BUILD_CONFIG) # repo root +MAKEDIR = os.path.join(BUILD_CONFIG, "make") +UPSTREAMDIR = os.path.join(ONIE_ROOT, "upstream") +PATCHDIR = os.path.join(ONIE_ROOT, "patches") +OVERRIDES = os.path.join(BUILD_CONFIG, "conf", "sbom", "license-overrides.json") +CPE_OVERRIDES = os.path.join(BUILD_CONFIG, "conf", "sbom", "cpe-overrides.json") + +# Make-variable prefixes that have a _VERSION/_TARBALL but are build-time only +# (the cross toolchain and its companion tools) -- never shipped in the image. +BUILD_ONLY_PREFIXES = { + "CROSSTOOL_NG", "GCC", "BINUTILS", "GDB", "GMP", "ISL", "MPFR", "MPC", + "MAKE", "M4", "AUTOCONF", "AUTOMAKE", "LIBTOOL", "NCURSES", "GETTEXT", + "LIBICONV", "DUMA", "LTRACE", "STRACE", "PESIGN", "GNU_EFI", + "XTOOLS", "XTOOLS_LINUX", +} + + +def run(cmd, **kw): + return subprocess.run(cmd, check=True, capture_output=True, text=True, **kw) + + +def make_dump(machine): + """Return {PREFIX: {version, tarball, urls[]}} for every *_VERSION the + build defines for MACHINE (i.e. every enabled package + toolchain bit).""" + sep = "\x1f" + eval_expr = ( + "onie-sbom-dump: ; @$(foreach v,$(sort $(filter %%_VERSION,$(.VARIABLES)))," + "$(info $(v:_VERSION=)%s$($(v))%s$($(v:_VERSION=_TARBALL))%s" + "$($(v:_VERSION=_TARBALL_URLS))%s$($(v:_VERSION=_DIR))))" + % (sep, sep, sep, sep) + ) + # Drop parent make's jobserver env so this introspection sub-make is clean. + env = {k: v for k, v in os.environ.items() + if k not in ("MAKEFLAGS", "MFLAGS", "MAKELEVEL")} + out = run(["make", "MACHINE=%s" % machine, "--eval=" + eval_expr, + "onie-sbom-dump"], cwd=BUILD_CONFIG, env=env).stdout + pkgs = {} + for line in out.splitlines(): + if sep not in line: + continue + parts = line.split(sep) + prefix = parts[0].strip() + if not prefix: + continue + pkgs[prefix] = { + "version": parts[1].strip() if len(parts) > 1 else "", + "tarball": parts[2].strip() if len(parts) > 2 else "", + "url": parts[3].strip() if len(parts) > 3 else "", + "dir": parts[4].strip() if len(parts) > 4 else "", + } + return pkgs + + +def shipped_fragment_prefixes(): + """Prefixes of packages whose fragment installs into $(SYSROOTDIR) (the + shipped rootfs). Prefix is taken from the fragment's *_TARBALL variable + (disambiguates e.g. UTILLINUX vs UTILLINUX_MAJOR).""" + infra = {"sysroot", "images", "signing-keys", "demo"} + prefixes = {} + for fn in os.listdir(MAKEDIR): + if not fn.endswith(".make") or fn[:-5] in infra: + continue + path = os.path.join(MAKEDIR, fn) + text = open(path, encoding="utf-8", errors="replace").read() + if "SYSROOTDIR" not in text: + continue + m = re.search(r"^([A-Z][A-Z0-9_]*)_TARBALL\b", text, re.MULTILINE) + if m: + prefixes[m.group(1)] = fn[:-5] + return prefixes + + +def sha256_for(tarball, downloaddir=None): + """SHA-256 of the source tarball. + + Hash the actual downloaded artifact so the SBOM attests what was really + built, independent of the repo's integrity-pin format (the build verifies + downloads against upstream/.sha1 or .sha256 depending on the tree + state; the SBOM should not care which). Fall back to the upstream/.sha256 + pin file if the artifact is not on disk, then give up. + """ + if downloaddir: + path = os.path.join(downloaddir, tarball) + if os.path.isfile(path): + h = hashlib.sha256() + with open(path, "rb") as fh: + for chunk in iter(lambda: fh.read(1 << 20), b""): + h.update(chunk) + return h.hexdigest() + f = os.path.join(UPSTREAMDIR, tarball + ".sha256") + if os.path.isfile(f): + return open(f).read().split()[0] + return None + + +def make_var(machine, var): + """Resolve a single make variable's value for MACHINE.""" + env = {k: v for k, v in os.environ.items() + if k not in ("MAKEFLAGS", "MFLAGS", "MAKELEVEL")} + out = run(["make", "MACHINE=%s" % machine, + "--eval=onie-sbom-var: ; @echo $(%s)" % var, + "onie-sbom-var"], cwd=BUILD_CONFIG, env=env).stdout + return out.strip() + + +def patches_for(fragment): + """Applied patch filenames from patches//series (pedigree).""" + series = os.path.join(PATCHDIR, fragment, "series") + if not os.path.isfile(series): + return [] + pats = [] + for line in open(series): + line = line.strip() + if line and not line.startswith("#"): + pats.append(line.split()[0]) + return pats + + +def detect_license(fragment, srcdir, overrides): + """SPDX id for a component: curated override wins; else askalono run over + the license files in the package's extracted source dir; else NOASSERTION.""" + if fragment in overrides: + return overrides[fragment], "override" + if not srcdir or not shutil.which("askalono"): + return "NOASSERTION", "undetermined" + if not os.path.isabs(srcdir): + srcdir = os.path.normpath(os.path.join(BUILD_CONFIG, srcdir)) + if not os.path.isdir(srcdir): + return "NOASSERTION", "no-source" + best, score = None, 0.0 + for root, dirs, files in os.walk(srcdir): + if root[len(srcdir):].count(os.sep) > 1: # top-level + one subdir (LICENSES/) + dirs[:] = [] + continue + for fn in files: + if not re.match(r"(?i)(copying|licen[cs]e|copyright)", fn): + continue + p = subprocess.run(["askalono", "--format", "json", "id", + os.path.join(root, fn)], capture_output=True, text=True) + try: + res = json.loads(p.stdout).get("result") + except ValueError: + res = None + if res: + lic = res.get("license", {}).get("name") + sc = res.get("score", 0.0) + if lic and sc > score: + best, score = lic, sc + if best and score >= 0.9: + return best, "askalono(%.2f)" % score + return "NOASSERTION", "low-confidence" + + +def license_entry(lic): + """A CycloneDX licenses[] entry: SPDX expression, single id, or name.""" + if lic == "NOASSERTION": + return {"license": {"name": "NOASSERTION"}} + if any(op in lic for op in (" AND ", " OR ", " WITH ")): + return {"expression": lic} + return {"license": {"id": lic}} + + +def canonical_source_url(urls, tarball): + """Pick the canonical upstream base URL (not the ONIE mirror cache) from a + space-separated _TARBALL_URLS list and join it with the tarball name.""" + words = [u for u in urls.split() if u] + bases = [u for u in words if "mirror.opencompute.org" not in u] or words + if not bases: + return "" + base = bases[0] + return base.rstrip("/") + "/" + tarball if tarball else base + + +def purl(name, version, url, sha256): + q = [] + if url: + q.append("download_url=" + url) + if sha256: + q.append("checksum=sha256:" + sha256) + p = "pkg:generic/%s@%s" % (name, version) + if q: + p += "?" + "&".join(q) + return p + + +def cpe_version(v): + """Normalize an ONIE version to an NVD-CPE-comparable form: drop a leading + 'v' and turn underscore separators into dots (e.g. lvm2 '2_02_105' -> + '2.02.105', btrfs-progs 'v4.9.1' -> '4.9.1').""" + v = (v or "").strip() + if v[:1].lower() == "v" and v[1:2].isdigit(): + v = v[1:] + v = v.replace("_", ".") + return v or "*" + + +def cpe_for(name, version, overrides): + """CPE 2.3 string for a component. + + Our components carry only a pkg:generic PURL, which grype cannot map to a + CVE -- it matches source-built packages to NVD via CPE. Without a CPE the + scan silently finds *nothing* (a false-clean report). The NVD vendor:product + rarely equals the ONIE package name (linux -> linux:linux_kernel, grub -> + gnu:grub2, util-linux -> kernel:util-linux, dropbear -> + dropbear_ssh_project:dropbear_ssh, ...), so a curated 'part:vendor:product' + override map (conf/sbom/cpe-overrides.json) wins; otherwise we emit the + syft-style default 'a::'.""" + key = name.lower() + pvp = overrides.get(key) or "a:%s:%s" % (key, key) + part, vendor, product = pvp.split(":") + return "cpe:2.3:%s:%s:%s:%s:*:*:*:*:*:*:*" % ( + part, vendor, product, cpe_version(version)) + + +def main(): + ap = argparse.ArgumentParser(description="Generate an ONIE image SBOM (CycloneDX 1.6)") + ap.add_argument("--machine", required=True) + ap.add_argument("--output", required=True, help="output CycloneDX 1.6 JSON path") + ap.add_argument("--spdx-output", help="also emit SPDX 2.3 JSON here (cyclonedx-cli)") + args = ap.parse_args() + + overrides = {} + if os.path.isfile(OVERRIDES): + overrides = json.load(open(OVERRIDES)) + + cpe_overrides = {} + if os.path.isfile(CPE_OVERRIDES): + cpe_overrides = {k.lower(): v for k, v in json.load(open(CPE_OVERRIDES)).items() + if not k.startswith("_")} + + enabled = make_dump(args.machine) + shipped_pref = shipped_fragment_prefixes() + downloaddir = make_var(args.machine, "DOWNLOADDIR") + + components = [] + warnings = [] + + def add(prefix, fragment, name, version, tarball, url): + sha = sha256_for(tarball, downloaddir) if tarball else None + src = canonical_source_url(url, tarball) + lic, how = detect_license(fragment, enabled.get(prefix, {}).get("dir", ""), overrides) + if lic == "NOASSERTION": + warnings.append("license undetermined: %s" % name) + comp = { + "type": "library", + "name": name, + "version": version, + "purl": purl(name, version, src, sha), + "cpe": cpe_for(name, version, cpe_overrides), + "licenses": [license_entry(lic)], + "properties": [{"name": "onie:fragment", "value": fragment}, + {"name": "onie:license_source", "value": how}], + } + if tarball and src: + ext = {"url": src, "type": "distribution", "comment": tarball} + if sha: + ext["hashes"] = [{"alg": "SHA-256", "content": sha}] + comp["externalReferences"] = [ext] + pats = patches_for(fragment) + if pats: + comp["pedigree"] = {"patches": [{"type": "unofficial", + "diff": {"url": "patches/%s/%s" % (fragment, p)}} + for p in pats]} + components.append(comp) + + # 1) shipped rootfs packages = enabled prefixes that install to SYSROOTDIR + for prefix, frag in sorted(shipped_pref.items()): + if prefix in enabled and enabled[prefix]["tarball"]: + e = enabled[prefix] + add(prefix, frag, frag, e["version"], e["tarball"], e["url"]) + + # 2) boot/runtime components (in the image, installed outside SYSROOTDIR) + if "LINUX" in enabled: + # kernel: tarball encodes LINUX_RELEASE (e.g. linux-6.18.34.tar.xz) + t = enabled["LINUX"]["tarball"] + ver = re.sub(r"^linux-|\.tar\..*$", "", t) or enabled["LINUX"]["version"] + add("LINUX", "kernel", "linux", ver, t, enabled["LINUX"]["url"]) + if "XTOOLS_LIBC" in enabled: + v = enabled["XTOOLS_LIBC"]["version"] + add("XTOOLS_LIBC", "uclibc-ng", "uClibc-ng", v, + "uClibc-ng-%s.tar.xz" % v, "") + if "GCC" in enabled: # GCC runtime libs (libgcc/libstdc++) ship + add("GCC", "gcc-runtime", "gcc-runtime", enabled["GCC"]["version"], "", "") + for boot in ("SHIM", "UBOOT"): + if boot in enabled and enabled[boot]["tarball"]: + e = enabled[boot] + frag = "shim" if boot == "SHIM" else "u-boot" + add(boot, frag, frag, e["version"], e["tarball"], e["url"]) + + sbom = { + "bomFormat": "CycloneDX", + "specVersion": "1.6", + "version": 1, + "metadata": { + "component": { + "type": "operating-system", + "name": "onie-%s" % args.machine, + }, + "tools": [{"name": "gen-sbom.py", "vendor": "ONIE"}], + }, + "components": sorted(components, key=lambda c: c["name"]), + } + with open(args.output, "w") as f: + json.dump(sbom, f, indent=2) + f.write("\n") + sys.stderr.write("Wrote %s: %d components\n" % (args.output, len(components))) + if args.spdx_output: + if shutil.which("cyclonedx-cli"): + # cyclonedx-cli is a .NET tool; run it in invariant-globalization + # mode so it does not require an ICU package to be installed (the + # JSON conversion is locale-independent). + cdx_env = dict(os.environ, DOTNET_SYSTEM_GLOBALIZATION_INVARIANT="1") + subprocess.run(["cyclonedx-cli", "convert", "--input-file", args.output, + "--output-file", args.spdx_output, + "--output-format", "spdxjson"], check=True, env=cdx_env) + sys.stderr.write("Wrote %s (SPDX 2.3)\n" % args.spdx_output) + else: + sys.stderr.write(" WARN: cyclonedx-cli not found; skipped SPDX output\n") + for w in warnings: + sys.stderr.write(" WARN: %s\n" % w) + + +if __name__ == "__main__": + main() diff --git a/build-config/scripts/install-sbom-tools.sh b/build-config/scripts/install-sbom-tools.sh new file mode 100755 index 000000000..9008fa2cb --- /dev/null +++ b/build-config/scripts/install-sbom-tools.sh @@ -0,0 +1,129 @@ +#!/bin/bash + +# Copyright (C) 2026 Brad House +# +# SPDX-License-Identifier: GPL-2.0 + +# +# Download, verify (sha256) and install the SBOM/license tooling (askalono, +# cyclonedx-cli, grype) used by scripts/gen-sbom.py. Modeled after SONiC's +# install_sbom_tool.sh: versions are pinned and every download is verified +# against a hardcoded SHA-256 hash. Any download failure or hash mismatch is +# fatal (exit 1). Re-running is idempotent: a tool already present at the +# pinned version is skipped. +# +# The install directory defaults to /usr/local/bin (system-wide, needs root), +# but can be overridden so the build can provision the tools into a writable +# build-local prefix without root: +# +# install-sbom-tools.sh [INSTALL_DIR] +# SBOM_TOOLS_DIR=/path/to/bin install-sbom-tools.sh +# +# The ONIE build (make/sbom.make) invokes it this way automatically when the +# tools are not already on PATH. +# +# Requires: curl, unzip, tar. +# + +set -euo pipefail + +INSTALL_DIR="${1:-${SBOM_TOOLS_DIR:-/usr/local/bin}}" +mkdir -p "$INSTALL_DIR" + +# -- Pinned versions --------------------------------------------------------- +ASKALONO_VERSION="0.5.0" +CYCLONEDX_VERSION="0.32.0" +GRYPE_VERSION="0.113.0" + +# -- Pinned download URLs ---------------------------------------------------- +ASKALONO_URL="https://github.com/jpeddicord/askalono/releases/download/${ASKALONO_VERSION}/askalono-Linux.zip" +CYCLONEDX_URL="https://github.com/CycloneDX/cyclonedx-cli/releases/download/v${CYCLONEDX_VERSION}/cyclonedx-linux-x64" +GRYPE_URL="https://github.com/anchore/grype/releases/download/v${GRYPE_VERSION}/grype_${GRYPE_VERSION}_linux_amd64.tar.gz" + +# -- Pinned SHA-256 hashes --------------------------------------------------- +ASKALONO_SHA256="8a007355b700137b48e7e39aab5d083acb9a0926f20c064ab4476b1624390e52" +CYCLONEDX_SHA256="454879e6a4a405c8a13bff49b8982adcb0596f3019b26b0811c66e4d7f0783e1" +GRYPE_SHA256="d87059d11616446a5dd817a47c21823676b4b24bdaac529695ca404a32ba339d" + +# verify_sha256 +verify_sha256() { + local file="$1" + local expected="$2" + local actual + + actual=$(sha256sum "$file" | awk '{print $1}') + if [ "$actual" != "$expected" ]; then + echo "Error: sha256 mismatch for $file" >&2 + echo " expected: $expected" >&2 + echo " actual: $actual" >&2 + exit 1 + fi +} + +# download +download() { + local url="$1" + local dest="$2" + + echo "Downloading $url" + if ! curl -fsSL -o "$dest" "$url"; then + echo "Error: failed to download $url" >&2 + exit 1 + fi +} + +install_askalono() { + if [ -x "${INSTALL_DIR}/askalono" ] && \ + "${INSTALL_DIR}/askalono" --version 2>/dev/null | grep -q "${ASKALONO_VERSION}"; then + echo "askalono ${ASKALONO_VERSION} already installed, skipping" + return 0 + fi + + local tmpdir + tmpdir=$(mktemp -d) + download "$ASKALONO_URL" "${tmpdir}/askalono-Linux.zip" + verify_sha256 "${tmpdir}/askalono-Linux.zip" "$ASKALONO_SHA256" + unzip -o -q "${tmpdir}/askalono-Linux.zip" -d "$tmpdir" + install -m 0755 "${tmpdir}/askalono" "${INSTALL_DIR}/askalono" + rm -rf "$tmpdir" + echo "Installed askalono ${ASKALONO_VERSION} to ${INSTALL_DIR}/askalono" +} + +install_cyclonedx() { + if [ -x "${INSTALL_DIR}/cyclonedx-cli" ] && \ + "${INSTALL_DIR}/cyclonedx-cli" --version 2>/dev/null | grep -q "${CYCLONEDX_VERSION}"; then + echo "cyclonedx-cli ${CYCLONEDX_VERSION} already installed, skipping" + return 0 + fi + + local tmpdir + tmpdir=$(mktemp -d) + download "$CYCLONEDX_URL" "${tmpdir}/cyclonedx-cli" + verify_sha256 "${tmpdir}/cyclonedx-cli" "$CYCLONEDX_SHA256" + install -m 0755 "${tmpdir}/cyclonedx-cli" "${INSTALL_DIR}/cyclonedx-cli" + rm -rf "$tmpdir" + echo "Installed cyclonedx-cli ${CYCLONEDX_VERSION} to ${INSTALL_DIR}/cyclonedx-cli" +} + +install_grype() { + if [ -x "${INSTALL_DIR}/grype" ] && \ + "${INSTALL_DIR}/grype" version 2>/dev/null | grep -q "${GRYPE_VERSION}"; then + echo "grype ${GRYPE_VERSION} already installed, skipping" + return 0 + fi + + local tmpdir + tmpdir=$(mktemp -d) + download "$GRYPE_URL" "${tmpdir}/grype.tar.gz" + verify_sha256 "${tmpdir}/grype.tar.gz" "$GRYPE_SHA256" + tar -xzf "${tmpdir}/grype.tar.gz" -C "$tmpdir" grype + install -m 0755 "${tmpdir}/grype" "${INSTALL_DIR}/grype" + rm -rf "$tmpdir" + echo "Installed grype ${GRYPE_VERSION} to ${INSTALL_DIR}/grype" +} + +install_askalono +install_cyclonedx +install_grype + +echo "SBOM tooling installation complete" diff --git a/build-config/scripts/mk-grub-efi-image b/build-config/scripts/mk-grub-efi-image index 6a6450996..3284704a7 100755 --- a/build-config/scripts/mk-grub-efi-image +++ b/build-config/scripts/mk-grub-efi-image @@ -66,7 +66,6 @@ GRUB_MODULES=" loadenv loopback linux - linuxefi lsefi lsefimmap lsefisystab @@ -114,7 +113,6 @@ GRUB_ENCRYPTION_MODULES=" fshelp crypto bufio archelp - is_sb_enabled " diff --git a/build-config/scripts/mk-part-table.py b/build-config/scripts/mk-part-table.py index 273966f77..1b4179b5c 100755 --- a/build-config/scripts/mk-part-table.py +++ b/build-config/scripts/mk-part-table.py @@ -1,4 +1,4 @@ -#!/usr/bin/python2 +#!/usr/bin/env python3 from struct import pack import sys @@ -23,8 +23,8 @@ # See MBR partition table entry format here: # http://en.wikipedia.org/wiki/Master_boot_record#Partition_table_entries def chs(sector_z): - C = sector_z / (63 * 255) - H = (sector_z % (63 * 255)) / 63 + C = sector_z // (63 * 255) + H = (sector_z % (63 * 255)) // 63 # convert zero-based sector to CHS format S = (sector_z % 63) + 1 # munge accord to partition table format @@ -42,7 +42,7 @@ def chs(sector_z): # # See the partition table format here: # http://en.wikipedia.org/wiki/Master_boot_record#Sector_layout -f = open(iso, 'r+') +f = open(iso, 'r+b') f.seek(0x1BE) f.write(pack("<8BLL48xH", 0x80, s_H, s_S, s_C, fs_type, e_H, e_S, e_C, start, length, 0xaa55)) diff --git a/build-config/scripts/onie-mk-iso.sh b/build-config/scripts/onie-mk-iso.sh index be641c42d..7bb880ab5 100755 --- a/build-config/scripts/onie-mk-iso.sh +++ b/build-config/scripts/onie-mk-iso.sh @@ -287,10 +287,8 @@ if [ "$UEFI_ENABLE" = "yes" ] ; then zfscrypt zfsinfo " - # linuxefi is an x86 specific - if [ ${ARCH} != "arm64" ]; then - GRUB_MODULES=$GRUB_MODULES" linuxefi" - fi + # grub 2.12+ unified linuxefi into the standard linux/initrd commands; + # the linuxefi module no longer exists. # Generate UEFI format GRUB image mkdir -p $RECOVERY_EFI_BOOT_DIR $GRUB_HOST_BIN_UEFI_DIR/grub-mkimage \ diff --git a/build-config/scripts/sbom-vuln-scan.py b/build-config/scripts/sbom-vuln-scan.py new file mode 100755 index 000000000..41a49e5ea --- /dev/null +++ b/build-config/scripts/sbom-vuln-scan.py @@ -0,0 +1,395 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2026 Brad House +# +# SPDX-License-Identifier: GPL-2.0 +# +# Scan a CycloneDX SBOM (see gen-sbom.py) for known vulnerabilities using +# grype, and suppress CVEs that ONIE has already fixed locally via a patch. +# +# ONIE has no package database -- it builds every component from an upstream +# source tarball and applies a series of local patches from patches//. +# When a patch fixes a CVE, the upstream version that grype keys off of is +# still "vulnerable" as far as the vulnerability database is concerned, even +# though the shipped binary is fixed. To avoid drowning in false positives we +# mine the patch tree for CVE references, emit an OpenVEX document declaring +# those CVEs "fixed", and cross-reference grype's output against the mined set. +# +# Modeled on SONiC's sbom_vuln_scan.py + sbom_extract_vex_from_patches.py +# (sonic-buildimage PR #27455), adapted to ONIE's patches/ layout. +# +# Usage: +# sbom-vuln-scan.py --sbom --output +# [--vex-output ] +# +# This is a report generator: it always exits 0. If grype is unavailable the +# VEX document is still written and the report records that grype was missing. + +import argparse +import json +import os +import re +import subprocess +import sys + +REPO_ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) +PATCHES_DIR = os.path.join(REPO_ROOT, "patches") + +CVE_RE = re.compile(r"CVE-\d{4}-\d{4,}", re.IGNORECASE) + + +def mine_patched_cves(patches_dir=PATCHES_DIR): + """Walk patches// and patches/// looking for CVE ids in + both patch filenames and patch file contents. + + Returns a list of dicts: {"cve_id", "patch_path", "package"} de-duplicated + on (cve_id, patch_path). cve_id is normalized to upper case. patch_path is + relative to the repo root. package is the top-level patches/ dir name. + """ + found = {} + + if not os.path.isdir(patches_dir): + return [] + + # Top-level packages: patches/ + for pkg in sorted(os.listdir(patches_dir)): + pkg_dir = os.path.join(patches_dir, pkg) + if not os.path.isdir(pkg_dir): + continue + + # Candidate dirs to scan files in: patches/ and patches// + scan_dirs = [pkg_dir] + for sub in sorted(os.listdir(pkg_dir)): + sub_dir = os.path.join(pkg_dir, sub) + if os.path.isdir(sub_dir): + scan_dirs.append(sub_dir) + + for d in scan_dirs: + for entry in sorted(os.listdir(d)): + fpath = os.path.join(d, entry) + if not os.path.isfile(fpath): + continue + + cves = set() + + # 1) CVE in the filename + for m in CVE_RE.findall(entry): + cves.add(m.upper()) + + # 2) CVE in the file contents + try: + with open(fpath, "r", encoding="utf-8", errors="replace") as fh: + for m in CVE_RE.findall(fh.read()): + cves.add(m.upper()) + except (OSError, IOError): + pass + + rel = os.path.relpath(fpath, REPO_ROOT) + for cve in cves: + key = (cve, rel) + if key not in found: + found[key] = { + "cve_id": cve, + "patch_path": rel, + "package": pkg, + } + + return list(found.values()) + + +def load_sbom_components(sbom_path): + """Return a map of lowercased component name -> purl from a CycloneDX SBOM.""" + name_to_purl = {} + try: + with open(sbom_path, "r", encoding="utf-8") as fh: + doc = json.load(fh) + except (OSError, IOError, ValueError): + return name_to_purl + + for comp in doc.get("components", []) or []: + name = comp.get("name") + purl = comp.get("purl") + if name and purl: + name_to_purl.setdefault(name.lower(), purl) + return name_to_purl + + +def build_vex(patched, name_to_purl): + """Build an OpenVEX v0.2.0 document from the mined patched CVEs. + + One statement per mined (cve, patch) hit. When the patched package name + maps to an SBOM component PURL, a products[] entry is attached; otherwise + products is omitted. + """ + statements = [] + for idx, item in enumerate(patched): + cve = item["cve_id"] + pkg = item["package"] + patch_path = item["patch_path"] + + stmt = { + "@id": "https://openvex.dev/statements/onie/%s/%d" % (cve, idx), + "vulnerability": {"name": cve}, + "status": "fixed", + "impact_statement": "Fixed by ONIE patch %s" % patch_path, + } + + purl = name_to_purl.get(pkg.lower()) + if purl: + stmt["products"] = [{"@id": purl}] + + statements.append(stmt) + + return { + "@context": "https://openvex.dev/ns/v0.2.0", + "@id": "https://openvex.dev/docs/onie/patched-cves", + "author": "ONIE build-config/scripts/sbom-vuln-scan.py", + "version": 1, + "statements": statements, + } + + +def run_grype(sbom_path): + """Run grype against the SBOM. Returns parsed JSON dict on success, or None + if grype is missing or fails.""" + try: + proc = subprocess.run( + ["grype", "sbom:%s" % sbom_path, "-o", "json"], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) + except (OSError, FileNotFoundError): + return None + + if proc.returncode != 0: + return None + + try: + return json.loads(proc.stdout.decode("utf-8", errors="replace")) + except ValueError: + return None + + +def parse_grype_matches(grype_json): + """Normalize grype JSON into a list of match dicts.""" + out = [] + for match in grype_json.get("matches", []) or []: + vuln = match.get("vulnerability", {}) or {} + artifact = match.get("artifact", {}) or {} + + fix = vuln.get("fix", {}) or {} + fix_versions = fix.get("versions", []) or [] + + out.append({ + "id": vuln.get("id", ""), + "package": artifact.get("name", ""), + "severity": vuln.get("severity", ""), + "installed_version": artifact.get("version", ""), + "fixed_version": ", ".join(fix_versions) if fix_versions else "", + }) + return out + + +# Most-severe first; unknown/blank sorts last. +SEVERITY_ORDER = { + "critical": 0, "high": 1, "medium": 2, "low": 3, "negligible": 4, +} + + +def _sev_key(sev): + return SEVERITY_ORDER.get((sev or "").lower(), 8) + + +def render_markdown(report, machine=None): + """Render the vulnerability report as a GitHub-flavored Markdown table.""" + s = report.get("summary", {}) + out = [] + title = "SBOM Vulnerability Scan" + if machine: + title += " — %s" % machine + out.append("## %s" % title) + out.append("") + if not report.get("grype_available", False): + out.append("> :warning: grype was not available; no vulnerability scan " + "was performed.") + out.append("") + out.append("| Metric | Count |") + out.append("| --- | ---: |") + out.append("| Total findings | %d |" % s.get("total", 0)) + out.append("| Suppressed (fixed by ONIE patch) | %d |" + % s.get("suppressed_by_vex", 0)) + out.append("| No fix available (won't-fix / disputed upstream) | %d |" + % s.get("no_fix_available", 0)) + out.append("| **Actionable (fix available)** | **%d** |" + % s.get("actionable", 0)) + out.append("") + + actionable = report.get("actionable", []) or [] + out.append("### Actionable vulnerabilities") + out.append("") + out.append("_Only findings with an upstream fix are listed; the " + "%d without a published fix are counted above but omitted " + "(no action available)._" % s.get("no_fix_available", 0)) + out.append("") + if actionable: + out.append("| Severity | ID | Package | Installed | Fixed in |") + out.append("| --- | --- | --- | --- | --- |") + for a in sorted(actionable, + key=lambda x: (_sev_key(x.get("severity")), + x.get("package", ""))): + out.append("| %s | %s | %s | %s | %s |" % ( + a.get("severity") or "-", a.get("id") or "-", + a.get("package") or "-", a.get("installed_version") or "-", + a.get("fixed_version") or "-")) + else: + out.append("None. :white_check_mark:") + out.append("") + + suppressed = report.get("suppressed", []) or [] + if suppressed: + out.append("
Suppressed — already fixed by ONIE " + "patches (%d)" % len(suppressed)) + out.append("") + out.append("| ID | Package | Fixed by patch |") + out.append("| --- | --- | --- |") + for sup in sorted(suppressed, key=lambda x: x.get("package", "")): + patch = (sup.get("reason", "") or "").replace( + "fixed by ONIE patch ", "") + out.append("| %s | %s | %s |" % ( + sup.get("id") or "-", sup.get("package") or "-", patch or "-")) + out.append("") + out.append("
") + out.append("") + + return "\n".join(out) + "\n" + + +def finalize(report, args): + """Write the JSON report + a Markdown table, and echo the table to stdout.""" + with open(args.output, "w", encoding="utf-8") as fh: + json.dump(report, fh, indent=2, sort_keys=False) + fh.write("\n") + + md = render_markdown(report, machine=args.machine) + if args.markdown: + with open(args.markdown, "w", encoding="utf-8") as fh: + fh.write(md) + sys.stdout.write(md) + + +def main(): + ap = argparse.ArgumentParser( + description="Scan a CycloneDX SBOM for vulnerabilities (grype) and " + "suppress CVEs already patched by ONIE (OpenVEX).") + ap.add_argument("--sbom", required=True, + help="Path to the CycloneDX JSON SBOM to scan.") + ap.add_argument("--output", required=True, + help="Path to write the vulnerability report JSON.") + ap.add_argument("--vex-output", default=None, + help="Path to write the OpenVEX JSON (default: alongside " + "--output as .vex.json).") + ap.add_argument("--markdown", default=None, + help="Path to write a Markdown vulnerability table (default: " + "alongside --output as .md). The table is " + "always echoed to stdout regardless.") + ap.add_argument("--machine", default=None, + help="Machine name, used only in the report title.") + args = ap.parse_args() + + base = os.path.splitext(args.output)[0] + if args.vex_output: + vex_output = args.vex_output + else: + vex_output = base + ".vex.json" + if not args.markdown: + args.markdown = base + ".md" + + # 1) Mine patched CVEs from the patch tree. + patched = mine_patched_cves() + patched_cve_to_patch = {} + for item in patched: + patched_cve_to_patch.setdefault(item["cve_id"], item["patch_path"]) + + # 2) Build + write the OpenVEX document. + name_to_purl = load_sbom_components(args.sbom) + vex = build_vex(patched, name_to_purl) + with open(vex_output, "w", encoding="utf-8") as fh: + json.dump(vex, fh, indent=2, sort_keys=False) + fh.write("\n") + + # 3) Run grype. + grype_json = run_grype(args.sbom) + + if grype_json is None: + report = { + "scanned": args.sbom, + "grype_available": False, + "note": "grype was not available or failed; no vulnerability " + "scan was performed. OpenVEX written to %s" % vex_output, + "summary": {"total": 0, "suppressed_by_vex": 0, "actionable": 0}, + "suppressed": [], + "actionable": [], + } + finalize(report, args) + sys.stderr.write( + "sbom-vuln-scan: grype unavailable; wrote VEX (%d patched CVEs) " + "and empty report to %s\n" % (len(patched_cve_to_patch), args.output)) + return 0 + + # 4) Cross-reference grype matches against the mined patched-CVE set, then + # split the rest by whether an upstream fix actually exists: + # * suppressed -- already fixed by an ONIE patch (VEX) + # * actionable -- a fixed version is available upstream -> we can act + # * no_fix -- no fixed version published. This usually means + # upstream has triaged it as won't-fix / disputed / + # not-exploitable, so there is nothing for us to do. + # We report it as a statistic only, not as an + # actionable item (listing it is noise). + matches = parse_grype_matches(grype_json) + suppressed = [] + actionable = [] + no_fix = [] + for m in matches: + patch_path = patched_cve_to_patch.get((m["id"] or "").upper()) + if patch_path: + entry = dict(m) + entry["reason"] = "fixed by ONIE patch %s" % patch_path + suppressed.append(entry) + elif m["fixed_version"]: + actionable.append(m) + else: + no_fix.append(m) + + def slim(items): + return [{"id": x["id"], "package": x["package"], "severity": x["severity"], + "installed_version": x["installed_version"], + "fixed_version": x["fixed_version"]} for x in items] + + # 5) Write the report. + report = { + "scanned": args.sbom, + "grype_available": True, + "summary": { + "total": len(matches), + "suppressed_by_vex": len(suppressed), + "no_fix_available": len(no_fix), + "actionable": len(actionable), + }, + "suppressed": suppressed, + # Kept in the JSON for auditability; intentionally NOT listed in the + # Markdown report (statistic only -- see no_fix_available above). + "no_fix": slim(no_fix), + "actionable": slim(actionable), + } + finalize(report, args) + + sys.stderr.write( + "sbom-vuln-scan: %d findings, %d suppressed by VEX, %d no-fix, " + "%d actionable (VEX: %s, report: %s)\n" % ( + len(matches), len(suppressed), len(no_fix), len(actionable), + vex_output, args.output)) + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/contrib/git-stats/README.md b/contrib/git-stats/README.md deleted file mode 100644 index 79dad81b4..000000000 --- a/contrib/git-stats/README.md +++ /dev/null @@ -1,55 +0,0 @@ -# Generate Git Repo Statistics - -This is a little git processing script to generate git repo -statistics, based on gitdm by Jonathan Corbet . - -Original source: `git://git.lwn.net/gitdm.git` - -# Running - -The script takes two arguments. - -## Argument 1 -- a range of git revisions - -Some examples: - -``` - .. - .. - ..HEAD - - 2018.05..HEAD -``` - -See the Specifying Ranges section of `gitrevisions(7)`. - -## Argument 2 -- a label for the report - -A meaningful label for the report, for example `yearly` or -`quarterly`. - -## Full Example - -To generate the stats from the 2015.02 to the 2016.02 release we would -do: - -``` - $ ./onie-git-stats 2015.02..2016.02 2015-year -``` - -To generate stats from the 2017.05 release up to the current HEAD we -would do: - -``` - $ ./onie-git-stats 2017.05..HEAD 2017-analysis -``` - -# Updating the maps - -From time to time new companies and email aliases are needed. These -changes are controlled by the gitdm configuration files in the -`gitdm-config` subdirectory. - -The most common changes are mapping an email domain name to a -corporate name for the report. This is controlled by the `domain-map` -file. See `gitdm/README` for complete configuration details. diff --git a/contrib/git-stats/gitdm-config/aliases b/contrib/git-stats/gitdm-config/aliases deleted file mode 100644 index c9ccb0724..000000000 --- a/contrib/git-stats/gitdm-config/aliases +++ /dev/null @@ -1,9 +0,0 @@ -# -# This is the email aliases file, mapping secondary addresses -# onto a single, canonical address. -# -corbet@eklektix.com corbet@lwn.net -pankajbansal3073@gmail.com pankaj.bansal@nxp.com -pankaj.bansal@puresoftware.com pankaj.bansal@nxp.com -wadelnn@users.noreply.github.com wadelnn@ingrasys.com -chihen.he@gmail.com wadelnn@ingrasys.com diff --git a/contrib/git-stats/gitdm-config/domain-map b/contrib/git-stats/gitdm-config/domain-map deleted file mode 100644 index e27bad9ac..000000000 --- a/contrib/git-stats/gitdm-config/domain-map +++ /dev/null @@ -1,332 +0,0 @@ -# -# Here is a set of mappings of domain names onto employer names. -# -5etech.eu 5e Technologies -6wind.com 6WIND -8d.com 8D Technologies -accton.com Accton Technology -aconex.com Aconex -adaptec.com Adaptec -addi-data.com ADDI-DATA GmbH -agemasystems.com Agema Systems -aist.go.jp National Institute of Advanced Industrial Science and Technology -akamai.com Akamai Technologies -alphanetworks.com Alpha Networks -alphanetworks.ocm Alpha Networks -amd.com AMD -am.sony.com Sony -anagramm.de Anagramm GmbH -analog.com Analog Devices -android.com Google -arastra.com Arastra Inc -areca.com.tw Areca -arm.com ARM -artecdesign.ee Artec Design -arvoo.nl ARVOO Engineering -atmel.com Atmel -atomide.com Atomide -avtrex.com Avtrex -axis.com Axis Communications -azingo.com Azingo -balabit.com BalaBit -balabit.hu BalaBit -baslerweb.com Basler Vision Technologies -bay.ws Bay -bitwagon.com BitWagon Software -bivio.net Bivio Networking -bluegiga.com Bluegiga -bluehost.com Bluehost -bluewatersys.com Bluewater Systems -boeing.com Boeing -boundarydevices.com Boundary Devices -broadcom.com Broadcom -brontes3d.com Brontes Technologies -bull.net Bull SAS -cam.ac.uk University of Cambridge -ccur.com Concurrent Computer Corporation -cdi.cz CDI.CZ -celestica.com Celestica -celestrius.com Celestrius -celunite.com Azingo -centecnetworks.com Centec Networks -centtech.com Centaur Technology -chelsio.com Chelsio -cisco.com Cisco -citi.umich.edu Univ. of Michigan CITI -citrix.com Citrix -clustcom.com Cluster Computing -clusterfs.com Sun -cn.fujitsu.com Fujitsu -cogentembedded.com Cogent Embedded, Inc. -compulab.co.il CompuLab -computergmbh.de CC Computer Consultants -comx.dk ComX Networks -conectiva.com.br Mandriva -coraid.com Coraid -cosmosbay.com Cosmosbay~Vectis -cozybit.com cozybit -cray.com Cray -cse-semaphore.com CSE Semaphore -csr.com CSR -cumulusnetworks.com Cumulus Networks -cyaninc.com Ciena -cyberguard.com Secure Computing -cybernetics.com Cybernetics -data.slu.se Uppsala University -dave.eu Dave S.r.l. -de.bosch.com Bosch -dell.com Dell EMC -dell.com) Dell EMC -deltaww.com Delta Networks -denx.de DENX Software Engineering -devicescape.com Devicescape -digi.com Digi International -dti2.net DTI2 - Desarrollo de la tecnologia de las comunicaciones -edesix.com Edesix Ltd -edge-core.com Edge-core Networks -einstruction.com eInstruction -eke.fi EKE-Electronics -elandigitalsystems.com Elan Digital Systems -elpa.it ELPA -embeddedalley.com Embedded Alley Solutions -emcraft.com EmCraft Systems -empirix.com Empirix -emulex.com Emulex -endrelia.com Endrelia -enea.com ENEA AB -ericsson.com Ericsson -escient.com Escient -esd-electronics.com ESD Electronics -esd.eu ESD Electronics -exaware.com Exaware -fastmail.fm FastMail.FM -fixstars.com Fixstars Technologies -foxconn.com Foxconn -free-electrons.com Free Electrons -freescale.com Freescale -fujitsu.com Fujitsu -gaisler.com Gaisler Research -gefanuc.com GE Fanuc -geomatys.fr Geomatys -google.com Google -gvs.co.yu GVS -hansenpartnership.com Hansen Partnership -harris.com Harris Corporation -hauppauge.com Hauppauge -hermes-softlab.com HERMES SoftLab -hevs.ch HES-SO Valais Wallis -highpoint-tech.com HighPoint Technologies -hitachi.co.jp Hitachi -hitachi.com Hitachi -hitachisoft.jp Hitachi -hp.com HP -huawei.com Huawei Technologies -hvsistemas.es HV Sistemas -ibm.com IBM -ibp.de ipb (uk) Ltd. -icplus.com.tw IC Plus -igel.co.jp igel -indt.org.br INdT -indt.org INdT -ingrasys.com Ingrasys Technology -inl.fr INL -inria.fr INRIA -intel.com Intel -intellitree.com IntelliTree Solutions -interfacemasters.com Interface Masters -intra2net.com Intra2net AG -inventec.com Inventec -iram.es IRAM -jmicron.com jmicron.com -jp.fujitsu.com Fujitsu -juniper.net Juniper Networks -katalix.com Katalix Systems -keyspan.com InnoSys -laptop.org OLPC -laurelnetworks.com ECI Telecom -lenovo.com Lenovo -linutronix.de linutronix -linuxant.com Linuxant -linux-foundation.org Linux Foundation -linx.net London Internet Exchange -lippert-at.de LiPPERT Embedded Computers GmbH -lippertembedded.de LiPPERT Embedded Computers GmbH -llnl.gov Lawrence Livermore National Laboratory -lnxi.com Linux Networx -logitech.com Logitech -lsi.com LSI Logic -lsil.com LSI Logic -lwn.net LWN.net -macqel.be Macq Electronique -macqel.com Macq Electronique -mandriva.com Mandriva -mandriva.com.br Mandriva -marvell.com Marvell -mellanox.co.il Mellanox -mellanox.com Mellanox -melware.de Cytronics & Melware -mev.co.uk MEV Limited -microgate.com MicroGate Systems -mips.com MIPS -miraclelinux.com Miracle Linux -mn-solutions.de M&N Solutions -moreton.com.au Secure Computing -motorola.com Motorola -movial.fi Movial -mpc-data.co.uk MPC Data -msi.com.tw Micro-Star International -mvista.com MontaVista -myri.com Myricom -namesys.com NameSys -nec.co.jp NEC -nec.com NEC -netapp.com NetApp -neteffect.com NetEffect -neterion.com Neterion -netxen.com NetXen -niasdigital.com Nias Digital -niif.hu NIIF Institute -nokia.com Nokia -nomadgs.com Nomad Global Solutions -nortel.com Nortel -novell.com Novell -nrl.navy.mil U.S. Naval Research Laboratory -ntt.co.jp NTT -ntts.co.jp NTT -nuovasystems.com Nuova Systems -nvidia.com NVidia -nvtl.com Novatel Wireless -nxp.com NXP (Qualcomm) -obsidianresearch.com Obsidian Research -oce.com Océ Technologies -octant-fr.com Octant Informatique -onelan.co.uk ONELAN -onstor.com Onstor -openedhand.com OpenedHand -opengridcomputing.com Open Grid Computing -openmoko.org OpenMoko -openvz.org Parallels -oracle.com Oracle -ornl.gov Oak Ridge National Laboratory -osdl.org Linux Foundation -ozlabs.org IBM -panasas.com Panasas -panasonic.com Panasonic -papercut.bz PaperCut Software -papercut.com PaperCut Software -parallels.com Parallels -pasemi.com PA Semi Corporation -pcs.de PCS Systemtechnik -pengutronix.de Pengutronix -pheonix.com Phoeonix -philosys.de Philosys Software -pikatech.com PIKA Technologies -pikron.com PiKRON s.r.o -platinasystems.com Platina Systems -pmc-sierra.com PMC-Sierra -profusion.mobi ProFUSION -promise.com Promise Technology -promwad.com Promwad -protei.ru Protei ltd -qlogic.com QLogic -quantatw.com Quanta Cloud Technology -qumranet.com Qumranet -rdc.com.tw RDC Semiconductor -realtek.com.tw Realtek -redhat.com Red Hat -reliablesolutions.de reliablesolutions -renesas.com Renesas Technology -road.de ROAD -rockwell.com Rockwell -rojant.com Rajant -rowland.harvard.edu Rowland Institute, Harvard -rtr.ca Real-Time Remedies -sagem.com Sagem Defense Sécurité -samsung.com Samsung -sanpeople.com SANPeople -savantav.com Savant Systems -secretlab.ca Secretlab -securecomputing.com Secure Computing -semihalf.com Semihalf Embedded Systems -sf-tec.de Science Fiction Technologies -sgi.com SGI -sicortex.com Sicortex -siemens.com Siemens -sierrawireless.com Sierra Wireless -sigma-chemnitz.de SIGMA Chemnitz -snapgear.com Snapgear -softwarefreedom.org Software Freedom Law Center -solarflare.com Solarflare Communications -solidboot.com Solid Boot Ltd. -sony.co.jp Sony -sonycom.com Sony -sony.com Sony -southpole.se South Pole AB -spidernet.net SpiderNet Services -starentnetworks.com Starent Networks -st.com ST Microelectronics -steeleye.com SteelEye -stlinux.com ST Microelectronics -sun.com Sun -suse.com Novell -suse.cz Novell -suse.de Novell -sw.ru Parallels -swsoft.com Parallels -tapsys.com Tapestry Systems -taskit.de taskit -telargo.com Telargo -teleca.com Teleca -tensilica.com Tensilica -terascala.com Terascala -thinktube.com Thinktube -thot-soft.com Thot-Soft 2002 -ti.com Texas Instruments -til-technologies.fr TIL Technologies -tls.msk.ru Telecom-Service -toptica.com TOPTICA Photonics -toshiba.co.jp Toshiba -total-knowledge.com Total Knowledge -towertech.it Tower Technologies -tpi.com TriplePoint -transitive.com Transitive -transmode.se Transmode Systems -tresys.com Tresys -trinnov.com Trinnov Audio -tripeaks.co.jp Tripeaks -trustedcs.com Trusted Computer Solutions -tundra.com Tundra Semiconductor -tungstengraphics.com Tungsten Graphics -tycho.nsa.gov US National Security Agency -ubuntu.com Canonical -uhulinux.hu UHU-Linux -unicontrol.de Unicontrol Systemtechnik -unisys.com Unisys -uq.edu.au University of Queensland -us.ibm.com IBM -valinux.co.jp VA Linux Systems Japan -verismonetworks.com Verismo -veritas.com Veritas -vernier.com Vernier Software and Technology -via.com.tw Via -vivecode.com Vivecode -vmware.com VMWare -volkswagen.de Volkswagen -voltaire.com Voltaire -vpop.net vpop.net -vt.edu Virginia Tech -vyatta.com Vyatta -wabtec.com Wabtec Railway Electronics -wacom.com Wacom -winbond.com Winbond Electronics -winbond.com.tw Winbond Electronics -wincor-nixdorf.com Wincor Nixdorf -windriver.com Wind River -wipro.com Wipro -wolfsonmicro.com Wolfson Microelectronics -xensource.com XenSource -xes-inc.com Extreme Engineering Solutions -xilinx.com Xilinx -xiv.co.il XIV Information Systems -xivstorage.com XIV Information Systems -yahoo-inc.com Yahoo diff --git a/contrib/git-stats/gitdm-config/filetypes.txt b/contrib/git-stats/gitdm-config/filetypes.txt deleted file mode 100644 index e24c396b4..000000000 --- a/contrib/git-stats/gitdm-config/filetypes.txt +++ /dev/null @@ -1,362 +0,0 @@ -# -*- coding:utf-8 -*- -# Copyright (C) 2006 Libresoft -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Library General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# Authors : Gregorio Robles -# Authors : Germán Póo-Caamaño -# -# This file contains associations parameters regarding filetypes -# (documentation, develompent, multimedia, images...) -# -# format: -# filetype [] -# -# Order: -# The list should keep an order, so filetypes can be counted properly. -# ie. we want ltmain.sh -> 'build' instead of 'code'. -# -# If there is an filetype which is not in order but has values, it will -# be added at the end. -# -order image,translation,ui,multimedia,package,build,code,documentation,devel-doc -# -# -# Code files (headers and the like included -# (most common languages first -# -filetype code \.c$ # C -filetype code \.pc$ # C -filetype code \.ec$ # C -filetype code \.ecp$ # C -filetype code \.C$ # C++ -filetype code \.cpp$ # C++ -filetype code \.c\+\+$ # C++ -filetype code \.cxx$ # C++ -filetype code \.cc$ # C++ -filetype code \.pcc$ # C++ -filetype code \.cpy$ # C++ -filetype code \.h$ # C or C++ header -filetype code \.hh$ # C++ header -filetype code \.hpp$ # C++ header -filetype code \.hxx$ # C++ header -filetype code \.sh$ # Shell -filetype code \.pl$ # Perl -filetype code \.pm$ # Perl -filetype code \.pod$ # Perl -filetype code \.perl$ # Perl -filetype code \.cgi$ # CGI -filetype code \.php$ # PHP -filetype code \.php3$ # PHP -filetype code \.php4$ # PHP -filetype code \.inc$ # PHP -filetype code \.py$ # Python -filetype code \.java$ # Java -filetype code \.class$ # Java Class (or at least a class in some OOPL -filetype code \.ada$ # ADA -filetype code \.ads$ # ADA -filetype code \.adb$ # ADA -filetype code \.pad$ # ADA -filetype code \.s$ # Assembly -filetype code \.S$ # Assembly -filetype code \.asm$ # Assembly -filetype code \.awk$ # awk -filetype code \.cs$ # C# -filetype code \.csh$ # CShell (including tcsh -filetype code \.cob$ # COBOL -filetype code \.cbl$ # COBOL -filetype code \.COB$ # COBOL -filetype code \.CBL$ # COBOL -filetype code \.exp$ # Expect -filetype code \.l$ # (F lex -filetype code \.ll$ # (F lex -filetype code \.lex$ # (F lex -filetype code \.f$ # Fortran -filetype code \.f77$ # Fortran -filetype code \.F$ # Fortran -filetype code \.hs$ # Haskell -filetype code \.lhs$ # Not preprocessed Haskell -filetype code \.el$ # LISP (including Scheme -filetype code \.scm$ # LISP (including Scheme -filetype code \.lsp$ # LISP (including Scheme -filetype code \.jl$ # LISP (including Scheme -filetype code \.ml$ # ML -filetype code \.ml3$ # ML -filetype code \.m3$ # Modula3 -filetype code \.i3$ # Modula3 -filetype code \.m$ # Objective-C -filetype code \.p$ # Pascal -filetype code \.pas$ # Pascal -filetype code \.rb$ # Ruby -filetype code \.sed$ # sed -filetype code \.tcl$ # TCL -filetype code \.tk$ # TCL -filetype code \.itk$ # TCL -filetype code \.y$ # Yacc -filetype code \.yy$ # Yacc -filetype code \.idl$ # CORBA IDL -filetype code \.gnorba$ # GNOME CORBA IDL -filetype code \.oafinfo$ # GNOME OAF -filetype code \.mcopclass$ # MCOP IDL compiler generated class -filetype code \.autoforms$ # Autoform -filetype code \.atf$ # Autoform -filetype code \.gnuplot$ -filetype code \.xs$ # Shared library? Seen a lot of them in gnome-perl -filetype code \.js$ # JavaScript (and who knows, maybe more -filetype code \.patch$ -filetype code \.diff$ # Sometimes patches appear this way -filetype code \.ids$ # Not really sure what this means -filetype code \.upd$ # ¿¿¿??? (from Kcontrol -filetype code $.ad$ # ¿¿¿??? (from Kdisplay and mc -filetype code $.i$ # Appears in the kbindings for Qt -filetype code $.pri$ # from Qt -filetype code \.schema$ # Not really sure what this means -filetype code \.fd$ # Something to do with latex -filetype code \.cls$ # Something to do with latex -filetype code \.pro$ # Postscript generation -filetype code \.ppd$ # PDF generation -filetype code \.dlg$ # Not really sure what this means -filetype code \.plugin$ # Plug-in file -filetype code \.dsp # Microsoft Developer Studio Project File -filetype code \.vim$ # vim syntax file -filetype code \.trm$ # gnuplot term file -filetype code \.font$ # Font mapping -filetype code \.ccg$ # C++ files - Found in gtkmm* -filetype code \.hg$ # C++ headers - Found in gtkmm* -filetype code \.dtd # XML Document Type Definition -filetype code \.bat # DOS batch files -filetype code \.vala # Vala -filetype code \.py\.in$ -filetype code \.rhtml$ # eRuby -filetype code \.sql$ # SQL script -# -# -# Development documentation files (for hacking generally -# -filetype devel-doc ^readme.*$ -filetype devel-doc ^changelog.* -filetype devel-doc ^todo.*$ -filetype devel-doc ^credits.*$ -filetype devel-doc ^authors.*$ -filetype devel-doc ^changes.*$ -filetype devel-doc ^news.*$ -filetype devel-doc ^install.*$ -filetype devel-doc ^hacking.*$ -filetype devel-doc ^copyright.*$ -filetype devel-doc ^licen(s|c)e.*$ -filetype devel-doc ^copying.*$ -filetype devel-doc manifest$ -filetype devel-doc faq$ -filetype devel-doc building$ -filetype devel-doc howto$ -filetype devel-doc design$ -filetype devel-doc \.files$ -filetype devel-doc files$ -filetype devel-doc subdirs$ -filetype devel-doc maintainers$ -filetype devel-doc developers$ -filetype devel-doc contributors$ -filetype devel-doc thanks$ -filetype devel-doc releasing$ -filetype devel-doc test$ -filetype devel-doc testing$ -filetype devel-doc build$ -filetype devel-doc comments?$ -filetype devel-doc bugs$ -filetype devel-doc buglist$ -filetype devel-doc problems$ -filetype devel-doc debug$ -filetype devel-doc hacks$ -filetype devel-doc hacking$ -filetype devel-doc versions?$ -filetype devel-doc mappings$ -filetype devel-doc tips$ -filetype devel-doc ideas?$ -filetype devel-doc spec$ -filetype devel-doc compiling$ -filetype devel-doc notes$ -filetype devel-doc missing$ -filetype devel-doc done$ -filetype devel-doc \.omf$ # XML-based format used in GNOME -filetype devel-doc \.lsm$ -filetype devel-doc ^doxyfile$ -filetype devel-doc \.kdevprj$ -filetype devel-doc \.directory$ -filetype devel-doc \.dox$ -filetype devel-doc \.doap$ -# -# -# Building, compiling, configuration and CVS admin files -# -filetype build \.in.*$ -filetype build configure.*$ -filetype build makefile.*$ -filetype build config\.sub$ -filetype build config\.guess$ -filetype build config\.status$ -filetype build ltmain\.sh$ -filetype build autogen\.sh$ -filetype build config$ -filetype build conf$ -filetype build cvsignore$ -filetype build \.cfg$ -filetype build \.m4$ -filetype build \.mk$ -filetype build \.mak$ -filetype build \.make$ -filetype build \.mbx$ -filetype build \.protocol$ -filetype build \.version$ -filetype build mkinstalldirs$ -filetype build install-sh$ -filetype build rules$ -filetype build \.kdelnk$ -filetype build \.menu$ -filetype build linguas$ # Build translations -filetype build potfiles.*$ # Build translations -filetype build \.shlibs$ # Shared libraries -# filetype build %debian% -# filetype build %specs/% -filetype build \.spec$ # It seems theyre necessary for RPM build -filetype build \.def$ # build bootstrap for DLLs on win32 -# -# -# Documentation files -# -# filetype documentation doc/% -# filetype documentation %HOWTO% -filetype documentation \.html$ -filetype documentation \.txt$ -filetype documentation \.ps(\.gz|\.bz2)?$ -filetype documentation \.dvi(\.gz|\.bz2)?$ -filetype documentation \.lyx$ -filetype documentation \.tex$ -filetype documentation \.texi$ -filetype documentation \.pdf(\.gz|\.bz2)?$ -filetype documentation \.djvu$ -filetype documentation \.epub$ -filetype documentation \.sgml$ -filetype documentation \.docbook$ -filetype documentation \.wml$ -filetype documentation \.xhtml$ -filetype documentation \.phtml$ -filetype documentation \.shtml$ -filetype documentation \.htm$ -filetype documentation \.rdf$ -filetype documentation \.phtm$ -filetype documentation \.tmpl$ -filetype documentation \.ref$ # References -filetype documentation \.css$ -# filetype documentation %tutorial% -filetype documentation \.templates$ -filetype documentation \.dsl$ -filetype documentation \.ent$ -filetype documentation \.xml$ -filetype documentation \.xmi$ -filetype documentation \.xsl$ -filetype documentation \.entities$ -filetype documentation \.[1-7]$ # Man pages -filetype documentation \.man$ -filetype documentation \.manpages$ -filetype documentation \.doc$ -filetype documentation \.rtf$ -filetype documentation \.wpd$ -filetype documentation \.qt3$ -filetype documentation man\d?/.*\.\d$ -filetype documentation \.docs$ -filetype documentation \.sdw$ # OpenOffice.org Writer document -filetype documentation \.odt$ # OpenOffice.org document -filetype documentation \.en$ # Files in English language -filetype documentation \.de$ # Files in German -filetype documentation \.es$ # Files in Spanish -filetype documentation \.fr$ # Files in French -filetype documentation \.it$ # Files in Italian -filetype documentation \.cz$ # Files in Czech -filetype documentation \.page$ # Mallard -filetype documentation \.page.stub$ # Mallard stub -# -# -# Images -# -filetype image \.png$ -filetype image \.jpg$ -filetype image \.jpeg$ -filetype image \.bmp$ -filetype image \.gif$ -filetype image \.xbm$ -filetype image \.eps$ -filetype image \.mng$ -filetype image \.pnm$ -filetype image \.pbm$ -filetype image \.ppm$ -filetype image \.pgm$ -filetype image \.gbr$ -filetype image \.svg$ -filetype image \.fig$ -filetype image \.tif$ -filetype image \.swf$ -filetype image \.svgz$ -filetype image \.shape$ # XML files used for shapes for instance in Kivio -filetype image \.sml$ # XML files used for shapes for instance in Kivio -filetype image \.bdf$ # vfontcap - Vector Font Capability Database (VFlib Version 2 -filetype image \.ico$ -filetype image \.dia$ # We consider .dia as images, I dont want them in unknown -# -# -# Translation files -# -filetype translation \.po$ -filetype translation \.pot$ -filetype translation \.charset$ -filetype translation \.mo$ -# -# -# User interface files -# -filetype ui \.desktop$ -filetype ui \.ui$ -filetype ui \.xpm$ -filetype ui \.xcf$ -filetype ui \.3ds$ -filetype ui \.theme$ -filetype ui \.kimap$ -filetype ui \.glade$ -filetype ui \.gtkbuilder$ -filetype ui rc$ -# -# -# Sound files -# -filetype multimedia \.mp3$ -filetype multimedia \.ogg$ -filetype multimedia \.wav$ -filetype multimedia \.au$ -filetype multimedia \.mid$ -filetype multimedia \.vorbis$ -filetype multimedia \.midi$ -filetype multimedia \.arts$ -# -# -# Packages (yes, there are people who upload packages to the repo) -# -filetype package \.tar$ -filetype package \.tar.gz$ -filetype package \.tar.bz2$ -filetype package \.tar.xz$ -filetype package \.tgz$ -filetype package \.deb$ -filetype package \.rpm$ -filetype package \.srpm$ -filetype package \.ebuild$ diff --git a/contrib/git-stats/gitdm/.gitignore b/contrib/git-stats/gitdm/.gitignore deleted file mode 100644 index f3d74a9a5..000000000 --- a/contrib/git-stats/gitdm/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.pyc -*~ diff --git a/contrib/git-stats/gitdm/COPYING b/contrib/git-stats/gitdm/COPYING deleted file mode 100644 index fe3eb43a6..000000000 --- a/contrib/git-stats/gitdm/COPYING +++ /dev/null @@ -1,2 +0,0 @@ -The code in this directory can be distributed under the terms of the GNU -General Public License, version 2. diff --git a/contrib/git-stats/gitdm/ConfigFile.py b/contrib/git-stats/gitdm/ConfigFile.py deleted file mode 100644 index 3a1e208cd..000000000 --- a/contrib/git-stats/gitdm/ConfigFile.py +++ /dev/null @@ -1,195 +0,0 @@ -# -# Stuff for dealing with configuration files. -# -# -# This code is part of the LWN git data miner. -# -# Copyright 2007-11 Eklektix, Inc. -# Copyright 2007-11 Jonathan Corbet -# -# This file may be distributed under the terms of the GNU General -# Public License, version 2. -# -import sys, re, datetime, os.path -import database - -# -# Read a line and strip out junk. -# -def ReadConfigLine (file): - line = file.readline () - if not line: - return None - line = line.split('#')[0] # Get rid of any comments - line = line.strip () # and extra white space - if len (line) == 0: # we got rid of everything - return ReadConfigLine (file) - return line - -# -# Give up and die. -# -def croak (message): - sys.stderr.write (message + '\n') - sys.exit (1) - -# -# Read a list of email aliases. -# -def ReadEmailAliases (name): - try: - file = open (name, 'r') - except IOError: - croak ('Unable to open email alias file %s' % (name)) - line = ReadConfigLine (file) - while line: - m = re.match ('^("[^"]+"|\S+)\s+(.+)$', line) - if not m or len (m.groups ()) != 2: - croak ('Funky email alias line "%s"' % (line)) - if m and m.group (2).find ('@') <= 0: - croak ('Non-addresses in email alias "%s"' % (line)) - database.AddEmailAlias (m.group (1).replace ('"', ''), m.group (2)) - line = ReadConfigLine (file) - file.close () - -# -# The Email/Employer map -# -EMMpat = re.compile (r'^([^\s]+)\s+([^<]+)\s*(<\s*(\d+-\d+-\d+)\s*)?$') - -def ReadEmailEmployers (name): - try: - file = open (name, 'r') - except IOError: - croak ('Unable to open email/employer file %s' % (name)) - line = ReadConfigLine (file) - while line: - m = EMMpat.match (line) - if not m: - croak ('Funky email/employer line "%s"' % (line)) - email = m.group (1) - company = m.group (2).strip () - enddate = ParseDate (m.group (4)) - database.AddEmailEmployerMapping (email, company, enddate) - line = ReadConfigLine (file) - file.close () - -def ParseDate (cdate): - if not cdate: - return None - sdate = cdate.split ('-') - return datetime.date (int (sdate[0]), int (sdate[1]), int (sdate[2])) - - -def ReadGroupMap (fname, employer): - try: - file = open (fname, 'r') - except IOError: - croak ('Unable to open group map file %s' % (fname)) - line = ReadConfigLine (file) - while line: - database.AddEmailEmployerMapping (line, employer) - line = ReadConfigLine (file) - file.close () - -# -# Read in a virtual employer description. -# -def ReadVirtual (file, name): - ve = database.VirtualEmployer (name) - line = ReadConfigLine (file) - while line: - sl = line.split (None, 1) - first = sl[0] - if first == 'end': - ve.store () - return - # - # Zap the "%" syntactic sugar if it's there - # - if first[-1] == '%': - first = first[:-1] - try: - percent = int (first) - except ValueError: - croak ('Bad split value "%s" for virtual empl %s' % (first, name)) - if not (0 < percent <= 100): - croak ('Bad split value "%s" for virtual empl %s' % (first, name)) - ve.addsplit (' '.join (sl[1:]), percent/100.0) - line = ReadConfigLine (file) - # - # We should never get here - # - croak ('Missing "end" line for virtual employer %s' % (name)) - -# -# Read file type patterns for more fine graned reports -# -def ReadFileType (filename): - try: - file = open (filename, 'r') - except IOError: - croak ('Unable to open file type mapping file %s' % (filename)) - patterns = {} - order = [] - regex_order = re.compile ('^order\s+(.*)$') - regex_file_type = re.compile ('^filetype\s+(\S+)\s+(.+)$') - line = ReadConfigLine (file) - while line: - o = regex_order.match (line) - if o: - # Consider only the first definition in the config file - elements = o.group(1).replace (' ', '') - order = order or elements.split(',') - line = ReadConfigLine (file) - continue - - m = regex_file_type.match (line) - if not m or len (m.groups ()) != 2: - ConfigFile.croak ('Funky file type line "%s"' % (line)) - if not patterns.has_key (m.group (1)): - patterns[m.group (1)] = [] - if m.group (1) not in order: - print '%s not found, appended to the last order' % m.group (1) - order.append (m.group (1)) - - patterns[m.group (1)].append (re.compile (m.group (2), re.IGNORECASE)) - - line = ReadConfigLine (file) - file.close () - return patterns, order - -# -# Read an overall config file. -# - -def ConfigFile (name, confdir): - try: - file = open (name, 'r') - except IOError: - try: - file = open (os.path.join (confdir, name), 'r') - except IOError: - croak ('Unable to open config file %s' % (name)) - line = ReadConfigLine (file) - while line: - sline = line.split (None, 2) - if len (sline) < 2: - croak ('Funky config line: "%s"' % (line)) - if sline[0] == 'EmailAliases': - ReadEmailAliases (os.path.join (confdir, sline[1])) - elif sline[0] == 'EmailMap': - ReadEmailEmployers (os.path.join (confdir, sline[1])) - elif sline[0] == 'GroupMap': - if len (sline) != 3: - croak ('Funky group map line "%s"' % (line)) - ReadGroupMap (os.path.join (confdir, sline[1]), sline[2]) - elif sline[0] == 'VirtualEmployer': - ReadVirtual (file, ' '.join (sline[1:])) - elif sline[0] == 'FileTypeMap': - patterns, order = ReadFileType (os.path.join (confdir, sline[1])) - database.FileTypes = database.FileType (patterns, order) - else: - croak ('Unrecognized config line: "%s"' % (line)) - line = ReadConfigLine (file) - diff --git a/contrib/git-stats/gitdm/README b/contrib/git-stats/gitdm/README deleted file mode 100644 index dab372e47..000000000 --- a/contrib/git-stats/gitdm/README +++ /dev/null @@ -1,213 +0,0 @@ -The code in this directory makes up the "git data miner," a simple hack -which attempts to figure things out from the revision history in a git -repository. - - -INSTALLING GITDM - -gitdm is a python script and doesn't need to be proper installed like other -normal programs. You just have to adjust your PATH variable, pointing it to -the directory of gitdm or alternatively create a symbolic link of the script -inside /usr/bin. - -Before actually run gitdm you may want also to update the configuration file -(gitdm.config) with the needed information. - - -RUNNING GITDM - -Run it like this: - - git log -p -M [details] | gitdm [options] - -Alternatively, you can run with: - - git log --numstat -M [details] | gitdm -n [options] - -The [details] tell git which changesets are of interest; the [options] can -be: - - -a If a patch contains signoff lines from both Andrew Morton - and Linus Torvalds, omit Linus's. - - -b dir Specify the base directory to fetch the configuration files. - - -c file Specify the name of the gitdm configuration file. - By default, "./gitdm.config" is used. - - -d Omit the developer reports, giving employer information - only. - - -D Rather than create the usual statistics, create a file (datelc.csv) - providing lines changed per day, where the first column displays - the changes happened only on that day and the second sums the day it - happnened with the previous ones. This option is suitable for - feeding to a tool like gnuplot. - - -h file Generate HTML output to the given file - - -l num Only list the top entries in each report. - - -n Use --numstat instead of generated patches to get the statistics. - - -o file Write text output to the given file (default is stdout). - - -p prefix Dump out the database categorized by changeset and by file type. - It requires -n, otherwise it is not possible to get separated results. - - -r pat Only generate statistics for changes to files whose - name matches the given regular expression. - - -s Ignore Signed-off-by lines which match the author of - each patch. - - -t Generate a report by type of contribution (code, documentation, etc.). - It requires -n, otherwise this option is ignored silently. - - - -u Group all unknown developers under the "(Unknown)" - employer. - - -x file Export raw statistics as CSV. - - -w Aggregate the data by weeks instead of months in the - CSV file when -x is used. - - -z Dump out the hacker database to "database.dump". - -A typical command line used to generate the "who write 2.6.x" LWN articles -looks like: - - git log -p -M v2.6.19..v2.6.20 | \ - gitdm -u -s -a -o results -h results.html - -or: - - git log --numstat -M v2.6.19..v2.6.20 | \ - gitdm -u -s -a -n -o results -h results.html - -CONFIGURATION FILE - -The main purpose of the configuration file is to direct the mapping of -email addresses onto employers. Please note that the config file parser is -exceptionally stupid and unrobust at this point, but it gets the job done. - -Blank lines and lines beginning with "#" are ignored. Everything else -specifies a file with some sort of mapping: - -EmailAliases file - - Developers often post code under a number of different email - addresses, but it can be desirable to group them all together in - the statistics. An EmailAliases file just contains a bunch of - lines of the form: - - alias@address canonical@address - - Any patches originating from alias@address will be treated as if - they had come from canonical@address. - - It may happen that some people set their git user data in the - following form: "joe.hacker@acme.org ". The - "Joe Hacker" is then considered as the email... but gitdm says - it is a "Funky" email. An alias line in the following form can - be used to alias these commits aliased to the correct email - address: - - "Joe Hacker" joe.hacker@acme.org - - -EmailMap file - - Map email addresses onto employers. These files contain lines - like: - - [user@]domain employer [< yyyy-mm-dd] - - If the "user@" portion is missing, all email from the given domain - will be treated as being associated with the given employer. If a - date is provided, the entry is only valid up to that date; - otherwise it is considered valid into the indefinite future. This - feature can be useful for properly tracking developers' work when - they change employers but do not change email addresses. - - -GroupMap file employer - - This is a variant of EmailMap provided for convenience; it contains - email addresses only, all of which are associated with the given - employer. - -VirtualEmployer name - nn% employer1 - ... -end - - This construct (which appears in the main configuration file) - allows causes the creation of a fake employer with the given - "name". It directs that any contributions attributed to that - employer should be split to other (real) employers using the given - percentages. The functionality works, but is primitive - there is, - for example, no check to ensure that the percentages add up to - something rational. - -FileTypeMap file - - Map file names/extensions onto file types. These files contain lines - like: - - order ,,..., - - filetype - ... - - This construct allows fine graned reports by type of contribution - (build, code, image, multimedia, documentation, etc.) - - Order is important because it is possible to have overlapping between - filenames. For instance, ltmain.sh fits better as 'build' instead of - 'code' (the filename instead of '\.sh$'). The first element in order - has precedence over the next ones. - - -OTHER TOOLS - -A few other tools have been added to this repository: - - treeplot - Reads a set of commits, then generates a graphviz file charting the - flow of patches into the mainline. Needs to be smarter, but, then, - so does everything else in this directory. - - findoldfiles - Simple brute-force crawler which outputs the names of any files - which have not been touched since the original (kernel) commit. - - committags - I needed to be able to quickly associate a given commit with the - major release which contains it. First attempt used - "git tags --contains="; after it ran for a solid week, I concluded - there must be a better way. This tool just reads through the repo, - remembering tags, and creating a Python dictionary containing the - association. The result is an ugly 10mb pickle file, but, even so, - it's still a better way. - - linetags - Crawls through a directory hierarchy, counting how many lines of - code are associated with each major release. Needs the pickle file - from committags to get the job done. - - -NOTES AND CREDITS - -Gitdm was written by Jonathan Corbet; many useful contributions have come -from Greg Kroah-Hartman. - -Please note that this tool is provided in the hope that it will be useful, -but it is not put forward as an example of excellence in design or -implementation. Hacking on gitdm tends to stop the moment it performs -whatever task is required of it at the moment. Patches to make it less -hacky, less ugly, and more robust are welcome. - -Jonathan Corbet -corbet@lwn.net diff --git a/contrib/git-stats/gitdm/changelogs b/contrib/git-stats/gitdm/changelogs deleted file mode 100755 index 1077a0363..000000000 --- a/contrib/git-stats/gitdm/changelogs +++ /dev/null @@ -1,131 +0,0 @@ -#!/usr/bin/pypy -# -*- python -*- -# -# Go munging through changelogs for interesting info. -# -# git log | changelogs -# -import gitlog -import sys - -# -# Stats gathering. -# -EmptyCulprits = { } -SingleSSCulprits = { } -NoSOBCulprits = { } - -def LogEmptyCulprit(culprit): - try: - EmptyCulprits[culprit] += 1 - except KeyError: - EmptyCulprits[culprit] = 1 - -def LogSSCulprit(culprit): - try: - SingleSSCulprits[culprit] += 1 - except KeyError: - SingleSSCulprits[culprit] = 1 - -def LogNoSOBCulprit(culprit): - try: - NoSOBCulprits[culprit] += 1 - except KeyError: - NoSOBCulprits[culprit] = 1 - -def SortedCulprits(culprits): - def compare(c1, c2): - return culprits[c2] - culprits[c1] - names = culprits.keys() - names.sort(compare) - return names - -def PrintCulprits(culprits, sorted): - for name in sorted: - print '\t%30s: %d' % (name, culprits[name]) -# -# Patch logging -# -SSPatches = { } -EmptyCLPatches = { } -NoSOBPatches = { } - -def LogSSPatch(p): - LogSSCulprit(p.author.name) - try: - SSPatches[p.author.name].append(p) - except KeyError: - SSPatches[p.author.name] = [p] - -def LogECLPatch(p): - LogEmptyCulprit(p.author.name) - try: - EmptyCLPatches[p.author.name].append(p) - except KeyError: - EmptyCLPatches[p.author.name] = [p] - -def LogNoSOB(p): - LogNoSOBCulprit(p.author.name) - try: - NoSOBPatches[p.author.name].append(p) - except KeyError: - NoSOBPatches[p.author.name] = [p] - -LinusURL = 'http://git.kernel.org/linus/' -def WritePatches(names, patches, file): - out = open(file, 'w') - for name in names: - out.write('

%s

\n
    \n' % name) - for p in patches[name]: - out.write('\t
  • %s %s\n' % (LinusURL, - p.commit, - p.commit, - p.desc)) - out.write('
\n\n') - out.close() - -# -# Main program. -# -Npatches = 0 -NemptyCL = 0 - -Nsinglesob = 0 -Nnosob = 0 -Nothers = 0 - -p = gitlog.grabpatch(sys.stdin) -while p: - #print p.commit, len(p.changelog) - Npatches += 1 - if len(p.changelog) == 0: - NemptyCL += 1 - LogECLPatch(p) - if len(p.signoffs) == 0: - Nnosob += 1 - LogNoSOB(p) - elif len(p.signoffs) == 1: - Nsinglesob += 1 - if p.othertags == 0: - LogSSPatch(p) - else: - Nothers += 1 - p = gitlog.grabpatch(sys.stdin) - -print '%d patches, %d w/o changelog' % (Npatches, NemptyCL) -print ' %d w/o signoff, %d w/1 signoff, %d no others, %d SS culprits' % \ - (Nnosob, Nsinglesob, Nsinglesob - Nothers, len(SingleSSCulprits)) -print '\nMost single signoffs:' -sorted = SortedCulprits(SingleSSCulprits)[:20] -PrintCulprits(SingleSSCulprits, sorted) -WritePatches(sorted, SSPatches, 'sspatches.html') - -print '\nMost empty changelogs:' -sorted = SortedCulprits(EmptyCulprits)[:20] -PrintCulprits(EmptyCulprits, sorted) -WritePatches(sorted, EmptyCLPatches, 'emptypatches.html') - -print '\nNoSOB:' -sorted = SortedCulprits(NoSOBCulprits) -PrintCulprits(NoSOBCulprits, sorted) -WritePatches(sorted, NoSOBPatches, 'nosobpatches.html') diff --git a/contrib/git-stats/gitdm/committags b/contrib/git-stats/gitdm/committags deleted file mode 100755 index d01523767..000000000 --- a/contrib/git-stats/gitdm/committags +++ /dev/null @@ -1,101 +0,0 @@ -#!/usr/bin/pypy -# -# Generate a database of commits and major versions they went into. -# -# This is the painfully slow reworked brute-force version that -# takes forever to run, but which hopefully gets the right results -# It has been pretty much superseded by inittags, though. -# -# committags [git-args] -# -# This code is part of the LWN git data miner. -# -# Copyright 2007-13 Eklektix, Inc. -# Copyright 2007-13 Jonathan Corbet -# -# This file may be distributed under the terms of the GNU General -# Public License, version 2. -# -import sys -import re -import os -import pickle -import argparse - -# -# Arg parsing stuff. -# -def setupargs(): - p = argparse.ArgumentParser() - # - # -d for the database - # -l to load it before running - # - p.add_argument('-d', '--database', help = 'Database name', - required = False, default = 'committags.db') - p.add_argument('-l', '--load', help = 'Load database at startup', - default = False, action = 'store_true') - # - # Args for git? - # - p.add_argument('-g', '--git', help = 'Arguments to git', - default = '') - # - # Where's the repo? - # - p.add_argument('-r', '--repository', help = 'Repository location', - default = '') - return p - - -p = setupargs() -args = p.parse_args() - -# -# Pull in an existing database if requested. -# -if args.load: - DB = pickle.load(open(args.database, 'r')) -else: - DB = { } -out = open(args.database, 'w') - -# -# Time to fire up git. -# -git = 'git log --pretty=format:%H ' + args.git -if args.repository: - os.chdir(args.repository) -input = os.popen(git, 'r') - -nc = 0 -for line in input.readlines(): - commit = line.strip() - # - # If we loaded a database and this commit is already there, we - # can quit. - # - if args.load and DB.has_key(commit): - break - # - # Figure out which version this one came from. - # - desc = os.popen('git describe --contains --match v\\* ' + commit, 'r') - tag = desc.readline().strip() - desc.close() - dash = tag.find('-') - if dash > 0: - DB[commit] = tag[:dash] - else: - DB[commit] = tag - # - # Give them something to watch. - # - nc += 1 - if (nc % 25) == 0: - print '%6d %s %s \r' % (nc, commit[:8], tag), - sys.stdout.flush() - -print '\nFound %d/%d commits' % (nc, len(DB.keys())) -pickle.dump(DB, out) -out.close() diff --git a/contrib/git-stats/gitdm/csvdump.py b/contrib/git-stats/gitdm/csvdump.py deleted file mode 100644 index c3f6b5ae2..000000000 --- a/contrib/git-stats/gitdm/csvdump.py +++ /dev/null @@ -1,92 +0,0 @@ -# -# aggregate per-month statistics for people -# -import sys, datetime -import csv - -class CSVStat: - def __init__ (self, name, email, employer, date): - self.name = name - self.email = email - self.employer = employer - self.added = self.removed = self.changesets = 0 - self.date = date - def accumulate (self, p): - self.added = self.added + p.added - self.removed = self.removed + p.removed - self.changesets += 1 - -PeriodCommitHash = { } - -def AccumulatePatch (p, Aggregate): - if (Aggregate == 'week'): - date = "%.2d-%.2d"%(p.date.isocalendar()[0], p.date.isocalendar()[1]) - elif (Aggregate == 'year'): - date = "%.2d"%(p.date.year) - else: - date = "%.2d-%.2d-01"%(p.date.year, p.date.month) - authdatekey = "%s-%s"%(p.author.name, date) - if authdatekey not in PeriodCommitHash: - empl = p.author.emailemployer (p.email, p.date) - stat = CSVStat (p.author.name, p.email, empl, date) - PeriodCommitHash[authdatekey] = stat - else: - stat = PeriodCommitHash[authdatekey] - stat.accumulate (p) - -ChangeSets = [] -FileTypes = [] - -def store_patch(patch): - if not patch.merge: - employer = patch.author.emailemployer(patch.email, patch.date) - employer = employer.name.replace('"', '.').replace ('\\', '.') - author = patch.author.name.replace ('"', '.').replace ('\\', '.') - author = patch.author.name.replace ("'", '.') - try: - domain = patch.email.split('@')[1] - except: - domain = patch.email - ChangeSets.append([patch.commit, str(patch.date), - patch.email, domain, author, employer, - patch.added, patch.removed]) - for (filetype, (added, removed)) in patch.filetypes.iteritems(): - FileTypes.append([patch.commit, filetype, added, removed]) - - -def save_csv (prefix='data'): - # Dump the ChangeSets - if len(ChangeSets) > 0: - fd = open('%s-changesets.csv' % prefix, 'w') - writer = csv.writer (fd, quoting=csv.QUOTE_NONNUMERIC) - writer.writerow (['Commit', 'Date', 'Domain', - 'Email', 'Name', 'Affliation', - 'Added', 'Removed']) - for commit in ChangeSets: - writer.writerow(commit) - - # Dump the file types - if len(FileTypes) > 0: - fd = open('%s-filetypes.csv' % prefix, 'w') - writer = csv.writer (fd, quoting=csv.QUOTE_NONNUMERIC) - - writer.writerow (['Commit', 'Type', 'Added', 'Removed']) - for commit in FileTypes: - writer.writerow(commit) - - - -def OutputCSV (file): - if file is None: - return - writer = csv.writer (file, quoting=csv.QUOTE_NONNUMERIC) - writer.writerow (['Name', 'Email', 'Affliation', 'Date', - 'Added', 'Removed', 'Changesets']) - for date, stat in PeriodCommitHash.items(): - # sanitise names " is common and \" sometimes too - empl_name = stat.employer.name.replace ('"', '.').replace ('\\', '.') - author_name = stat.name.replace ('"', '.').replace ('\\', '.') - writer.writerow ([author_name, stat.email, empl_name, stat.date, - stat.added, stat.removed, stat.changesets]) - -__all__ = [ 'AccumulatePatch', 'OutputCSV', 'store_patch' ] diff --git a/contrib/git-stats/gitdm/database.py b/contrib/git-stats/gitdm/database.py deleted file mode 100644 index cb242c146..000000000 --- a/contrib/git-stats/gitdm/database.py +++ /dev/null @@ -1,322 +0,0 @@ -# -# The "database". -# -# This code is part of the LWN git data miner. -# -# Copyright 2007-11 Eklektix, Inc. -# Copyright 2007-11 Jonathan Corbet -# -# This file may be distributed under the terms of the GNU General -# Public License, version 2. -# -import sys, datetime - - -class Hacker: - def __init__ (self, name, id, elist, email): - self.name = name - self.id = id - self.employer = [ elist ] - self.email = [ email ] - self.changed = self.added = self.removed = 0 - self.patches = [ ] - self.signoffs = [ ] - self.reviews = [ ] - self.tested = [ ] - self.reports = [ ] - self.testcred = self.repcred = 0 - self.versions = [ ] - - def addemail (self, email, elist): - self.email.append (email) - self.employer.append (elist) - HackersByEmail[email] = self - - def emailemployer (self, email, date): - for i in range (0, len (self.email)): - if self.email[i] == email: - for edate, empl in self.employer[i]: - if edate > date: - return empl - print 'OOPS. ', self.name, self.employer, self.email, email, date - return None # Should not happen - - def addpatch (self, patch): - self.added += patch.added - self.removed += patch.removed - self.changed += max(patch.added, patch.removed) - self.patches.append (patch) - - # - # Note that the author is represented in this release. - # - def addversion (self, release): - if release not in self.versions: - self.versions.append (release) - # - # There's got to be a better way. - # - def addsob (self, patch): - self.signoffs.append (patch) - def addreview (self, patch): - self.reviews.append (patch) - def addtested (self, patch): - self.tested.append (patch) - def addreport (self, patch): - self.reports.append (patch) - - def reportcredit (self, patch): - self.repcred += 1 - def testcredit (self, patch): - self.testcred += 1 - -HackersByName = { } -HackersByEmail = { } -HackersByID = { } -MaxID = 0 - -def StoreHacker (name, elist, email): - global MaxID - - id = MaxID - MaxID += 1 - h = Hacker (name, id, elist, email) - HackersByName[name] = h - HackersByEmail[email] = h - HackersByID[id] = h - return h - -def LookupEmail (addr): - try: - return HackersByEmail[addr] - except KeyError: - return None - -def LookupName (name): - try: - return HackersByName[name] - except KeyError: - return None - -def LookupID (id): - try: - return HackersByID[id] - except KeyError: - return None - -def LookupStoreHacker(name, email, mapunknown = True): - email = RemapEmail(email) - h = LookupEmail(email) - if h: # already there - return h - elist = LookupEmployer(email, mapunknown) - h = LookupName(name) - if h: # new email - h.addemail(email, elist) - return h - return StoreHacker(name, elist, email) - - -def AllHackers (): - return HackersByID.values () - -def DumpDB (): - out = open ('database.dump', 'w') - names = HackersByName.keys () - names.sort () - for name in names: - h = HackersByName[name] - out.write ('%4d %s %d p (+%d -%d) sob: %d\n' % (h.id, h.name, - len (h.patches), - h.added, h.removed, - len (h.signoffs))) - for i in range (0, len (h.email)): - out.write ('\t%s -> \n' % (h.email[i])) - for date, empl in h.employer[i]: - out.write ('\t\t %d-%d-%d %s\n' % (date.year, date.month, date.day, - empl.name)) - if h.versions: - out.write ('\tVersions: %s\n' % ','.join (h.versions)) - -# -# Hack: The first visible tag comes a ways into the stream; when we see it, -# push it backward through the changes we've already seen. -# -def ApplyFirstTag (tag): - for n in HackersByName.keys (): - if HackersByName[n].versions: - HackersByName[n].versions = [tag] - -# -# Employer info. -# -class Employer: - def __init__ (self, name): - self.name = name - self.added = self.removed = self.count = self.changed = 0 - self.sobs = 0 - self.hackers = [ ] - - def AddCSet (self, patch): - self.added += patch.added - self.removed += patch.removed - self.changed += max(patch.added, patch.removed) - self.count += 1 - if patch.author not in self.hackers: - self.hackers.append (patch.author) - - def AddSOB (self): - self.sobs += 1 - -Employers = { } - -def GetEmployer (name): - try: - return Employers[name] - except KeyError: - e = Employer (name) - Employers[name] = e - return e - -def AllEmployers (): - return Employers.values () - -# -# Certain obnoxious developers, who will remain nameless (because we -# would never want to run afoul of Thomas) want their work split among -# multiple companies. Let's try to cope with that. Let's also hope -# this doesn't spread. -# -class VirtualEmployer (Employer): - def __init__ (self, name): - Employer.__init__ (self, name) - self.splits = [ ] - - def addsplit (self, name, fraction): - self.splits.append ((name, fraction)) - - # - # Go through and (destructively) apply our credits to the - # real employer. Only one level of weirdness is supported. - # - def applysplits (self): - for name, fraction in self.splits: - real = GetEmployer (name) - real.added += int (self.added*fraction) - real.removed += int (self.removed*fraction) - real.changed += int (self.changed*fraction) - real.count += int (self.count*fraction) - self.__init__ (name) # Reset counts just in case - - def store (self): - if Employers.has_key (self.name): - print Employers[self.name] - sys.stderr.write ('WARNING: Virtual empl %s overwrites another\n' - % (self.name)) - if len (self.splits) == 0: - sys.stderr.write ('WARNING: Virtual empl %s has no splits\n' - % (self.name)) - # Should check that they add up too, but I'm lazy - Employers[self.name] = self - -class FileType: - def __init__ (self, patterns={}, order=[]): - self.patterns = patterns - self.order = order - - def guess_file_type (self, filename, patterns=None, order=None): - patterns = patterns or self.patterns - order = order or self.order - - for file_type in order: - if patterns.has_key (file_type): - for patt in patterns[file_type]: - if patt.search (filename): - return file_type - - return 'unknown' - -# -# By default we recognize nothing. -# -FileTypes = FileType ({}, []) - -# -# Mix all the virtual employers into their real destinations. -# -def MixVirtuals (): - for empl in AllEmployers (): - if isinstance (empl, VirtualEmployer): - empl.applysplits () - -# -# The email map. -# -EmailAliases = { } - -def AddEmailAlias (variant, canonical): - if EmailAliases.has_key (variant): - sys.stderr.write ('Duplicate email alias for %s\n' % (variant)) - EmailAliases[variant] = canonical - -def RemapEmail (email): - email = email.lower () - try: - return EmailAliases[email] - except KeyError: - return email - -# -# Email-to-employer mapping. -# -EmailToEmployer = { } -nextyear = datetime.date.today () + datetime.timedelta (days = 365) - -def AddEmailEmployerMapping (email, employer, end = nextyear): - if end is None: - end = nextyear - email = email.lower () - empl = GetEmployer (employer) - try: - l = EmailToEmployer[email] - for i in range (0, len(l)): - date, xempl = l[i] - if date == end: # probably both nextyear - print 'WARNING: duplicate email/empl for %s' % (email) - if date > end: - l.insert (i, (end, empl)) - return - l.append ((end, empl)) - except KeyError: - EmailToEmployer[email] = [(end, empl)] - -def MapToEmployer (email, unknown = 0): - # Somebody sometimes does s/@/ at /; let's fix it. - email = email.lower ().replace (' at ', '@') - try: - return EmailToEmployer[email] - except KeyError: - pass - namedom = email.split ('@') - if len (namedom) < 2: - print 'Oops...funky email %s' % email - return [(nextyear, GetEmployer ('Funky'))] - s = namedom[1].split ('.') - for dots in range (len (s) - 2, -1, -1): - addr = '.'.join (s[dots:]) - try: - return EmailToEmployer[addr] - except KeyError: - pass - # - # We don't know who they work for. - # - if unknown: - return [(nextyear, GetEmployer ('(Unknown)'))] - return [(nextyear, GetEmployer (email))] - - -def LookupEmployer (email, mapunknown = 0): - elist = MapToEmployer (email, mapunknown) - return elist # GetEmployer (ename) - diff --git a/contrib/git-stats/gitdm/findoldfiles b/contrib/git-stats/gitdm/findoldfiles deleted file mode 100755 index 493d5d3e9..000000000 --- a/contrib/git-stats/gitdm/findoldfiles +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/python -# -# Another quick hack of a script to find files unchanged -# since a given commit. -# -# This code is part of the LWN git data miner. -# -# Copyright 2007-11 Eklektix, Inc. -# Copyright 2007-11 Jonathan Corbet -# -# This file may be distributed under the terms of the GNU General -# Public License, version 2. -# -import sys, os - -OriginalSin = '1da177e4c3f41524e886b7f1b8a0c1fc7321cac2' - -def CheckFile(file): - git = os.popen('git log --pretty=oneline -1 ' + file, 'r') - line = git.readline() - if line.startswith(OriginalSin): - print file - git.close() -# -# Here we just plow through all the files. -# -if len(sys.argv) != 2: - sys.stderr.write('Usage: findoldfiles directory\n') - sys.exit(1) - -os.chdir(sys.argv[1]) -files = os.popen('/usr/bin/find . -type f', 'r') -for file in files.readlines(): - if file.find('.git/') < 0: - CheckFile(file[:-1]) diff --git a/contrib/git-stats/gitdm/firstlast b/contrib/git-stats/gitdm/firstlast deleted file mode 100755 index 2b07952ee..000000000 --- a/contrib/git-stats/gitdm/firstlast +++ /dev/null @@ -1,194 +0,0 @@ -#!/usr/bin/pypy -# -*- python -*- -# -# Crank through the log looking at when developers did their first and -# last patches. -# -# git log | firstlast -v versiondb -# -import argparse, pickle -import sys -import gitlog -import database -import ConfigFile -from utils import accumulator -# -# Arg processing -# -def SetupArgs(): - p = argparse.ArgumentParser() - p.add_argument('-v', '--versiondb', help = 'Version database file', - required = False, default = 'committags.db') - p.add_argument('-c', '--config', help = 'Configuration file', - required = True) - p.add_argument('-d', '--dbdir', help = 'Where to find the config database files', - required = False, default = '') - p.add_argument('-f', '--first', help = 'First version for detailed tracking', - required = False, default = '') - p.add_argument('-l', '--last', help = 'Last version for detailed tracking', - required = False, default = '') - p.add_argument('-m', '--minversions', required = False, default = 1, type = int, - help = 'How many versions an author contributes to for counting') - return p.parse_args() - -# -# Try to track the first directory a new developer touches. -# -FirstDirs = { } - -def TrackFirstDirs(patch): - dirs = [ ] - for file in patch.files: - split = file.split('/') - if split[0] in ['arch', 'drivers', 'fs']: - track = '/'.join(split[0:2]) - else: - track = split[0] - if track not in dirs: - dirs.append(track) - for dir in dirs: - try: - FirstDirs[dir] += 1 - except KeyError: - FirstDirs[dir] = 1 - -def cmpdirs(d1, d2): - return FirstDirs[d2] - FirstDirs[d1] - -def PrintFirstDirs(): - print '\nDirectories touched by first commits:' - dirs = FirstDirs.keys() - dirs.sort(cmpdirs) - for dir in dirs[:20]: - print '%5d: %s' % (FirstDirs[dir], dir) - -# -# Let's also track who they worked for. -# -FirstEmpls = { } - -def TrackFirstEmpl(name): - try: - FirstEmpls[name] += 1 - except KeyError: - FirstEmpls[name] = 1 - -def cmpempls(e1, e2): - return FirstEmpls[e2] - FirstEmpls[e1] - -def PrintFirstEmpls(): - empls = FirstEmpls.keys() - empls.sort(cmpempls) - print '\nEmployers:' - for e in empls[:30]: - print '%5d: %s' % (FirstEmpls[e], e) - # - # We "know" that unknown/none are always the top two... - # - companies = 0 - for e in empls[2:]: - companies += FirstEmpls[e] - print 'Companies: %d' % (companies) - -# -# Version comparison stuff. Kernel-specific, obviously. -# -def die(gripe): - sys.stderr.write(gripe + '\n') - sys.exit(1) - -def versionmap(vers): - split = vers.split('.') - if not (2 <= len(split) <= 4): - die('funky version %s' % (vers)) - if split[0] in ['v2', '2']: - return int(split[2]) - if split[0] in ['v3', '3']: - return 100 + int(split[1]) - if split[0] in ['v4', '4']: - return 120 + int(split[1]) - die('Funky version %s' % (vers)) - -T_First = 0 -T_Last = 999999 - -def SetTrackingVersions(args): - global T_First, T_Last - if args.first: - T_First = versionmap(args.first) - if args.last: - T_Last = versionmap(args.last) - -def TrackingVersion(vers): - return T_First <= versionmap(vers) <= T_Last - -# -# Main program. -# -args = SetupArgs() -VDB = pickle.load(open(args.versiondb, 'r')) -ConfigFile.ConfigFile(args.config, args.dbdir) -SetTrackingVersions(args) - -Firsts = accumulator() -Lasts = accumulator() -Singles = accumulator() -Versions = accumulator() -# -# Read through the full patch stream and collect the relevant info. -# -patch = gitlog.grabpatch(sys.stdin) -while patch: - try: - v = VDB[patch.commit] - except KeyError: - print 'Funky commit', patch.commit - patch = gitlog.grabpatch(sys.stdin) - continue - # - # The first patch we see is the last they committed, since git - # lists things in backwards order. - # - if len(patch.author.patches) == 0: - patch.author.lastvers = v - Lasts.append(v, patch.author) - patch.author.firstvers = v - patch.author.addpatch(patch) - Versions.append(patch.author.id, v, unique = True) - patch = gitlog.grabpatch(sys.stdin) - -# -# Pass over all the hackers we saw and collate stuff. -# -for h in database.AllHackers(): - if len(h.patches) > 0 and len(Versions[h.id]) >= args.minversions: - Firsts.append(h.firstvers, h) - if h.firstvers == h.lastvers: - Singles.incr(h.firstvers) - # - # Track details, but only for versions we care about - # - if TrackingVersion(h.firstvers): - p = h.patches[-1] - TrackFirstDirs(p) - try: - empl = h.emailemployer(p.email, p.date) - except AttributeError: - print 'No email on ', p.commit - continue - if empl.name == '(Unknown)': - print 'UNK: %s %s' % (p.email, h.name) - TrackFirstEmpl(empl.name) - -versions = Lasts.keys() - -def cmpvers(v1, v2): - return versionmap(v1) - versionmap(v2) # reverse sort -versions.sort(cmpvers) -for v in versions: - if args.minversions <= 1: - print v, len(Firsts[v]), len(Lasts[v]), Singles[v] - else: - print v, len(Firsts.get(v, [])), len(Lasts.get(v, [])) -PrintFirstDirs() -PrintFirstEmpls() diff --git a/contrib/git-stats/gitdm/gitdm b/contrib/git-stats/gitdm/gitdm deleted file mode 100755 index c2b20cd98..000000000 --- a/contrib/git-stats/gitdm/gitdm +++ /dev/null @@ -1,571 +0,0 @@ -#!/usr/bin/pypy -#-*- coding:utf-8 -*- -# - -# -# This code is part of the LWN git data miner. -# -# Copyright 2007-13 Eklektix, Inc. -# Copyright 2007-13 Jonathan Corbet -# Copyright 2011 Germán Póo-Caamaño -# -# This file may be distributed under the terms of the GNU General -# Public License, version 2. - - -import database, csvdump, ConfigFile, reports -import getopt, datetime -import os, re, sys, rfc822, string, os.path -import logparser -from patterns import patterns - -Today = datetime.date.today() - -# -# Remember author names we have griped about. -# -GripedAuthorNames = [ ] - -# -# Control options. -# -MapUnknown = 0 -DevReports = 1 -DateStats = 0 -AuthorSOBs = 1 -FileFilter = None -CSVFile = None -CSVPrefix = None -AkpmOverLt = 0 -DumpDB = 0 -CFName = 'gitdm.config' -DirName = '' -Aggregate = 'month' -Numstat = 0 -ReportByFileType = 0 -ReportUnknowns = False -CompanyFilter = None -FileReport = None -# -# Options: -# -# -a Andrew Morton's signoffs shadow Linus's -# -b dir Specify the base directory to fetch the configuration files -# -c cfile Specify a configuration file -# -C company Only consider patches from -# -d Output individual developer stats -# -D Output date statistics -# -f file Write touched-files report to -# -h hfile HTML output to hfile -# -l count Maximum length for output lists -# -n Use numstats instead of generated patch from git log -# -o file File for text output -# -p prefix Prefix for CSV output -# -r pattern Restrict to files matching pattern -# -s Ignore author SOB lines -# -u Map unknown employers to '(Unknown)' -# -U Dump unknown hackers in report -# -x file.csv Export raw statistics as CSV -# -w Aggregrate the raw statistics by weeks instead of months -# -y Aggregrate the raw statistics by years instead of months -# -z Dump out the hacker database at completion - -def ParseOpts(): - global MapUnknown, DevReports - global DateStats, AuthorSOBs, FileFilter, AkpmOverLt, DumpDB - global CFName, CSVFile, CSVPrefix,DirName, Aggregate, Numstat - global ReportByFileType, ReportUnknowns, CompanyFilter, FileReport - - opts, rest = getopt.getopt(sys.argv[1:], 'ab:dC:c:Df:h:l:no:p:r:stUuwx:yz') - for opt in opts: - if opt[0] == '-a': - AkpmOverLt = 1 - elif opt[0] == '-b': - DirName = opt[1] - elif opt[0] == '-C': - CompanyFilter = opt[1] - elif opt[0] == '-c': - CFName = opt[1] - elif opt[0] == '-d': - DevReports = 0 - elif opt[0] == '-D': - DateStats = 1 - elif opt[0] == '-f': - FileReport = opt[1] - elif opt[0] == '-h': - reports.SetHTMLOutput(open(opt[1], 'w')) - elif opt[0] == '-l': - reports.SetMaxList(int(opt[1])) - elif opt[0] == '-n': - Numstat = 1 - elif opt[0] == '-o': - reports.SetOutput(open(opt[1], 'w')) - elif opt[0] == '-p': - CSVPrefix = opt[1] - elif opt[0] == '-r': - print 'Filter on "%s"' % (opt[1]) - FileFilter = re.compile(opt[1]) - elif opt[0] == '-s': - AuthorSOBs = 0 - elif opt[0] == '-t': - ReportByFileType = 1 - elif opt[0] == '-u': - MapUnknown = 1 - elif opt[0] == '-U': - ReportUnknowns = True - elif opt[0] == '-x': - CSVFile = open(opt[1], 'w') - print "open output file " + opt[1] + "\n" - elif opt [0] == '-w': - Aggregate = 'week' - elif opt [0] == '-y': - Aggregate = 'year' - elif opt[0] == '-z': - DumpDB = 1 - -# -# Tracking for file accesses. -# -FileAccesses = { } - -def AddAccess(path): - try: - FileAccesses[path] += 1 - except KeyError: - FileAccesses[path] = 1 - -def NoteFileAccess(paths): - # - # Keep separate track of what we've noted in this set so that each level - # of the tree only gets a single note from one patch. - # - noted = [ ] - for path in paths: - if path.startswith('a/') or path.startswith('b/'): - path = path[2:] - AddAccess(path) - noted.append(path) - path, last = os.path.split(path) - while path and path not in ['a', 'b', '/']: - if path in noted: - break - noted.append(path) - AddAccess(path) - path, last = os.path.split(path) - -# -# Local version still, for now -# -def LookupStoreHacker(name, email): - return database.LookupStoreHacker(name, email, MapUnknown) - -# -# Date tracking. -# - -DateMap = { } - -def AddDateLines(date, lines): - if lines > 1000000: - print 'Skip big patch (%d)' % lines - return - try: - DateMap[date] += lines - except KeyError: - DateMap[date] = lines - -def PrintDateStats(): - dates = DateMap.keys() - dates.sort() - total = 0 - datef = open('datelc.csv', 'w') - datef.write('Date,Changed,Total Changed\n') - for date in dates: - total += DateMap[date] - datef.write('%d/%02d/%02d,%d,%d\n' % (date.year, date.month, date.day, - DateMap[date], total)) - - -# -# Let's slowly try to move some smarts into this class. -# -class patch: - (ADDED, REMOVED) = range(2) - - def __init__(self, commit): - self.commit = commit - self.merge = self.added = self.removed = 0 - self.author = LookupStoreHacker('Unknown hacker', 'unknown@hacker.net') - self.email = 'unknown@hacker.net' - self.sobs = [ ] - self.reviews = [ ] - self.testers = [ ] - self.reports = [ ] - self.filetypes = {} - self.files = [ ] - - def addreviewer(self, reviewer): - self.reviews.append(reviewer) - - def addtester(self, tester): - self.testers.append(tester) - - def addreporter(self, reporter): - self.reports.append(reporter) - - def addfiletype(self, filetype, added, removed): - if self.filetypes.has_key(filetype): - self.filetypes[filetype][self.ADDED] += added - self.filetypes[filetype][self.REMOVED] += removed - else: - self.filetypes[filetype] = [added, removed] - - def addfile(self, name): - self.files.append(name) - - -def parse_numstat(line, file_filter): - """ - Receive a line of text, determine if fits a numstat line and - parse the added and removed lines as well as the file type. - """ - m = patterns['numstat'].match(line) - if m: - filename = m.group(3) - # If we have a file filter, check for file lines. - if file_filter and not file_filter.search(filename): - return None, None, None, None - - try: - added = int(m.group(1)) - removed = int(m.group(2)) - except ValueError: - # A binary file (image, etc.) is marked with '-' - added = removed = 0 - - m = patterns['rename'].match(filename) - if m: - filename = '%s%s%s' % (m.group(1), m.group(3), m.group(4)) - - filetype = database.FileTypes.guess_file_type(os.path.basename(filename)) - return filename, filetype, added, removed - else: - return None, None, None, None - -# -# The core hack for grabbing the information about a changeset. -# -def grabpatch(logpatch): - m = patterns['commit'].match(logpatch[0]) - if not m: - return None - - p = patch(m.group(1)) - ignore = (FileFilter is not None) - need_bline = False - for Line in logpatch[1:]: - # - # Maybe it's an author line? - # - m = patterns['author'].match(Line) - if m: - p.email = database.RemapEmail(m.group(2)) - p.author = LookupStoreHacker(m.group(1), p.email) - continue - # - # Could be a signed-off-by: - # - m = patterns['signed-off-by'].match(Line) - if m: - email = database.RemapEmail(m.group(2)) - sobber = LookupStoreHacker(m.group(1), email) - if sobber != p.author or AuthorSOBs: - p.sobs.append((email, LookupStoreHacker(m.group(1), m.group(2)))) - continue - # - # Various other tags of interest. - # - m = patterns['reviewed-by'].match(Line) - if m: - email = database.RemapEmail(m.group(2)) - p.addreviewer(LookupStoreHacker(m.group(1), email)) - continue - m = patterns['tested-by'].match(Line) - if m: - email = database.RemapEmail(m.group(2)) - p.addtester(LookupStoreHacker(m.group(1), email)) - p.author.testcredit(patch) - continue - # Reported-by: - m = patterns['reported-by'].match(Line) - if m: - email = database.RemapEmail(m.group(2)) - p.addreporter(LookupStoreHacker(m.group(1), email)) - p.author.reportcredit(patch) - continue - # Reported-and-tested-by: - m = patterns['reported-and-tested-by'].match(Line) - if m: - email = database.RemapEmail(m.group(2)) - h = LookupStoreHacker(m.group(1), email) - p.addreporter(h) - p.addtester(h) - p.author.reportcredit(patch) - p.author.testcredit(patch) - continue - # - # If this one is a merge, make note of the fact. - # - m = patterns['merge'].match(Line) - if m: - p.merge = 1 - continue - # - # See if it's the date. - # - m = patterns['date'].match(Line) - if m: - dt = rfc822.parsedate(m.group(2)) - p.date = datetime.date(dt[0], dt[1], dt[2]) - if p.date > Today: - sys.stderr.write('Funky date: %s\n' % p.date) - p.date = Today - continue - if not Numstat: - # - # If we have a file filter, check for file lines. - # - if FileFilter: - ignore = ApplyFileFilter(Line, ignore) - # - # If we are tracking files touched, look for a relevant line here. - # - if FileReport and not ignore: - m = patterns['filea'].match(Line) - if m: - file = m.group(1) - if file == '/dev/null': - need_bline = True - continue - p.addfile(m.group(1)) - continue - elif need_bline: - m = patterns['fileb'].match(Line) - if m: - p.addfile(m.group(1)) - need_bline = False - continue - # - # OK, maybe it's part of the diff itself. - # - if not ignore: - if patterns['add'].match(Line): - p.added += 1 - continue - if patterns['rem'].match(Line): - p.removed += 1 - else: - # - # Grab data in the numstat format. - # - (filename, filetype, added, removed) = parse_numstat(Line, FileFilter) - if filename: - p.added += added - p.removed += removed - p.addfiletype(filetype, added, removed) - p.addfile(filename) - - if '@' in p.author.name: - GripeAboutAuthorName(p.author.name) - - return p - -def GripeAboutAuthorName(name): - if name in GripedAuthorNames: - return - GripedAuthorNames.append(name) - print '%s is an author name, probably not what you want' % (name) - -def ApplyFileFilter(line, ignore): - # - # If this is the first file line (--- a/), set ignore one way - # or the other. - # - m = patterns['filea'].match(line) - if m: - file = m.group(1) - if FileFilter.search(file): - return 0 - return 1 - # - # For the second line, we can turn ignore off, but not on - # - m = patterns['fileb'].match(line) - if m: - file = m.group(1) - if FileFilter.search(file): - return 0 - return ignore - -def is_svntag(logpatch): - """ - This is a workaround for a bug on the migration to Git - from Subversion found in GNOME. It may happen in other - repositories as well. - """ - - for Line in logpatch: - m = patterns['svn-tag'].match(Line.strip()) - if m: - sys.stderr.write('(W) detected a commit on a svn tag: %s\n' % - (m.group(0),)) - return True - - return False - -# -# If this patch is signed off by both Andrew Morton and Linus Torvalds, -# remove the (redundant) Linus signoff. -# -def TrimLTSOBs(p): - if AkpmOverLt == 1 and Linus in p.sobs and Akpm in p.sobs: - p.sobs.remove(Linus) - - -# -# Here starts the real program. -# -ParseOpts() - -# -# Read the config files. -# -ConfigFile.ConfigFile(CFName, DirName) - -# -# Let's pre-seed the database with a couple of hackers -# we want to remember. -# -if AkpmOverLt == 1: - Linus = ('torvalds@linux-foundation.org', - LookupStoreHacker('Linus Torvalds', 'torvalds@linux-foundation.org')) - Akpm = ('akpm@linux-foundation.org', - LookupStoreHacker('Andrew Morton', 'akpm@linux-foundation.org')) - -TotalChanged = TotalAdded = TotalRemoved = 0 - -# -# Snarf changesets. -# -print >> sys.stderr, 'Grabbing changesets...\r', - -patches = logparser.LogPatchSplitter(sys.stdin) -printcount = CSCount = 0 - -for logpatch in patches: - if (printcount % 50) == 0: - print >> sys.stderr, 'Grabbing changesets...%d\r' % printcount, - printcount += 1 - - # We want to ignore commits on svn tags since in Subversion - # thats mean a copy of the whole repository, which leads to - # wrong results. Some migrations from Subversion to Git does - # not catch all this tags/copy and import them just as a new - # big changeset. - if is_svntag(logpatch): - continue - - p = grabpatch(logpatch) - if not p: - break -# if p.added > 100000 or p.removed > 100000: -# print 'Skipping massive add', p.commit -# continue - if FileFilter and p.added == 0 and p.removed == 0: - continue - # - # Apply the company filter if it exists. - # - empl = p.author.emailemployer(p.email, p.date) - if CompanyFilter and empl.name != CompanyFilter: - continue - # - # Now note the file accesses if need be. - # - if FileReport: - NoteFileAccess(p.files) - # - # Record some global information - but only if this patch had - # stuff which wasn't ignored. - # - if ((p.added + p.removed) > 0 or not FileFilter) and not p.merge: - TotalAdded += p.added - TotalRemoved += p.removed - TotalChanged += max(p.added, p.removed) - AddDateLines(p.date, max(p.added, p.removed)) - empl.AddCSet(p) - if AkpmOverLt: - TrimLTSOBs(p) - for sobemail, sobber in p.sobs: - empl = sobber.emailemployer(sobemail, p.date) - empl.AddSOB() - - if not p.merge: - p.author.addpatch(p) - for sobemail, sob in p.sobs: - sob.addsob(p) - for hacker in p.reviews: - hacker.addreview(p) - for hacker in p.testers: - hacker.addtested(p) - for hacker in p.reports: - hacker.addreport(p) - CSCount += 1 - csvdump.AccumulatePatch(p, Aggregate) - csvdump.store_patch(p) -print >> sys.stderr, 'Grabbing changesets...done ' - -if DumpDB: - database.DumpDB() -database.MixVirtuals() - -# -# Say something -# -hlist = database.AllHackers() -elist = database.AllEmployers() -ndev = nempl = 0 -for h in hlist: - if len(h.patches) > 0: - ndev += 1 -for e in elist: - if e.count > 0: - nempl += 1 -reports.Write('Processed %d csets from %d developers\n' % (CSCount, - ndev)) -reports.Write('%d employers found\n' % (nempl)) -reports.Write('A total of %d lines added, %d removed (delta %d)\n' % - (TotalAdded, TotalRemoved, TotalAdded - TotalRemoved)) -if TotalChanged == 0: - TotalChanged = 1 # HACK to avoid div by zero -if DateStats: - PrintDateStats() - -if CSVPrefix: - csvdump.save_csv(CSVPrefix) - -if CSVFile: - csvdump.OutputCSV(CSVFile) - CSVFile.close() - -if DevReports: - reports.DevReports(hlist, TotalChanged, CSCount, TotalRemoved) -if ReportUnknowns: - reports.ReportUnknowns(hlist, CSCount) -reports.EmplReports(elist, TotalChanged, CSCount) - -if ReportByFileType and Numstat: - reports.ReportByFileType(hlist) - -if FileReport: - reports.FileAccessReport(FileReport, FileAccesses, CSCount) diff --git a/contrib/git-stats/gitdm/gitdm.config b/contrib/git-stats/gitdm/gitdm.config deleted file mode 100644 index 3ae2f20ea..000000000 --- a/contrib/git-stats/gitdm/gitdm.config +++ /dev/null @@ -1,27 +0,0 @@ -# -# This is a sample gitdm configuration file. -# - -# -# EmailAliases lets us cope with developers who use more -# than one address. -# -EmailAliases sample-config/aliases - -# -# EmailMap does the main work of mapping addresses onto -# employers. -# -EmailMap sample-config/domain-map - -# -# Use GroupMap to map a file full of addresses to the -# same employer -# -# GroupMap sample-config/illuminati The Illuminati -# -# -# Use FileTypeMap to map a file types to file names using regular -# regular expressions. -# -FileTypeMap sample-config/filetypes.txt diff --git a/contrib/git-stats/gitdm/gitlog.py b/contrib/git-stats/gitdm/gitlog.py deleted file mode 100644 index 8b8d52356..000000000 --- a/contrib/git-stats/gitdm/gitlog.py +++ /dev/null @@ -1,204 +0,0 @@ -# -# Stuff for dealing with the git log output. -# -# Someday this will be the only version of grabpatch, honest. -# -import re, rfc822, datetime -from patterns import patterns -import database - - -# -# Input file handling. Someday it would be good to make this smarter -# so that it handles running git with the right options and such. -# -# Someday. -# -SavedLine = '' - -def getline(input): - global SavedLine - if SavedLine: - ret = SavedLine - SavedLine = '' - return ret - l = input.readline() - if l: - return l.rstrip() - return None - -def SaveLine(line): - global SavedLine - SavedLine = line - -# -# A simple state machine based on where we are in the patch. The -# first stuff we get is the header. -# -S_HEADER = 0 -# -# Then comes the single-line description. -# -S_DESC = 1 -# -# ...the full changelog... -# -S_CHANGELOG = 2 -# -# ...the tag section.... -# -S_TAGS = 3 -# -# ...the numstat section. -# -S_NUMSTAT = 4 - -S_DONE = 5 - -# -# The functions to handle each of these states. -# -def get_header(patch, line, input): - if line == '': - if patch.author == '': - print 'Funky auth line in', patch.commit - patch.author = database.LookupStoreHacker('Unknown', - 'unknown@hacker.net') - return S_DESC - m = patterns['author'].match(line) - if m: - patch.email = database.RemapEmail(m.group(2)) - patch.author = database.LookupStoreHacker(m.group(1), patch.email) - else: - m = patterns['date'].match(line) - if m: - dt = rfc822.parsedate(m.group(2)) - patch.date = datetime.date(dt[0], dt[1], dt[2]) - return S_HEADER - -def get_desc(patch, line, input): - if not line: - print 'Missing desc in', patch.commit - return S_CHANGELOG - patch.desc = line - line = getline(input) - while line: - patch.desc += line - line = getline(input) - return S_CHANGELOG - -tagline = re.compile(r'^\s+(([-a-z]+-by)|cc):.*@.*$', re.I) -def get_changelog(patch, line, input): - if not line: - if patch.templog: - patch.changelog += patch.templog - patch.templog = '' - if patterns['commit'].match(line): - # No changelog at all - usually a Linus tag - SaveLine(line) - return S_DONE - elif tagline.match(line): - if patch.templog: - patch.changelog += patch.templog - return get_tag(patch, line, input) - else: - patch.templog += line + '\n' - return S_CHANGELOG - -def get_tag(patch, line, input): - # - # Some people put blank lines in the middle of tags. - # - if not line: - return S_TAGS - # - # A new commit line says we've gone too far. - # - if patterns['commit'].match(line): - SaveLine(line) - return S_DONE - # - # Check for a numstat line - # - if patterns['numstat'].match(line): - return get_numstat(patch, line, input) - # - # Look for interesting tags - # - m = patterns['signed-off-by'].match(line) - if m: - patch.signoffs.append(m.group(2)) - else: - # - # Look for other tags indicating that somebody at least - # looked at the patch. - # - for tag in ('acked-by', 'reviewed-by', 'tested-by'): - if patterns[tag].match(line): - patch.othertags += 1 - break - return S_TAGS - -def get_numstat(patch, line, input): - m = patterns['numstat'].match(line) - if not m: - return S_DONE - try: - patch.addfile(int(m.group(1)), int(m.group(2)), m.group(3)) - # - # Binary files just have "-" in the line fields. In this case, set - # the counts to zero so that we at least track that the file was - # touched. - # - except ValueError: - patch.addfile(0, 0, m.group(3)) - return S_NUMSTAT - -grabbers = [ get_header, get_desc, get_changelog, get_tag, get_numstat ] - - -# -# A variant on the gitdm patch class. -# -class patch: - def __init__(self, commit): - self.commit = commit - self.desc = '' - self.changelog = '' - self.templog = '' - self.author = '' - self.signoffs = [ ] - self.othertags = 0 - self.added = self.removed = 0 - self.files = [ ] - - def addfile(self, added, removed, file): - self.added += added - self.removed += removed - self.files.append(file) - -def grabpatch(input): - # - # If it's not a patch something is screwy. - # - line = getline(input) - if line is None: - return None - m = patterns['commit'].match(line) - if not m: - print 'noncommit', line - return None - p = patch(m.group(1)) - state = S_HEADER - # - # Crank through the patch. - # - while state != S_DONE: - line = getline(input) - if line is None: - if state != S_NUMSTAT: - print 'Ran out of patch', state - return None - return p - state = grabbers[state](p, line, input) - return p diff --git a/contrib/git-stats/gitdm/grabdates b/contrib/git-stats/gitdm/grabdates deleted file mode 100755 index 31557924e..000000000 --- a/contrib/git-stats/gitdm/grabdates +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/pypy -# -*- python -*- -# -# git log | grep '^Date:' | grabdates -# -import sys -from utils import accumulator - -tzs = accumulator() - -for line in sys.stdin.readlines(): - split = line.split() - if split[0] != 'Date:': - print 'Funky line: ', line - sys.exit(1) - zone = int(split[-1]) - tzs.incr(zone) - -zones = tzs.keys() -zones.sort() -for zone in zones: - print '%05d %d' % (zone, tzs[zone]) diff --git a/contrib/git-stats/gitdm/inittags b/contrib/git-stats/gitdm/inittags deleted file mode 100755 index 3e8291372..000000000 --- a/contrib/git-stats/gitdm/inittags +++ /dev/null @@ -1,82 +0,0 @@ -#!/usr/bin/pypy -# -*- python -*- -# -# Generate a database of commits and major versions they went into. -# -# A brute-force quickish way of mapping commits to major versions -# -# This code is part of the LWN git data miner. -# -# Copyright 2007-13 Eklektix, Inc. -# Copyright 2007-13 Jonathan Corbet -# -# This file may be distributed under the terms of the GNU General -# Public License, version 2. -# -import sys -import re -import os -import pickle -import argparse - -# -# Arg parsing stuff. -# -def setupargs(): - p = argparse.ArgumentParser() - # - # -d for the database - # -l to load it before running - # - p.add_argument('-d', '--database', help = 'Database name', - required = False, default = 'committags.db') - p.add_argument('-l', '--load', help = 'Load database at startup', - default = False, action = 'store_true') - # - # Where's the repo? - # - p.add_argument('-r', '--repository', help = 'Repository location', - default = '') - p.add_argument('-v', '--version', help = 'Current dev version', - required = True, type = int) - return p - - -p = setupargs() -args = p.parse_args() - -# -# Pull in an existing database if requested. -# -if args.load: - DB = pickle.load(open(args.database, 'r')) -else: - DB = { } -out = open(args.database, 'w') -if args.repository: - os.chdir(args.repository) - -def GetCommits(range, tag): - git = 'git log --pretty=format:%H ' + range - input = os.popen(git, 'r') - for line in input.readlines(): - DB[line.strip()] = tag - input.close() - -initial = '1da177e4c3f41524e886b7f1b8a0c1fc7321cac2' -DB[initial] = 'v2.6.12' -GetCommits('1da177e4c3f41524e886b7f1b8a0c1fc7321cac2..v2.6.12', 'v2.6.12') -for v in range(13, 40): - GetCommits('v2.6.%d..v2.6.%d' % (v - 1, v), 'v2.6.%d' % (v)) -GetCommits('v2.6.39..v3.0', 'v3.0') -for v in range(1, 20): - GetCommits('v3.%d..v3.%d' % (v - 1, v), 'v3.%d' % (v)) -GetCommits('v3.19..v4.0', 'v4.0') -final = args.version -for v in range(1, final): - GetCommits('v4.%d..v4.%d' % (v - 1, v), 'v4.%d' % (v)) -GetCommits('v4.%d..' % (final - 1), 'v4.%d' % (final)) - -print '\nFound %d commits' % (len(DB.keys())) -pickle.dump(DB, out) -out.close() diff --git a/contrib/git-stats/gitdm/linetags b/contrib/git-stats/gitdm/linetags deleted file mode 100755 index 5106be23b..000000000 --- a/contrib/git-stats/gitdm/linetags +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/pypy -# -# Find out how many lines were introduced in each major release. -# -# linetags -# -# This code is part of the LWN git data miner. -# -# Copyright 2007-11 Eklektix, Inc. -# Copyright 2007-11 Jonathan Corbet -# -# This file may be distributed under the terms of the GNU General -# Public License, version 2. -# -import sys, re, os, pickle - -CommitLines = { } - -commitpat = re.compile(r'^([\da-f][\da-f]+) ') - -def GetCommitLines(file): - print file - blame = os.popen('git blame -p ' + file, 'r') - for line in blame.readlines(): - m = commitpat.search(line) - # - # All-zero commits mean we got fed a file that git doesn't - # know about. We could throw an exception and abort processing - # now, or we can just silently ignore it... - # - if not m or m.group(1) == '0000000000000000000000000000000000000000': - continue - try: - CommitLines[m.group(1)] += 1 - except KeyError: - CommitLines[m.group(1)] = 1 - blame.close() - -# -# Try to figure out which tag is the first to contain each commit. -# -refpat = re.compile(r'^(v2\.6\.\d\d).*$') -def CommitToTag(commit): - try: - return DB[commit] - except KeyError: - print 'Missing commit %s' % (commit) - return 'WTF?' - -TagLines = { } -def MapCommits(): - print 'Mapping tags...' - for commit in CommitLines.keys(): - tag = CommitToTag(commit) - try: - TagLines[tag] += CommitLines[commit] - except KeyError: - TagLines[tag] = CommitLines[commit] - -# -# Here we just plow through all the files. -# -if len(sys.argv) != 2: - sys.stderr.write('Usage: linetags directory\n') - sys.exit(1) -# -# Grab the tags/version database. -# -dbf = open('committags.db', 'r') -DB = pickle.load(dbf) -dbf.close() - -out = open('linetags.out', 'w') -os.chdir(sys.argv[1]) -files = os.popen('/usr/bin/find . -type f', 'r') -for file in files.readlines(): - if file.find('.git/') < 0: - GetCommitLines(file[:-1]) -MapCommits() -# print TagLines -tags = TagLines.keys() -tags.sort() -for tag in tags: - out.write('%s %d\n' % (tag, TagLines[tag])) -out.close() diff --git a/contrib/git-stats/gitdm/logparser.py b/contrib/git-stats/gitdm/logparser.py deleted file mode 100644 index b375034a4..000000000 --- a/contrib/git-stats/gitdm/logparser.py +++ /dev/null @@ -1,90 +0,0 @@ -#!/usr/bin/env python -#-*- coding:utf-8 -*- -# -# Copyright © 2009 Germán Póo-Caamaño -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Library General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - -import sys -from patterns import patterns - -class LogPatchSplitter: - """ - LogPatchSplitters provides a iterator to extract every - changeset from a git log output. - - Typical use case: - - patches = LogPatchSplitter(sys.stdin) - - for patch in patches: - parse_patch(patch) - """ - - def __init__(self, fd): - self.fd = fd - self.buffer = None - self.patch = [] - - def __iter__(self): - return self - - def next(self): - patch = self.__grab_patch__() - if not patch: - raise StopIteration - return patch - - def __grab_patch__(self): - """ - Extract a patch from the file descriptor and the - patch is returned as a list of lines. - """ - - patch = [] - line = self.buffer or self.fd.readline() - - while line: - m = patterns['commit'].match(line) - if m: - patch = [line] - break - line = self.fd.readline() - - if not line: - return None - - line = self.fd.readline() - while line: - # If this line starts a new commit, drop out. - m = patterns['commit'].match(line) - if m: - self.buffer = line - break - - patch.append(line) - self.buffer = None - line = self.fd.readline() - - return patch - - -if __name__ == '__main__': - patches = LogPatchSplitter(sys.stdin) - - for patch in patches: - print '---------- NEW PATCH ----------' - for line in patch: - print line, diff --git a/contrib/git-stats/gitdm/patterns.py b/contrib/git-stats/gitdm/patterns.py deleted file mode 100644 index df56d6baf..000000000 --- a/contrib/git-stats/gitdm/patterns.py +++ /dev/null @@ -1,53 +0,0 @@ -# -# -*- coding:utf-8 -*- -# Pull together regular expressions used in multiple places. -# -# This code is part of the LWN git data miner. -# -# Copyright 2007-11 Eklektix, Inc. -# Copyright 2007-11 Jonathan Corbet -# Copyright 2011 Germán Póo-Caamaño -# -# This file may be distributed under the terms of the GNU General -# Public License, version 2. -# -import re - -# -# Some people, when confronted with a problem, think "I know, I'll use regular -# expressions." Now they have two problems. -# -- Jamie Zawinski -# -_pemail = r'\s+"?([^<]+)"?\s<([^>]+)>' # just email addr + name - -patterns = { - 'tagcommit': re.compile (r'^commit ([\da-f]+) .*tag: (v[23]\.\d(\.\d\d?)?)'), - 'commit': re.compile (r'^commit ([0-9a-f ]+)'), - 'author': re.compile (r'^Author:' + _pemail + '$'), - 'signed-off-by': re.compile (r'^\s+signed-off-by:' + _pemail + '.*$', re.I), - 'merge': re.compile (r'^Merge:.*$'), - 'add': re.compile (r'^\+[^+].*$'), - 'rem': re.compile (r'^-[^-].*$'), - 'date': re.compile (r'^(Commit)?Date:\s+(.*)$'), - # filea, fileb are used only in 'parche mode' (-p) - 'filea': re.compile (r'^---\s+(.*)$'), - 'fileb': re.compile (r'^\+\+\+\s+(.*)$'), - 'acked-by': re.compile (r'^\s+Acked-by:' + _pemail+ '.*$'), - 'reviewed-by': re.compile (r'^\s+Reviewed-by:' + _pemail+ '.*$'), - 'tested-by': re.compile (r'^\s+tested-by:' + _pemail + '.*$', re.I), - 'reported-by': re.compile (r'^\s+Reported-by:' + _pemail + '.*$'), - 'reported-and-tested-by': re.compile (r'^\s+reported-and-tested-by:' + _pemail + '.*$', re.I), - # - # Merges are described with a variety of lines. - # - 'ExtMerge': re.compile(r'^ +Merge( (branch|branches|tag|tags) .* of)? ([^ ]+:[^ ]+)( into .*)?\n$'), - 'IntMerge': re.compile(r'^ +(Merge|Pull) .* into .*$'), - # PIntMerge2 = re.compile(r"^ +Merge branch(es)? '.*$"), - 'IntMerge2': re.compile(r"^ +Merge .*$"), - # Another way to get the statistics (per file). - # It implies --numstat - 'numstat': re.compile('^(\d+|-)\s+(\d+|-)\s+(.*)$'), - 'rename' : re.compile('(.*)\{(.*) => (.*)\}(.*)'), - # Detect errors on svn conversions - 'svn-tag': re.compile("^svn path=/tags/(.*)/?; revision=([0-9]+)$"), -} diff --git a/contrib/git-stats/gitdm/reports.py b/contrib/git-stats/gitdm/reports.py deleted file mode 100644 index 1c707d01e..000000000 --- a/contrib/git-stats/gitdm/reports.py +++ /dev/null @@ -1,463 +0,0 @@ -# -# A new home for the reporting code. -# -# This code is part of the LWN git data miner. -# -# Copyright 2007-13 Eklektix, Inc. -# Copyright 2007-13 Jonathan Corbet -# -# This file may be distributed under the terms of the GNU General -# Public License, version 2. -# - -import sys - -Outfile = sys.stdout -HTMLfile = None -ListCount = 999999 - - -def SetOutput(file): - global Outfile - Outfile = file - -def SetHTMLOutput(file): - global HTMLfile - HTMLfile = file - -def SetMaxList(max): - global ListCount - ListCount = max - - -def Write(stuff): - Outfile.write(stuff) - - - -# -# HTML output support stuff. -# -HTMLclass = 0 -HClasses = ['Even', 'Odd'] - -THead = '''

- - -''' - -def BeginReport(title): - global HTMLclass - - Outfile.write('\n%s\n' % title) - if HTMLfile: - HTMLfile.write(THead % title) - HTMLclass = 0 - -TRow = ''' - -''' - -TRowStr = ''' - -''' - -def ReportLine(text, count, pct): - global HTMLclass - if count == 0: - return - Outfile.write ('%-25s %4d (%.1f%%)\n' % (text, count, pct)) - if HTMLfile: - HTMLfile.write(TRow % (HClasses[HTMLclass], text, count, pct)) - HTMLclass ^= 1 - -def ReportLineStr(text, count, extra): - global HTMLclass - if count == 0: - return - Outfile.write ('%-25s %4d %s\n' % (text, count, extra)) - if HTMLfile: - HTMLfile.write(TRowStr % (HClasses[HTMLclass], text, count, extra)) - HTMLclass ^= 1 - -def EndReport(): - if HTMLfile: - HTMLfile.write('
%s
%s%d%.1f%%
%s%d%s
\n\n') - -# -# Comparison and report generation functions. -# -def ComparePCount(h1, h2): - return len(h2.patches) - len(h1.patches) - -def ReportByPCount(hlist, cscount): - hlist.sort(ComparePCount) - count = 0 - BeginReport('Developers with the most changesets') - for h in hlist: - pcount = len(h.patches) - changed = max(h.added, h.removed) - delta = h.added - h.removed - if pcount > 0: - ReportLine(h.name, pcount, (pcount*100.0)/cscount) - count += 1 - if count >= ListCount: - break - EndReport() - -def CompareLChanged(h1, h2): - return h2.changed - h1.changed - -def ReportByLChanged(hlist, totalchanged): - hlist.sort(CompareLChanged) - count = 0 - BeginReport('Developers with the most changed lines') - for h in hlist: - pcount = len(h.patches) - if h.changed > 0: - ReportLine(h.name, h.changed, (h.changed*100.0)/totalchanged) - count += 1 - if count >= ListCount: - break - EndReport() - -def CompareLRemoved(h1, h2): - return (h2.removed - h2.added) - (h1.removed - h1.added) - -def ReportByLRemoved(hlist, totalremoved): - hlist.sort(CompareLRemoved) - count = 0 - BeginReport('Developers with the most lines removed') - for h in hlist: - pcount = len(h.patches) - changed = max(h.added, h.removed) - delta = h.added - h.removed - if delta < 0: - ReportLine(h.name, -delta, (-delta*100.0)/totalremoved) - count += 1 - if count >= ListCount: - break - EndReport() - -def CompareEPCount(e1, e2): - return e2.count - e1.count - -def ReportByPCEmpl(elist, cscount): - elist.sort(CompareEPCount) - count = 0 - BeginReport('Top changeset contributors by employer') - for e in elist: - if e.count != 0: - ReportLine(e.name, e.count, (e.count*100.0)/cscount) - count += 1 - if count >= ListCount: - break - EndReport() - - -def CompareELChanged(e1, e2): - return e2.changed - e1.changed - -def ReportByELChanged(elist, totalchanged): - elist.sort(CompareELChanged) - count = 0 - BeginReport('Top lines changed by employer') - for e in elist: - if e.changed != 0: - ReportLine(e.name, e.changed, (e.changed*100.0)/totalchanged) - count += 1 - if count >= ListCount: - break - EndReport() - - - -def CompareSOBs(h1, h2): - return len(h2.signoffs) - len(h1.signoffs) - -def ReportBySOBs(hlist): - hlist.sort(CompareSOBs) - totalsobs = 0 - for h in hlist: - totalsobs += len(h.signoffs) - count = 0 - BeginReport('Developers with the most signoffs (total %d)' % totalsobs) - for h in hlist: - scount = len(h.signoffs) - if scount > 0: - ReportLine(h.name, scount, (scount*100.0)/totalsobs) - count += 1 - if count >= ListCount: - break - EndReport() - -# -# Reviewer reporting. -# -def CompareRevs(h1, h2): - return len(h2.reviews) - len(h1.reviews) - -def ReportByRevs(hlist): - hlist.sort(CompareRevs) - totalrevs = 0 - for h in hlist: - totalrevs += len(h.reviews) - count = 0 - BeginReport('Developers with the most reviews (total %d)' % totalrevs) - for h in hlist: - scount = len(h.reviews) - if scount > 0: - ReportLine(h.name, scount, (scount*100.0)/totalrevs) - count += 1 - if count >= ListCount: - break - EndReport() - -# -# tester reporting. -# -def CompareTests(h1, h2): - return len(h2.tested) - len(h1.tested) - -def ReportByTests(hlist): - hlist.sort(CompareTests) - totaltests = 0 - for h in hlist: - totaltests += len(h.tested) - count = 0 - BeginReport('Developers with the most test credits (total %d)' % totaltests) - for h in hlist: - scount = len(h.tested) - if scount > 0: - ReportLine(h.name, scount, (scount*100.0)/totaltests) - count += 1 - if count >= ListCount: - break - EndReport() - -def CompareTestCred(h1, h2): - return h2.testcred - h1.testcred - -def ReportByTestCreds(hlist): - hlist.sort(CompareTestCred) - totaltests = 0 - for h in hlist: - totaltests += h.testcred - count = 0 - BeginReport('Developers who gave the most tested-by credits (total %d)' % totaltests) - for h in hlist: - if h.testcred > 0: - ReportLine(h.name, h.testcred, (h.testcred*100.0)/totaltests) - count += 1 - if count >= ListCount: - break - EndReport() - - - -# -# Reporter reporting. -# -def CompareReports(h1, h2): - return len(h2.reports) - len(h1.reports) - -def ReportByReports(hlist): - hlist.sort(CompareReports) - totalreps = 0 - for h in hlist: - totalreps += len(h.reports) - count = 0 - BeginReport('Developers with the most report credits (total %d)' % totalreps) - for h in hlist: - scount = len(h.reports) - if scount > 0: - ReportLine(h.name, scount, (scount*100.0)/totalreps) - count += 1 - if count >= ListCount: - break - EndReport() - -def CompareRepCred(h1, h2): - return h2.repcred - h1.repcred - -def ReportByRepCreds(hlist): - hlist.sort(CompareRepCred) - totalreps = 0 - for h in hlist: - totalreps += h.repcred - count = 0 - BeginReport('Developers who gave the most report credits (total %d)' % totalreps) - for h in hlist: - if h.repcred > 0: - ReportLine(h.name, h.repcred, (h.repcred*100.0)/totalreps) - count += 1 - if count >= ListCount: - break - EndReport() - -# -# Versions. -# -def CompareVersionCounts(h1, h2): - if h1.versions and h2.versions: - return len(h2.versions) - len(h1.versions) - if h2.versions: - return 1 - if h1.versions: - return -1 - return 0 - -def MissedVersions(hv, allv): - missed = [v for v in allv if v not in hv] - missed.reverse() - return ' '.join(missed) - -def ReportVersions(hlist): - hlist.sort(CompareVersionCounts) - BeginReport('Developers represented in the most kernel versions') - count = 0 - allversions = hlist[0].versions - for h in hlist: - ReportLineStr(h.name, len(h.versions), MissedVersions(h.versions, allversions)) - count += 1 - if count >= ListCount: - break - EndReport() - - -def CompareESOBs(e1, e2): - return e2.sobs - e1.sobs - -def ReportByESOBs(elist): - elist.sort(CompareESOBs) - totalsobs = 0 - for e in elist: - totalsobs += e.sobs - count = 0 - BeginReport('Employers with the most signoffs (total %d)' % totalsobs) - for e in elist: - if e.sobs > 0: - ReportLine(e.name, e.sobs, (e.sobs*100.0)/totalsobs) - count += 1 - if count >= ListCount: - break - EndReport() - -def CompareHackers(e1, e2): - return len(e2.hackers) - len(e1.hackers) - -def ReportByEHackers(elist): - elist.sort(CompareHackers) - totalhackers = 0 - for e in elist: - totalhackers += len(e.hackers) - count = 0 - BeginReport('Employers with the most hackers (total %d)' % totalhackers) - for e in elist: - nhackers = len(e.hackers) - if nhackers > 0: - ReportLine(e.name, nhackers, (nhackers*100.0)/totalhackers) - count += 1 - if count >= ListCount: - break - EndReport() - - -def DevReports(hlist, totalchanged, cscount, totalremoved): - ReportByPCount(hlist, cscount) - ReportByLChanged(hlist, totalchanged) - ReportByLRemoved(hlist, totalremoved) - ReportBySOBs(hlist) - ReportByRevs(hlist) - ReportByTests(hlist) - ReportByTestCreds(hlist) - ReportByReports(hlist) - ReportByRepCreds(hlist) - -def EmplReports(elist, totalchanged, cscount): - ReportByPCEmpl(elist, cscount) - ReportByELChanged(elist, totalchanged) - ReportByESOBs(elist) - ReportByEHackers(elist) - -# -# Who are the unknown hackers? -# -def IsUnknown(h): - empl = h.employer[0][0][1].name - return h.email[0] == empl or empl == '(Unknown)' - -def ReportUnknowns(hlist, cscount): - # - # Trim the list to just the unknowns; try to work properly whether - # mapping to (Unknown) is happening or not. - # - ulist = [ h for h in hlist if IsUnknown(h) ] - ulist.sort(ComparePCount) - count = 0 - BeginReport('Developers with unknown affiliation') - for h in ulist: - pcount = len(h.patches) - if pcount > 0: - ReportLine(h.name, pcount, (pcount*100.0)/cscount) - count += 1 - if count >= ListCount: - break - EndReport() - - - -def ReportByFileType(hacker_list): - total = {} - total_by_hacker = {} - - BeginReport('Developer contributions by type') - for h in hacker_list: - by_hacker = {} - for patch in h.patches: - # Get a summary by hacker - for (filetype, (added, removed)) in patch.filetypes.iteritems(): - if by_hacker.has_key(filetype): - by_hacker[filetype][patch.ADDED] += added - by_hacker[filetype][patch.REMOVED] += removed - else: - by_hacker[filetype] = [added, removed] - - # Update the totals - if total.has_key(filetype): - total[filetype][patch.ADDED] += added - total[filetype][patch.REMOVED] += removed - else: - total[filetype] = [added, removed, []] - - # Print a summary by hacker - print h.name - for filetype, counters in by_hacker.iteritems(): - print '\t', filetype, counters - h_added = by_hacker[filetype][patch.ADDED] - h_removed = by_hacker[filetype][patch.REMOVED] - total[filetype][2].append([h.name, h_added, h_removed]) - - # Print the global summary - BeginReport('Contributions by type and developers') - for filetype, (added, removed, hackers) in total.iteritems(): - print filetype, added, removed - for h, h_added, h_removed in hackers: - print '\t%s: [%d, %d]' % (h, h_added, h_removed) - - # Print the very global summary - BeginReport('General contributions by type') - for filetype, (added, removed, hackers) in total.iteritems(): - print filetype, added, removed - -# -# The file access report is a special beast. -# -def FileAccessReport(name, accesses, total): - outf = open(name, 'w') - files = accesses.keys() - files.sort() - for file in files: - a = accesses[file] - outf.write('%6d %6.1f%% %s\n' % (a, (100.0*a)/total, file)) - outf.close() diff --git a/contrib/git-stats/gitdm/sample-config/aliases b/contrib/git-stats/gitdm/sample-config/aliases deleted file mode 100644 index 8cd50db3e..000000000 --- a/contrib/git-stats/gitdm/sample-config/aliases +++ /dev/null @@ -1,5 +0,0 @@ -# -# This is the email aliases file, mapping secondary addresses -# onto a single, canonical address. -# -corbet@eklektix.com corbet@lwn.net diff --git a/contrib/git-stats/gitdm/sample-config/domain-map b/contrib/git-stats/gitdm/sample-config/domain-map deleted file mode 100644 index 28ff88aca..000000000 --- a/contrib/git-stats/gitdm/sample-config/domain-map +++ /dev/null @@ -1,308 +0,0 @@ -# -# Here is a set of mappings of domain names onto employer names. -# -5etech.eu 5e Technologies -8d.com 8D Technologies -aconex.com Aconex -adaptec.com Adaptec -addi-data.com ADDI-DATA GmbH -aist.go.jp National Institute of Advanced Industrial Science and Technology -akamai.com Akamai Technologies -amd.com AMD -am.sony.com Sony -anagramm.de Anagramm GmbH -analog.com Analog Devices -android.com Google -arastra.com Arastra Inc -areca.com.tw Areca -arm.com ARM -artecdesign.ee Artec Design -arvoo.nl ARVOO Engineering -atmel.com Atmel -atomide.com Atomide -avtrex.com Avtrex -axis.com Axis Communications -azingo.com Azingo -balabit.com BalaBit -balabit.hu BalaBit -baslerweb.com Basler Vision Technologies -bay.ws Bay -bitwagon.com BitWagon Software -bivio.net Bivio Networking -bluegiga.com Bluegiga -bluehost.com Bluehost -bluewatersys.com Bluewater Systems -boeing.com Boeing -boundarydevices.com Boundary Devices -broadcom.com Broadcom -brontes3d.com Brontes Technologies -bull.net Bull SAS -cam.ac.uk University of Cambridge -ccur.com Concurrent Computer Corporation -cdi.cz CDI.CZ -celestrius.com Celestrius -celunite.com Azingo -centtech.com Centaur Technology -chelsio.com Chelsio -cisco.com Cisco -citi.umich.edu Univ. of Michigan CITI -citrix.com Citrix -clustcom.com Cluster Computing -clusterfs.com Sun -cn.fujitsu.com Fujitsu -compulab.co.il CompuLab -computergmbh.de CC Computer Consultants -comx.dk ComX Networks -conectiva.com.br Mandriva -coraid.com Coraid -cosmosbay.com Cosmosbay~Vectis -cozybit.com cozybit -cray.com Cray -cse-semaphore.com CSE Semaphore -csr.com CSR -cyberguard.com Secure Computing -cybernetics.com Cybernetics -data.slu.se Uppsala University -dave.eu Dave S.r.l. -de.bosch.com Bosch -dell.com Dell -denx.de DENX Software Engineering -devicescape.com Devicescape -digi.com Digi International -dti2.net DTI2 - Desarrollo de la tecnologia de las comunicaciones -edesix.com Edesix Ltd -einstruction.com eInstruction -eke.fi EKE-Electronics -elandigitalsystems.com Elan Digital Systems -elpa.it ELPA -embeddedalley.com Embedded Alley Solutions -emcraft.com EmCraft Systems -empirix.com Empirix -emulex.com Emulex -endrelia.com Endrelia -enea.com ENEA AB -ericsson.com Ericsson -escient.com Escient -esd-electronics.com ESD Electronics -esd.eu ESD Electronics -fastmail.fm FastMail.FM -fixstars.com Fixstars Technologies -free-electrons.com Free Electrons -freescale.com Freescale -fujitsu.com Fujitsu -gaisler.com Gaisler Research -gefanuc.com GE Fanuc -geomatys.fr Geomatys -google.com Google -gvs.co.yu GVS -hansenpartnership.com Hansen Partnership -harris.com Harris Corporation -hauppauge.com Hauppauge -hermes-softlab.com HERMES SoftLab -hevs.ch HES-SO Valais Wallis -highpoint-tech.com HighPoint Technologies -hitachi.co.jp Hitachi -hitachi.com Hitachi -hitachisoft.jp Hitachi -hp.com HP -huawei.com Huawei Technologies -hvsistemas.es HV Sistemas -ibm.com IBM -ibp.de ipb (uk) Ltd. -icplus.com.tw IC Plus -igel.co.jp igel -indt.org.br INdT -indt.org INdT -inl.fr INL -inria.fr INRIA -intel.com Intel -intellitree.com IntelliTree Solutions -intra2net.com Intra2net AG -iram.es IRAM -jmicron.com jmicron.com -jp.fujitsu.com Fujitsu -katalix.com Katalix Systems -keyspan.com InnoSys -laptop.org OLPC -laurelnetworks.com ECI Telecom -linutronix.de linutronix -linuxant.com Linuxant -linux-foundation.org Linux Foundation -linx.net London Internet Exchange -lippert-at.de LiPPERT Embedded Computers GmbH -lippertembedded.de LiPPERT Embedded Computers GmbH -llnl.gov Lawrence Livermore National Laboratory -lnxi.com Linux Networx -logitech.com Logitech -lsi.com LSI Logic -lsil.com LSI Logic -lwn.net LWN.net -macqel.be Macq Electronique -macqel.com Macq Electronique -mandriva.com Mandriva -mandriva.com.br Mandriva -marvell.com Marvell -mellanox.co.il Mellanox -melware.de Cytronics & Melware -mev.co.uk MEV Limited -microgate.com MicroGate Systems -mips.com MIPS -miraclelinux.com Miracle Linux -mn-solutions.de M&N Solutions -moreton.com.au Secure Computing -motorola.com Motorola -movial.fi Movial -mpc-data.co.uk MPC Data -msi.com.tw Micro-Star International -mvista.com MontaVista -myri.com Myricom -namesys.com NameSys -nec.co.jp NEC -nec.com NEC -netapp.com NetApp -neteffect.com NetEffect -neterion.com Neterion -netxen.com NetXen -niasdigital.com Nias Digital -niif.hu NIIF Institute -nokia.com Nokia -nomadgs.com Nomad Global Solutions -nortel.com Nortel -novell.com Novell -nrl.navy.mil U.S. Naval Research Laboratory -ntt.co.jp NTT -ntts.co.jp NTT -nuovasystems.com Nuova Systems -nvidia.com NVidia -nvtl.com Novatel Wireless -obsidianresearch.com Obsidian Research -oce.com Océ Technologies -octant-fr.com Octant Informatique -onelan.co.uk ONELAN -onstor.com Onstor -openedhand.com OpenedHand -opengridcomputing.com Open Grid Computing -openmoko.org OpenMoko -openvz.org Parallels -oracle.com Oracle -ornl.gov Oak Ridge National Laboratory -osdl.org Linux Foundation -ozlabs.org IBM -panasas.com Panasas -panasonic.com Panasonic -papercut.bz PaperCut Software -papercut.com PaperCut Software -parallels.com Parallels -pasemi.com PA Semi Corporation -pcs.de PCS Systemtechnik -pengutronix.de Pengutronix -pheonix.com Phoeonix -philosys.de Philosys Software -pikatech.com PIKA Technologies -pikron.com PiKRON s.r.o -pmc-sierra.com PMC-Sierra -profusion.mobi ProFUSION -promise.com Promise Technology -promwad.com Promwad -protei.ru Protei ltd -qlogic.com QLogic -qumranet.com Qumranet -rdc.com.tw RDC Semiconductor -realtek.com.tw Realtek -redhat.com Red Hat -reliablesolutions.de reliablesolutions -renesas.com Renesas Technology -road.de ROAD -rockwell.com Rockwell -rojant.com Rajant -rowland.harvard.edu Rowland Institute, Harvard -rtr.ca Real-Time Remedies -sagem.com Sagem Defense Sécurité -samsung.com Samsung -sanpeople.com SANPeople -savantav.com Savant Systems -secretlab.ca Secretlab -securecomputing.com Secure Computing -semihalf.com Semihalf Embedded Systems -sf-tec.de Science Fiction Technologies -sgi.com SGI -sicortex.com Sicortex -siemens.com Siemens -sierrawireless.com Sierra Wireless -sigma-chemnitz.de SIGMA Chemnitz -snapgear.com Snapgear -softwarefreedom.org Software Freedom Law Center -solarflare.com Solarflare Communications -solidboot.com Solid Boot Ltd. -sony.co.jp Sony -sonycom.com Sony -sony.com Sony -southpole.se South Pole AB -spidernet.net SpiderNet Services -starentnetworks.com Starent Networks -st.com ST Microelectronics -steeleye.com SteelEye -stlinux.com ST Microelectronics -sun.com Sun -suse.com Novell -suse.cz Novell -suse.de Novell -sw.ru Parallels -swsoft.com Parallels -tapsys.com Tapestry Systems -taskit.de taskit -telargo.com Telargo -teleca.com Teleca -tensilica.com Tensilica -terascala.com Terascala -thinktube.com Thinktube -thot-soft.com Thot-Soft 2002 -ti.com Texas Instruments -til-technologies.fr TIL Technologies -tls.msk.ru Telecom-Service -toptica.com TOPTICA Photonics -toshiba.co.jp Toshiba -total-knowledge.com Total Knowledge -towertech.it Tower Technologies -tpi.com TriplePoint -transitive.com Transitive -transmode.se Transmode Systems -tresys.com Tresys -trinnov.com Trinnov Audio -tripeaks.co.jp Tripeaks -trustedcs.com Trusted Computer Solutions -tundra.com Tundra Semiconductor -tungstengraphics.com Tungsten Graphics -tycho.nsa.gov US National Security Agency -ubuntu.com Canonical -uhulinux.hu UHU-Linux -unicontrol.de Unicontrol Systemtechnik -unisys.com Unisys -uq.edu.au University of Queensland -us.ibm.com IBM -valinux.co.jp VA Linux Systems Japan -verismonetworks.com Verismo -veritas.com Veritas -vernier.com Vernier Software and Technology -via.com.tw Via -vivecode.com Vivecode -vmware.com VMWare -volkswagen.de Volkswagen -voltaire.com Voltaire -vpop.net vpop.net -vt.edu Virginia Tech -vyatta.com Vyatta -wabtec.com Wabtec Railway Electronics -wacom.com Wacom -winbond.com Winbond Electronics -winbond.com.tw Winbond Electronics -wincor-nixdorf.com Wincor Nixdorf -windriver.com Wind River -wipro.com Wipro -wolfsonmicro.com Wolfson Microelectronics -xensource.com XenSource -xes-inc.com Extreme Engineering Solutions -xilinx.com Xilinx -xiv.co.il XIV Information Systems -xivstorage.com XIV Information Systems -yahoo-inc.com Yahoo diff --git a/contrib/git-stats/gitdm/sample-config/filetypes.txt b/contrib/git-stats/gitdm/sample-config/filetypes.txt deleted file mode 100644 index e24c396b4..000000000 --- a/contrib/git-stats/gitdm/sample-config/filetypes.txt +++ /dev/null @@ -1,362 +0,0 @@ -# -*- coding:utf-8 -*- -# Copyright (C) 2006 Libresoft -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Library General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# Authors : Gregorio Robles -# Authors : Germán Póo-Caamaño -# -# This file contains associations parameters regarding filetypes -# (documentation, develompent, multimedia, images...) -# -# format: -# filetype [] -# -# Order: -# The list should keep an order, so filetypes can be counted properly. -# ie. we want ltmain.sh -> 'build' instead of 'code'. -# -# If there is an filetype which is not in order but has values, it will -# be added at the end. -# -order image,translation,ui,multimedia,package,build,code,documentation,devel-doc -# -# -# Code files (headers and the like included -# (most common languages first -# -filetype code \.c$ # C -filetype code \.pc$ # C -filetype code \.ec$ # C -filetype code \.ecp$ # C -filetype code \.C$ # C++ -filetype code \.cpp$ # C++ -filetype code \.c\+\+$ # C++ -filetype code \.cxx$ # C++ -filetype code \.cc$ # C++ -filetype code \.pcc$ # C++ -filetype code \.cpy$ # C++ -filetype code \.h$ # C or C++ header -filetype code \.hh$ # C++ header -filetype code \.hpp$ # C++ header -filetype code \.hxx$ # C++ header -filetype code \.sh$ # Shell -filetype code \.pl$ # Perl -filetype code \.pm$ # Perl -filetype code \.pod$ # Perl -filetype code \.perl$ # Perl -filetype code \.cgi$ # CGI -filetype code \.php$ # PHP -filetype code \.php3$ # PHP -filetype code \.php4$ # PHP -filetype code \.inc$ # PHP -filetype code \.py$ # Python -filetype code \.java$ # Java -filetype code \.class$ # Java Class (or at least a class in some OOPL -filetype code \.ada$ # ADA -filetype code \.ads$ # ADA -filetype code \.adb$ # ADA -filetype code \.pad$ # ADA -filetype code \.s$ # Assembly -filetype code \.S$ # Assembly -filetype code \.asm$ # Assembly -filetype code \.awk$ # awk -filetype code \.cs$ # C# -filetype code \.csh$ # CShell (including tcsh -filetype code \.cob$ # COBOL -filetype code \.cbl$ # COBOL -filetype code \.COB$ # COBOL -filetype code \.CBL$ # COBOL -filetype code \.exp$ # Expect -filetype code \.l$ # (F lex -filetype code \.ll$ # (F lex -filetype code \.lex$ # (F lex -filetype code \.f$ # Fortran -filetype code \.f77$ # Fortran -filetype code \.F$ # Fortran -filetype code \.hs$ # Haskell -filetype code \.lhs$ # Not preprocessed Haskell -filetype code \.el$ # LISP (including Scheme -filetype code \.scm$ # LISP (including Scheme -filetype code \.lsp$ # LISP (including Scheme -filetype code \.jl$ # LISP (including Scheme -filetype code \.ml$ # ML -filetype code \.ml3$ # ML -filetype code \.m3$ # Modula3 -filetype code \.i3$ # Modula3 -filetype code \.m$ # Objective-C -filetype code \.p$ # Pascal -filetype code \.pas$ # Pascal -filetype code \.rb$ # Ruby -filetype code \.sed$ # sed -filetype code \.tcl$ # TCL -filetype code \.tk$ # TCL -filetype code \.itk$ # TCL -filetype code \.y$ # Yacc -filetype code \.yy$ # Yacc -filetype code \.idl$ # CORBA IDL -filetype code \.gnorba$ # GNOME CORBA IDL -filetype code \.oafinfo$ # GNOME OAF -filetype code \.mcopclass$ # MCOP IDL compiler generated class -filetype code \.autoforms$ # Autoform -filetype code \.atf$ # Autoform -filetype code \.gnuplot$ -filetype code \.xs$ # Shared library? Seen a lot of them in gnome-perl -filetype code \.js$ # JavaScript (and who knows, maybe more -filetype code \.patch$ -filetype code \.diff$ # Sometimes patches appear this way -filetype code \.ids$ # Not really sure what this means -filetype code \.upd$ # ¿¿¿??? (from Kcontrol -filetype code $.ad$ # ¿¿¿??? (from Kdisplay and mc -filetype code $.i$ # Appears in the kbindings for Qt -filetype code $.pri$ # from Qt -filetype code \.schema$ # Not really sure what this means -filetype code \.fd$ # Something to do with latex -filetype code \.cls$ # Something to do with latex -filetype code \.pro$ # Postscript generation -filetype code \.ppd$ # PDF generation -filetype code \.dlg$ # Not really sure what this means -filetype code \.plugin$ # Plug-in file -filetype code \.dsp # Microsoft Developer Studio Project File -filetype code \.vim$ # vim syntax file -filetype code \.trm$ # gnuplot term file -filetype code \.font$ # Font mapping -filetype code \.ccg$ # C++ files - Found in gtkmm* -filetype code \.hg$ # C++ headers - Found in gtkmm* -filetype code \.dtd # XML Document Type Definition -filetype code \.bat # DOS batch files -filetype code \.vala # Vala -filetype code \.py\.in$ -filetype code \.rhtml$ # eRuby -filetype code \.sql$ # SQL script -# -# -# Development documentation files (for hacking generally -# -filetype devel-doc ^readme.*$ -filetype devel-doc ^changelog.* -filetype devel-doc ^todo.*$ -filetype devel-doc ^credits.*$ -filetype devel-doc ^authors.*$ -filetype devel-doc ^changes.*$ -filetype devel-doc ^news.*$ -filetype devel-doc ^install.*$ -filetype devel-doc ^hacking.*$ -filetype devel-doc ^copyright.*$ -filetype devel-doc ^licen(s|c)e.*$ -filetype devel-doc ^copying.*$ -filetype devel-doc manifest$ -filetype devel-doc faq$ -filetype devel-doc building$ -filetype devel-doc howto$ -filetype devel-doc design$ -filetype devel-doc \.files$ -filetype devel-doc files$ -filetype devel-doc subdirs$ -filetype devel-doc maintainers$ -filetype devel-doc developers$ -filetype devel-doc contributors$ -filetype devel-doc thanks$ -filetype devel-doc releasing$ -filetype devel-doc test$ -filetype devel-doc testing$ -filetype devel-doc build$ -filetype devel-doc comments?$ -filetype devel-doc bugs$ -filetype devel-doc buglist$ -filetype devel-doc problems$ -filetype devel-doc debug$ -filetype devel-doc hacks$ -filetype devel-doc hacking$ -filetype devel-doc versions?$ -filetype devel-doc mappings$ -filetype devel-doc tips$ -filetype devel-doc ideas?$ -filetype devel-doc spec$ -filetype devel-doc compiling$ -filetype devel-doc notes$ -filetype devel-doc missing$ -filetype devel-doc done$ -filetype devel-doc \.omf$ # XML-based format used in GNOME -filetype devel-doc \.lsm$ -filetype devel-doc ^doxyfile$ -filetype devel-doc \.kdevprj$ -filetype devel-doc \.directory$ -filetype devel-doc \.dox$ -filetype devel-doc \.doap$ -# -# -# Building, compiling, configuration and CVS admin files -# -filetype build \.in.*$ -filetype build configure.*$ -filetype build makefile.*$ -filetype build config\.sub$ -filetype build config\.guess$ -filetype build config\.status$ -filetype build ltmain\.sh$ -filetype build autogen\.sh$ -filetype build config$ -filetype build conf$ -filetype build cvsignore$ -filetype build \.cfg$ -filetype build \.m4$ -filetype build \.mk$ -filetype build \.mak$ -filetype build \.make$ -filetype build \.mbx$ -filetype build \.protocol$ -filetype build \.version$ -filetype build mkinstalldirs$ -filetype build install-sh$ -filetype build rules$ -filetype build \.kdelnk$ -filetype build \.menu$ -filetype build linguas$ # Build translations -filetype build potfiles.*$ # Build translations -filetype build \.shlibs$ # Shared libraries -# filetype build %debian% -# filetype build %specs/% -filetype build \.spec$ # It seems theyre necessary for RPM build -filetype build \.def$ # build bootstrap for DLLs on win32 -# -# -# Documentation files -# -# filetype documentation doc/% -# filetype documentation %HOWTO% -filetype documentation \.html$ -filetype documentation \.txt$ -filetype documentation \.ps(\.gz|\.bz2)?$ -filetype documentation \.dvi(\.gz|\.bz2)?$ -filetype documentation \.lyx$ -filetype documentation \.tex$ -filetype documentation \.texi$ -filetype documentation \.pdf(\.gz|\.bz2)?$ -filetype documentation \.djvu$ -filetype documentation \.epub$ -filetype documentation \.sgml$ -filetype documentation \.docbook$ -filetype documentation \.wml$ -filetype documentation \.xhtml$ -filetype documentation \.phtml$ -filetype documentation \.shtml$ -filetype documentation \.htm$ -filetype documentation \.rdf$ -filetype documentation \.phtm$ -filetype documentation \.tmpl$ -filetype documentation \.ref$ # References -filetype documentation \.css$ -# filetype documentation %tutorial% -filetype documentation \.templates$ -filetype documentation \.dsl$ -filetype documentation \.ent$ -filetype documentation \.xml$ -filetype documentation \.xmi$ -filetype documentation \.xsl$ -filetype documentation \.entities$ -filetype documentation \.[1-7]$ # Man pages -filetype documentation \.man$ -filetype documentation \.manpages$ -filetype documentation \.doc$ -filetype documentation \.rtf$ -filetype documentation \.wpd$ -filetype documentation \.qt3$ -filetype documentation man\d?/.*\.\d$ -filetype documentation \.docs$ -filetype documentation \.sdw$ # OpenOffice.org Writer document -filetype documentation \.odt$ # OpenOffice.org document -filetype documentation \.en$ # Files in English language -filetype documentation \.de$ # Files in German -filetype documentation \.es$ # Files in Spanish -filetype documentation \.fr$ # Files in French -filetype documentation \.it$ # Files in Italian -filetype documentation \.cz$ # Files in Czech -filetype documentation \.page$ # Mallard -filetype documentation \.page.stub$ # Mallard stub -# -# -# Images -# -filetype image \.png$ -filetype image \.jpg$ -filetype image \.jpeg$ -filetype image \.bmp$ -filetype image \.gif$ -filetype image \.xbm$ -filetype image \.eps$ -filetype image \.mng$ -filetype image \.pnm$ -filetype image \.pbm$ -filetype image \.ppm$ -filetype image \.pgm$ -filetype image \.gbr$ -filetype image \.svg$ -filetype image \.fig$ -filetype image \.tif$ -filetype image \.swf$ -filetype image \.svgz$ -filetype image \.shape$ # XML files used for shapes for instance in Kivio -filetype image \.sml$ # XML files used for shapes for instance in Kivio -filetype image \.bdf$ # vfontcap - Vector Font Capability Database (VFlib Version 2 -filetype image \.ico$ -filetype image \.dia$ # We consider .dia as images, I dont want them in unknown -# -# -# Translation files -# -filetype translation \.po$ -filetype translation \.pot$ -filetype translation \.charset$ -filetype translation \.mo$ -# -# -# User interface files -# -filetype ui \.desktop$ -filetype ui \.ui$ -filetype ui \.xpm$ -filetype ui \.xcf$ -filetype ui \.3ds$ -filetype ui \.theme$ -filetype ui \.kimap$ -filetype ui \.glade$ -filetype ui \.gtkbuilder$ -filetype ui rc$ -# -# -# Sound files -# -filetype multimedia \.mp3$ -filetype multimedia \.ogg$ -filetype multimedia \.wav$ -filetype multimedia \.au$ -filetype multimedia \.mid$ -filetype multimedia \.vorbis$ -filetype multimedia \.midi$ -filetype multimedia \.arts$ -# -# -# Packages (yes, there are people who upload packages to the repo) -# -filetype package \.tar$ -filetype package \.tar.gz$ -filetype package \.tar.bz2$ -filetype package \.tar.xz$ -filetype package \.tgz$ -filetype package \.deb$ -filetype package \.rpm$ -filetype package \.srpm$ -filetype package \.ebuild$ diff --git a/contrib/git-stats/gitdm/sample-config/xorg/gitdm.config-xserver b/contrib/git-stats/gitdm/sample-config/xorg/gitdm.config-xserver deleted file mode 100644 index 1a3526c4f..000000000 --- a/contrib/git-stats/gitdm/sample-config/xorg/gitdm.config-xserver +++ /dev/null @@ -1,23 +0,0 @@ -# -# This is a sample gitdm configuration file for X.org xserver -# - -# -# EmailAliases lets us cope with developers who use more -# than one address. -# -EmailAliases sample-config/aliases - -# -# EmailMap does the main work of mapping addresses onto -# employers. -# -EmailMap sample-config/domain-map - -# -# Use GroupMap to map a file full of addresses to the -# same employer -# -GroupMap sample-config/xorg/group-map-intel Intel -GroupMap sample-config/xorg/group-map-redhat Red Hat -GroupMap sample-config/xorg/group-map-apple Apple diff --git a/contrib/git-stats/gitdm/sample-config/xorg/group-map-apple b/contrib/git-stats/gitdm/sample-config/xorg/group-map-apple deleted file mode 100644 index 46e1f0402..000000000 --- a/contrib/git-stats/gitdm/sample-config/xorg/group-map-apple +++ /dev/null @@ -1 +0,0 @@ -jeremyhu@apple.com diff --git a/contrib/git-stats/gitdm/sample-config/xorg/group-map-intel b/contrib/git-stats/gitdm/sample-config/xorg/group-map-intel deleted file mode 100644 index 4a2a098ee..000000000 --- a/contrib/git-stats/gitdm/sample-config/xorg/group-map-intel +++ /dev/null @@ -1,4 +0,0 @@ -keithp@keithp.com -krh@bitplanet.net -jbarnes@virtuousgeek.org -chris@chris-wilson.co.uk diff --git a/contrib/git-stats/gitdm/sample-config/xorg/group-map-redhat b/contrib/git-stats/gitdm/sample-config/xorg/group-map-redhat deleted file mode 100644 index c71b3fd21..000000000 --- a/contrib/git-stats/gitdm/sample-config/xorg/group-map-redhat +++ /dev/null @@ -1 +0,0 @@ -peter.hutterer@who-t.net diff --git a/contrib/git-stats/gitdm/tests/expected-datelc b/contrib/git-stats/gitdm/tests/expected-datelc deleted file mode 100644 index f65ea9209..000000000 --- a/contrib/git-stats/gitdm/tests/expected-datelc +++ /dev/null @@ -1,2 +0,0 @@ -2009/12/03 27 27 -2009/12/15 14 41 diff --git a/contrib/git-stats/gitdm/tests/expected-results.txt b/contrib/git-stats/gitdm/tests/expected-results.txt deleted file mode 100644 index 049f8878b..000000000 --- a/contrib/git-stats/gitdm/tests/expected-results.txt +++ /dev/null @@ -1,46 +0,0 @@ -Processed 10 csets from 4 developers -4 employers found -A total of 24 lines added, 24 removed (delta 0) - -Developers with the most changesets -Martin Nordholts 6 (60.0%) -Random Joe 2 (20.0%) -Line Remover 1 (10.0%) -Punk Rocker 1 (10.0%) - -Developers with the most changed lines -Line Remover 14 (34.1%) -Random Joe 13 (31.7%) -Martin Nordholts 10 (24.4%) -Punk Rocker 1 (2.4%) - -Developers with the most lines removed -Line Remover 14 (58.3%) - -Developers with the most signoffs (total 2) -Martin Nordholts 2 (100.0%) - -Developers with the most reviews (total 0) - -Developers with the most test credits (total 0) - -Developers who gave the most tested-by credits (total 0) - -Developers with the most report credits (total 0) - -Developers who gave the most report credits (total 0) - -Top changeset contributors by employer -enselic@gmail.com 6 (60.0%) -random.joe@example.com 2 (20.0%) -line.remover@bogus.bo 1 (10.0%) -punk.rocker@example.com 1 (10.0%) - -Top lines changed by employer -line.remover@bogus.bo 14 (34.1%) -enselic@gmail.com 13 (31.7%) -random.joe@example.com 13 (31.7%) -punk.rocker@example.com 1 (2.4%) - -Employers with the most signoffs (total 2) -enselic@gmail.com 2 (100.0%) diff --git a/contrib/git-stats/gitdm/tests/gitdm-tests.py b/contrib/git-stats/gitdm/tests/gitdm-tests.py deleted file mode 100755 index a68003ead..000000000 --- a/contrib/git-stats/gitdm/tests/gitdm-tests.py +++ /dev/null @@ -1,129 +0,0 @@ -#!/usr/bin/python -# - -# -# This code is part of the LWN git data miner. -# -# Copyright 2009 Martin Nordholts -# -# This file may be distributed under the terms of the GNU General -# Public License, version 2. - -import unittest, subprocess, os - -class GitdmTests(unittest.TestCase): - - ## - # Setup test fixture. - # - def setUp(self): - self.srcdir = os.getcwd () - self.git_dir = os.path.join (self.srcdir, "tests/testrepo") - if not os.path.exists (self.git_dir): - self.fail ("'" + self.git_dir + "' didn't exist, you probably "+ - "didn't run the test with the source root as the working directory.") - - - ## - # Makes sure that the statistics collected for the test repository - # is the expected statistics. Note that the test must be run with - # the working directory as the source root and with git in the - # PATH. - # - def testResultOutputRegressionTest(self): - - # Build paths - actual_results_path = os.path.join (self.srcdir, "tests/actual-results.txt") - expected_results_path = os.path.join (self.srcdir, "tests/expected-results.txt") - - # Run actual test - self.runOutputFileRegressionTest (expected_results_path, - actual_results_path, - ["-o", actual_results_path]) - - - ## - # Does a regression test on the datelc (data line count) file - # - def testDateLineCountOutputRegressionTest(self): - - # Build paths - actual_datelc_path = os.path.join (self.srcdir, "datelc") - expected_datelc_path = os.path.join (self.srcdir, "tests/expected-datelc") - - # Run actual test - self.runOutputFileRegressionTest (expected_datelc_path, - actual_datelc_path, - ["-D"]) - - - ## - # Run a test, passing path to file with expected output, path to - # file which will countain the actual output, and arguments to - # pass to gitdm. We both make sure the file where the result will - # be put when gitdm is run does not exist beforehand, and we clean - # up after we are done. - # - def runOutputFileRegressionTest(self, expected_output_path, actual_output_path, arguments): - - # Make sure we can safely run the test - self.ensureFileDoesNotExist (actual_output_path) - - try: - # Collect statistics - self.runGitdm (arguments) - - # Make sure we got the result we expected - self.assertFilesEqual (expected_output_path, actual_output_path) - - finally: - # Remove any file we created, also if test fails - self.purgeFile (actual_output_path) - - - ## - # If passed file exists, delete it. - # - def purgeFile(self, filename): - if os.path.exists (filename): - os.remove (filename) - - - ## - # Make sure the file does not exist so we don't risk overwriting - # an important file. - # - def ensureFileDoesNotExist(self, filename): - if os.path.exists (filename): - self.fail ("The file '" + filename + "' exists, failing " - "test to avoid overwriting file.") - - - ## - # Run gitdm on the test repository with the passed arguments. - # - def runGitdm(self, arguments): - git_log_process = subprocess.Popen (["git", "--git-dir", self.git_dir, "log", "-p", "-M"], - stdout=subprocess.PIPE) - gitdm_process = subprocess.Popen (["./gitdm"] + arguments, - stdin=git_log_process.stdout) - gitdm_process.communicate () - - - ## - # Makes sure the files have the same content. - # - def assertFilesEqual(self, file1, file2): - f = open (file1, 'r') - file1_contents = f.read () - f.close () - f = open (file2, 'r') - file2_contents = f.read () - f.close () - self.assertEqual (file1_contents, file2_contents, - "The files '" + file1 + "' and '" + - file2 + "' were not equal!") - - -if __name__ == '__main__': - unittest.main () diff --git a/contrib/git-stats/gitdm/tests/testrepo/HEAD b/contrib/git-stats/gitdm/tests/testrepo/HEAD deleted file mode 100644 index cb089cd89..000000000 --- a/contrib/git-stats/gitdm/tests/testrepo/HEAD +++ /dev/null @@ -1 +0,0 @@ -ref: refs/heads/master diff --git a/contrib/git-stats/gitdm/tests/testrepo/config b/contrib/git-stats/gitdm/tests/testrepo/config deleted file mode 100644 index 96ecd4486..000000000 --- a/contrib/git-stats/gitdm/tests/testrepo/config +++ /dev/null @@ -1,6 +0,0 @@ -[core] - repositoryformatversion = 0 - filemode = true - bare = true -[gc] - pruneexpire = now diff --git a/contrib/git-stats/gitdm/tests/testrepo/info/refs b/contrib/git-stats/gitdm/tests/testrepo/info/refs deleted file mode 100644 index 84de6b61e..000000000 --- a/contrib/git-stats/gitdm/tests/testrepo/info/refs +++ /dev/null @@ -1 +0,0 @@ -2a3beb7042492ce6a0dc88ed59d04633b08b7bbc refs/heads/master diff --git a/contrib/git-stats/gitdm/tests/testrepo/objects/info/packs b/contrib/git-stats/gitdm/tests/testrepo/objects/info/packs deleted file mode 100644 index 8638101cf..000000000 --- a/contrib/git-stats/gitdm/tests/testrepo/objects/info/packs +++ /dev/null @@ -1,2 +0,0 @@ -P pack-f62fb949b32db1bccdc300fc13de20bca92b4c01.pack - diff --git a/contrib/git-stats/gitdm/tests/testrepo/objects/pack/pack-f62fb949b32db1bccdc300fc13de20bca92b4c01.idx b/contrib/git-stats/gitdm/tests/testrepo/objects/pack/pack-f62fb949b32db1bccdc300fc13de20bca92b4c01.idx deleted file mode 100644 index 09c10995304705a114d2389eaf953001b4e4cd8c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1912 zcmexg;-AdGz`z8=Fu(|8pkt6cH83;K92Ojy6)27kvjN3Hm>r5afHXGD2^5E6E+88l z<_3!6!#qHFLYNn*h7`;PRF97NfnvC@08ow`EC|#mOhqgLGz)}9X@JFnW>ShJfMyVb zC4uVbg{6RYQG%s``eo3tERatPEC)0PCuZV)ZI-Yr%$-|F3CrIh<*gEZ}JD$Xc@Sf92G9GgLPx)+i=amw6GGgoQ?LIH^?SWyKk5kG+mZr``VV$iD zq#qwBl@V%;-fy<-!m{=*`BReDoF{yceBf)iFe%E7Il#d)W`nD0LBX+`Gk9O^HZI72 zsdTx#aMqn&0#+yHFW$>kP*+sQIIAVf_i(G&2_I&r=AyFQ%m3?Xr6I08t zmWR0q)Qq>yT$S74!f*CXCT6ep!-_}Rc^`u+g1y}LFRG6WUAAba_NLR%=02Le>EbnK z?{3X?gU;im!|OIgUQYgFlP5 zTke#ap?{mT`Q@5|9S_(hR^OB5qFim4j7^dH;pH*4F4>W*9!=VIi7ViDUKxYt zk5tWAU{$aih_iszmM^gC@Bmf^g+P7>u0D*(lSn5zkhf$F%n0{KsY)np4$T{Tc0&Dawt#k9I-J%NF~ylLLAB_!+&0LvYdlK=n! diff --git a/contrib/git-stats/gitdm/tests/testrepo/objects/pack/pack-f62fb949b32db1bccdc300fc13de20bca92b4c01.pack b/contrib/git-stats/gitdm/tests/testrepo/objects/pack/pack-f62fb949b32db1bccdc300fc13de20bca92b4c01.pack deleted file mode 100644 index 14ab4dbdf3a1a7d2d651507454383d17239d406d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2883 zcmZ{lc{~%28^<@=)V^#>QV}9K%MnGE=4KX~Gjfa^Im%JV%(t8gVa+vZNK|ypH>Bns zU%tj-lxxVA%FIo*M)>KE-=F??{(RoA_w#w4*XzNWnxg>#fXH^q=fd!mtC^-@?ML92 z0?MU&s()swPMws?sB1_~mjw8rq|_CS^Mp;q?z$eqj}q^2B@yOFG<%8M=?uhakAfTTQ6K(rgS_IvyU*2U_p5%_qb0l*|lM+g-YFz~X9pbAyfQ!}F>~9>ZA38w1An zJ}RUuv+G`TF`Eg<^DEC2r?O99bAGM1{w6yc20DYdl)i#a8|IKP#cYXx6~mRX`BtU5 zUnCv=l_Xtj#GGA|I&JUE)gJpV*`RpHsFA3?Za4?Vu)_(pYb%l05c0EzC3IoI2bsTr zF2zG5X=61HW?I(w>w)VBa4n7LtvrbJECHAo*m`S(x+>z-xBRNrC-!0WZ-7O)!_~s= z+)wqGhP3Oz?{J$iy6gEmevE3cnGKBPNJx6EPqnm_;zLCp>qoyyRY)MN+QRE#|d2{SpXM8JGP?2R3tCdK#!Ou}*^^;3#H!=Ks9Usd0K zPC*F99UHH0i$Q*N-kN&eQa%5o*lbkGWTW-dp@qHP_u&nG6ON%`1Txz(h3GitICS%F z&9?@sx@U_4YW4%dzqTx9ZQ+EKn!B%^JFb-PdRt1FTo*LI3Gg|NUM5LyZ-ChIX9Jc3 zVLH16uIVhWx^c8}=5-F{VI2fk`Re7;ct~*_Z9bwu zYM53&7D_r<@}bTXINzGE#yMmUCXV`&2MRYQa(t&!*Kv~**MpDfkX;(I>2NF8l0T9} z(?61c#Td(l#JRwng7{PgRua<2z(Y1j7FD)*fi8xZJ6JGdXR)u}P%;X zs=f;IzF7ILvP?dy@TC_bd{ibJL8N_EZeiVBXB2Lz-T$UGymC zj~m>|jmn`d37gALF4DAAGdnvt>V_CvwB*R(VNPSoKFT@7yhg>FVyM zpKz`=Ma6snn7+3a)s?am#H2Tn^O;4;IX0yF6FjpLjtcFA)r!+eb>5hVg4+N!oss&g?=(i5Vvt20LNE})w3DJmEsB8J7*~=|6s6Ikflt*k5!|#E759jx(q511M z_S41K=@?vR=~e*3Kltm4+jS5709+s2>_~=|%CoJEQ&zY5?9ThRruvh!x^ZIUI!5Uy z5pNq1`Hx_a1GMdkIDi#r-ygTn{J)C(2g}4*h+1r}zibM33C#1Bi6qs1vxcnG)^Pd z)60JR4(S=;z8s^X?S`kjqs~07^9HCYh@Qdhg-X9Vh4h*|xVC8UmXhFG`LIwsdB)nh zNE}be>!U+N6yfpQ28^!Y$k3p)m{R@Cis*C) z4Tk9*OIIvRW;{7n`kL;6^u=x}(xTq2X?b#o2+UVq@ka+u@3ae>W3<*;b^Cb2_%K~| z@Q59u@Z+OF zj~`>Y&?K~e2TuB5`Wb?J2>>YMz}g!ic#2&*9g<`s4q6nZN6$vvcm$wJr;Bapti*$) zhvHkR3LwVs#hE?30^*5@C_Cv2Id1i@M>*JfrqB1h6Yc)SS|KmzoHA`Vhq4EcwO`nP zGpsZdBqK7dpwayTG2J+6NwuMQg{~F?Yn{OPL@HjoUO7eiMwI#d}oxEmiK$V z2f_dVG)scm^nXbmxW%?4O(=KKBTee8Kw15e?juc}S==N~Ln=RJHGd}A4a~DSk9w!b zQ17<8tKToYWYroiA*uMgNb^E>w)KlN>jI+R`R>>G$uRpwsqhk)q zBpK9(i515hsO)6OdiOQb?Z{g{s%u&WCyUmins&Yq4hBfhLTP+p{82o`qsOo$GV!xT z%~>E!tAyF;48rXG+5rMwjS$P)395E{qN=p>XtZx&zsnOudWVC|;6_w&TRlCKrHy%GU9nzstS%gLkR`} zU}V^XDWKyvkztq@nYibfnf*4=40U_c;=kR1vx(qKI|4u7zM9V$jw-Fqj@^THimU$8 z>W~)&?8CuGZzQ(w=Y0cI#B?`^Rb2J1rMh{zU}VJ2@t^N7@FP)g1>t_!!`)eU z%s)Y*{@Tnk>x-Z$Y?Aq9j?#2JBCD5i265o>P3m`GiMEx@PTE+XaY;cK`}D&$s-LiV zf)vZ7{CEgFs1DN(j6aR1G<1*j8I~#lb_+yOc0#xvCEPGxPaHB6tbW#j<)5gSpK+su z0CEUecR)Ph4}*uKD*(V*BA}fR5uSoa=1<=QHve;YvTOlW1&N;bngs&nuyEHFQ9Na} z5AD*0aZ+R0xO6d?=o7A8OwsGMj`z?5C$Brw4zI2x{8sws_yzxvG&7}Y0DvJaZEu%0 W53Mn`Efv|6P`q28j9fC#1^o}>1zaHj diff --git a/contrib/git-stats/gitdm/tests/testrepo/packed-refs b/contrib/git-stats/gitdm/tests/testrepo/packed-refs deleted file mode 100644 index b62e86f86..000000000 --- a/contrib/git-stats/gitdm/tests/testrepo/packed-refs +++ /dev/null @@ -1,2 +0,0 @@ -# pack-refs with: peeled -2a3beb7042492ce6a0dc88ed59d04633b08b7bbc refs/heads/master diff --git a/contrib/git-stats/gitdm/treeplot b/contrib/git-stats/gitdm/treeplot deleted file mode 100755 index b6eedcb9d..000000000 --- a/contrib/git-stats/gitdm/treeplot +++ /dev/null @@ -1,333 +0,0 @@ -#!/usr/bin/python -# -# Create a graph of patch flow into the mainline. -# -# This code is part of the LWN git data miner. -# -# Copyright 2007-11 Eklektix, Inc. -# Copyright 2007-11 Jonathan Corbet -# -# This file may be distributed under the terms of the GNU General -# Public License, version 2. -# -import sys -from patterns import patterns - -# -# The various types of commit we understand. -# -class Commit: - def __init__(self, id, parent): - self.id = id - self.parent = parent - self.ismerge = 0 - self.treepriority = 0 -# -# Merges are special -# -class Merge (Commit): - def __init__(self, id, parent): - Commit.__init__(self, id, parent) - self.ismerge = 1 - self.internal = 1 # Two branches within a repo? - self.parents = [ parent ] - - def addparent(self, parentid): - self.parents.append(parentid) - - def addtree(self, tree): - self.tree = tree - self.internal = 0 - -# -# Trees: where the commits come from. -# -class Tree: - def __init__(self, name, url): - self.name = name - self.url = url - self.inputs = [ ] - self.commits = [ ] - - def addcommit(self, id): - self.commits.append(id) - - def addinput(self, tree): - if tree not in self.inputs: - self.inputs.append(tree) - # print '%s -> %s' % (tree.name, self.name) - -Mainline = Tree('Mainline', - 'git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git') -KnownTrees = { Mainline.url: Mainline } - -def NormalizeURL(url): - if url[:4] == 'git:': - return url - if url == '../net-2.6/': - url = 'git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6' - url = url.replace('master.kernel.org:', 'git://git.kernel.org') - if url[-18:] == 'torvalds/linux-2.6': - url += '.git' - if url[:8] == '/pub/scm': - url = 'git://git.kernel.org' + url - return url - -def LookupTree(url): - url = NormalizeURL(url) - try: - return KnownTrees[url] - except KeyError: - tree = Tree(url, url) - KnownTrees[url] = tree - return tree - -# -# We track which tree every commit belongs to. -# -CommitTrees = { } -class CTEntry: - def __init__ (self, tree, priority, path): - self.tree = tree - self.priority = priority - self.path = path - -def AddCommitTree(id, entry): -# print 'add: ', id, '[', -# for tree in entry.path: -# print tree.name, -# print ']' - try: - oldentry = CommitTrees[id] - if entry.priority < oldentry.priority: - CommitTrees[id] = entry - except KeyError: - CommitTrees[id] = entry - - -def LookupCommitTree(id): - try: - return CommitTrees[id] - except KeyError: - print 'Unfound commit %s' % (id) - return CTEntry (Mainline, 0, []) - -# -# Input handling with one-line pushback. -# -SavedLine = None -Input = sys.stdin - -def GetLine(): - global SavedLine - if SavedLine: - ret = SavedLine - SavedLine = None - return ret - return Input.readline() - -def SaveLine(line): - global SavedLine - SavedLine = line - -# -# Pull in a commit and see what it is. -# -def GetCommit(): - # - # Skip junk up to the next commit. - # - while 1: - line = GetLine() - if not line: - return None - m = patterns['commit'].match(line) - if m: - break - - # - # Look at the commit and see how many parents we have. - # - ids = m.group(1).split() - if len(ids) <= 1: - if len(CommitTrees.values()) > 0: - print 'No-Parent commit:', ids[0] - return GetCommit() - print 'Did you run git with --parents?' - print ids - sys.exit(1) - if len(ids) == 2: # Simple commit - return Commit(ids[0], ids[1]) - # - # OK, we have a merge. - # - merge = Merge(ids[0], ids[1]) - for id in ids[2:]: - merge.addparent(id) - # - # We need to figure out what kind of merge it is, so read through the - # descriptive text to the merge line. - # - while 1: - line = GetLine() - if not line: - print 'EOF looking for merge line' - return None - # - # Maybe it's an external merge? - # - m = patterns['ExtMerge'].match(line) - if m: - merge.addtree(LookupTree(m.group(3))) - return merge - # - # OK, maybe it's internal - # - if patterns['IntMerge'].match(line) or patterns['IntMerge2'].match(line): - #print 'Internal:', line[:-1] - merge.internal = 1 - return merge - m = patterns['commit'].match(line) - if m: - print 'Hit next commit (%s) looking for merge line' % (m.group(1)) - SaveLine(line) - return GetCommit() - -# -# Print out a tree and its inputs -# -def PrintTree(tree, indent = ''): - print '%s%4d %s' % (indent, len(tree.commits), tree.name) - for input in tree.inputs: - PrintTree(input, indent + ' ') - -# -# Let's try to build a data structure giving the patch flows. -# -class FlowNode: - def __init__(self, tree): - self.tree = tree - self.inputs = { } - self.commits = 0 - -def BuildFlowTree(): - rootnode = FlowNode(Mainline) - notree = Tree('[No tree]', '') - for centry in CommitTrees.values(): - path = centry.path - if not path: - path = [ notree ] - FillFlowPath(path, rootnode) - return rootnode - -def FillFlowPath(path, node): - node.commits += 1 - if len(path) == 0: - return - next, rest = path[0], path[1:] - try: - nextnode = node.inputs[next.name] - except KeyError: - nextnode = node.inputs[next.name] = FlowNode(next) - return FillFlowPath(rest, nextnode) - -def PrintFlowTree(ftree, indent = ''): - print '%s%3d %s' % (indent, ftree.commits, ftree.tree.name) - inputs = ftree.inputs.values() - inputs.sort(GVSort) - for input in inputs: - PrintFlowTree(input, indent + ' ') - -# -# Something for graphviz -# -GVHeader = '''digraph "runtree" { -graph [ label = "Patch flow into the mainline", - concentrate = true, - nodesep = 0.1, - rankdir = LR ]; -node [shape = polygon, - sides = 4, - height = 0.3 - fontsize = 8]; -''' - - -MainlineCommits = 0 - -def GVTree(ftree): - global MainlineCommits - MainlineCommits = ftree.commits - gvf = open('runtree.gv', 'w') - gvf.write(GVHeader) - inputs = ftree.inputs.values() - inputs.sort(GVSort) - for input in inputs: - GVPrintNode(gvf, input, 'Mainline') - gvf.write('}\n') - -def GVNodeName(treename): - sname = treename.split('/') - if treename.find('kernel.org') >= 0: - return '%s/%s' % (sname[-2], sname[-1]) - sep = treename.find ('://') - if sep > 0: - return treename[sep+3:] - return treename - -def GVSort(n1, n2): - return n2.commits - n1.commits - -def GVPrintNode(gvf, node, parent): - name = GVNodeName(node.tree.name) - gvf.write ('"%s" -> "%s" [taillabel = "%d", labelfontsize = 8' % (name, parent, node.commits)) - gvf.write (', arrowsize = 0.5') - if MainlineCommits/node.commits < 20: - gvf.write(', color = red') - elif MainlineCommits/node.commits < 100: - gvf.write(', color = orange'); - gvf.write(']\n') - inputs = node.inputs.values() - if inputs: - inputs.sort(GVSort) - for input in inputs: - GVPrintNode(gvf, input, name) - -# -# Main code. -# -commit = GetCommit() -ncommits = 0 -while commit: - ncommits += 1 - entry = LookupCommitTree(commit.id) - tree = entry.tree - priority = entry.priority - tree.addcommit(commit.id) - # - # For regular commits, just remember the tree involved - # - if not commit.ismerge: - AddCommitTree(commit.parent, entry) - # - # For merges we have to deal with all the parents. - # - else: - AddCommitTree(commit.parents[0], CTEntry (tree, priority, entry.path)) - if commit.internal: - for p in commit.parents[1:]: - path = entry.path + [tree] - AddCommitTree(p, CTEntry (tree, priority, entry.path)) - else: - for p in commit.parents[1:]: - path = entry.path + [commit.tree] - AddCommitTree(p, CTEntry (commit.tree, priority + 1, path)) - if commit.tree is not Mainline: - tree.addinput(commit.tree) - commit = GetCommit() - -#PrintTree(Mainline) -ftree = BuildFlowTree() -PrintFlowTree(ftree) -GVTree(ftree) -print '%d commits total, %d trees' % (MainlineCommits, len (KnownTrees.keys())) diff --git a/contrib/git-stats/gitdm/utils.py b/contrib/git-stats/gitdm/utils.py deleted file mode 100644 index 2b3be5d8c..000000000 --- a/contrib/git-stats/gitdm/utils.py +++ /dev/null @@ -1,37 +0,0 @@ -# -# Useful utilities. -# -# -# A simple class for accumulating counts or lists -# -class accumulator: - def __init__(self): - self._data = { } - - def incr(self, key, increment = 1): - try: - self._data[key] += increment - except KeyError: - self._data[key] = increment - - def get(self, key, default = None): - try: - return self._data[key] - except KeyError: - return default - - def append(self, key, item, unique = False): - if unique and self._data.has_key(key) and \ - item in self._data[key]: - return - try: - self._data[key].append(item) - except KeyError: - self._data[key] = [item] - - def keys(self): - return self._data.keys() - - def __getitem__(self, key): - return self._data[key] - diff --git a/contrib/git-stats/onie-git-stats b/contrib/git-stats/onie-git-stats deleted file mode 100755 index d799a46a4..000000000 --- a/contrib/git-stats/onie-git-stats +++ /dev/null @@ -1,94 +0,0 @@ -#!/bin/sh - -# -# Copyright 2018 Curt Brune -# All rights reserved. -# - -# Generate git repo statistics based on git commit ranges - -exe=$(basename $0) -usage() { - echo "Usage: $exe " - echo "example: $exe 2018.02..HEAD quarterly" - echo "example: $exe 2017.02..2018.02 yearly" -} - -if [ -n "$1" ] ; then - range="$1" -else - echo "Error: expecting a range in the form of a git revision range" - usage - exit 1 -fi -shift 1 - -if [ -n "$1" ] ; then - prefix="$1" -else - echo "Error: expecting output file prefix" - usage - exit 1 -fi - -# gitdm executable -if [ -z "$GITDM" ] ; then - GITDM="$(dirname $(realpath $0))/gitdm/gitdm" -fi -[ -x "$GITDM" ] || { - echo "Error: Unable to find gitdm executable" - exit 1 -} - -# gitdm configuration -if [ -z "$GITDM_CFG_DIR" ] ; then - GITDM_CFG_DIR="$(dirname $(realpath $0))/gitdm-config" -fi -[ -d "$GITDM_CFG_DIR" ] || { - echo "Error: Unable to find gitdm configuration directory" - exit 1 -} - -echo "Using gitdm exe: $GITDM" -echo "Using gitdm config directory: $GITDM_CFG_DIR" - -gitdm_cfg="/tmp/${prefix}-gitdm.cfg" -cat< $gitdm_cfg -# -# EmailAliases lets us cope with developers who use more -# than one address. -# -EmailAliases $GITDM_CFG_DIR/aliases - -# -# EmailMap does the main work of mapping addresses onto -# employers. -# -EmailMap $GITDM_CFG_DIR/domain-map - -# -# Use GroupMap to map a file full of addresses to the -# same employer -# -# GroupMap sample-config/illuminati The Illuminati -# -# -# Use FileTypeMap to map a file types to file names using regular -# regular expressions. -# -FileTypeMap $GITDM_CFG_DIR/filetypes.txt -EOF - -output_txt="/tmp/${prefix}-results.txt" -output_html="/tmp/${prefix}-results.html" - -echo "Generating stats for range: $range ..." -git log -p -M "$range" | \ - python $GITDM \ - -o "$output_txt" \ - -h "$output_html" \ - -c $gitdm_cfg - -echo "Stats available here:" -echo " $output_txt" -echo " $output_html" diff --git a/contrib/oce/build-onie.py b/contrib/oce/build-onie.py index 626829a21..b428e4f96 100755 --- a/contrib/oce/build-onie.py +++ b/contrib/oce/build-onie.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # ----------------------------------------------------------------------------- # Copyright (C) 2014-2015 Carlos Cardenas @@ -129,10 +129,10 @@ def list_all(): key=lambda t: t[0])) for key, values in sorted_dict.items(): - print key + print(key) for v in values: - print '\t{0}'.format(v) - print '\n' + print('\t{0}'.format(v)) + print('\n') def build(machine_or_vendor, dry_run=True, args='', targets=None): @@ -142,14 +142,14 @@ def build(machine_or_vendor, dry_run=True, args='', targets=None): if is_vendor(machine_or_vendor): # build everything under that vendor - print 'Building everything for vendor: {0}'.format(machine_or_vendor) + print('Building everything for vendor: {0}'.format(machine_or_vendor)) machines = VENDOR_MACHINES[machine_or_vendor] for machine in machines: build(machine, dry_run, args, targets) elif is_machine(machine_or_vendor): vendor = get_vendor(machine_or_vendor) - print 'Building {0} / {1}'.format(vendor, machine_or_vendor) + print('Building {0} / {1}'.format(vendor, machine_or_vendor)) machine_root = os.path.join(MACHINE_ROOT_PATH, vendor) add_targets = '' if targets is not None and len(targets) > 0: @@ -161,12 +161,12 @@ def build(machine_or_vendor, dry_run=True, args='', targets=None): else: cmd = 'make {0} MACHINE={1} all {2}'.\ format(args, machine_or_vendor, add_targets) - print cmd + print(cmd) if not dry_run: subprocess.check_call(cmd, shell=True) else: - print 'Invalid Target: {0}'.format(machine_or_vendor) + print('Invalid Target: {0}'.format(machine_or_vendor)) def main(): @@ -199,10 +199,10 @@ def main(): sys.exit(0) if args.build: - print 'cd {0}'.format(BUILD_CONFIG_PATH) + print('cd {0}'.format(BUILD_CONFIG_PATH)) os.chdir(BUILD_CONFIG_PATH) if 'all' in args.build: - for vendor in VENDOR_MACHINES.keys(): + for vendor in list(VENDOR_MACHINES.keys()): build(vendor, args.dry_run, args.make_args, args.target) else: for b in args.build: diff --git a/contrib/oce/eyes.py b/contrib/oce/eyes.py index 08856ce9a..0e05aef5c 100755 --- a/contrib/oce/eyes.py +++ b/contrib/oce/eyes.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # ----------------------------------------------------------------------------- # Copyright (C) 2015-2016 Carlos Cardenas @@ -8,7 +8,7 @@ # ----------------------------------------------------------------------------- -from cStringIO import StringIO +from io import StringIO import logging import os import os.path @@ -324,7 +324,7 @@ def validate_eyes_url(): def validate_options(options): # check all keys in args.option to ensure they are supported # while checking, type convert - for key, value in options.iteritems(): + for key, value in options.items(): if key in OPTIONS.keys(): options[key] = OPTIONS[key](value) else: diff --git a/contrib/oce/modules/dnsmasq.py b/contrib/oce/modules/dnsmasq.py index b31fd2e01..d7520d1c3 100644 --- a/contrib/oce/modules/dnsmasq.py +++ b/contrib/oce/modules/dnsmasq.py @@ -1,5 +1,5 @@ -import ipaddr +import ipaddress DEFAULT_LEASE_TIME = 600 DEFAULT_MAX_LEASE_TIME = 7200 @@ -89,12 +89,12 @@ def add_subnet(subnets, subnet_cidr_str, gateway_str=None): value = {} - subnet = ipaddr.IPv4Network(subnet_cidr_str) - value['network'] = subnet.network + subnet = ipaddress.IPv4Network(subnet_cidr_str, strict=False) + value['network'] = subnet.network_address value['netmask'] = subnet.netmask - value['broadcast'] = subnet.broadcast + value['broadcast'] = subnet.broadcast_address if gateway_str is not None and gateway_str != '': - gateway = ipaddr.IPv4Address(gateway_str) + gateway = ipaddress.IPv4Address(gateway_str) value['gateway'] = gateway subnets.append(value) @@ -132,14 +132,14 @@ def build_config(output, test_args): hosts_filename = os.path.join(test_args['test_dir'], DEFAULT_HOSTS_FILENAME) - temp = ipaddr.IPv4Network(test_args['ip_cidr']) - values['subnet_cidr'] = '{0}/{1}'.format(temp.network, temp.prefixlen) + temp = ipaddress.IPv4Network(test_args['ip_cidr'], strict=False) + values['subnet_cidr'] = '{0}/{1}'.format(temp.network_address, temp.prefixlen) gateway_addr = None if 'dhcp_gateway' in test_args: gateway_addr = test_args['dhcp_gateway'] if 'dhcp_next_server' in test_args: - next_server = ipaddr.IPv4Address(test_args['dhcp_next_server']) + next_server = ipaddress.IPv4Address(test_args['dhcp_next_server']) values['dhcp_next_server'] = next_server if 'enable_dns' in test_args: diff --git a/contrib/oce/modules/iscdhcp.py b/contrib/oce/modules/iscdhcp.py index 8559c9be0..ab819a851 100644 --- a/contrib/oce/modules/iscdhcp.py +++ b/contrib/oce/modules/iscdhcp.py @@ -1,5 +1,5 @@ -import ipaddr +import ipaddress DEFAULT_LEASE_TIME = 600 DEFAULT_MAX_LEASE_TIME = 7200 @@ -111,15 +111,15 @@ class "onie-vendor-classes" { def add_subnet(subnets, subnet_cidr_str, gateway_str=None, next_server_str=None): value = {} - subnet = ipaddr.IPv4Network(subnet_cidr_str) - value['network'] = subnet.network + subnet = ipaddress.IPv4Network(subnet_cidr_str, strict=False) + value['network'] = subnet.network_address value['netmask'] = subnet.netmask - value['broadcast'] = subnet.broadcast + value['broadcast'] = subnet.broadcast_address if gateway_str is not None and gateway_str != '': - gateway = ipaddr.IPv4Address(gateway_str) + gateway = ipaddress.IPv4Address(gateway_str) value['gateway'] = gateway if next_server_str is not None and next_server_str != '': - next_server = ipaddr.IPv4Address(next_server_str) + next_server = ipaddress.IPv4Address(next_server_str) value['next_server'] = next_server subnets.append(value) diff --git a/contrib/oce/test-onie.py b/contrib/oce/test-onie.py index 7252af066..750aa46dc 100755 --- a/contrib/oce/test-onie.py +++ b/contrib/oce/test-onie.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # ----------------------------------------------------------------------------- # Copyright (C) 2014-2016 Carlos Cardenas @@ -107,19 +107,19 @@ def validate_mac_address(mac_address_str): def validate_ip_cidr(ip_cidr_str): try: - import ipaddr - return ipaddr.IPv4Network(ip_cidr_str) is not None + import ipaddress + return ipaddress.IPv4Network(ip_cidr_str, strict=False) is not None except ImportError: - logger.critical('ipaddr module is not in path') + logger.critical('ipaddress module is not in path') return False - except ipaddr.AddressValueError: + except ipaddress.AddressValueError: return False def validate_options(options): # check all keys in args.option to ensure they are supported # while checking, type convert - for key, value in options.iteritems(): + for key, value in options.items(): if key in OPTIONS.keys(): options[key] = OPTIONS[key](value) else: @@ -186,7 +186,7 @@ def list_tests(): tests = TEST_DEFINE['tests'] sorted_keys = sorted(tests.keys(), key=lambda k: int(k)) for k in sorted_keys: - print 'Test {0} => {1}'.format(k, tests[k]['name']) + print('Test {0} => {1}'.format(k, tests[k]['name'])) def test_case_file_name(test_args): @@ -197,7 +197,7 @@ def test_case_file_name(test_args): ''' # we need to get the name template and return the new name # return None if not required - s_name = map(lambda x: x.strip(), test_args['test']['name'].split('-')) + s_name = list(map(lambda x: x.strip(), test_args['test']['name'].split('-'))) if s_name[-1] in TEST_DEFINE['names']: from jinja2 import Template template = Template(TEST_DEFINE['names'][s_name[-1]]) @@ -274,7 +274,7 @@ def test_case_file_name(test_args): def validate_network_info(test_args): - import ipaddr + import ipaddress import netifaces import socket @@ -302,22 +302,24 @@ def validate_network_info(test_args): # Get first INET address inet = net_addrs[netifaces.AF_INET][0] - ipv4_network = ipaddr.IPv4Network('{0[addr]}/{0[netmask]}'.format(inet)) - dut_address = ipaddr.IPv4Address(test_args['ip_address']) - dut_cidr = ipaddr.IPv4Network(test_args['ip_cidr']) + ipv4_network = ipaddress.IPv4Network('{0[addr]}/{0[netmask]}'.format(inet), + strict=False) + dut_address = ipaddress.IPv4Address(test_args['ip_address']) + dut_cidr = ipaddress.IPv4Network(test_args['ip_cidr'], strict=False) test_args['host_ipv4_addr'] = inet['addr'] test_args['host_local_name'] = socket.gethostname() # Check dut_address - if ipv4_network.Contains(dut_address) is False: + if (dut_address in ipv4_network) is False: logger.critical('Interface {0} cannot support DUT address {1}'. format(test_args['interface'], dut_address)) sys.exit(-3) # Check dut_cidr - temp_cidr = ipaddr.IPv4Network('{0}/{1}'.format( - dut_address, dut_cidr.prefixlen)) - if ipv4_network.Contains(temp_cidr) is False: + temp_cidr = ipaddress.IPv4Network('{0}/{1}'.format( + dut_address, dut_cidr.prefixlen), + strict=False) + if temp_cidr.subnet_of(ipv4_network) is False: logger.critical('Interface {0} cannot support DUT cidr {1}'. format(test_args['interface'], test_args['ip_cidr'])) sys.exit(-3) @@ -427,7 +429,7 @@ def prepare_test_case(test_args): def configure_test(args): import shutil import stat - import ipaddr + import ipaddress test = TEST_DEFINE['tests'][str(args.test)] out = 'Configuring for Test {0} - {1[name]}'.format(args.test, test) logger.info(out) @@ -435,11 +437,11 @@ def configure_test(args): # update ip_cidr and mac_address, CLI args take precendence if 'ip_cidr' in DUT_CONFIG: - ip_address = ipaddr.IPv4Network(DUT_CONFIG['ip_cidr']) + ip_address = ipaddress.IPv4Interface(DUT_CONFIG['ip_cidr']) test_args['ip_cidr'] = DUT_CONFIG['ip_cidr'] if args.ip_cidr: - ip_address = ipaddr.IPv4Network(args.ip_cidr) + ip_address = ipaddress.IPv4Interface(args.ip_cidr) test_args['ip_cidr'] = args.ip_cidr if 'mac_address' in DUT_CONFIG: @@ -713,18 +715,18 @@ def main(): running_procs[svc] = proc # wait on user input try: - raw_input('\n\nPress enter to stop all services\n\n') + input('\n\nPress enter to stop all services\n\n') except: pass - for svc, proc in running_procs.iteritems(): + for svc, proc in running_procs.items(): logger.info('Sending SIGTERM to {0}'.format(svc)) child_procs = proc.children(recursive=True) for p in child_procs: psutil.Popen('sudo kill -9 {0}'.format(p.pid), shell=True) proc.terminate() - for svc, proc in running_procs.iteritems(): + for svc, proc in running_procs.items(): logger.info('Waiting for {0} to cleanup'.format(svc)) proc.wait() diff --git a/contrib/onie-server/dhcp-server.py b/contrib/onie-server/dhcp-server.py index 723e2b617..5d022ec61 100644 --- a/contrib/onie-server/dhcp-server.py +++ b/contrib/onie-server/dhcp-server.py @@ -25,7 +25,7 @@ def decimalIPToDotted(ip): while (decimal > 0): octet,ip = divmod(ip,decimal) octets.append(str(octet)) - decimal = decimal/256 + decimal = decimal//256 return '.'.join(octets) # Init global variables @@ -128,33 +128,33 @@ def parseoptions(options_in_hex): options = {} while (options_in_hex): - option = int(options_in_hex[0:2], 16) + option = int(options_in_hex[0:2].decode('latin-1'), 16) # END if (option == 255): # print "END OPTIONs" return options - length = int(options_in_hex[2:4], 16) + length = int(options_in_hex[2:4].decode('latin-1'), 16) last_character = (length * 2) + 4 value = options_in_hex[4:last_character] options_in_hex = options_in_hex[last_character:] # print "OPTION %s, LENGTH %s, VALUE %s" % (option, length, value) if (option == 53): - options['type'] = int(value, 16) + options['type'] = int(value.decode('latin-1'), 16) # print "TYPE: %s" % (options['type']) elif (option == 1): - options['subnet_mask'] = int(value, 16) + options['subnet_mask'] = int(value.decode('latin-1'), 16) # print "MASK: %s" % (options['subnet_mask']) elif (option == 50): - options['requested_ip'] = decimalIPToDotted(int(value, 16)) + options['requested_ip'] = decimalIPToDotted(int(value.decode('latin-1'), 16)) # print "REQUEST_IP: %s" % (options['requested_ip']) elif (option == 61): id_type = value[:2] id_mac = value[2:] - options['client_id_type'] = int(id_type, 16) - options['client_id_mac'] = int(id_mac, 16) + options['client_id_type'] = int(id_type.decode('latin-1'), 16) + options['client_id_mac'] = int(id_mac.decode('latin-1'), 16) # Some option that we haven't implemented yet else: @@ -175,7 +175,7 @@ def reqparse(s, message): #handles either DHCPDiscover or DHCPRequest # Some clients want the reply broadcast to them but most will set this # flag to 0x0000 which means they want you to unicast it to them. broadcast_reply = False - flags = int(messagesplit[6], 16) + flags = int(messagesplit[6].decode('latin-1'), 16) if (flags == 32768): broadcast_reply = True @@ -195,65 +195,65 @@ def reqparse(s, message): #handles either DHCPDiscover or DHCPRequest lease = get_lease(client_mac) sys.stderr.write("RX Discover\n") sys.stderr.write("TX Offer %s\n" % (lease)) - data='\x02\x01\x06\x00' + data=b'\x02\x01\x06\x00' # XID data+=binascii.unhexlify(messagesplit[4]) # SECS - data+='\x00\x04' + data+=b'\x00\x04' # FLAGS if (broadcast_reply): - data+='\x80\x00' + data+=b'\x80\x00' else: - data+='\x00\x00' + data+=b'\x00\x00' # Address for client - data+='\x00'*4+socket.inet_aton(lease) + data+=b'\x00'*4+socket.inet_aton(lease) # Server IP data+=socket.inet_aton(server_host) # Gateway IP? - data+='\x00'*4 + data+=b'\x00'*4 # Client MAC Address data+=binascii.unhexlify(client_mac) # 10 octets of 0s - data+='\x00'*10 + data+=b'\x00'*10 # 192 octets of 0s for BOOTP legacy - data+='\x00'*192 + data+=b'\x00'*192 # Magic Cookie - data+='\x63\x82\x53\x63' + data+=b'\x63\x82\x53\x63' # DHCP Options... # 53 = DHCP Offer - data+='\x35\x01\x02' + data+=b'\x35\x01\x02' # 54 = DHCP Server - data+='\x36\x04'+socket.inet_aton(server_host) + data+=b'\x36\x04'+socket.inet_aton(server_host) # 51 = Lease Time - data+='\x33\x04'+binascii.unhexlify(hex(leasetime)[2:].rjust(8,'0')) + data+=b'\x33\x04'+binascii.unhexlify(hex(leasetime)[2:].rjust(8,'0')) # 1 = Subnet Mask - data+='\x01\x04'+socket.inet_aton(subnet_mask) + data+=b'\x01\x04'+socket.inet_aton(subnet_mask) # 28 = Broadcast Address - data+='\x1c\x04'+socket.inet_aton(broadcast) + data+=b'\x1c\x04'+socket.inet_aton(broadcast) # 3 = Router - data+='\x03\x04'+socket.inet_aton(gw) + data+=b'\x03\x04'+socket.inet_aton(gw) # 6 = DNS Server - data+='\x06\x04'+socket.inet_aton(dnsserver) + data+=b'\x06\x04'+socket.inet_aton(dnsserver) # End - data+='\xff' + data+=b'\xff' # DHCP Request elif (options['type'] == 3 and 'requested_ip' in options): @@ -263,47 +263,47 @@ def reqparse(s, message): #handles either DHCPDiscover or DHCPRequest sys.stderr.write("RX Request %s, lease %s\n" % (options['requested_ip'], lease)) sys.stderr.write("TX Ack\n\n") - data='\x02\x01\x06\x00' + data=b'\x02\x01\x06\x00' data+=binascii.unhexlify(messagesplit[4]) # XID - data+='\x00\x00'# SECS + data+=b'\x00\x00'# SECS # FLAGS if (broadcast_reply): - data+='\x80\x00' + data+=b'\x80\x00' else: - data+='\x00\x00' + data+=b'\x00\x00' # Client IP - data+='\x00'*4 + data+=b'\x00'*4 # Your (Client) IP data+=binascii.unhexlify(messagesplit[15][messagesplit[15].\ - find('3204')+4:messagesplit[15].\ - find('3204')+12]) - data+=socket.inet_aton(server_host)+'\x00'*4 - data+=binascii.unhexlify(client_mac)+'\x00'*202 + find(b'3204')+4:messagesplit[15].\ + find(b'3204')+12]) + data+=socket.inet_aton(server_host)+b'\x00'*4 + data+=binascii.unhexlify(client_mac)+b'\x00'*202 # Magic Cookie - data+='\x63\x82\x53\x63' + data+=b'\x63\x82\x53\x63' # DHCP Options... # 53 = DHCP Offer - data+='\x35\x01\05' + data+=b'\x35\x01\05' # 54 = DHCP Server - data+='\x36\x04'+socket.inet_aton(server_host) + data+=b'\x36\x04'+socket.inet_aton(server_host) # 1 = Subnet Mask - data+='\x01\x04'+socket.inet_aton(subnet_mask) + data+=b'\x01\x04'+socket.inet_aton(subnet_mask) # 3 = Router - data+='\x03\x04'+socket.inet_aton(server_host) + data+=b'\x03\x04'+socket.inet_aton(server_host) # 51 = Lease Time - data+='\x33\x04'+binascii.unhexlify(hex(leasetime)[2:].rjust(8,'0')) + data+=b'\x33\x04'+binascii.unhexlify(hex(leasetime)[2:].rjust(8,'0')) # End - data+='\xff' + data+=b'\xff' if (data): if (broadcast_reply): @@ -326,7 +326,7 @@ def reqparse(s, message): #handles either DHCPDiscover or DHCPRequest client_mac[6:8], client_mac[8:10], client_mac[10:12]) - print "arp -s %s %s %s" % (lease, client_mac_pretty, gw) + print("arp -s %s %s %s" % (lease, client_mac_pretty, gw)) subprocess.Popen(["arp", "-s", lease, client_mac_pretty, gw], stdout=subprocess.PIPE, stderr=subprocess.PIPE, @@ -340,7 +340,7 @@ def reqparse(s, message): #handles either DHCPDiscover or DHCPRequest try: (message, address) = rxs.recvfrom(8192) # only serve if a dhcp request - if not message.startswith('\x01') and not address[0] == '0.0.0.0': + if not message.startswith(b'\x01') and not address[0] == '0.0.0.0': continue reqparse(rxs, message) release() diff --git a/contrib/onie-server/onie-server.py b/contrib/onie-server/onie-server.py index a642f1ca4..59528436f 100644 --- a/contrib/onie-server/onie-server.py +++ b/contrib/onie-server/onie-server.py @@ -20,7 +20,7 @@ import select import sys from threading import Thread -from Queue import Queue, Empty +from queue import Queue, Empty from shutil import copyfile from subprocess import check_output @@ -33,7 +33,7 @@ def clearScreen(): return def pauseUntilEnter(msg): - raw_input(msg) + input(msg) return def streamWatcher(identifier, stream): @@ -54,24 +54,24 @@ def printer(): break else: identifier, line = item - print identifier + ':', line.rstrip() + print(identifier + ':', line.rstrip()) # Make sure there is an onie-installer image in the onie-server directory. clearScreen() onie = "onie-installer" if (not os.path.exists(onie)): - print "We do not have an onie-installer image. Please place an " \ + print("We do not have an onie-installer image. Please place an " \ "onie-installer binary for the OS you wish to install, in the " \ "same directory as this script. You should name the image " \ - "'onie-installer'\n" + "'onie-installer'\n") exit() # Figure out what interfaces we have and their IP addresses. If we have two # interfaces (ideally we will) then ask which interface will be connected to # the bare-metal switch and which will be used for Internet access -print "We need to determine which of the interfaces on your laptop " \ +print("We need to determine which of the interfaces on your laptop " \ "is connected to the Internet and which is connected to the switch " \ - "you want to boot." + "you want to boot.") inside_ip = False outside_ip = False @@ -85,7 +85,7 @@ def platform_get_ipaddrs(): Default Gateway . . . . . . . . . : 10.0.1.1 ''' ipaddrs = [] - output = check_output(['ipconfig']) + output = check_output(['ipconfig'], universal_newlines=True) for line in output.split('\n'): result = re.search('IPv4 Address.*?(\d+\.\d+\.\d+\.\d+)', line) if (result): @@ -124,9 +124,9 @@ def platform_get_ipaddrs(): # prefer Linux ip tool and fallback to ifconfig for Mac and Linux # distros that lack ip tool try: - output = check_output(['ip', 'addr', 'show']) + output = check_output(['ip', 'addr', 'show'], universal_newlines=True) except OSError: - output = check_output(['ifconfig']) + output = check_output(['ifconfig'], universal_newlines=True) for line in output.split('\n'): result = re.search('inet (addr:)?(\d+\.\d+\.\d+\.\d+)', line) if (result): @@ -142,14 +142,14 @@ def get_addresses(): return addresses for ip in get_addresses(): - print "\nWhat type of interface is %s?" % ip - print "1: This interface is connected to the Internet" - print "2: This interface is connected to my bare-metal switch" - print "3: Neither...ignore it" + print("\nWhat type of interface is %s?" % ip) + print("1: This interface is connected to the Internet") + print("2: This interface is connected to my bare-metal switch") + print("3: Neither...ignore it") int_type = False while (not int_type): - int_type = raw_input('') + int_type = input('') if (int_type): int_type = int(int_type) @@ -157,13 +157,13 @@ def get_addresses(): outside_ip = True elif (int_type == 2): inside_ip = ip - mask = raw_input('\nSubnet Mask [255.255.255.0]: ') + mask = input('\nSubnet Mask [255.255.255.0]: ') if (not mask): mask = "255.255.255.0" elif (int_type == 3): pass else: - print "ERROR: '%s' is not a valid option" % int_type + print("ERROR: '%s' is not a valid option" % int_type) int_type = False clearScreen() @@ -172,11 +172,11 @@ def get_addresses(): # interface connecting to the switch so prompt them to let them enter it # manually. if (not inside_ip): - print "Hmmm, we couldn't find the IP address of the interface that is " \ - "connected to your bare-metal switch. Please enter it manually:\n" - inside_ip = raw_input("IP Address: ") + print("Hmmm, we couldn't find the IP address of the interface that is " \ + "connected to your bare-metal switch. Please enter it manually:\n") + inside_ip = input("IP Address: ") if (inside_ip): - mask = raw_input('\nSubnet Mask [255.255.255.0]: ') + mask = input('\nSubnet Mask [255.255.255.0]: ') clearScreen() if (not mask): mask = "255.255.255.0" @@ -187,30 +187,30 @@ def get_addresses(): exit() if (not outside_ip): - print "Hmmm, we couldn't find the IP address of the interface that is " \ + print("Hmmm, we couldn't find the IP address of the interface that is " \ "connected to the Internet. Please enter it manually or just " \ - "press ENTER if you don't have one.\n" - outside_ip = raw_input("IP Address: ") + "press ENTER if you don't have one.\n") + outside_ip = input("IP Address: ") clearScreen() # See if we can ping to the outside world. This isn't critical but if it fails # then print a message explaining that apt commands will fail. if (not outside_ip): - print "You do not have an interface that is connected to the Internet. " \ + print("You do not have an interface that is connected to the Internet. " \ "This isn't a huge deal, just be aware that your switch will not " \ - "have Internet connectivity to do things such as 'apt-get'.\n" + "have Internet connectivity to do things such as 'apt-get'.\n") pauseUntilEnter("Press ENTER to continue\n") clearScreen() # Start a DHCP server that listens on the INSIDE interface. -print "Starting the DHCP server, Web server and Proxy server...\n" -dhcp_proc = subprocess.Popen(["python", "dhcp-server.py", inside_ip, mask], +print("Starting the DHCP server, Web server and Proxy server...\n") +dhcp_proc = subprocess.Popen(["python3", "dhcp-server.py", inside_ip, mask], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False) # Start a web server that listens on the INSIDE interface. -web_proc = subprocess.Popen(["python", "web-server.py", inside_ip], +web_proc = subprocess.Popen(["python3", "web-server.py", inside_ip], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False) @@ -218,16 +218,16 @@ def get_addresses(): # If we have an OUTSIDE interface then start a proxy server that listens on the # INSIDE interface. if (outside_ip): - proxy_proc = subprocess.Popen(["python", "proxy-server.py", inside_ip], + proxy_proc = subprocess.Popen(["python3", "proxy-server.py", inside_ip], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False) else: proxy_proc = False -print "The DHCP, Web, and Proxy servers are all running.\nWhen you have " \ +print("The DHCP, Web, and Proxy servers are all running.\nWhen you have " \ "finished installing the OS on your switch press ENTER to shut down " \ - "the DHCP, Web, and Proxy servers.\n" + "the DHCP, Web, and Proxy servers.\n") # Now print the STDOUT and STDERR from all three servers if (dhcp_proc): diff --git a/contrib/onie-server/proxy-server.py b/contrib/onie-server/proxy-server.py index d6104339e..99982a20f 100644 --- a/contrib/onie-server/proxy-server.py +++ b/contrib/onie-server/proxy-server.py @@ -1,7 +1,7 @@ -# -*- coding: cp1252 -*- +# -*- coding: utf-8 -*- # # -#Copyright (c) <2009> +#Copyright (c) <2009> # #Permission is hereby granted, free of charge, to any person #obtaining a copy of this software and associated documentation @@ -25,15 +25,15 @@ #OTHER DEALINGS IN THE SOFTWARE. """\ -Copyright (c) <2009> +Copyright (c) <2009> ************************************** *** Python Proxy - A Fast HTTP proxy *** ************************************** -Neste momento este proxy é um Elie Proxy. +Neste momento este proxy é um Elie Proxy. -Suporta os métodos HTTP: +Suporta os métodos HTTP: - OPTIONS; - GET; - HEAD; @@ -44,44 +44,44 @@ - CONENCT. Suporta: - - Conexões dos cliente em IPv4 ou IPv6; - - Conexões ao alvo em IPv4 e IPv6; - - Conexões todo o tipo de transmissão de dados TCP (CONNECT tunneling), - p.e. ligações SSL, como é o caso do HTTPS. + - Conexões dos cliente em IPv4 ou IPv6; + - Conexões ao alvo em IPv4 e IPv6; + - Conexões todo o tipo de transmissão de dados TCP (CONNECT tunneling), + p.e. ligações SSL, como é o caso do HTTPS. A fazer: - - Verificar se o input vindo do cliente está correcto; - - Enviar os devidos HTTP erros se não, ou simplesmente quebrar a ligação; + - Verificar se o input vindo do cliente está correcto; + - Enviar os devidos HTTP erros se não, ou simplesmente quebrar a ligação; - Criar um gestor de erros; - Criar ficheiro log de erros; - - Colocar excepções nos sítios onde é previsível a ocorrência de erros, + - Colocar excepções nos sítios onde é previsível a ocorrência de erros, p.e.sockets e ficheiros; - Rever tudo e melhorar a estrutura do programar e colocar nomes adequados nas - variáveis e métodos; + variáveis e métodos; - Comentar o programa decentemente; - Doc Strings. Funcionalidades futuras: - - Adiconar a funcionalidade de proxy anónimo e transparente; + - Adiconar a funcionalidade de proxy anónimo e transparente; - Suportar FTP?. -(!) Atenção o que se segue só tem efeito em conexões não CONNECT, para estas o - proxy é sempre Elite. +(!) Atenção o que se segue só tem efeito em conexões não CONNECT, para estas o + proxy é sempre Elite. -Qual a diferença entre um proxy Elite, Anónimo e Transparente? - - Um proxy elite é totalmente anónimo, o servidor que o recebe não consegue ter - conhecimento da existência do proxy e não recebe o endereço IP do cliente; - - Quando é usado um proxy anónimo o servidor sabe que o cliente está a usar um - proxy mas não sabe o endereço IP do cliente; - É enviado o cabeçalho HTTP "Proxy-agent". - - Um proxy transparente fornece ao servidor o IP do cliente e um informação que - se está a usar um proxy. - São enviados os cabeçalhos HTTP "Proxy-agent" e "HTTP_X_FORWARDED_FOR". +Qual a diferença entre um proxy Elite, Anónimo e Transparente? + - Um proxy elite é totalmente anónimo, o servidor que o recebe não consegue ter + conhecimento da existência do proxy e não recebe o endereço IP do cliente; + - Quando é usado um proxy anónimo o servidor sabe que o cliente está a usar um + proxy mas não sabe o endereço IP do cliente; + É enviado o cabeçalho HTTP "Proxy-agent". + - Um proxy transparente fornece ao servidor o IP do cliente e um informação que + se está a usar um proxy. + São enviados os cabeçalhos HTTP "Proxy-agent" e "HTTP_X_FORWARDED_FOR". """ -import socket, thread, select, sys +import socket, _thread, select, sys __version__ = '0.1.0 Draft 1' BUFLEN = 8192 @@ -91,7 +91,7 @@ class ConnectionHandler: def __init__(self, connection, address, timeout): self.client = connection - self.client_buffer = '' + self.client_buffer = b'' self.timeout = timeout self.method, self.path, self.protocol = self.get_base_header() if self.method=='CONNECT': @@ -105,20 +105,20 @@ def __init__(self, connection, address, timeout): def get_base_header(self): while 1: self.client_buffer += self.client.recv(BUFLEN) - end = self.client_buffer.find('\n') + end = self.client_buffer.find(b'\n') if end!=-1: break - print '%s'%self.client_buffer[:end]#debug - data = (self.client_buffer[:end+1]).split() + print('%s'%self.client_buffer[:end].decode('latin-1'))#debug + data = (self.client_buffer[:end+1]).decode('latin-1').split() self.client_buffer = self.client_buffer[end+1:] return data def method_CONNECT(self): self._connect_target(self.path) - self.client.send(HTTPVER+' 200 Connection established\n'+ - 'Proxy-agent: %s\n\n'%VERSION) - self.client_buffer = '' - self._read_write() + self.client.send((HTTPVER+' 200 Connection established\n'+ + 'Proxy-agent: %s\n\n'%VERSION).encode('latin-1')) + self.client_buffer = b'' + self._read_write() def method_others(self): self.path = self.path[7:] @@ -126,9 +126,9 @@ def method_others(self): host = self.path[:i] path = self.path[i:] self._connect_target(host) - self.target.send('%s %s %s\n'%(self.method, path, self.protocol)+ + self.target.send(('%s %s %s\n'%(self.method, path, self.protocol)).encode('latin-1')+ self.client_buffer) - self.client_buffer = '' + self.client_buffer = b'' self._read_write() def _connect_target(self, host): @@ -143,7 +143,7 @@ def _connect_target(self, host): self.target.connect(address) def _read_write(self): - time_out_max = self.timeout/3 + time_out_max = self.timeout//3 socs = [self.client, self.target] count = 0 while 1: @@ -172,10 +172,10 @@ def start_server(host='localhost', port=8080, IPv6=False, timeout=60, soc_type=socket.AF_INET soc = socket.socket(soc_type) soc.bind((host, port)) - print "Serving on %s:%d."%(host, port)#debug + print("Serving on %s:%d."%(host, port))#debug soc.listen(0) while 1: - thread.start_new_thread(handler, soc.accept()+(timeout,)) + _thread.start_new_thread(handler, soc.accept()+(timeout,)) if __name__ == '__main__': if (len(sys.argv) <= 1): diff --git a/contrib/onie-server/web-server.py b/contrib/onie-server/web-server.py index 21d92caa3..ab43c5231 100644 --- a/contrib/onie-server/web-server.py +++ b/contrib/onie-server/web-server.py @@ -3,8 +3,8 @@ # # SPDX-License-Identifier: GPL-2.0 -import SimpleHTTPServer -import SocketServer +import http.server +import socketserver import sys if (len(sys.argv) <= 1): @@ -14,10 +14,10 @@ inside_ip = sys.argv[1] web_port = 80 -Handler = SimpleHTTPServer.SimpleHTTPRequestHandler +Handler = http.server.SimpleHTTPRequestHandler try: - httpd = SocketServer.TCPServer((inside_ip, web_port), Handler) + httpd = socketserver.TCPServer((inside_ip, web_port), Handler) except: sys.stderr.write("We were unable to start the web server. Normally when " \ "this happens it is because there is some other process " \ diff --git a/emulation/ci-boot-test.sh b/emulation/ci-boot-test.sh new file mode 100755 index 000000000..c247e4a58 --- /dev/null +++ b/emulation/ci-boot-test.sh @@ -0,0 +1,228 @@ +#!/bin/bash + +# Copyright (C) 2026 Brad House +# +# SPDX-License-Identifier: GPL-2.0 + +# +# CI boot-validation harness for the kvm_x86_64 ONIE recovery image. +# +# Boots the recovery ISO headlessly under QEMU + OVMF (UEFI), captures the +# serial console, and asserts that ONIE boots PAST GRUB INTO THE OS. ONIE +# routes GRUB, the kernel and userspace all to ttyS0, so a serial capture is +# sufficient -- no graphical/OCR interaction is needed. +# +# PASS = all boot milestones observed AND no kernel panic. +# FAIL = a milestone is missing or the kernel panicked (e.g. init died). +# +# Two modes (BOOT_MODE): +# relaxed (default) Secure-Boot-RELAXED: plain OVMF varstore, no keys +# enrolled. shim still chainloads grub->kernel, so it validates +# "does it boot" independent of the SB signature chain. Boots on +# the default 'pc' machine (ONIE's onie-vm.sh reference machine). +# secureboot Secure-Boot-ENFORCED: enrolls the demonstration PK/KEK/db from +# KEYS_DIR into an OVMF varstore (virt-fw-vars), boots the secboot +# OVMF firmware on 'q35,smm=on' with the flash secure flag, and +# asserts ONIE boots -- i.e. the shim/grub/kernel signing chain +# verifies under enforcement. Also runs a NEGATIVE control with +# the db omitted, which MUST be rejected (proves SB is enforcing, +# not merely permissive). +# +# Usage: ci-boot-test.sh [timeout_secs] +# Env: SERIAL_LOG= serial log path (default ./onie-boot-serial.log) +# BOOT_MODE=relaxed|secureboot (default relaxed) +# KEYS_DIR=

encryption/machines/kvm_x86_64/keys (secureboot) +# +# Requires on the host: qemu-system-x86_64, ovmf (apt: qemu-system-x86 ovmf). +# secureboot mode additionally needs virt-fw-vars (apt: python3-virt-firmware). +# On GitHub Actions, add the kvm udev rule first so /dev/kvm is usable; QEMU +# falls back to TCG automatically via accel=kvm:tcg if KVM is unavailable. + +set -uo pipefail + +ISO="${1:?usage: ci-boot-test.sh [timeout_secs]}" +TIMEOUT="${2:-300}" +SERIAL_LOG="${SERIAL_LOG:-onie-boot-serial.log}" +BOOT_MODE="${BOOT_MODE:-relaxed}" + +# Terminal-state markers run_qemu polls for (to stop QEMU as soon as the outcome +# is decided instead of waiting out the timeout): +# READY_BOOT - a successful boot has reached the ONIE console/discovery prompt. +# READY_NEG - the SB negative control has resolved: either rejected (expected) +# or, unexpectedly, reached GRUB/ONIE (caught by the assertions). +READY_BOOT='Please press Enter to activate this console|discover: (ONIE|Rescue)|Starting ONIE Service Discovery' +READY_NEG='Security Violation|Access Denied|verification failed|GNU GRUB|ONIE: (OS Install|Rescue) Mode' + +[ -r "$ISO" ] || { echo "ERROR: ISO not readable: $ISO" >&2; exit 2; } + +# A fixed owner GUID for the enrolled demo keys -- deterministic on purpose so +# runs are reproducible; the value is immaterial for boot verification. +SB_OWNER_GUID="a9b1c2d3-0011-4caf-8bad-f00d0c1e0001" + +# --- locate OVMF firmware (Ubuntu 24.04 dropped the 2MB files -> probe _4M first) --- +OVMF_CODE=""; OVMF_CODE_SB=""; OVMF_VARS_SRC="" +for c in /usr/share/OVMF/OVMF_CODE_4M.fd /usr/share/OVMF/OVMF_CODE.fd \ + /usr/share/edk2/ovmf/OVMF_CODE.fd; do + [ -f "$c" ] && OVMF_CODE="$c" && break +done +for c in /usr/share/OVMF/OVMF_CODE_4M.secboot.fd /usr/share/OVMF/OVMF_CODE.secboot.fd \ + /usr/share/edk2/ovmf/OVMF_CODE.secboot.fd; do + [ -f "$c" ] && OVMF_CODE_SB="$c" && break +done +for v in /usr/share/OVMF/OVMF_VARS_4M.fd /usr/share/OVMF/OVMF_VARS.fd \ + /usr/share/edk2/ovmf/OVMF_VARS.fd; do + [ -f "$v" ] && OVMF_VARS_SRC="$v" && break +done +[ -n "$OVMF_CODE" ] && [ -n "$OVMF_VARS_SRC" ] || { + echo "ERROR: OVMF firmware not found (apt install ovmf)" >&2; exit 2; } + +WORK="$(mktemp -d)" +trap 'rm -rf "$WORK"' EXIT + +# --- boot QEMU headless, serial(ttyS0) -> file, -no-reboot so a panic doesn't +# loop. Polls the serial log and stops QEMU as soon as the boot reaches a +# terminal state (the , e.g. the console prompt) or panics -- +# ONIE boots to an idle console and never exits, so without this we would +# dead-wait the full timeout on every (successful) boot. The timeout is now +# only hit by a genuinely stuck boot. +# Args: [extra qemu args...] +run_qemu() { + local ready_re="$1" code="$2" vars="$3" log="$4"; shift 4 + : >"$log" + qemu-system-x86_64 \ + -m 2048 -smp 2 \ + -drive if=pflash,format=raw,readonly=on,file="$code" \ + -drive if=pflash,format=raw,file="$vars" \ + -cdrom "$ISO" -boot d \ + -netdev user,id=onienet -device virtio-net,netdev=onienet \ + -display none -serial "file:$log" -no-reboot \ + "$@" >/dev/null 2>&1 & + local qpid=$! t=0 + while kill -0 "$qpid" 2>/dev/null; do + if grep -Eaq "$ready_re" "$log" || grep -aq 'Kernel panic' "$log"; then break; fi + [ "$t" -ge "$TIMEOUT" ] && break + sleep 1; t=$((t + 1)) + done + kill "$qpid" 2>/dev/null; sleep 1; kill -9 "$qpid" 2>/dev/null; wait "$qpid" 2>/dev/null + if grep -aq 'Kernel panic' "$log"; then echo " (stopped at ${t}s: kernel panic)" + elif grep -Eaq "$ready_re" "$log"; then echo " (stopped at ${t}s: reached terminal state)" + else echo " (stopped at ${t}s: TIMEOUT, no terminal marker)"; fi +} + +# --- assert the ONIE boot milestones in a captured serial log. Sets `fail`. --- +fail=0 +chk() { #