Skip to content

image/docker: use unified configfile search for cert directories#746

Open
jankaluza wants to merge 2 commits intocontainers:mainfrom
jankaluza:certs.d
Open

image/docker: use unified configfile search for cert directories#746
jankaluza wants to merge 2 commits intocontainers:mainfrom
jankaluza:certs.d

Conversation

@jankaluza
Copy link
Copy Markdown
Member

Switch dockerCertDir to use the new
configfile.ContainersResourceDirs for resolving certificate directories.

Switch `dockerCertDir` to use the new
`configfile.ContainersResourceDirs` for resolving certificate
directories.

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
@github-actions github-actions bot added storage Related to "storage" package image Related to "image" package labels Apr 7, 2026
for _, dir := range candidates {
info, err := os.Stat(dir)
if err != nil {
if errors.Is(err, fs.ErrNotExist) || errors.Is(err, fs.ErrPermission) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

why do we skip permission errors?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I thought it is a good idea to fallback to next directory if we cannot access some directory. In my opinion, this function should find valid directory which we can read files from.

Thinking about it now, maybe showing a warning in the ErrPermission case would be good thing to do. Or do you think this condition should be removed?

Comment on lines +35 to +36
// userConfigPathForResourceDirs is a test hook for ContainersResourceDirs.
userConfigPathForResourceDirs = UserConfigPath
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

it is not clear to me why do you need this? The other test does not need it? you can just sentenv the XDG_CONFIG_HOME dir?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This was the best way I found out to let the userConfigPath fail with an error for the user config path resolution failure is ignored test. I admit I'm not the go expert, so maybe there is better way to do that.

In that test, I want to test that even if userConfigPath returns an error, other directories are evaluated. This behavior is aligned with the original code and I wanted to keep it.

I therefore needed to find a way how to monkey-patch the userConfigPath to generate an error so I can test its handling. Maybe I'm just trying to come up with Python solution in go lang :-).

//
// The search covers, where configured (listed here from lowest to highest precedence.
// It can be extended with additional absolute directories via extraDirs (lowest precedence).
func ContainersResourceDirs(conf *Directory) ([]string, error) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

API wise I am not to sure we just want to return the list here?

certs.d just needs the first match starting with home, etc, /usr... so would it not be more logical to pass in the name we search as argument and the return a signle full path and exit early?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I wanted to make it more generic and let the caller to decide what to do with these directories. But if you think we can just return single directory, I'm also fine changing it.

func ContainersResourceDirs(conf *Directory) ([]string, error) {
candidates := make([]string, 0, 7+len(conf.ExtraDirs))

userConfig, _ := userConfigPathForResourceDirs()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

error should not be silently ignored

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This is aligned with the old code - it used homedir.Get() which ignores the error the same way:

func Get() string {
	homedir, _ := unshare.HomeDir()
	return homedir
}

I can add warning here in the ContainersResourceDirs so the error message about missing homedir is logged. I believe we still want to try other directories if homedir cannot be found, so this error should not be fatal.

path string
absolute bool
var perHostCertDirs = []string{
etcDir + "/docker/certs.d",
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@mtrmac Do we still want this path? API wise it seems rather ugly to define that search order with that additional path.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

That's a good point and it would make the API cleaner definitely.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We do need it. It’s never been deprecated by us, and it’s the one place users can use to affect both consumers.

See e.g. https://github.com/search?q=repo%3Aopenshift%2Fmachine-config-operator%20%2Fdocker%2Fcerts.d&type=code for a minimal proof.

@jankaluza
Copy link
Copy Markdown
Member Author

@Luap99 , thanks for the review :-). I will change the code once we finish discussions for all the suggested changes.

Copy link
Copy Markdown
Contributor

@mtrmac mtrmac left a comment

Choose a reason for hiding this comment

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

(Just a random note for now)

return "", err
}
return fullCertDirPath, nil
return "", nil
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hum, the code is not actually ready to consume "". I guess we never ran into that.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Well, the code works, but it is not as good as it could be. The previous code returned non-existing directory while the current code returns "" in this case. I think "" is cleaner, because returning non-existing directory looks weird to me.

The directory is then passed to tlsclientconfig.SetupCertificates(certDir, tlsClientConfig) as certDir. This function tries to read that empty dir and returns nil error in case it does not exist.

But I will add check for empty certDir to not even call SetupCertificates. Tell me if you want me to go back to old behavior.

Signed-off-by: Jan Kaluza <jkaluza@redhat.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

image Related to "image" package storage Related to "storage" package

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants