Skip to content
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

Cache location config #120

Merged
merged 14 commits into from
May 17, 2023
Merged

Conversation

jhiemstrawisc
Copy link
Contributor

See Issue #118

There has been desire to create a method by which users can configure
where to store the key cache without setting the env var $XDG_CACHE_HOME
or relying on the user to have a home dir. This is especially relevant
in cases where the library is embedded in a daemon (e.g. XRootD or HTCondor)
that may have a preferencial key cache location. This commit adds a familiar
config_set_str and config_get_str API for passing a new cache home to
the library through the use of the keycache.cache_home key.

As with config_set_int and config_get_int, these new functions can be
easily updated in the future as the project develops and new
configuration keys are desired. This would entail adding a new check for
the desired key and the logic to handle any values associated with that key.

Some comments/questions:

  • Do we need to add a mutex/lock to any of this configuration?
  • Are we interested in more robust error handling in the case that
    a garbage path is provided to the configuration API? I made the
    assumption that we weren't, since there were no checks on what
    was supplied by XDG_CACHE_HOME. Currently, the implementation
    tries to create whatever directory is passed through the API if it doesn't
    exist, but this could break if the user has insufficient permissions to
    write to that location, or the path contains invalid chars (and probably
    some other things I'm not thinking of).
  • I lumped the directory handling/creation methods into the configuration
    class. Would we rather those be moved to a new class dedicated to this
    type of functionality? I noticed in testing that if XDG_CACHE_HOME is
    set to a directory that doesn't already exist, the current code will fail if
    any parent dirs need to be created. The new config API attempts to create
    those parent dirs, so maybe a stub class to handle these types of things
    would be useful.

There has been desire to create a method by which users can configure
where to store the key cache without setting the env var `$XDG_CACHE_HOME`
or relying on the user to have a home dir. This is especially relevant
in cases where the library is embedded in a daemon (e.g. XRootD or HTCondor)
that may have a preferencial key cache location. This commit adds a familiar
`config_set_str` and `config_get_str` API for passing a new cache home to
the library through the use of the `keycache.cache_home` key.

As with `config_set_int` and `config_get_int`, these new functions can be
easily updated in the future as the project develops and new
configuration keys are desired. This would entail adding a new check for
the desired key and the logic to handle any values associated with that key.
Getting rid of a few commented blurbs, cleaning up a few extraneous
spaces, etc.
src/scitokens.cpp Outdated Show resolved Hide resolved
src/scitokens.cpp Outdated Show resolved Hide resolved
src/scitokens_cache.cpp Outdated Show resolved Hide resolved
src/scitokens_cache.cpp Outdated Show resolved Hide resolved
src/scitokens_internal.cpp Outdated Show resolved Hide resolved
src/scitokens_internal.cpp Outdated Show resolved Hide resolved
src/scitokens_internal.h Show resolved Hide resolved
src/scitokens_internal.h Show resolved Hide resolved
test/main.cpp Show resolved Hide resolved
test/main.cpp Outdated Show resolved Hide resolved
src/scitokens_cache.cpp Outdated Show resolved Hide resolved
src/scitokens_internal.cpp Outdated Show resolved Hide resolved
src/scitokens_internal.cpp Outdated Show resolved Hide resolved
src/scitokens_internal.cpp Outdated Show resolved Hide resolved
src/scitokens_internal.cpp Outdated Show resolved Hide resolved
src/scitokens_internal.h Outdated Show resolved Hide resolved
@bbockelm
Copy link
Contributor

Suddenly I have opinions about allowing the robot to fix, and not just complain about, linter issues!

I would like to make this thread safe. Can you please replace the the storage of this information with a std::shared_ptrstd::string?

src/scitokens.cpp Outdated Show resolved Hide resolved
src/scitokens_internal.cpp Outdated Show resolved Hide resolved
std::string component;

while (std::getline(ss, component, '/')) {
pathComponents.push_back(component);
Copy link
Contributor

Choose a reason for hiding this comment

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

What happens if someone provides a path of ///foo//bar? May need an if (!component.empty()) here to avoid inserting unnecessary items.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You caught my sinful shortcut. Since ultimately this output only gets passed to mkdir, the POSIX standard should suppress the extra slashes (so that the cache would be dumped at /foo/bar even if it was specified as ///foo//bar). But I agree, I should add the check in case this function ever gets used in another spot where someone might not know about that peculiarity.

std::vector<std::string> pathComponents = path_split(dir_path);
for (const auto &component : pathComponents) {
currentLevel += "/" + component;
if (!check_dir(currentLevel)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Don't check the dir first; just create it and inspect the mkdir return code (if it's EEXIST, then the directory already exists and move on).

For error message creation, it would be better to have an output variable that's the error message so you can say precisely the file operation that failed. The caller of this function currently has something generic that won't be useful for debugging.

The previous code worked when configured to use a cache home like `///foo//bar`,
but it wasn't set up to handle this situation robustly -- small future changes
could have easily broken the functionality, so I modified the path parsing and
directory checking functions to better handle this.

I also changed the way error messages are propagated by these new config options
to make sure that any errors thrown when calling `mkdir()` make it to the config
API's err_msg output variable. This should make debugging a bit easier in any
cases where someone unwittingly tries to plop their cache someplace where they
don't have read/write access.
src/scitokens_internal.cpp Outdated Show resolved Hide resolved
src/scitokens_internal.cpp Outdated Show resolved Hide resolved
src/scitokens_internal.cpp Outdated Show resolved Hide resolved
src/scitokens_internal.cpp Outdated Show resolved Hide resolved
src/scitokens_internal.cpp Outdated Show resolved Hide resolved
src/scitokens_internal.cpp Outdated Show resolved Hide resolved
src/scitokens_internal.h Outdated Show resolved Hide resolved
@jhiemstrawisc
Copy link
Contributor Author

Hmm, any ideas what might be causing the EnforcerTest to fail in the one instance? When I run locally, all tests pass.

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@djw8605
Copy link
Contributor

djw8605 commented May 3, 2023

You say that, but now it looks good. Are you happy with this pull request now?

@bbockelm
Copy link
Contributor

bbockelm commented May 4, 2023

@jhiemstrawisc - can you clean up the remaining linter items? Once that's done, I think we're ready to go.

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@jhiemstrawisc
Copy link
Contributor Author

@bbockelm Okay, latest commit made the linter happy, and all the tests are passing.

@JaimeFrey
Copy link
Contributor

The symbols config_set_str() and friends seem far too generic for a public library with C bindings.

Unfortunately, the choice of names for the config_set_blah() family of APIs is
quite generic and poses the potential to cause C symbol collisions when SciTokens
is used by large projects that dynamically load lots of libraries (a la HTCondor).
A reasonable plan to address this, since those APIs are in use and changing their
names would be API-breaking, seems to be adding a second set of prefixed APIs, with
the intention of deprecating the old functions at the next major release.
src/scitokens.cpp Outdated Show resolved Hide resolved
src/scitokens.h Outdated Show resolved Hide resolved
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@JaimeFrey
Copy link
Contributor

With the new config functions prefixed with scitokens_, I suggest changing the unprefixed versions to just call the prefixed ones. That avoids a clone of the code, where the two copies can diverge in functionality by accident.

…_set_blah()

To cut down on code duplication, the config_set_blah() family of APIs have been
changed to immediately call the scitokens-prefixed family of APIs under the hood.
src/scitokens.h Outdated Show resolved Hide resolved
Per Jaime's comment, since we plan to deprecate the `config_set_blah()` family of
functions in favor of the prefixed versions, I've updated the internal API documentation
to point people toward the preferred APIs.
@jhiemstrawisc
Copy link
Contributor Author

Anything else on this, or are we ready to wrap things up?

@JaimeFrey
Copy link
Contributor

Nothing from my end.

@djw8605
Copy link
Contributor

djw8605 commented May 15, 2023

I wonder how fast we can depreciate the config_* functions. Is HTCondor already using them? I know xrootd isn't. If no one is using them, can we just remove them already?

@timtheisen
Copy link
Contributor

timtheisen commented May 15, 2023

Good point. The config_set_str() and config_get_str() were never released. Why release a deprecated API?

HTCondor does not use config_set_int() or config_get_int().

From HTCondor's point of view, it could be removed immediately.

@JaimeFrey
Copy link
Contributor

I just noticed that the other functions start with scitoken_, not scitokens_. Most, though not all, are dealing with a single SciToken object.

@jhiemstrawisc
Copy link
Contributor Author

Oh, I thought I had heard that the older config_set/get_int functions were already in use by someone somewhere. If nobody is using them at this point, I'll update to just get rid of them.

…oken

It looks like the config_set/get_blah APIs weren't actually in use and hadn't been
released, so instead of keeping them around, we decided to just delete them.

Also, the `scitokens`-prefixed versions of these APIs were changed to be prefixed
by `scitoken` to match other functions in the library.
src/scitokens.cpp Outdated Show resolved Hide resolved
src/scitokens.h Outdated Show resolved Hide resolved
test/main.cpp Outdated Show resolved Hide resolved
test/main.cpp Outdated Show resolved Hide resolved
test/main.cpp Outdated Show resolved Hide resolved
test/main.cpp Outdated Show resolved Hide resolved
test/main.cpp Outdated Show resolved Hide resolved
test/main.cpp Outdated Show resolved Hide resolved
jhiemstrawisc and others added 2 commits May 16, 2023 08:44
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
I mistakenly removed the `config_set/get_int` APIs when removing `config_set/get_str`.
@timtheisen
Copy link
Contributor

I think that Brian B wanted to have the C++ deprecated decorator (not just a comment).

https://en.cppreference.com/w/cpp/language/attributes/deprecated

@JaimeFrey
Copy link
Contributor

Since scitokens.h contains C declarations, I don't think the C++ deprecated decorator is appropriate (or even allowed).

@jhiemstrawisc
Copy link
Contributor Author

jhiemstrawisc commented May 16, 2023

Brian B said to worry about any deprecated decorators in another PR at another time. I think he's looking to have this PR wrapped up expediently.

It looks like the deprecated decorator for C is supported after C23: https://en.cppreference.com/w/c/language/attributes/deprecated, whereas the deprecated decorator for C++ has been supported since C++14.

@bbockelm
Copy link
Contributor

Yeah - unfortunately, we’ll need to wrap the deprecated stuff in some macro as it’s only recently standardized in C… hence punting it to a new PR.

@jhiemstrawisc
Copy link
Contributor Author

Since we aren't adding the decorator for deprecation warnings in this PR, is there anything else needed to close this?

@timtheisen
Copy link
Contributor

I think that it is good to go.

@JaimeFrey
Copy link
Contributor

Nothing from me.

@djw8605
Copy link
Contributor

djw8605 commented May 17, 2023

Is config_get_int and config_set_int being used anywhere? I still think we can remove it without depreciating it.

Otherwise, I think we're in good shape here.

@timtheisen
Copy link
Contributor

Let's keep config_get_int and config_set_int for now. If we remove them, we'd have to bump the library to version 2.0 for the ABI change. We need to get this out the door without delay. We can deal with the deprecated methods in the future.

@djw8605 djw8605 merged commit dc2919b into scitokens:master May 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants