build providers: idempotent destroy for LXD
Metadata
Current evaluation
Merged fix making LXD provider destroy idempotent. Resolves AttributeError crash during cleanup when container launch fails. Prevents NoneType sync errors and displays a clean error message instead.
Suggested action: —
No scores available.
Issue body
Fixes SNAPCRAFT-MB
Signed-off-by: Sergio Schvezov <sergio.schvezov@canonical.com>
- [ ] Have you followed the [guidelines for contributing](https://github.com/snapcore/snapcraft/blob/master/CONTRIBUTING.md)?
- [ ] Have you signed the [CLA](http://www.ubuntu.com/legal/contributors/)?
- [ ] Have you successfully run `./runtests.sh static`?
- [ ] Have you successfully run `./runtests.sh tests/unit`?
-----
Before
```
(snapcraft) multipass@lxd-snapcraft:~/t$ snapcraft --use-lxd
Using 'snap/snapcraft.yaml': Project assets will be searched for from the 'snap' directory.
The LXD provider is offered as a technology preview for early adopters.
The command line interface, container names or lifecycle handling may change in upcoming releases.
Launching a container.
Sorry, an error occurred in Snapcraft:
Traceback (most recent call last):
File "/home/multipass/snapcraft/snapcraft/internal/build_providers/_base_provider.py", line 249, in launch_instance
self._start()
File "/home/multipass/snapcraft/snapcraft/internal/build_providers/_lxd/_lxd.py", line 166, in _start
raise errors.ProviderInstanceNotFoundError(instance_name=self.instance_name)
snapcraft.internal.build_providers.errors.ProviderInstanceNotFoundError: Cannot find an instance named 'snapcraft-test'.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/multipass/snapcraft/snapcraft/internal/build_providers/_lxd/_lxd.py", line 151, in _launch
container = self._lxd_client.containers.create(config, wait=True)
File "/home/multipass/venv/snapcraft/lib/python3.6/site-packages/pylxd/models/container.py", line 276, in create
response = client.api.containers.post(json=config, target=target)
File "/home/multipass/venv/snapcraft/lib/python3.6/site-packages/pylxd/client.py", line 168, in post
self._assert_response(response, allowed_status_codes=(200, 201, 202))
File "/home/multipass/venv/snapcraft/lib/python3.6/site-packages/pylxd/client.py", line 108, in _assert_response
raise exceptions.LXDAPIException(response)
pylxd.exceptions.LXDAPIException: No storage pool found. Please create a new storage pool
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/multipass/snapcraft/snapcraft/internal/build_providers/_base_provider.py", line 117, in __enter__
self.create()
File "/home/multipass/snapcraft/snapcraft/internal/build_providers/_lxd/_lxd.py", line 246, in create
self.launch_instance()
File "/home/multipass/snapcraft/snapcraft/internal/build_providers/_base_provider.py", line 257, in launch_instance
self._launch()
File "/home/multipass/snapcraft/snapcraft/internal/build_providers/_lxd/_lxd.py", line 155, in _launch
) from lxd_api_error
snapcraft.internal.build_providers.errors.ProviderLaunchError: An error occurred with the instance when trying to launch with 'LXD': No storage pool found. Please create a new storage pool.
Ensure that 'LXD' is setup correctly and try again.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/multipass/venv/snapcraft/bin/snapcraft", line 11, in <module>
load_entry_point('snapcraft', 'console_scripts', 'snapcraft')()
File "/home/multipass/snapcraft/snapcraft/cli/__main__.py", line 81, in run
run_snapcraft(prog_name="snapcraft")
File "/home/multipass/venv/snapcraft/lib/python3.6/site-packages/click/core.py", line 722, in __call__
return self.main(*args, **kwargs)
File "/home/multipass/venv/snapcraft/lib/python3.6/site-packages/click/core.py", line 697, in main
rv = self.invoke(ctx)
File "/home/multipass/venv/snapcraft/lib/python3.6/site-packages/click/core.py", line 1043, in invoke
return Command.invoke(self, ctx)
File "/home/multipass/venv/snapcraft/lib/python3.6/site-packages/click/core.py", line 895, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/home/multipass/venv/snapcraft/lib/python3.6/site-packages/click/core.py", line 535, in invoke
return callback(*args, **kwargs)
File "/home/multipass/venv/snapcraft/lib/python3.6/site-packages/click/decorators.py", line 17, in new_func
return f(get_current_context(), *args, **kwargs)
File "/home/multipass/snapcraft/snapcraft/cli/_runner.py", line 93, in run
ctx.forward(lifecyclecli.commands["snap"])
File "/home/multipass/venv/snapcraft/lib/python3.6/site-packages/click/core.py", line 553, in forward
return self.invoke(cmd, **kwargs)
File "/home/multipass/venv/snapcraft/lib/python3.6/site-packages/click/core.py", line 535, in invoke
return callback(*args, **kwargs)
File "/home/multipass/snapcraft/snapcraft/cli/lifecycle.py", line 272, in snap
_execute(steps.PRIME, parts=[], pack_project=True, output=output, **kwargs)
File "/home/multipass/snapcraft/snapcraft/cli/lifecycle.py", line 98, in _execute
with build_provider_class(project=project, echoer=echo) as instance:
File "/home/multipass/snapcraft/snapcraft/internal/build_providers/_base_provider.py", line 120, in __enter__
self.destroy()
File "/home/multipass/snapcraft/snapcraft/internal/build_providers/_lxd/_lxd.py", line 250, in destroy
self._stop()
File "/home/multipass/snapcraft/snapcraft/internal/build_providers/_lxd/_lxd.py", line 196, in _stop
self._container.sync()
AttributeError: 'NoneType' object has no attribute 'sync'
We would appreciate it if you created a bug report at
https://launchpad.net/snapcraft/+filebug with the above text included.
```
and after
```
(snapcraft) multipass@lxd-snapcraft:~/t$ snapcraft --use-lxd
Using 'snap/snapcraft.yaml': Project assets will be searched for from the 'snap' directory.
The LXD provider is offered as a technology preview for early adopters.
The command line interface, container names or lifecycle handling may change in upcoming releases.
Launching a container.
An error occurred with the instance when trying to launch with 'LXD': No storage pool found. Please create a new storage pool.
Ensure that 'LXD' is setup correctly and try again.
```
Evaluation history
| Date | Model | Scores | Action | Summary |
|---|---|---|---|---|
| qwen/qwen3.6-35b-a3b | — | — | Merged fix making LXD provider destroy idempotent. Resolves AttributeError crash during cleanup when container launch fails. Prevents NoneType sync errors and displays a clean error message instead. | |
| qwen3.6-35b-a3b-mtp-q6 | — | — | Merged into master. Fixes SNAPCRAFT-MB by making LXD container destruction idempotent. Prevents AttributeError crashes during failed launches or missing instances, ensuring graceful error reporting and cleanup. | |
| qwen3.6-35b-a3b-mtp-q6 | — | — | Merged into master. Fixed an AttributeError crash during LXD container destruction when launch fails. The destroy operation is now idempotent, preventing NoneType sync errors and displaying a clean error message. |
Update history
No update history recorded yet.
Related issues
| Issue | Project | State | Summary | Similarity |
|---|---|---|---|---|
| #3115 build providers: ignore missing LXD instance when cleaning project | snapcraft | merged | Merged fix for SNAPCRAFT-1DB that catches the pylxd.NotFound exception during project cleanup, preventing failures when the LXD instance is manually deleted. Approved and passed CI. | |
| #2936 build providers: clean up LXD startup message | snapcraft | merged | Merged removal of a confusing LXD startup message about waiting for cloud-init, which misled users into thinking data was being sent to the cloud. The change aligns with the transition to profile containers and was approved. |