Skip to content

Feat/12394 v2 Prepare for release 1.0.2-dev (init command, CPU ranges, Suricata spec) - #30

Closed
KEIAHNY wants to merge 4 commits into
mainfrom
12394-feat-release-1.0.2-dev-v2
Closed

KEIAHNY wants to merge 4 commits into
mainfrom
12394-feat-release-1.0.2-dev-v2

Conversation

@KEIAHNY

@KEIAHNY KEIAHNY commented Sep 27, 2026 •

Copy link
Copy Markdown
Collaborator

PR Type

Enhancement, Documentation


Description

  • Add init command generating default configuration file

  • Support CPU range expansion in max_cpu_usage_vec

  • Document required Suricata branch and commit

  • Bump version to 1.0.2-dev


Diagram Walkthrough

flowchart LR
  CLI["CLI arguments"] -- "init subcommand" --> Init["config_gen::init writes DEFAULT_CONFIG"]
  CLI -- "var -C cpu values" --> Parse["parse_cpu_list expands ranges"]
  Conf["suriconf.yaml max_cpu_usage_vec"] --> Find["find_max_cpu_usage_vec expands ranges"]
  Parse --> CPUs["Vec<u64> CPUs"]
  Find --> CPUs
Loading

File Walkthrough

Relevant files
Enhancement
5 files
yaml.rs
Add CPU range parsing and expansion helpers                           
+38/-11 
argument.rs
Add Init subcommand and string CPU list                                   
+14/-2   
main.rs
Handle init command before main workflow                                 
+10/-1   
config_gen.rs
New module writing default config file                                     
+16/-0   
lib.rs
Register config_gen module and DEFAULT_CONFIG constant     
+4/-1     
Documentation
2 files
README.md
Update Suricata version, branch, and init usage                   
+14/-8   
ISSUES.md
Minor updates to issues documentation                                       
+0/-3     
Configuration changes
2 files
suriconf.yaml
Bump version and update default paths                                       
+4/-4     
Cargo.toml
Bump package version to 1.0.2-dev                                               
+1/-1     
Additional files
3 files
suricata.yaml +0/-2347
suricata.yaml.in +0/-2339
suriconf.yaml.in +0/-6     

@KEIAHNY KEIAHNY self-assigned this Sep 27, 2026
@github-actions

Copy link
Copy Markdown

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Unbounded allocation

expand_cpu_range collects (start..=end) into a Vec with no upper bound on the range size. A value like -C 0-99999999999 from the CLI or max_cpu_usage_vec: ["0-99999999999"] in the config file will attempt to allocate a Vec of ~100 billion u64 entries, causing memory exhaustion and an OOM abort. Consider validating that end - start stays within a sane bound (e.g., the number of CPUs on the system, or a small constant) before collecting.

fn expand_cpu_range(s: &str) -> Option<Vec<u64>> {
    let s = s.trim();
    match s.split_once('-') {
        Some((start, end)) => {
            let start: u64 = start.trim().parse().ok()?;
            let end: u64 = end.trim().parse().ok()?;
            (start <= end).then(|| (start..=end).collect())
        }
        None => Some(vec![s.parse().ok()?]),
    }
Inaccurate doc

The doc comment for the Init command reads "Change directory for generated Suriconf configuration file", which describes the previous semantics of a different command and does not match what Init does (generate the default Suriconf configuration file). This text becomes the CLI help output shown by -h/--help, so it will confuse users of the newly documented suriconf init command.

/// Change directory for generated Suriconf configuration file

Init {

@github-actions

Copy link
Copy Markdown

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
Support comma-separated CPU ranges during parsing

The function only supports single values or single ranges, but typical CPU-set
syntax (both for Suricata and common CLI usage) is comma-separated, e.g. 0-2,5,7.
Input like 0-2,5 currently fails to parse and causes a panic via the caller's
.expect(). Split on commas first and expand each part, so combined range/list
expressions are handled correctly.

src/yaml.rs [1050-1060]

 fn expand_cpu_range(s: &str) -> Option<Vec<u64>> {
     let s = s.trim();
-    match s.split_once('-') {
-        Some((start, end)) => {
-            let start: u64 = start.trim().parse().ok()?;
-            let end: u64 = end.trim().parse().ok()?;
-            (start <= end).then(|| (start..=end).collect())
+    let mut cpus = Vec::new();
+    for part in s.split(',') {
+        let part = part.trim();
+        if part.is_empty() {
+            return None;
         }
-        None => Some(vec![s.parse().ok()?]),
+        match part.split_once('-') {
+            Some((start, end)) => {
+                let start: u64 = start.trim().parse().ok()?;
+                let end: u64 = end.trim().parse().ok()?;
+                if start > end {
+                    return None;
+                }
+                cpus.extend(start..=end);
+            }
+            None => cpus.push(part.parse().ok()?),
+        }
     }
+    Some(cpus)
 }
Suggestion importance[1-10]: 5

__

Why: The current expand_cpu_range fails on inputs like 0-2,5, and such a token could appear via a single CLI argument or a string value in the YAML sequence, causing a panic. The improved code correctly implements comma-splitting, but since the CLI uses space as value_delimiter and YAML sequences are already split, this is a robustness enhancement rather than a critical bug.

Low
General
Handle init errors gracefully without panicking

Panicking on a user-facing error such as a refused overwrite or unwritable path
prints a noisy "thread panicked" backtrace instead of a clean CLI message. Print the
error to stderr and exit with a non-zero status code, consistent with typical CLI
behavior.

src/main.rs [26-31]

     if let Some(Commands::Init { output, force }) = &args.cmd {
         if let Err(e) = init(output, *force) {
-            panic!("{e}");
+            eprintln!("Error: {e}");
+            process::exit(1);
         }
         process::exit(0);
     }
Suggestion importance[1-10]: 5

__

Why: Replacing panic! with eprintln! and a non-zero exit code gives a clean CLI error message without a backtrace, which is appropriate for user-facing errors like a refused overwrite. It is a valid but non-critical error-handling improvement.

Low
Create output parent directories in init

fs::write fails with a raw OS error if the target directory does not exist, which is
likely when users pass a nested path like ./config/suriconf.yaml. Create parent
directories before writing so the --output option works for any valid path.

src/config_gen.rs [7-16]

 pub fn init(output: &PathBuf, force: bool) -> io::Result<()> {
     if output.exists() && !force {
         return Err(io::Error::new(
             io::ErrorKind::AlreadyExists,
             format!("refusing to overwrite {:?} (use --force)", output),
         ));
     }
+    if let Some(parent) = output.parent() {
+        if !parent.as_os_str().is_empty() {
+            fs::create_dir_all(parent)?;
+        }
+    }
     fs::write(output, DEFAULT_CONFIG)?;
     Ok(())
 }
Suggestion importance[1-10]: 5

__

Why: fs::write will fail for nested output paths like ./config/suriconf.yaml when the directory does not exist, and the suggested fs::create_dir_all on the parent fixes that. The change is correct and low-risk, but only affects non-default output paths, so impact is moderate.

Low
Include invalid input in parse error message

When parsing fails, this panics with a generic message that does not indicate which
value was invalid, making CLI usage errors hard to diagnose (e.g. --cpu 8-x or an
empty token). Include the offending input in the error so users can immediately see
what failed to parse.

src/yaml.rs [864-866]

         self.max_cpu_usage_vec = if let Some(Commands::Var { max_cpu_usage_vec: Some(max_cpu_usage_vec), .. }) = &args.cmd {
-            parse_cpu_list(&max_cpu_usage_vec).expect("Unable to parse max cpu usage vector.")
+            parse_cpu_list(&max_cpu_usage_vec)
+                .unwrap_or_else(|| panic!("Unable to parse max cpu usage vector: {max_cpu_usage_vec:?}."))
         }  else {
Suggestion importance[1-10]: 3

__

Why: Including the offending max_cpu_usage_vec values in the panic message is a small diagnostic improvement that helps users identify malformed input like --cpu 8-x. The suggestion is accurate but offers only a marginal improvement to error reporting.

Low
  • Author self-review: I have reviewed the PR code suggestions, and addressed the relevant ones.

@KEIAHNY

KEIAHNY commented Sep 28, 2026

Copy link
Copy Markdown
Collaborator Author

Closing – applying changes.

@KEIAHNY KEIAHNY closed this Sep 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant