Repository navigation
Ship a Linux package with the release (1.5.0.0) - #8
Merged
Merged
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
60-libgphoto2*.rules sorts after 60-canonwebapi.rules and, on add/bind events of a PTP device, sets MODE="0664", GROUP="plugdev": after a reboot, replug or camera power-on the service user could no longer open the camera. install.sh only sent a change event, which libgphoto2 skips, so it did not show right after the installation. The rule now uses final assignments and only matches Canon PTP cameras (printers and scanners are left alone). install.sh applies it with an add event and waits for udev before starting the service; --uninstall sends the same event so a plugged camera gets its default ownership back. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
install.sh only checked Canon.API up front: a missing libEDSDK.so, unit or udev rule was found after the service had been stopped. It now checks root, x86_64, that systemd runs as init (not only that systemctl exists), libusb and every package file before the first change; --uninstall needs root and systemd only. After the restart it waits a few seconds and fails when the service is not running, pointing to journalctl, instead of reporting a successful installation of a service that crash-loops. Also: the comment of the copy loop says what it leaves alone (appsettings.Local.json and logs/), and the root check message no longer ends with a space when there is no argument. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
NoNewPrivileges, PrivateTmp, ProtectSystem=full (/opt, where the logs are written, stays writable) and ProtectHome. PrivateDevices would hide the camera, MemoryDenyWriteExecute breaks the JIT and an address family restriction would block the netlink socket used for hot plug: the unit says so, so they are not added later by mistake. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The single file loaded libicu at runtime: on a minimal system the service aborted with "Couldn't find a valid ICU package" and crash-looped. The API only uses the invariant culture, so the net10.0 target now uses invariant globalization. Checked with an ICU that cannot be found (DOTNET_SYSTEM_GLOBALIZATION_APPLOCALICU=99.9): the previous build aborts, this one answers /status. The comment of the property group no longer reads as if it made the publish self-contained: the publish command line does. README lists the actual requirements (glibc 2.27, libstdc++ of GCC 7, libusb, systemd; no ICU) and the tested distribution instead of untested examples. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The catch around startup only logged the error, so the process exited with code 0 when the port was in use or appsettings.Local.json was invalid: launchers did not see the failure and systemd's Restart=on-failure never fired. Checked on the published Linux package with port 5097 held by another process: exit code 0 before, 1 now; a normal stop (SIGTERM) still exits with 0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The windows and linux jobs run NuGet build logic, the tests and the package checks with a persisted contents: write token. The workflow now defaults to contents: read, only prepare (version commit) and release (GitHub release, AutoUpdater XML) get contents: write, and the build jobs check out without persisting credentials. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The release job also runs on workflow_dispatch: it checks out the selected branch, downloads both packages, lists them and generates the AutoUpdater XML (printed); only "Create GitHub Release" and "Commit AutoUpdater XML" are limited to tag pushes. A dry run now covers the download and the XML generation, and still publishes nothing. - The AutoUpdater XML is written with a UTF-8 BOM, as Windows PowerShell always wrote it: the feed stays byte identical (pwsh on Linux dropped the BOM). - The Linux archive records root (0/0) as owner: extracted with sudo, its files belonged to the runner's uid, whose local user could edit install.sh before root runs it. - 30 minute timeout on the build jobs of both workflows (a hung check held a runner for 6 hours), and no comments that restate the code. README states what a failure leaves behind: a failed build job publishes nothing; a release job that fails after creating the release leaves the feed (and the photo booths) on the previous version until it is rerun. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
README: stop the service before running Canon.API by hand (one program at a time can use the camera, and the service also listens on port 5000). CLAUDE.md: the release no longer publishes only -f net10.0-windows; it publishes the Windows package with -f net10.0-windows -r win-x64 and the Linux package with -f net10.0 -r linux-x64. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The design still described the udev rule, the install.sh checks, the service unit and the release dry run as they were before the fixes, and the README requirements summary did not mention libstdc++. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
dansleboby
marked this pull request as ready for review
October 5, 2026 03:22
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
CanonWebAPI-linux-x64.tar.gz(folderCanonWebAPI/): self-contained single-fileCanon.APIfor Linux x64 (no .NET or ICU to install) withlibEDSDK.so, plusinstall.sh, which installs it as thecanonwebapisystemd service in/opt/canonwebapi(hardened unit), with a udev rule that gives the service user the Canon PTP cameras. The rule uses final assignments:60-libgphoto2*.rulessorts after it and would give the camera back toplugdevat every replug, power-on or reboot.install.shchecks the system and the package before changing anything and fails when the service does not stay up;install.sh --uninstallremoves everything. Manual updates (run theinstall.shof the new archive).tools/Test-Package.ps1starts a published package from a temporary copy and checks that/statusanswers (camera connected, or "No Canon camera detected"): it fails when the EDSDK library cannot be loaded.prepare(tag check, version) ->windows+linuxin parallel (build, test, publish, check, archive) ->releasewith both packages and the AutoUpdater XML, only when both succeeded. The build jobs get a read-only token.workflow_dispatchruns a dry run that also downloads both packages and generates the XML in the release job, but creates no release and pushes nothing. The Windows package and the feed are unchanged (the generated XML is byte identical, UTF-8 BOM included).Restart=on-failureand launchers see it.Design:
specs/2026-10-04-linux-package-design.md, plan:specs/2026-10-04-linux-package-plan.md.Test plan
Canon.APIandinstall.sh);Test-Package.ps1passes on the package and fails withoutlibEDSDK.so;install.shsimulated without root (install, update keepingappsettings.Local.json, re-run, double uninstall, missing package file);bash -n, shellcheck,udevadm verify,systemd-analyze verifyclean; the release XML step produces the currentdocs/autoupdate.xmlbyte for byte.build-and-test(Windows) andbuild-and-test-linuxpass, including both package checks.install.shon a real machine (Ubuntu 26.04) with the EOS R100:root:canonwebapi 0660after the install and after two real power-ons (desktop user keeps its ACL);tools/Test-Camera.ps1against the service: 14/14 (live view, 4 captures in 1.2-1.3 s, 3 flash changes each followed by a capture, power cycle with the live view running, capture after it);/opt/canonwebapiand the user; the camera returns toroot:plugdev 0664.main, then thev1.5.0.0tag on the owner's go-ahead.🤖 Generated with Claude Code