Skip to content

Conversation

mviswanathsai
Copy link
Contributor

@mviswanathsai mviswanathsai commented Feb 9, 2025

While reviewing the satellite code, I realized that DefaultZotConfig is a misleading name. Initially, I mistook it for a constant representing a default configuration for the ZotConfig type.

As we continue building the satellite, we may introduce additional configuration options within DefaultZotConfig to facilitate marshaling config.json. Given this evolution, the name DefaultZotConfig could become increasingly ambiguous.

To improve clarity, I have refactored the structure of ZotConfig (previously DefaultZotConfig) for better readability.

Additionally, I will reword certain parts for further clarity. Would love to hear what you think about this change. We can further refine by adding more configurable fields (that can be un-marshalled), using pointers for optional fields, etc.

Summary by CodeRabbit

  • New Features

    • Introduced a new configuration file with updated storage, HTTP, and logging settings.
  • Refactor

    • Improved configuration handling and updated remote registry URL assignments for better consistency.
    • Simplified function return types for error handling.
    • Enhanced context cancellation support to provide more robust shutdown behavior.
  • Chores

    • Removed deprecated configuration options and legacy validation steps.
    • Simplified configuration structure by eliminating outdated extension settings.
    • Updated paths for configuration files to reflect new naming conventions.
    • Removed the old default Zot configuration and related methods.

Copy link
Contributor

coderabbitai bot commented Feb 9, 2025

Walkthrough

This pull request modifies the configuration handling and runtime commands in multiple components. Key changes include updating the type of the defaultZotConfig variable to registry.ZotConfig, revising method calls for configuration reading, and removing the DefaultZotConfig structure along with its associated methods. The introduction of a new zot-config.json file replaces the old configuration file, and several adjustments to error handling and logging improve clarity. The overall structure simplifies the configuration management and runtime command setup.

Changes

File(s) Change Summary
cmd/container_runtime/containerd.go
cmd/container_runtime/crio.go
cmd/main.go
Updated defaultZotConfig type from registry.DefaultZotConfig to registry.ZotConfig; modified method calls for reading configuration and obtaining URLs.
registry/default_config.go Removed the DefaultZotConfig structure and its associated methods, eliminating previous configuration management functionality.
internal/utils/utils.go Removed the LaunchDefaultZotRegistry function, which handled launching the default Zot registry.
registry/launch-registry.go Changed LaunchRegistry function signature to return a single error instead of a tuple.
registry/zot_config.go Introduced ZotConfig struct and related types; added methods for configuration handling.
registry/config.json
zot-config.json
config.json
internal/config/constants.go
Removed registry/config.json; added zot-config.json with new settings; updated paths and properties in config.json and constants.
internal/config/config.go Renamed error collection variable for clarity and improved error handling logic.

Possibly related PRs

  • bug fixes in robot account in ground control and fixing unauthorized error while pulling the images #69: The changes in the main PR and the retrieved PR are related as both modify the handling of the defaultZotConfig variable, specifically changing its type from registry.DefaultZotConfig to registry.ZotConfig, affecting how the configuration is processed in their respective functions.
  • Fix the ZTR process #97: The changes in the main PR are related to those in the retrieved PR as both involve modifications to the defaultZotConfig variable type in functions that are part of the container runtime setup, specifically impacting the SetupContainerRuntimeCommand function.
  • Decouple zot registry from satellite #23: The changes in the main PR and the retrieved PR are related as both modify the type of the defaultZotConfig variable from registry.DefaultZotConfig to registry.ZotConfig in their respective functions, indicating a direct connection at the code level.

Suggested reviewers

  • Vad1mo

Poem

Hopping through the code with glee,
I nibbled on configs, one, two, three.
Carrots of change light up my day,
With structured hops, I lead the way.
A bunny's cheer in every byte—
CodeRabbit sings, "All is bright!"
🥕🐰

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@github-actions github-actions bot added the golang label Feb 9, 2025
@mviswanathsai
Copy link
Contributor Author

CC: @bupd @Vad1mo

@Mehul-Kumar-27
Copy link
Collaborator

@mviswanathsai, it would be great if you could add support for extensions in Zot as well. Please take a look at this doc: https://zotregistry.dev/v2.1.2/admin-guide/admin-configuration/#extensions. You can skip the UI extension; the most required ones are Scrub and Sync.

@mviswanathsai
Copy link
Contributor Author

@Mehul-Kumar-27 I see... scrub seems super useful. I will add the config options in the config struct. And then parse it and update the zot config accordingly. Will that be it, or am I missing something?

@Mehul-Kumar-27
Copy link
Collaborator

@Mehul-Kumar-27 I see... scrub seems super useful. I will add the config options in the config struct. And then parse it and update the zot config accordingly. Will that be it, or am I missing something?

Yes, scrub only has one field enable just add the configuration so that user can add that, for sync the structure would be quite different. You can look at this for more info how to structure the struct for the sync. https://github.com/project-zot/zot/tree/main/pkg/extensions/sync

@mviswanathsai
Copy link
Contributor Author

Right, thanks for the heads up. As you said, scrub is pretty straight-forward. I will have to take a deeper look at sync.

@mviswanathsai
Copy link
Contributor Author

@Mehul-Kumar-27 it seems like sync is used for mirroring purposes. If we allow the zot registry to directly mirror from the upstream repo, what will be the role of satellite in that case?

@mviswanathsai
Copy link
Contributor Author

Should we add a check to satellite to check if an artifact is already present in the local repository before pulling from the upstream to handle these cases?

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (7)
registry/default_config.go (7)

