-
Couldn't load subscription status.
- Fork 16
feat: make Juju.temp_dir public, improve docs #205
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
base: main
Are you sure you want to change the base?
Conversation
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.
This seems like a reasonable solution to the reported issue. I've noted a few potential additions to the documentation, as well as suggested an alternative method name. The return type should probably be a Path too.
I thought about whether this should be a top-level helper function instead, but I think it will be a lot more ergonomic as a method since we need to know the binary location, so a Juju instance would likely be a required argument anyway.
|
|
||
| # Keep the public methods in alphabetical order, so we don't have to think | ||
| @functools.cached_property | ||
| def temp_dir(self) -> str: |
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.
Probably nicer to return a pathlib.Path object instead of a str -- path-like objects can be used with the dir argument of the tempfile functions.
| """Path of a temporary directory accessible by the Juju CLI. | ||
| The directory is created and cached on first use. If :attr:`cli_binary` points to a Juju |
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.
We should make it clear that this returns the path to the conventional system or snap temporary directory. The fact that it's a cached property helps, but I do wonder if users will at first think of using it like you would with tempfile.TemporaryDirectory() ....
Maybe the initial line could end with 'typically /tmp' to make it clear via an example.
I wonder if 'The directory is created and cached on first use.' should be expanded to include:
- The directory is created on first use if it doesn't exist.
- The cached path is returned on later uses.
- This will be the same directory for all
Jujuinstances with the same binary, and indeed across multiple runs of the program. - We don't clean up any files created there.
| """Securely transfer files within a model. | ||
| A local *source* or *destination* must be accessible by the Juju CLI (important if Juju | ||
| is installed as a confined snap). See :attr:`temp_dir` for an example. |
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.
| is installed as a confined snap). See :attr:`temp_dir` for an example. | |
| is installed as a confined snap). See :attr:`temp_dir` for an example of how to create a | |
| temporary file accessible by Juju. |
|
|
||
| # Keep the public methods in alphabetical order, so we don't have to think | ||
| @functools.cached_property | ||
| def temp_dir(self) -> str: |
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.
Maybe the name default_temp_dir would make the semantics clearer, though it would mean that what we're asking users to write whenever they use tempfile methods would be a little bit longer.
| with tempfile.NamedTemporaryFile('w+', dir=juju.temp_dir) as file: | ||
| file.write('contents') | ||
| file.flush() | ||
| juju.scp(file.name, 'ubuntu/0:/path/to/destination') |
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.
If temp_dir is a pathlib.Path, I'd personally use it like this:
| with tempfile.NamedTemporaryFile('w+', dir=juju.temp_dir) as file: | |
| file.write('contents') | |
| file.flush() | |
| juju.scp(file.name, 'ubuntu/0:/path/to/destination') | |
| (juju.temp_dir / 'cont').write_text('contents') | |
| juju.scp(juju.temp_dir / 'cont', 'ubuntu/0:/path/to/destination') |
Practicality over purity: if it's an integration test, there will be only a few named files.
The named temp file would be still useful in a case where Jubilant is used in production and the process is long-lived. In that case very many scp calls could be expected.
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.
Brainstorming a little bit, I agree that this is a nice UX -- probably the way we'd normally do it in tests is using pytest's tmp_path fixture, which takes care of cleanup when the fixture exits. But of course that specific fixture won't work with snap Juju. I'm wondering if we could provide cleanup functionality in a similar way though. For example, Juju.temp_dir could create and return a subdir of the current temp location and record created directories, and the juju fixture could clean them up on exiting.
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.
Looks good overall.
Let's settle on the API first.
|
It seems like (at least with the methods we have now), the use-cases for this are:
I wonder if it would be better to solve those cases (particularly Perhaps this is too "magic" or high-level for Jubilant, but it seems like it would be nicer if the user didn't need to know about snap confinement or that a |
|
@tonyandrewmeyer That's a good idea. I think it should be doable and not too hard:
These would only be done if Juju was installed as a snap ( Does that seems reasonable? I think I have an untested PoC of this idea here. |
|
It would probably be nice if On that front, I notice that we just Could be made nicer with something like this: if isinstance(charm, Path):
if charm.is_absolute():
charm = str(charm)
else:
charm = f'./{charm}' |
This makes the
Juju._temp_dirhelper public, for use by tests that doscpand the like, when Juju is running as a snap.I'm not entirely sure this is a good idea, or necessarily the API we want, so would like feedback on that.
Fixes #201.