-
Notifications
You must be signed in to change notification settings - 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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -97,7 +97,36 @@ def __repr__(self) -> str: | |||||||||||||
| ] | ||||||||||||||
| return f'Juju({", ".join(args)})' | ||||||||||||||
|
|
||||||||||||||
| # 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 commentThe reason will be displayed to describe this comment to others. Learn more. Maybe the name |
||||||||||||||
| """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 | ||||||||||||||
|
Comment on lines
+102
to
+104
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 Maybe the initial line could end with 'typically I wonder if 'The directory is created and cached on first use.' should be expanded to include:
|
||||||||||||||
| CLI installed as a snap, this will be a directory accessible to the snap (under | ||||||||||||||
| ``~/snap/juju/common``), otherwise it will be under ``/tmp``. | ||||||||||||||
|
|
||||||||||||||
| Example:: | ||||||||||||||
|
|
||||||||||||||
| juju = jubilant.Juju() | ||||||||||||||
| with tempfile.NamedTemporaryFile('w+', dir=juju.temp_dir) as file: | ||||||||||||||
| file.write('contents') | ||||||||||||||
| file.flush() | ||||||||||||||
| juju.scp(file.name, 'ubuntu/0:/path/to/destination') | ||||||||||||||
|
Comment on lines
+111
to
+114
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If
Suggested change
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 commentThe 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 |
||||||||||||||
| """ | ||||||||||||||
| if self._juju_is_snap: | ||||||||||||||
| # If Juju is running as a snap, we can't use /tmp, so put temp files here instead. | ||||||||||||||
| temp_dir = os.path.expanduser('~/snap/juju/common') | ||||||||||||||
| os.makedirs(temp_dir, exist_ok=True) | ||||||||||||||
| return temp_dir | ||||||||||||||
| else: | ||||||||||||||
| return tempfile.gettempdir() | ||||||||||||||
|
|
||||||||||||||
| @functools.cached_property | ||||||||||||||
| def _juju_is_snap(self) -> bool: | ||||||||||||||
| which = shutil.which(self.cli_binary) | ||||||||||||||
| return which is not None and '/snap/' in which | ||||||||||||||
|
|
||||||||||||||
| # Keep the public methods below in alphabetical order, so we don't have to think | ||||||||||||||
| # about where to put each new method. | ||||||||||||||
|
|
||||||||||||||
| def add_model( | ||||||||||||||
|
|
@@ -162,7 +191,7 @@ def add_secret( | |||||||||||||
| if info is not None: | ||||||||||||||
| args.extend(['--info', info]) | ||||||||||||||
|
|
||||||||||||||
| with tempfile.NamedTemporaryFile('w+', dir=self._temp_dir) as file: | ||||||||||||||
| with tempfile.NamedTemporaryFile('w+', dir=self.temp_dir) as file: | ||||||||||||||
| _yaml.safe_dump(content, file) | ||||||||||||||
| file.flush() | ||||||||||||||
| args.extend(['--file', file.name]) | ||||||||||||||
|
|
@@ -935,7 +964,7 @@ def run( | |||||||||||||
| args.extend(['--wait', f'{wait}s']) | ||||||||||||||
|
|
||||||||||||||
| with ( | ||||||||||||||
| tempfile.NamedTemporaryFile('w+', dir=self._temp_dir) | ||||||||||||||
| tempfile.NamedTemporaryFile('w+', dir=self.temp_dir) | ||||||||||||||
| if params is not None | ||||||||||||||
| else contextlib.nullcontext() | ||||||||||||||
| ) as params_file: | ||||||||||||||
|
|
@@ -977,6 +1006,9 @@ def scp( | |||||||||||||
| ) -> None: | ||||||||||||||
| """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 commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||
|
|
||||||||||||||
| Args: | ||||||||||||||
| source: Source of file, in format ``[[<user>@]<target>:]<path>``. | ||||||||||||||
| destination: Destination for file, in format ``[<user>@]<target>[:<path>]``. | ||||||||||||||
|
|
@@ -1177,7 +1209,7 @@ def update_secret( | |||||||||||||
| if auto_prune: | ||||||||||||||
| args.append('--auto-prune') | ||||||||||||||
|
|
||||||||||||||
| with tempfile.NamedTemporaryFile('w+', dir=self._temp_dir) as file: | ||||||||||||||
| with tempfile.NamedTemporaryFile('w+', dir=self.temp_dir) as file: | ||||||||||||||
| _yaml.safe_dump(content, file) | ||||||||||||||
| file.flush() | ||||||||||||||
| args.extend(['--file', file.name]) | ||||||||||||||
|
|
@@ -1269,21 +1301,6 @@ def wait( | |||||||||||||
| raise TimeoutError(f'wait timed out after {timeout}s') | ||||||||||||||
| raise TimeoutError(f'wait timed out after {timeout}s\n{status}') | ||||||||||||||
|
|
||||||||||||||
| @functools.cached_property | ||||||||||||||
| def _juju_is_snap(self) -> bool: | ||||||||||||||
| which = shutil.which(self.cli_binary) | ||||||||||||||
| return which is not None and '/snap/' in which | ||||||||||||||
|
|
||||||||||||||
| @functools.cached_property | ||||||||||||||
| def _temp_dir(self) -> str: | ||||||||||||||
| if self._juju_is_snap: | ||||||||||||||
| # If Juju is running as a snap, we can't use /tmp, so put temp files here instead. | ||||||||||||||
| temp_dir = os.path.expanduser('~/snap/juju/common') | ||||||||||||||
| os.makedirs(temp_dir, exist_ok=True) | ||||||||||||||
| return temp_dir | ||||||||||||||
| else: | ||||||||||||||
| return tempfile.gettempdir() | ||||||||||||||
|
|
||||||||||||||
|
|
||||||||||||||
| def _format_config(k: str, v: ConfigValue) -> str: | ||||||||||||||
| if v is None: # type: ignore | ||||||||||||||
|
|
||||||||||||||
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.Pathobject instead of astr-- path-like objects can be used with thedirargument of thetempfilefunctions.