82-88: Consider handling IPv6 addresses in URL generation.

The GetLocalRegistryURL method might not handle IPv6 addresses correctly as they need to be enclosed in square brackets.

 func (c *ZotConfig) GetLocalRegistryURL() string {
 	address := c.HTTP.Address
 	if !strings.HasPrefix(address, "http://") && !strings.HasPrefix(address, "https://") {
 		address = "http://" + address
 	}
-	return fmt.Sprintf("%s:%s", address, c.HTTP.Port)
+	// Handle IPv6 addresses
+	if strings.Contains(address, ":") && !strings.Contains(address, "://") {
+		parts := strings.Split(address, "://")
+		if len(parts) == 2 {
+			return fmt.Sprintf("%s://[%s]:%s", parts[0], parts[1], c.HTTP.Port)
+		}
+		return fmt.Sprintf("http://[%s]:%s", address, c.HTTP.Port)
+	}
+	return fmt.Sprintf("%s:%s", address, c.HTTP.Port)

90-110: Consider adding file existence check before opening.

The ReadZotConfig function could benefit from checking if the file exists before attempting to open it.

 func ReadZotConfig(filePath string, zotConfig *ZotConfig) error {
+	if _, err := os.Stat(filePath); os.IsNotExist(err) {
+		return fmt.Errorf("config file does not exist: %s", filePath)
+	}
 	file, err := os.Open(filePath)

151-179: Consider caching reflection results for better performance.

The validateExtensionsOrder function uses reflection for each validation. Consider caching the field information if this function is called frequently.

+var extensionFieldsCache struct {
+	once   sync.Once
+	fields []reflect.StructField
+}
+
 func validateExtensionsOrder(extensions *ZotExtensions) error {
-	// Extract the non-nil extension fields in the order they appear
 	var usedExtensions []string
 
 	val := reflect.ValueOf(extensions)
-	typ := val.Type()
+	
+	// Initialize cache if needed
+	extensionFieldsCache.once.Do(func() {
+		typ := reflect.TypeOf((*ZotExtensions)(nil)).Elem()
+		fields := make([]reflect.StructField, typ.NumField())
+		for i := 0; i < typ.NumField(); i++ {
+			fields[i] = typ.Field(i)
+		}
+		extensionFieldsCache.fields = fields
+	})
 
 	for i := 0; i < val.NumField(); i++ {
 		field := val.Field(i)
 		if !field.IsNil() { // Only include non-nil fields (enabled extensions)
-			usedExtensions = append(usedExtensions, typ.Field(i).Tag.Get("json"))
+			usedExtensions = append(usedExtensions, extensionFieldsCache.fields[i].Tag.Get("json"))
 		}
 	}

181-229: Consider adding TLS certificate validation.

The validateSyncConfig function could include validation of TLS certificates when TLSVerify is true and CertDir is specified.

 		if reg.TLSVerify && reg.CertDir != "" {
+			if _, err := os.Stat(reg.CertDir); os.IsNotExist(err) {
+				return fmt.Errorf("sync.registries[%d].certDir does not exist: %s", i, reg.CertDir)
+			}
+			// Optionally, validate certificate files
+			certFiles, err := os.ReadDir(reg.CertDir)
+			if err != nil {
+				return fmt.Errorf("sync.registries[%d].certDir is not readable: %w", i, err)
+			}
+			if len(certFiles) == 0 {
+				return fmt.Errorf("sync.registries[%d].certDir contains no certificates", i)
+			}
 		}

239-249: Consider validating port number range.

The validateHTTPConfig function should check if the port number is within the valid range (1-65535).

 	portPattern := `^\d{1,5}$`
 	if matched, _ := regexp.MatchString(portPattern, http.Port); !matched {
 		return fmt.Errorf("http.port must be a valid numeric string")
 	}
+	port, _ := strconv.Atoi(http.Port)
+	if port < 1 || port > 65535 {
+		return fmt.Errorf("http.port must be between 1 and 65535")
+	}

251-257: Consider case-insensitive log level validation.

The validateLogConfig function should handle log levels case-insensitively for better user experience.

 func validateLogConfig(log ZotLogConfig) error {
 	validLevels := map[string]bool{"debug": true, "info": true, "warn": true, "error": true}
-	if !validLevels[log.Level] {
+	if !validLevels[strings.ToLower(log.Level)] {
 		return fmt.Errorf("log.level must be one of: debug, info, warn, error")
 	}

259-265: Consider adding minimum interval validation.

The validateInterval function should enforce a minimum interval to prevent excessive resource usage.

 func validateInterval(interval string) error {
-	_, err := time.ParseDuration(interval)
+	duration, err := time.ParseDuration(interval)
 	if err != nil {
 		return fmt.Errorf("invalid interval format: %w", err)
 	}
+	if duration < time.Minute {
+		return fmt.Errorf("interval must be at least 1 minute")
+	}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6b3839b and effcf04.

📒 Files selected for processing (2)
  • cmd/root.go (1 hunks)
  • registry/default_config.go (2 hunks)
🔇 Additional comments (6)
cmd/root.go (3)

100-104: LGTM! Type and method name changes improve clarity.

The update from DefaultZotConfig to ZotConfig and ReadConfig to ReadZotConfig better reflects the purpose of these entities.


106-108: LGTM! Added validation improves robustness.

The new validation step ensures configuration correctness before proceeding with registry setup.


110-110: LGTM! Method call updated for consistency.

The GetLocalRegistryURL method call is correctly updated to work with the new ZotConfig type.

registry/default_config.go (3)

15-18: LGTM! Well-defined extension order.

The predefined order of extensions helps maintain consistency and prevents configuration errors.


20-80: LGTM! Well-structured configuration types.

The new configuration types are well-organized and properly tagged for JSON serialization. The modular structure improves maintainability and makes the configuration more extensible.


114-148: LGTM! Comprehensive validation logic.

The Validate method thoroughly checks all configuration aspects, including required fields and nested structures.

@Mehul-Kumar-27
Copy link
Collaborator

@Mehul-Kumar-27 it seems like sync is used for mirroring purposes. If we allow the zot registry to directly mirror from the upstream repo, what will be the role of satellite in that case?

We discussed the sync and scrub features in one of our weekly meetings, and we wanted to include them in the Zot configuration. However, there are some nuances to this, as Zot does not provide these extensions in the way we currently start it. For these extensions to work, Zot requires the full binary, as they fall under specific build tags. A possible workaround is to build the satellite with these build tags. While we can add build tags later, for now, these configs need to be included in the Zot configuration.

@mviswanathsai
Copy link
Contributor Author

mviswanathsai commented Feb 12, 2025

Right, I wanted to ask about the mention of "full binary" in the zot docs too. Thanks.

We can handle that in another PR if you want. We'll need to check for the extensions field being not nil (Edit: and check that the extensions are enabled), and then pull the right binary for zot accordingly. There might be other hidden nuances to this change though. Do you see anything else?

@Vad1mo
Copy link
Contributor

Vad1mo commented Feb 18, 2025

Should we add a check to satellite to check if an artifact is already present in the local repository before pulling from the upstream to handle these cases?

Makes sense yes

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (5)
cmd/root.go (2)

103-103: Improve error messaging context.
It might be more informative to log a message like "error reading zot config" here, since it’s specifically the config-read step failing, not actually the Zot server launch.

- log.Error().Err(err).Msg("error launching default zot registry")
+ log.Error().Err(err).Msg("error reading zot config")

107-107: Set name clarity.
SetRemoteRegistryURL(...) is a bit ambiguous, given that it merges local and remote semantics. Consider adjusting to SetLocalRegistryURL(...) if that’s the actual intention.

registry/zot_config.go (3)

20-28: Use pointers for optional fields if extended further.
Currently, Extensions is a pointer, but if other fields (like DistSpecVersion or RemoteURL) become optional, consider pointers for clearer distinction of unset vs. empty.


150-179: Strict extension ordering.
This approach ensures that critical features like sync or scrub run in the defined sequence. However, it may be beneficial to allow more flexibility or user-defined ordering if future requirements change.


239-249: HTTP config checks are straightforward.
Verifying address and numeric port is sufficient here. Potential future expansions might account for TLS settings.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 16db996 and f422b12.

📒 Files selected for processing (4)
  • cmd/root.go (1 hunks)
  • internal/utils/utils.go (1 hunks)
  • registry/launch-registry.go (2 hunks)
  • registry/zot_config.go (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (15)
registry/launch-registry.go (2)

7-7: Refactor to single error return makes the usage clearer.
This change from (bool, error) to returning only error eliminates extra logic and simplifies the calling code.


18-18: Consistent error handling and return type.
Replacing false, err with return err and true, nil with return nil ensures consistency with the updated function signature. Good job removing the boolean return code to clarify intent.

Also applies to: 21-21

internal/utils/utils.go (1)

53-53: Direct assignment of the launch outcome to err is concise.
Previously returning both a boolean and an error could add overhead to decision-making. Now it’s straightforward to check if err != nil for failures.

cmd/root.go (1)

100-101: Explicit ZotConfig usage increases clarity.
Renaming from DefaultZotConfig to ZotConfig aligns with the refactoring. The new naming is direct and avoids confusion about whether it’s a fallback or a configurable default.

registry/zot_config.go (11)

1-19: File organization is well structured.
Good job creating a standalone file to encapsulate all Zot config logic. The var validExtensionsOrder is a beneficial reference for extension validation.


29-32: Good approach for grouping extension logic.
Defining separate structs like ZotExtensions helps maintain modular design and can be extended easily for more features like search or metrics.


34-38: Clarify usage of CredentialsFile.
If multiple registries share the same credentials, consider clarifying how this file is structured or if per-registry credentials are possible.


64-67: Scrub interval usage.
Ensure the user is aware that an incorrect interval format will prevent Scrub from running. It's already validated below, so that’s helpful.


82-88: Return format for local registry URL is flexible yet consistent.
Appending the scheme if missing is user-friendly. Great approach to guarantee a valid format for consumers.


112-148: Extensive validation is commendable.
The multi-step validations for storage, HTTP, log, and extensions reduce runtime errors. Consider logging partial validity info for troubleshooting.


181-229: Rich sync config validation.
Checking each registry’s poll intervals, URLs, and tag constraints up-front helps avoid mysterious failures. Great job ensuring it’s robust and thorough.


251-257: Log level validation is beneficial for debugging.
Restricting log levels to recognized values helps prevent misconfiguration.


259-265: Interval parsing.
Time-based string parsing is straightforward and consistent with Go’s standard library.


267-269: Flexibly set remote URL.
Using a helper method for setting RemoteURL is convenient for dynamic adjustments.


271-279: indexOf utility is concise.
A small helper like this keeps your code DRY and more readable, especially when validating extension order or searching arrays.

@Vad1mo
Copy link
Contributor

Vad1mo commented Mar 5, 2025

Makes sense

@mviswanathsai
Copy link
Contributor Author

I need to look into the build process for the Zot registry.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (4)
registry/zot_config.go (3)

20-27: Consider documenting optional fields.

While the ZotConfig struct is straightforward, consider adding field-level comments or docstrings to clarify their usage, especially for RemoteURL and Extensions, as they may be optional or have special usage conditions.


40-50: Add doc comments for clarity.

The RegistryConfig fields are self-explanatory but would benefit from inline comments to convey their intended usage (e.g., PollInterval, OnDemand).


82-88: Handle existing ports in the address.

If the user-supplied c.HTTP.Address already includes a port, concatenating c.HTTP.Port may result in a malformed URL (e.g., “https://mydomain:8080:5000”). Consider parsing the address first and conditionally appending c.HTTP.Port.

internal/utils/utils.go (1)

94-97: Consider returning the cancel function.

By discarding the cancel function from signal.NotifyContext, the caller cannot manually cancel if needed. Returning (context.Context, context.CancelFunc) is a common pattern that grants more control.

-func SetupContext(context context.Context) context.Context {
-	ctx, _ := signal.NotifyContext(context, syscall.SIGTERM, syscall.SIGINT)
-	return ctx
+func SetupContext(parent context.Context) (context.Context, context.CancelFunc) {
+	ctx, cancel := signal.NotifyContext(parent, syscall.SIGTERM, syscall.SIGINT)
+	return ctx, cancel
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f422b12 and caa4b20.

📒 Files selected for processing (4)
  • cmd/container_runtime/crio.go (4 hunks)
  • cmd/root.go (4 hunks)
  • internal/utils/utils.go (2 hunks)
  • registry/zot_config.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • cmd/container_runtime/crio.go
  • cmd/root.go
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (20)
registry/zot_config.go (19)

1-13: No issues found in package declaration and imports.

All imported packages appear to be actively used in the code.


15-18: The validExtensionsOrder declaration looks good.

It provides a clear reference for enforcing a specific loading sequence for extensions.


29-32: The ZotExtensions struct is concise.

Defining separate fields for each extension (sync, scrub) is clear.


34-38: SyncConfig looks coherent.

It cleanly captures required sync parameters, with “enable” gating further validations.


52-57: ContentConfig is straightforward.

Ensures prefix, destination, and optional tag filters are well-defined.


59-62: TagsConfig is minimal and purposeful.

Regex-based approach plus a semver boolean is appropriate.


64-67: ScrubConfig fields are consistent.

Enabling the scrub functionality with an interval is neatly modeled.


69-71: ZotStorageConfig is concise.

Root directory is the sole requirement, which is validated.


73-76: ZotHTTPConfig is well-defined.

Address and port are validated later, ensuring correct usage.


78-80: ZotLogConfig is minimal and effective.

Captures log level for validation against known levels.


90-110: [Duplicate from previous review] Recommend validating configuration after reading.

As noted in a past review, calling c.Validate() at the end of ReadZotConfig helps detect invalid data earlier, even before using the config.


112-148: Validation logic appears robust.

All core checks are properly handled for required fields, HTTP, logs, and optional extensions.


181-229: validateSyncConfig is thorough.

Proper checks for URLs, intervals, and content structure.


231-238: validateTagsConfig is concise and covers potential regex errors.

No additional concerns.


239-249: validateHTTPConfig covers empty address and port checks.

The patterns match the typical constraints for numeric ports.


251-257: validateLogConfig enumerates valid levels cleanly.

No issues here.


259-265: validateInterval properly uses time.ParseDuration.

Catches invalid time formats.


267-269: SetZotRemoteURL is straightforward.

Simply assigns the new value.


271-279: indexOf effectively finds the index of a string in a slice.

Implementation is correct and returns -1 if not found.

internal/utils/utils.go (1)

53-58: Simplified error handling is approved.

Eliminating intermediate variables and checking err directly is more concise and still handles failure paths clearly.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (4)
registry/zot_config.go (4)

19-26: Structure looks good, but consider using pointers for optional fields.

The ZotConfig struct is well-structured with appropriate JSON tags. Since Extensions is already a pointer, consider making other optional fields pointers as well for consistency and to clearly indicate which fields are optional.


28-31: Consider making extension config structs pointers.

Since SyncConfig and ScrubConfig could be optional within the extensions, consider making them pointer types to avoid reflection-based nil checks that may cause panics.

type ZotExtensions struct {
-	Sync  SyncConfig  `json:"sync"`
-	Scrub ScrubConfig `json:"scrub"`
+	Sync  *SyncConfig  `json:"sync,omitempty"`
+	Scrub *ScrubConfig `json:"scrub,omitempty"`
}

81-87: Improve URL formation in GetRegistryURL.

The current implementation may lead to malformed URLs for certain inputs. Consider using the URL package to construct a proper URL.

func (c *ZotConfig) GetRegistryURL() string {
-	address := c.HTTP.Address
-	if !strings.HasPrefix(address, "http://") && !strings.HasPrefix(address, "https://") {
-		address = "http://" + address
-	}
-	return fmt.Sprintf("%s:%s", address, c.HTTP.Port)
+	scheme := "http"
+	address := c.HTTP.Address
+	
+	// Extract scheme if present
+	if strings.HasPrefix(address, "http://") {
+		address = strings.TrimPrefix(address, "http://")
+	} else if strings.HasPrefix(address, "https://") {
+		scheme = "https"
+		address = strings.TrimPrefix(address, "https://")
+	}
+	
+	return fmt.Sprintf("%s://%s:%s", scheme, address, c.HTTP.Port)
}

233-235: Enhance SetZotRemoteURL with validation.

The SetZotRemoteURL method should validate the URL before setting it to ensure it's properly formatted.

func (c *ZotConfig) SetZotRemoteURL(url string) {
+	// Validate URL format
+	_, err := url.Parse(url)
+	if err != nil {
+		// Log a warning or return an error
+		// For now, just set it anyway
+	}
	c.RemoteURL = url
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between caa4b20 and 66c1fc8.

📒 Files selected for processing (4)
  • cmd/root.go (3 hunks)
  • internal/utils/utils.go (0 hunks)
  • registry/config.json (1 hunks)
  • registry/zot_config.go (1 hunks)
💤 Files with no reviewable changes (1)
  • internal/utils/utils.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • cmd/root.go
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (2)
registry/zot_config.go (1)

89-109: Call Validate() after loading config in ReadZotConfig.

It's a good practice to validate the configuration immediately after loading it to fail fast on invalid data.

func ReadZotConfig(filePath string, zotConfig *ZotConfig) error {
	file, err := os.Open(filePath)
	if err != nil {
		return fmt.Errorf("could not open file: %w", err)
	}
	defer file.Close()

	// Read the file contents
	bytes, err := io.ReadAll(file)
	if err != nil {
		return fmt.Errorf("could not read file: %w", err)
	}

	// Unmarshal the JSON into a Config struct
	err = json.Unmarshal(bytes, &zotConfig)
	if err != nil {
		return fmt.Errorf("could not unmarshal JSON: %w", err)
	}
+	
+	// Validate the configuration
+	if err := zotConfig.Validate(); err != nil {
+		return fmt.Errorf("invalid configuration: %w", err)
+	}
	
	return nil
}
registry/config.json (1)

13-18: Review the default enabled state for the scrub extension.

The scrub extension is enabled by default with a 24-hour interval. Consider whether this is the desired default behavior, as it might be better to have extensions disabled by default and let users explicitly enable them.

Do users expect scrub to be enabled by default? The documentation or previous configurations might provide insight.

@mviswanathsai
Copy link
Contributor Author

mviswanathsai commented Mar 10, 2025

If I remove the cancel() func in handleRegistrySetup(), and then run go run main.go and then hit ctrl + c, the Zot registry shuts down as expected. What I expected was that the execution of main.go should be stopped, but it didn't.

I expected the ctx.Done() to receive the signal and thus the server would shut down (inside SetupServer). That didn't happen either. Thoughts? @Mehul-Kumar-27 @bupd

For more context: https://github.com/container-registry/harbor-satellite/blob/main/internal/server/server.go#L61-L63

g.Go(func() error {
                // this should be triggered, but it isn't if we remove the cancel() func call inside `handleRegistrySetup`
		<-a.ctx.Done()
		a.Logger.Warn().Msg("Shutting down server")
		err := a.Shutdown(a.ctx)
		if err != nil {
			return fmt.Errorf("error shutting down server: %w", err)
		}
		return nil
	})

Copy link
Contributor

@Vad1mo Vad1mo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest, we delegate the validation part, to ZOT or alternativly use the ZOT validation on our side

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
cmd/main.go (1)

84-85: Consider a more descriptive variable name for the read ZotConfig.
Currently, defaultZotConfig might suggest a hardcoded default rather than a user-defined configuration read from file. If desired, rename it to something like localZotCfg for clarity:

- var defaultZotConfig registry.ZotConfig
+ var localZotCfg registry.ZotConfig
registry/default_config.go (2)

30-58: Well-structured configuration types for sync functionality.

The new configuration types (SyncConfig, RegistryConfig, ContentConfig, TagsConfig) are well-organized with appropriate JSON tags and follow a clear hierarchy. This structure will make it easier to add more configurable fields in the future as mentioned in the PR objectives.

Consider adding descriptive comments to each struct field to document their purpose and valid values, which would further improve clarity for users.


193-200: Consider adding regex complexity limits.

While the regex validation correctly checks syntax, consider adding checks for regex complexity to prevent potential DoS vulnerabilities from complex patterns.

func validateTagsConfig(tags *TagsConfig) error {
	if tags.Regex != "" {
		if _, err := regexp.Compile(tags.Regex); err != nil {
			return fmt.Errorf("tags.regex is not a valid regex: %w", err)
		}
+		// Check for potentially problematic regex patterns
+		if strings.Count(tags.Regex, ".*") > 3 || strings.Count(tags.Regex, "(.+)+") > 0 {
+			return fmt.Errorf("tags.regex may contain inefficient patterns that could cause performance issues")
+		}
	}
	return nil
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6f27110 and aae2422.

📒 Files selected for processing (38)
  • registry/default_config.go (3 hunks)
  • cmd/container_runtime/containerd.go (1 hunks)
  • cmd/container_runtime/crio.go (3 hunks)
  • cmd/main.go (2 hunks)
  • registry/default_config.go (1 hunks)
  • cmd/main.go (1 hunks)
  • registry/default_config.go (4 hunks)
  • registry/default_config.go (5 hunks)
  • cmd/main.go (1 hunks)
  • registry/default_config.go (3 hunks)
  • cmd/container_runtime/crio.go (1 hunks)
  • cmd/main.go (1 hunks)
  • internal/utils/utils.go (1 hunks)
  • registry/launch-registry.go (2 hunks)
  • cmd/main.go (1 hunks)
  • cmd/main.go (0 hunks)
  • internal/utils/utils.go (1 hunks)
  • cmd/container_runtime/crio.go (1 hunks)
  • cmd/main.go (1 hunks)
  • registry/zot_config.go (1 hunks)
  • cmd/main.go (1 hunks)
  • internal/utils/utils.go (0 hunks)
  • registry/zot_config.go (0 hunks)
  • internal/utils/utils.go (1 hunks)
  • registry/zot_config.go (0 hunks)
  • registry/config.json (1 hunks)
  • internal/utils/utils.go (1 hunks)
  • cmd/main.go (1 hunks)
  • cmd/main.go (1 hunks)
  • registry/config.json (0 hunks)
  • registry/zot_config.go (0 hunks)
  • zot-config.json (1 hunks)
  • internal/config/config.go (2 hunks)
  • config.json (3 hunks)
  • registry/zot_config.go (0 hunks)
  • cmd/main.go (0 hunks)
  • internal/config/config.go (1 hunks)
  • internal/config/constants.go (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • registry/zot_config.go
🚧 Files skipped from review as they are similar to previous changes (19)
  • registry/zot_config.go
  • internal/config/config.go
  • registry/config.json
  • internal/utils/utils.go
  • cmd/container_runtime/containerd.go
  • registry/launch-registry.go
  • zot-config.json
  • internal/utils/utils.go
  • internal/config/config.go
  • registry/zot_config.go
  • internal/utils/utils.go
  • registry/default_config.go
  • internal/utils/utils.go
  • config.json
  • registry/config.json
  • cmd/container_runtime/crio.go
  • registry/default_config.go
  • registry/default_config.go
  • registry/default_config.go
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (12)
cmd/container_runtime/crio.go (1)

169-169: Method name change from GetLocalRegistryURL() to GetRegistryURL()

This change reflects the refactoring of the DefaultZotConfig to ZotConfig structure. The method name is now more concise and accurately represents its purpose without using redundant "Local" qualifier, which aligns with the PR objectives of improving clarity.

Make sure that all other places where the old method was used have been updated consistently to avoid any runtime errors.

internal/config/constants.go (1)

14-14: Config file path update to match refactored structure

The path update from ./registry/config.json to ./zot-config.json is consistent with the refactoring of DefaultZotConfig. This change improves clarity by using a more descriptive filename that directly indicates its purpose for Zot configuration.

Ensure that:

  1. The new path is used consistently across the codebase
  2. Any existing deployments are updated to use the new config file path
  3. Documentation is updated to reflect this change
registry/default_config.go (10)

7-7: Added URL package for configuration validation.

The net/url package has been appropriately added to support URL validation of registry endpoints in the new sync configuration.


24-26: Good documentation improvement for extensions configuration.

The additional comments and documentation link for the ZotExtensions struct provide helpful context about ordering requirements and direct users to the official documentation. This improves maintainability.


61-61: JSON tag consistency for ScrubConfig.

The JSON tag addition for the Enable field in ScrubConfig maintains consistency with the new configuration types.


86-87: Improved function naming and documentation.

Renaming from ReadConfig to ReadZotConfig makes the function's purpose clearer and more specific, addressing the PR objective of removing misleading naming.


105-105: Separated configuration reading from validation.

Removing validation from the ReadZotConfig function is a good separation of concerns. This allows the config to be read without validation, then validated separately when needed.


108-110: Clear documentation for validation function.

The improved comment explaining the purpose of validation and its relationship to Zot's behavior provides good context for why early validation is beneficial.


112-112: Enhanced error messages.

Using fmt.Errorf for error messages improves readability and maintainability compared to plain error strings. The explicit field names in error messages will help users understand exactly what needs to be fixed.

Also applies to: 116-116


133-138: Conditional validation for optional extensions.

The code now properly checks if sync is enabled before validating its configuration, which is a good practice for optional features.


143-200: Comprehensive validation for sync configuration.

The new validation functions provide thorough checking of all sync-related configurations:

  • Ensures registries are specified when sync is enabled
  • Validates URLs are properly formatted
  • Checks time intervals are valid
  • Verifies required fields are present
  • Validates regex patterns for tags

This robust validation will help prevent runtime errors and provide clear error messages to users.


203-203: Consistent error message formatting.

All validation functions now use a consistent error formatting style with fmt.Errorf, making error messages clearer and more maintainable.

Also applies to: 208-208, 216-216

@mviswanathsai
Copy link
Contributor Author

I suggest, we delegate the validation part, to ZOT or alternativly use the ZOT validation on our side

delegated the validation to Zot instead, and removed the data model.

@Vad1mo
Copy link
Contributor

Vad1mo commented Mar 24, 2025

@mviswanathsai ping

@mviswanathsai
Copy link
Contributor Author

Rebased and ready to go

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
registry/zot_config.go (1)

69-89: 🛠️ Refactor suggestion

Update function comment to match implementation and add validation.

The comment refers to "ReadConfig" but the function is named "ReadZotConfig". Also, the function doesn't perform validation after reading the configuration.

-// ReadConfig reads a JSON file from the specified path and unmarshals it into a ZotConfig struct.
+// ReadZotConfig reads a JSON file from the specified path and unmarshals it into a ZotConfig struct.
func ReadZotConfig(filePath string, zotConfig *ZotConfig) error {
	file, err := os.Open(filePath)
	if err != nil {
		return fmt.Errorf("could not open file: %w", err)
	}
	defer file.Close()

	// Read the file contents
	bytes, err := io.ReadAll(file)
	if err != nil {
		return fmt.Errorf("could not read file: %w", err)
	}

	// Unmarshal the JSON into a Config struct
	err = json.Unmarshal(bytes, &zotConfig)
	if err != nil {
		return fmt.Errorf("could not unmarshal JSON: %w", err)
	}
+	
+	// Validate the configuration
+	if err := zotConfig.Validate(); err != nil {
+		return fmt.Errorf("validation failed: %w", err)
+	}
	return nil
}
🧹 Nitpick comments (2)
registry/zot_config.go (2)

61-67: Consider supporting HTTPS by default in registry URL.

The method adds "http://" prefix if no scheme is present, which might not be secure for production environments. Consider either using "https://" by default or providing an option to specify the scheme.

func (c *ZotConfig) GetRegistryURL() string {
	address := c.HTTP.Address
	if !strings.HasPrefix(address, "http://") && !strings.HasPrefix(address, "https://") {
-		address = "http://" + address
+		// Use HTTPS by default for better security
+		address = "https://" + address
	}
	return fmt.Sprintf("%s:%s", address, c.HTTP.Port)
}

91-93: Add URL validation to SetZotRemoteURL method.

The method doesn't validate the URL before setting it, which could lead to issues if an invalid URL is provided.

func (c *ZotConfig) SetZotRemoteURL(url string) {
+	// Basic validation to ensure URL has a scheme
+	if !strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://") {
+		url = "https://" + url
+	}
	c.RemoteURL = url
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between aae2422 and ac7fc48.

📒 Files selected for processing (12)
  • cmd/container_runtime/containerd.go (1 hunks)
  • cmd/container_runtime/crio.go (4 hunks)
  • cmd/main.go (2 hunks)
  • config.json (3 hunks)
  • internal/config/config.go (3 hunks)
  • internal/config/constants.go (1 hunks)
  • internal/utils/utils.go (1 hunks)
  • registry/config.json (0 hunks)
  • registry/default_config.go (0 hunks)
  • registry/launch-registry.go (2 hunks)
  • registry/zot_config.go (1 hunks)
  • zot-config.json (1 hunks)
💤 Files with no reviewable changes (2)
  • registry/config.json
  • registry/default_config.go
🚧 Files skipped from review as they are similar to previous changes (8)
  • registry/launch-registry.go
  • internal/config/config.go
  • zot-config.json
  • cmd/container_runtime/containerd.go
  • cmd/main.go
  • internal/config/constants.go
  • config.json
  • cmd/container_runtime/crio.go
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (2)
internal/utils/utils.go (2)

18-18:

✅ Verification successful

Verify if newly imported scheduler package is used.

The scheduler package has been imported but there doesn't appear to be any new usage of it in the modified file. Ensure it's actually needed and remove if unnecessary.


🏁 Script executed:

#!/bin/bash
# Check if scheduler package is used in utils.go
rg -A 3 -B 3 "scheduler\." internal/utils/utils.go

Length of output: 595


Verified: Scheduler Package is Actively Used

The scheduler package is indeed utilized within the Init function in internal/utils/utils.go (see calls to scheduler.NewBasicScheduler and scheduler.GetSchedulerKey), so the import is justified.


144-159:

❓ Verification inconclusive

Verify LaunchDefaultZotRegistry function removal impact.

According to the AI summary, the LaunchDefaultZotRegistry function has been removed, but this removal is not shown in the diff. Ensure all references to this function have been updated to use the new registry.LaunchRegistry() function instead.


🏁 Script executed:

#!/bin/bash
# Check for any remaining references to the old function
rg "LaunchDefaultZotRegistry" --type go

Length of output: 39


Action Required: Manually Verify Removal of LaunchDefaultZotRegistry

The repository search for "LaunchDefaultZotRegistry" returned no matches, which indicates that references to this function have likely been removed. However, since the output is inconclusive, please manually verify that all references to LaunchDefaultZotRegistry have been completely replaced with registry.LaunchRegistry() across all relevant parts of the codebase.

  • Confirm that no deprecated references remain in any module or test.
  • Double-check that replacement usage aligns with the intended behavior.

@mviswanathsai
Copy link
Contributor Author

Rebased this one. This should be good to review and merge @Vad1mo @bupd

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ac7fc48 and b957144.

📒 Files selected for processing (12)
  • cmd/container_runtime/containerd.go (1 hunks)
  • cmd/container_runtime/crio.go (4 hunks)
  • cmd/main.go (1 hunks)
  • config.json (3 hunks)
  • internal/config/config.go (2 hunks)
  • internal/config/constants.go (1 hunks)
  • internal/utils/utils.go (0 hunks)
  • registry/config.json (0 hunks)
  • registry/default_config.go (0 hunks)
  • registry/launch-registry.go (2 hunks)
  • registry/zot_config.go (1 hunks)
  • zot-config.json (1 hunks)
💤 Files with no reviewable changes (3)
  • registry/config.json
  • internal/utils/utils.go
  • registry/default_config.go
🚧 Files skipped from review as they are similar to previous changes (8)
  • internal/config/constants.go
  • zot-config.json
  • cmd/container_runtime/containerd.go
  • internal/config/config.go
  • registry/launch-registry.go
  • config.json
  • cmd/container_runtime/crio.go
  • registry/zot_config.go
🧰 Additional context used
🧬 Code Definitions (1)
cmd/main.go (3)
registry/zot_config.go (2)
  • ZotConfig (11-17)
  • ReadZotConfig (70-89)
internal/config/getters.go (2)
  • GetZotConfigPath (14-16)
  • SetRemoteRegistryURL (18-21)
registry/launch-registry.go (1)
  • LaunchRegistry (7-22)
🪛 golangci-lint (1.64.8)
cmd/main.go

100-100: Error return value of config.SetRemoteRegistryURL is not checked

(errcheck)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (3)
cmd/main.go (3)

89-91: Ensure consistency in error handling and cancellation.

The cancel() call was added to ensure the context is properly canceled when there's an error handling the own registry. This is good practice for cleaning up resources, but make sure this pattern is applied consistently throughout the codebase for similar error scenarios.


102-110: Good refactoring of registry launch function.

The switch from utils.LaunchDefaultZotRegistry() to registry.LaunchRegistry(config.GetZotConfigPath()) better aligns with the PR's goal of clarifying the Zot configuration handling. This change makes it clearer that you're launching a registry with a specific configuration rather than a "default" one.


93-107:

❓ Verification inconclusive

Verify configuration compatibility.

The refactoring from DefaultZotConfig to ZotConfig changes how configuration is read and processed. Ensure that the existing configuration files are compatible with the new structure or provide a migration path for users.


🏁 Script executed:

#!/bin/bash
# Check if there are any existing configuration files that might need migration
fd -g "*zot*.json" -t f
# If found, check their structure to see if they match the new expected format
fd -g "*zot*.json" -t f --exec cat {}

Length of output: 295


Configuration compatibility verification required

  • The configuration file zot-config.json (as shown by the FD script) contains keys "distSpecVersion", "storage", "http", and "log".
  • Confirm that the new ZotConfig struct correctly reads these fields (especially for computing the registry URL via GetRegistryURL()), ensuring backward compatibility with legacy config files.
  • If the legacy configuration fields are not entirely compatible with the new structure, please implement a migration path or provide clear user guidance for updating their configuration.
🧰 Tools
🪛 golangci-lint (1.64.8)

100-100: Error return value of config.SetRemoteRegistryURL is not checked

(errcheck)

Comment on lines +93 to +100
log.Info().Msg("Launching default registry")
var defaultZotConfig registry.ZotConfig
if err := registry.ReadZotConfig(config.GetZotConfigPath(), &defaultZotConfig); err != nil {
log.Error().Err(err).Msg("Error launching default zot registry")
return fmt.Errorf("error reading config: %w", err)
}
defaultZotURL := defaultZotConfig.GetLocalRegistryURL()
if err := config.SetRemoteRegistryURL(defaultZotURL); err != nil {
log.Error().Err(err).Msg("Error writing the remote registry URL")
cancel()
return err
}

config.SetRemoteRegistryURL(defaultZotConfig.GetRegistryURL())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Check the return value of config.SetRemoteRegistryURL.

You're properly handling the error from registry.ReadZotConfig, but ignoring the potential error from config.SetRemoteRegistryURL. This function writes to the configuration file and could fail.

- config.SetRemoteRegistryURL(defaultZotConfig.GetRegistryURL())
+ if err := config.SetRemoteRegistryURL(defaultZotConfig.GetRegistryURL()); err != nil {
+   log.Error().Err(err).Msg("Error setting remote registry URL")
+   return fmt.Errorf("error setting remote registry URL: %w", err)
+ }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
log.Info().Msg("Launching default registry")
var defaultZotConfig registry.ZotConfig
if err := registry.ReadZotConfig(config.GetZotConfigPath(), &defaultZotConfig); err != nil {
log.Error().Err(err).Msg("Error launching default zot registry")
return fmt.Errorf("error reading config: %w", err)
}
defaultZotURL := defaultZotConfig.GetLocalRegistryURL()
if err := config.SetRemoteRegistryURL(defaultZotURL); err != nil {
log.Error().Err(err).Msg("Error writing the remote registry URL")
cancel()
return err
}
config.SetRemoteRegistryURL(defaultZotConfig.GetRegistryURL())
log.Info().Msg("Launching default registry")
var defaultZotConfig registry.ZotConfig
if err := registry.ReadZotConfig(config.GetZotConfigPath(), &defaultZotConfig); err != nil {
log.Error().Err(err).Msg("Error launching default zot registry")
return fmt.Errorf("error reading config: %w", err)
}
if err := config.SetRemoteRegistryURL(defaultZotConfig.GetRegistryURL()); err != nil {
log.Error().Err(err).Msg("Error setting remote registry URL")
return fmt.Errorf("error setting remote registry URL: %w", err)
}
🧰 Tools
🪛 golangci-lint (1.64.8)

100-100: Error return value of config.SetRemoteRegistryURL is not checked

(errcheck)

Copy link
Collaborator

@bupd bupd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@Vad1mo
Copy link
Contributor

Vad1mo commented Mar 29, 2025

@mviswanathsai, can you fix the linter error?

@mviswanathsai
Copy link
Contributor Author

@Vad1mo, I am actually not getting any linter errors when I run golangci-lint locally. I am unable to locate the issue.

@mviswanathsai
Copy link
Contributor Author

As a sidenote, might be a good idea to bump the golangci-lint version that runs in the github workflow. The version v1.54 of golangci-lint we use isn't built with go v1.24.

I wonder how it runs without issues. Locally for me, it was complaining until I updated my golangci-lint version to v1.64.

@Vad1mo Vad1mo merged commit 9858e13 into container-registry:main Mar 31, 2025
4 of 6 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Apr 9, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants