-
Notifications
You must be signed in to change notification settings - Fork 23
Refactor DefaultZotConfig
#75
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor DefaultZotConfig
#75
Conversation
WalkthroughThis pull request modifies the configuration handling and runtime commands in multiple components. Key changes include updating the type of the Changes
Possibly related PRs
Suggested reviewers
Poem
✨ Finishing Touches
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
@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. |
@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 |
Right, thanks for the heads up. As you said, scrub is pretty straight-forward. I will have to take a deeper look at sync. |
@Mehul-Kumar-27 it seems like |
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? |
There was a problem hiding this 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 whenTLSVerify
is true andCertDir
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
📒 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
toZotConfig
andReadConfig
toReadZotConfig
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 newZotConfig
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.
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. |
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? |
Makes sense yes |
There was a problem hiding this 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 toSetLocalRegistryURL(...)
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 (likeDistSpecVersion
orRemoteURL
) 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
📒 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 onlyerror
eliminates extra logic and simplifies the calling code.
18-18
: Consistent error handling and return type.
Replacingfalse, err
withreturn err
andtrue, nil
withreturn 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 toerr
is concise.
Previously returning both a boolean and an error could add overhead to decision-making. Now it’s straightforward to check iferr != nil
for failures.cmd/root.go (1)
100-101
: ExplicitZotConfig
usage increases clarity.
Renaming fromDefaultZotConfig
toZotConfig
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. Thevar validExtensionsOrder
is a beneficial reference for extension validation.
29-32
: Good approach for grouping extension logic.
Defining separate structs likeZotExtensions
helps maintain modular design and can be extended easily for more features likesearch
ormetrics
.
34-38
: Clarify usage ofCredentialsFile
.
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 settingRemoteURL
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.
Makes sense |
I need to look into the build process for the Zot registry. |
There was a problem hiding this 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 forRemoteURL
andExtensions
, 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, concatenatingc.HTTP.Port
may result in a malformed URL (e.g., “https://mydomain:8080:5000”). Consider parsing the address first and conditionally appendingc.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
📒 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
: ThevalidExtensionsOrder
declaration looks good.It provides a clear reference for enforcing a specific loading sequence for extensions.
29-32
: TheZotExtensions
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 ofReadZotConfig
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 usestime.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.
There was a problem hiding this 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. SinceExtensions
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
andScrubConfig
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 inGetRegistryURL
.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
: EnhanceSetZotRemoteURL
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
📒 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
: CallValidate()
after loading config inReadZotConfig
.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.
If I remove the I expected the 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
}) |
There was a problem hiding this 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
6f27110
to
aae2422
Compare
There was a problem hiding this 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 likelocalZotCfg
for clarity:- var defaultZotConfig registry.ZotConfig + var localZotCfg registry.ZotConfigregistry/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
📒 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 fromGetLocalRegistryURL()
toGetRegistryURL()
This change reflects the refactoring of the
DefaultZotConfig
toZotConfig
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 structureThe path update from
./registry/config.json
to./zot-config.json
is consistent with the refactoring ofDefaultZotConfig
. This change improves clarity by using a more descriptive filename that directly indicates its purpose for Zot configuration.Ensure that:
- The new path is used consistently across the codebase
- Any existing deployments are updated to use the new config file path
- 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 inScrubConfig
maintains consistency with the new configuration types.
86-87
: Improved function naming and documentation.Renaming from
ReadConfig
toReadZotConfig
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
delegated the validation to Zot instead, and removed the data model. |
@mviswanathsai ping |
aae2422
to
ac7fc48
Compare
Rebased and ready to go |
There was a problem hiding this 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 suggestionUpdate 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
📒 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.goLength of output: 595
Verified: Scheduler Package is Actively Used
The scheduler package is indeed utilized within the
Init
function ininternal/utils/utils.go
(see calls toscheduler.NewBasicScheduler
andscheduler.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 newregistry.LaunchRegistry()
function instead.
🏁 Script executed:
#!/bin/bash # Check for any remaining references to the old function rg "LaunchDefaultZotRegistry" --type goLength 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 toLaunchDefaultZotRegistry
have been completely replaced withregistry.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.
ac7fc48
to
b957144
Compare
There was a problem hiding this 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
📒 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()
toregistry.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
toZotConfig
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 viaGetRegistryURL()
), 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)
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()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
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)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@mviswanathsai, can you fix the linter error? |
@Vad1mo, I am actually not getting any linter errors when I run golangci-lint locally. I am unable to locate the issue. |
As a sidenote, might be a good idea to bump the I wonder how it runs without issues. Locally for me, it was complaining until I updated my |
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
Refactor
Chores