refactor: pid1-exe#22
Conversation
- Remove implicit default attributes - Add `pub(crate)` to `user_id` + `group_id` for consistency
psibi
left a comment
There was a problem hiding this comment.
Refuse to compile on Windows (or any other non-unix platform)
We want this to compile on Windows platform as this is often a dependency on our projects which can be used on Windows platforms.
|
TL;DR: You can still support windows fine, but as
Uhh... then that is a mistake on your end? You clearly have no Windows support in the CLI project, so compiling it for Windows achieves nothing. For the library, it's the same concern and integration should properly communicate that. Presently your lib docs and README advise the following: use pid1::Pid1Settings;
use std::time::Duration;
fn main() {
Pid1Settings::new()
.enable_log(true) // Optional: for debugging
.timeout(Duration::from_secs(2)) // Optional: timeout for graceful shutdown
.launch()
.expect("Launch failed");
// Rest of the logic...
println!("Hello world");
}When your actual project is cross-platform and wants to integrate It's literally 2 lines?:
+[target.'cfg(unix)'.dependencies]
pid1 = "0.1.6"
fn main() {
+ #[cfg(unix)]
pid1::Pid1Settings::new()
.enable_log(true) // Optional: for debugging
.timeout(std::time::Duration::from_secs(2)) // Optional: timeout for graceful shutdown
.launch()
.expect("Launch failed");
// Rest of the logic...
println!("Hello world");
}That's sufficient no? Presently your Windows platform support for compilation with the library crate is just: Lines 26 to 35 in 2e8ec76 Lines 106 to 112 in 2e8ec76 So you're building the Why would you want to hide that detail for such a minor convenience? (it's not exactly helpful to imply Windows support at a glance, but then realize that's not the case at all, far better to be explicit) FWIW, besides
Again, the changes in this PR are not breaking for these consumers of the Making the change to the library (via a separate PR) would require a semver bump to |
|
If the improvement to handling platforms correctly is still an issue despite my feedback, let me know and I can remove that from this PR. Are the other changes welcomed? |
psibi
left a comment
There was a problem hiding this comment.
Overall LGTM, I believe the CI should pass.
|
|
||
| /// Process to run | ||
| #[arg(required = true)] | ||
| #[arg(trailing_var_arg = true)] |
There was a problem hiding this comment.
Any reason why we are removing required = true ?
There was a problem hiding this comment.
It can be added back if you prefer it for clarity.
I removed it as it is implicitly true as a default (for a positional arg). Similarly a positional arg of Vec is implicitly required = false.
|
It is late here, I'll look into the test failures tomorrow. Not quite sure from the failure outputs on Ubuntu runners why two of the tests failed from these PR changes. |
|
I don't see any relationship between the Consulting Gemini as I'm not familiar with your test suite:
Unfortunately with that context, and my lack of expertise in this scenario, I could not deduce how much of this advice from Gemini was legitimate.
I looked at our test suite and we specifically:
I'm not sure exactly when you'd need Other notes:
|
|
I've gone ahead an made the changes to drop I've also revised your The output from 2023 is from a different 2023: Lines 15 to 23 in a416936 2026: pid1-rs/pid1/examples/simple.rs Lines 15 to 31 in 2e8ec76 I'm not even sure how relevant the information is in this document now that you've got what looks to be the equivalent tests covered in your The
Log for process not running as PID 1 was dropped since too: Lines 43 to 57 in a416936 Lines 92 to 105 in 2e8ec76 Logs can appear a bit racey for the immediate exit, where it appears to reap before the logs in this case, but can equally output as reaped after: $ docker run --rm --name pid1rs pid1rstest
pid1-rs: Process running as PID 1
pid1-rs: Reaped PID 7
In the simple process, going to sleep. Process ID is 7
Args: ["/simple"] |
|
@psibi Could you please run the workflows again to confirm tests in CI pass? Thank you |
This PR is only applying changes to the
pid1-exepackage, I've avoided touching the library until feedback of this PR is received.--helpoutput. I tidied up the CLI code a bit along the way, it should not introduce any regressions.Functional changes (beyond
--helpoutput)--is now optional, theclapparser won't swallow options from the RHS of thecommandpositional arg.Cargo.tomlnow restricts thepid1dep to unix platforms only. As the other deps are cross-platform, it's best practice AFAIK to leave those without a constraint (thus they are downloaded/compiled), even though the CLI itself will fail to compile.Compilation for Windows now fails like so:
The prior "implementation" seemed rather misleading? For which no context was available on related PRs where these additions slipped in (presumably the intent was to avoid noisy compile errors?):
--helpoutput comparison0.1.6:Revised via this PR:
Diff from
0.1.6:--workdirdescription typodirecory=>directorydescription typo ~~proess=>process`~~ (EDIT: Revised description entirely)--envoption value format communicates expected structure--versionoptionFull change overview
The diff should be fairly straight-forward, but if additional context for anything is needed, hopefully this documents my reasoning well enough 😅
cfgattributes for conditional compilation (along withwindowscompilation "support").unixplatforms are actually supported, make that explicit with an compilation failure on unsupported platforms.compile_error!is used for a friendly failure message.#[cfg(target_family = "unix")]shortened to alias#[cfg(unix)]clap:usagecrate feature was added for generating the usage in--helpoutput, previously this was blank. Alternatively it could be set with a hard-coded string if not adding theusagefeature.Pid1Apprefactored:user_id/group_idwere added, they were excluded frompub(crate)visibility already established on other fields in the struct. Added for consistency.commandattribute annotating the struct adds a--versionoption andabout(-h/--help) that sourcesdescriptionfromCargo.toml. The existing description inCargo.tomlwas not accurate, I iterated through a few variations before settling on the one committed, though I'm not sure how well "signal handling" maps to what is effectively only support for graceful exit? (SIGCHLDaside for zombie reaping)--timeoutdescription revised to more clearly communicate it's a grace period that escalates toSIGKILL, rather than just a timeout on the child process exiting without context to an outcome.argattributes adjusted to remove implicit defaults. Additionally--env+--timeouthave more helpful contextualvalue_nameset, while--user-id/--group-idremove the_(the previous values here were implicit already from the field name).commandfieldargattribute now hastrailing_var_arg = true.--separator is now optional between the wrappedcommandandpid1-exeCLI options.--,clapwould treat anything other than positional args on the RHS ofcommandparsed as part of thepid1-exeoptions (eg:--help).--envremoved thevalue_parserin favor of aimpl FromStrand wrapper typeKeyValue(OsString, OsString)instead of(OsString, OsString).bpaf).KeyValuetype from thewasmiprojectclapCLI (which in an earlier iteration had a familiar looking error string).Pid1App::run()refactored:child=>cmdfor theletbinding that's actually the configured/parsed command to execute. There's also no need for the rebinding directly after to set the args. The args can use theVectype as-is instead of slice syntax (the vec is casted implicitly to a slice).git blamewas potential race condition without any other details.pid != 1condition, but registering the signals is only relevant whenpid == 1, so would be redundant (given theexec/exitpaths).pid1lib, it seems more appropriate to have a convenience in the lib for a CLI to call, simplifying any CLI implementation.pid != 1conditional does not need to wrap subsequent logic in anelsebranch, as it already performsexecinto the command, with process exit if that fails.pid1lib was of no value, but could not express such tersely without language that was already similarly conveyed in the small logic for that branch 😅 (thus assumed reader is familiar with why)--verbosewas used to highlight when not PID1, I thinktini/dumb-initcan do such. I could add a follow-up PR addressing that.let childbinding with.spawn()+match { ... }? Simplified to using.spawn().unwrap_or_else( ... ).