{"owner":"canonical","repo":"lxd","hasSkills":true,"totalSkillsCount":4,"totalTokensCount":2965,"categories":["project-spec","root-instruction","copilot-instructions"],"hasMcp":false,"mcpConfig":null,"found":["doc/api.md","test/AGENTS.md","AGENTS.md",".github/copilot-instructions.md"],"skills":{"doc/api.md":"(api-specification)=\n# Main API specification\n\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../_static/swagger-ui/swagger-ui.css\" ></link>\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../_static/swagger-override.css\" ></link>\n<div id=\"swagger-ui\"></div>\n\n<script src=\"../_static/swagger-ui/swagger-ui-bundle.js\" charset=\"UTF-8\"> </script>\n<script src=\"../_static/swagger-ui/swagger-ui-standalone-preset.js\" charset=\"UTF-8\"> </script>\n<script>\nwindow.onload = function() {\n  // Begin Swagger UI call region\n  const ui = SwaggerUIBundle({\n    url: window.location.pathname +\"../rest-api.yaml\",\n    dom_id: '#swagger-ui',\n    deepLinking: true,\n    presets: [\n      SwaggerUIBundle.presets.apis,\n      SwaggerUIStandalonePreset\n    ],\n    plugins: [],\n    validatorUrl: \"none\",\n    defaultModelsExpandDepth: -1,\n    supportedSubmitMethods: []\n  })\n  // End Swagger UI call region\n\n  window.ui = ui\n}\n</script>\n","test/AGENTS.md":"# AGENTS.md — Test Suite\n\nThis file provides agent instructions specific to the `test/` directory.\nSee `../AGENTS.md` at the repository root for the full development runbook.\nSee `README.md` in this directory for test coding conventions and environment variables.\n\n## Running tests\n\nIntegration tests require root. Use `sudo -E` to preserve environment variables:\n\n```bash\n# Run all tests\nsudo -E ./test/main.sh group:all\n\n# Run a specific group\nsudo -E ./test/main.sh group:cluster\n\n# Run against specific backends\nsudo -E LXD_BACKENDS=\"btrfs lvm\" ./test/main.sh group:standalone\n\n# Repeat tests (useful to catch races)\nsudo -E LXD_REPEAT_TESTS=10 ./test/main.sh group:standalone\n```\n\nUnit tests (no root needed):\n\n```bash\nmake check-unit\n```\n\n## Shell script style (test/*.sh)\n\n- No trailing whitespace, and no tab characters (use spaces for indentation).\n- New `test_*` functions must be registered in `test/includes/test-groups.sh`\n  (checked by `test/lint/test-tests.sh`).\n- Avoid `grep -q` in pipelines under `set -o pipefail` (can cause SIGPIPE issues);\n  avoid `grep -v` at the end of a pipeline to test for absence of a pattern — its\n  exit code doesn't reliably reflect that.\n","AGENTS.md":"# AGENTS.md — LXD Agent Instructions\n\nLXD is a modern, secure system container and virtual machine manager written in Go.\nModule: `github.com/canonical/lxd`.\n\n## Prerequisites\n\nLXD requires the Go version listed in `doc/requirements.md` or higher and is only tested with the Golang compiler.\n- CGO native dependencies (dqlite, liblxc). Fetch them once with:\n\n  ```bash\n  make deps\n  ```\n\n  This builds the native libraries under `$(go env GOPATH)/deps` (or `vendor/` in a\n  release tarball). Set the environment variables printed by `make env` if you build\n  outside of `make`.\n\n- The `client` (lxc CLI) and some test binaries build without CGO and have no native deps.\n\n## Repository layout\n\n```\nlxd/            Main daemon\nlxc/            Client CLI\nlxd-agent/      VM guest agent\nclient/         Go client library\nshared/         Code shared across components\ntest/\n  suites/       Integration test suites (bash)\n  snap/         Snap integration test scripts (run directly)\n  local-snap.sh Snap integration test runner (sourced by test/snap/* scripts)\n  lint/         Lint scripts\n  includes/\n    snap-helpers.sh  Shared snap integration test helpers\ndoc/            Sphinx documentation\n```\n\n### Auto-generated files — do not edit manually\n\nUpdate these via the listed `make` target instead of editing by hand:\n\n| File | Command |\n|------|---------|\n| `lxd/metadata/configuration.json`, `doc/metadata.txt` | `make update-metadata` |\n| `lxd/auth/entitlements_generated.go`, `lxd/auth/drivers/openfga_model.openfga` | `make update-auth` |\n| `go.mod`, `go.sum`, `tools/go.mod`, `tools/go.sum` | `make update-gomod` |\n| `doc/rest-api.yaml` | `make update-api` |\n\n## Build\n\n```bash\n# CGO-free client only (no native deps needed)\nmake client\n\n# Full daemon (requires CGO deps)\nmake lxd\n\n# Everything\nmake\n```\n\n## Validate before committing\n\nRun these in order. Each must pass before moving to the next.\n\n```bash\n# 1. Static analysis (golangci-lint, errortype, zerolint, generated-file checks)\nmake static-analysis\n\n# 2. Unit tests\nmake check-unit\n\n# 3. Full build\nmake\n```\n\n`make static-analysis` may regenerate output (e.g. `doc/rest-api.yaml`, generated DB code,\nauth entitlements, metadata docs) and errors out if that leaves an uncommitted diff; it\nnever prompts or commits on its own (stdin is closed for the checks it runs), so it's safe\nto run from an agent session. If it reports drift, re-run `make update-api`,\n`make update-auth`, `make update-metadata`, or `make update-schema` (whichever produced the\nfile in question) to regenerate it, then stop and leave the diff for a human to review and\ncommit; these four targets never call git themselves. Do not run an individual `check-*`\ntarget (e.g. `make check-api`) or `scripts/check-and-commit.sh` directly, and do not run\nother `update-*` targets like `update-gomod`, `update-golangci`, or `update-godeps` as a\nsubstitute; unlike the four above, those call `check-and-commit.sh` directly and will\nprompt interactively to commit, which hangs an agent session with no one to answer.\n\n`make static-analysis` requires network access (it installs/updates golangci-lint,\nerrortype, zerolint, goimports, and go-swagger at versions pinned in `tools/go.mod`).\nIf you don't have network access, skip it and rely on the style rules below plus\n`make check-unit` and `make` — a maintainer or CI will run the full\n`make static-analysis` before merge.\n\n## Integration tests\n\nIntegration tests require root, a running LXD daemon, and (for some suites) MicroCeph /\nMicroOVN. See `test/README.md` for full setup instructions.\n\n```bash\n# Run a specific suite\nsudo ./test/main.sh <suite-name>\n\n# Run a snap integration suite\nsudo -E ./test/snap/cgroup latest/edge\n```\n\n## Key conventions\n\n### Commit format\n\nSee [`COMMITS.md`](COMMITS.md) for the full commit prefix table and signing requirements.\n\n### Error messages\n\n- Use gerund form: `\"Failed connecting to target\"` not `\"Failed to connect to target\"`.\n- Use `\"cannot\"` not `\"unable to\"` and not contractions (`\"does not\"` not `\"doesn't\"`).\n- US English spelling throughout (`behavior`, `color`, `initialize`).\n\n### Go code style\n\n- No inline variable declarations inside `if` conditions — assign on a separate line first.\n- Prefer early returns to reduce nesting.\n- Check `shared/` for existing helpers before implementing utilities from scratch.\n  Common helpers include `shared.ParseCert([]byte)` for PEM parsing,\n  `shared.CertFingerprint(cert)` for SHA-256 fingerprints, and\n  `shared.SplitNTrimSpace(s, sep, n, trim)` for splitting and trimming.\n\n### Additional Go style rules (enforced by `make static-analysis`)\n\n- Use `shared.IsFalse(x)` / `shared.IsTrue(x)` directly — do not write\n  `!shared.IsTrue(x)` or `!shared.IsFalse(x)`.\n- Always use the parenthesized `import (...)` block, even for a single import\n  (except `import \"C\"` for cgo).\n- Do not alias `github.com/canonical/lxd/client` as `lxd` — this collides\n  conceptually with the LXD daemon package name.\n- Prefer structured logging: `logger.Error(\"message\", logger.Ctx{\"key\": val})` over\n  `logger.Errorf(\"message: %v\", val)` — use the `f`-suffixed variants (`Debugf`,\n  `Infof`, `Warnf`, `Errorf`) only when the format string actually contains a `%` verb.\n- Add a blank line after a closing `}` of a block before the next statement, unless\n  the next line continues the same construct (e.g. `} else {` or another `case`).\n\n### Shell test style\n\n- Use `jq --exit-status` (`jq -e`) when asserting field presence or values.\n- For expected command failure: `if cmd_should_fail; then echo \"ERROR: ...\"; exit 1; fi`\n- Avoid `grep -c` for presence/absence checks; use `grep -wF` or exact CSV output instead.\n- Use `sub_test \"...\"` labels to mark meaningful test phases.\n\n## Code review\n\nUse these checks alongside `make static-analysis`, `make check-unit`, and\n`make`; `COMMITS.md` remains the source for commit prefixes and signing rules.\nReport only findings that require human action. Do not repeat issues already\nenforced by static analysis or lint checks; run the relevant check and report\nits output instead.\n\n### Go and test quality\n\n- Capitalize the first word of error messages. Preserve the gerund form,\n  `cannot`, and US English conventions listed above.\n- Prefer short variable declarations when a separate declaration and assignment\n  are unnecessary.\n- Document exported functions and types, and end doc comments with a period.\n- Prefer table-driven unit tests for homogeneous cases. Consider whether new\n  tests add enough value to justify their complexity and runtime.\n- Read each changed function in full before commenting. Flag added branching in\n  already long functions and repeated logic that should be factored out.\n\n### Cluster and network correctness\n\n- Check whether state is local or cluster-wide, and whether operations need\n  member targeting or notifications to other members.\n- Consider partial failure across members, leader-only assumptions, partitions,\n  retries and idempotency, timeouts, TLS or authentication errors, and\n  validation of untrusted network input.\n- Avoid repeated database queries inside loops or transactions. A write\n  transaction holds dqlite's cluster-wide write lock and can block other\n  writes.\n\n### API and generated files\n\n- Follow existing API conventions. A database entity with its own ID should\n  have its own URL; avoid APIs that recursively create or update multiple\n  entities without a strong justification.\n- Changes to `shared/api/` may also require updates to `doc/rest-api.yaml` and\n  `doc/api-extensions.md`. New configuration keys require `make update-metadata`.\n- Never edit generated files directly. Use the `make` targets in the generated\n  files table above.\n\n### Choosing integration tests\n\n| Changed area | Suggested test |\n|---|---|\n| `lxd/cluster/` | `group:cluster` or a `clustering_*` test |\n| `lxd/network/` | `group:network` |\n| `lxd/storage/` | `group:standalone_storage` or `group:cluster_storage` |\n| `lxd/storage/replicator/` | `group:cluster_storage` or `clustering_replicator_*` |\n| `lxd/instance/` | `group:instance` |\n| `lxd/auth/`, `lxd/identity/` | `auth` |\n| `lxc/` | `basic` or the matching subcommand test |\n| `shared/` | Search the suites for the affected consumer |\n\nIntegration tests require a live environment; report them as follow-ups when\nthey cannot be run. Do not clean up state after a failed test: preserve it for\ninspection and debugging.\n",".github/copilot-instructions.md":"# LXD Copilot Instructions\n\nLXD is a modern, secure system container and virtual machine manager.\nLXD requires the Go version listed in `doc/requirements.md` or higher and is only tested with the Golang compiler.\nSee `AGENTS.md` for the full development runbook.\n\n## Repository layout\n\n```\nlxd/        Main daemon          lxc/        Client CLI\nclient/     Go client library    shared/     Shared utilities\nlxd-agent/  VM guest agent       test/       Integration tests\ndoc/        Sphinx docs          scripts/    Utility scripts\n```\n\nKey locations: API handlers `lxd/api*.go`, device drivers `lxd/device/`, storage `lxd/storage/drivers/`, network `lxd/network/`, database `lxd/db/`, unit tests `*_test.go`, integration tests `test/suites/*.sh`.\n\n## Commit requirements\n\nSee [`COMMITS.md`](../COMMITS.md) for the full commit prefix table and signing requirements.\n\n## Code style\n\n- **No inline variable declarations in `if`** — assign on a separate line before the `if`.\n- **Check `shared/` for helpers** before reimplementing: `shared.ParseCert`, `shared.CertFingerprint`, `shared.GetRemoteCertificate`, `shared.SplitNTrimSpace`.\n- Comment all exported functions and types; end comments with a period.\n- Write table-driven unit tests where applicable.\n\n## Error messages (Go string literals only)\n\n- Gerund form: `\"Failed connecting\"` not `\"Failed to connect\"`.\n- Use `\"cannot\"` not `\"unable to\"`; no contractions (`\"does not\"` not `\"doesn't\"`).\n- US English spelling: `behavior`, `canceled`, `initialize`.\n- When changing error messages, update matching assertions in `test/suites/*.sh`.\n"},"files":{"doc/api.md":"(api-specification)=\n# Main API specification\n\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../_static/swagger-ui/swagger-ui.css\" ></link>\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../_static/swagger-override.css\" ></link>\n<div id=\"swagger-ui\"></div>\n\n<script src=\"../_static/swagger-ui/swagger-ui-bundle.js\" charset=\"UTF-8\"> </script>\n<script src=\"../_static/swagger-ui/swagger-ui-standalone-preset.js\" charset=\"UTF-8\"> </script>\n<script>\nwindow.onload = function() {\n  // Begin Swagger UI call region\n  const ui = SwaggerUIBundle({\n    url: window.location.pathname +\"../rest-api.yaml\",\n    dom_id: '#swagger-ui',\n    deepLinking: true,\n    presets: [\n      SwaggerUIBundle.presets.apis,\n      SwaggerUIStandalonePreset\n    ],\n    plugins: [],\n    validatorUrl: \"none\",\n    defaultModelsExpandDepth: -1,\n    supportedSubmitMethods: []\n  })\n  // End Swagger UI call region\n\n  window.ui = ui\n}\n</script>\n","test/AGENTS.md":"# AGENTS.md — Test Suite\n\nThis file provides agent instructions specific to the `test/` directory.\nSee `../AGENTS.md` at the repository root for the full development runbook.\nSee `README.md` in this directory for test coding conventions and environment variables.\n\n## Running tests\n\nIntegration tests require root. Use `sudo -E` to preserve environment variables:\n\n```bash\n# Run all tests\nsudo -E ./test/main.sh group:all\n\n# Run a specific group\nsudo -E ./test/main.sh group:cluster\n\n# Run against specific backends\nsudo -E LXD_BACKENDS=\"btrfs lvm\" ./test/main.sh group:standalone\n\n# Repeat tests (useful to catch races)\nsudo -E LXD_REPEAT_TESTS=10 ./test/main.sh group:standalone\n```\n\nUnit tests (no root needed):\n\n```bash\nmake check-unit\n```\n\n## Shell script style (test/*.sh)\n\n- No trailing whitespace, and no tab characters (use spaces for indentation).\n- New `test_*` functions must be registered in `test/includes/test-groups.sh`\n  (checked by `test/lint/test-tests.sh`).\n- Avoid `grep -q` in pipelines under `set -o pipefail` (can cause SIGPIPE issues);\n  avoid `grep -v` at the end of a pipeline to test for absence of a pattern — its\n  exit code doesn't reliably reflect that.\n","AGENTS.md":"# AGENTS.md — LXD Agent Instructions\n\nLXD is a modern, secure system container and virtual machine manager written in Go.\nModule: `github.com/canonical/lxd`.\n\n## Prerequisites\n\nLXD requires the Go version listed in `doc/requirements.md` or higher and is only tested with the Golang compiler.\n- CGO native dependencies (dqlite, liblxc). Fetch them once with:\n\n  ```bash\n  make deps\n  ```\n\n  This builds the native libraries under `$(go env GOPATH)/deps` (or `vendor/` in a\n  release tarball). Set the environment variables printed by `make env` if you build\n  outside of `make`.\n\n- The `client` (lxc CLI) and some test binaries build without CGO and have no native deps.\n\n## Repository layout\n\n```\nlxd/            Main daemon\nlxc/            Client CLI\nlxd-agent/      VM guest agent\nclient/         Go client library\nshared/         Code shared across components\ntest/\n  suites/       Integration test suites (bash)\n  snap/         Snap integration test scripts (run directly)\n  local-snap.sh Snap integration test runner (sourced by test/snap/* scripts)\n  lint/         Lint scripts\n  includes/\n    snap-helpers.sh  Shared snap integration test helpers\ndoc/            Sphinx documentation\n```\n\n### Auto-generated files — do not edit manually\n\nUpdate these via the listed `make` target instead of editing by hand:\n\n| File | Command |\n|------|---------|\n| `lxd/metadata/configuration.json`, `doc/metadata.txt` | `make update-metadata` |\n| `lxd/auth/entitlements_generated.go`, `lxd/auth/drivers/openfga_model.openfga` | `make update-auth` |\n| `go.mod`, `go.sum`, `tools/go.mod`, `tools/go.sum` | `make update-gomod` |\n| `doc/rest-api.yaml` | `make update-api` |\n\n## Build\n\n```bash\n# CGO-free client only (no native deps needed)\nmake client\n\n# Full daemon (requires CGO deps)\nmake lxd\n\n# Everything\nmake\n```\n\n## Validate before committing\n\nRun these in order. Each must pass before moving to the next.\n\n```bash\n# 1. Static analysis (golangci-lint, errortype, zerolint, generated-file checks)\nmake static-analysis\n\n# 2. Unit tests\nmake check-unit\n\n# 3. Full build\nmake\n```\n\n`make static-analysis` may regenerate output (e.g. `doc/rest-api.yaml`, generated DB code,\nauth entitlements, metadata docs) and errors out if that leaves an uncommitted diff; it\nnever prompts or commits on its own (stdin is closed for the checks it runs), so it's safe\nto run from an agent session. If it reports drift, re-run `make update-api`,\n`make update-auth`, `make update-metadata`, or `make update-schema` (whichever produced the\nfile in question) to regenerate it, then stop and leave the diff for a human to review and\ncommit; these four targets never call git themselves. Do not run an individual `check-*`\ntarget (e.g. `make check-api`) or `scripts/check-and-commit.sh` directly, and do not run\nother `update-*` targets like `update-gomod`, `update-golangci`, or `update-godeps` as a\nsubstitute; unlike the four above, those call `check-and-commit.sh` directly and will\nprompt interactively to commit, which hangs an agent session with no one to answer.\n\n`make static-analysis` requires network access (it installs/updates golangci-lint,\nerrortype, zerolint, goimports, and go-swagger at versions pinned in `tools/go.mod`).\nIf you don't have network access, skip it and rely on the style rules below plus\n`make check-unit` and `make` — a maintainer or CI will run the full\n`make static-analysis` before merge.\n\n## Integration tests\n\nIntegration tests require root, a running LXD daemon, and (for some suites) MicroCeph /\nMicroOVN. See `test/README.md` for full setup instructions.\n\n```bash\n# Run a specific suite\nsudo ./test/main.sh <suite-name>\n\n# Run a snap integration suite\nsudo -E ./test/snap/cgroup latest/edge\n```\n\n## Key conventions\n\n### Commit format\n\nSee [`COMMITS.md`](COMMITS.md) for the full commit prefix table and signing requirements.\n\n### Error messages\n\n- Use gerund form: `\"Failed connecting to target\"` not `\"Failed to connect to target\"`.\n- Use `\"cannot\"` not `\"unable to\"` and not contractions (`\"does not\"` not `\"doesn't\"`).\n- US English spelling throughout (`behavior`, `color`, `initialize`).\n\n### Go code style\n\n- No inline variable declarations inside `if` conditions — assign on a separate line first.\n- Prefer early returns to reduce nesting.\n- Check `shared/` for existing helpers before implementing utilities from scratch.\n  Common helpers include `shared.ParseCert([]byte)` for PEM parsing,\n  `shared.CertFingerprint(cert)` for SHA-256 fingerprints, and\n  `shared.SplitNTrimSpace(s, sep, n, trim)` for splitting and trimming.\n\n### Additional Go style rules (enforced by `make static-analysis`)\n\n- Use `shared.IsFalse(x)` / `shared.IsTrue(x)` directly — do not write\n  `!shared.IsTrue(x)` or `!shared.IsFalse(x)`.\n- Always use the parenthesized `import (...)` block, even for a single import\n  (except `import \"C\"` for cgo).\n- Do not alias `github.com/canonical/lxd/client` as `lxd` — this collides\n  conceptually with the LXD daemon package name.\n- Prefer structured logging: `logger.Error(\"message\", logger.Ctx{\"key\": val})` over\n  `logger.Errorf(\"message: %v\", val)` — use the `f`-suffixed variants (`Debugf`,\n  `Infof`, `Warnf`, `Errorf`) only when the format string actually contains a `%` verb.\n- Add a blank line after a closing `}` of a block before the next statement, unless\n  the next line continues the same construct (e.g. `} else {` or another `case`).\n\n### Shell test style\n\n- Use `jq --exit-status` (`jq -e`) when asserting field presence or values.\n- For expected command failure: `if cmd_should_fail; then echo \"ERROR: ...\"; exit 1; fi`\n- Avoid `grep -c` for presence/absence checks; use `grep -wF` or exact CSV output instead.\n- Use `sub_test \"...\"` labels to mark meaningful test phases.\n\n## Code review\n\nUse these checks alongside `make static-analysis`, `make check-unit`, and\n`make`; `COMMITS.md` remains the source for commit prefixes and signing rules.\nReport only findings that require human action. Do not repeat issues already\nenforced by static analysis or lint checks; run the relevant check and report\nits output instead.\n\n### Go and test quality\n\n- Capitalize the first word of error messages. Preserve the gerund form,\n  `cannot`, and US English conventions listed above.\n- Prefer short variable declarations when a separate declaration and assignment\n  are unnecessary.\n- Document exported functions and types, and end doc comments with a period.\n- Prefer table-driven unit tests for homogeneous cases. Consider whether new\n  tests add enough value to justify their complexity and runtime.\n- Read each changed function in full before commenting. Flag added branching in\n  already long functions and repeated logic that should be factored out.\n\n### Cluster and network correctness\n\n- Check whether state is local or cluster-wide, and whether operations need\n  member targeting or notifications to other members.\n- Consider partial failure across members, leader-only assumptions, partitions,\n  retries and idempotency, timeouts, TLS or authentication errors, and\n  validation of untrusted network input.\n- Avoid repeated database queries inside loops or transactions. A write\n  transaction holds dqlite's cluster-wide write lock and can block other\n  writes.\n\n### API and generated files\n\n- Follow existing API conventions. A database entity with its own ID should\n  have its own URL; avoid APIs that recursively create or update multiple\n  entities without a strong justification.\n- Changes to `shared/api/` may also require updates to `doc/rest-api.yaml` and\n  `doc/api-extensions.md`. New configuration keys require `make update-metadata`.\n- Never edit generated files directly. Use the `make` targets in the generated\n  files table above.\n\n### Choosing integration tests\n\n| Changed area | Suggested test |\n|---|---|\n| `lxd/cluster/` | `group:cluster` or a `clustering_*` test |\n| `lxd/network/` | `group:network` |\n| `lxd/storage/` | `group:standalone_storage` or `group:cluster_storage` |\n| `lxd/storage/replicator/` | `group:cluster_storage` or `clustering_replicator_*` |\n| `lxd/instance/` | `group:instance` |\n| `lxd/auth/`, `lxd/identity/` | `auth` |\n| `lxc/` | `basic` or the matching subcommand test |\n| `shared/` | Search the suites for the affected consumer |\n\nIntegration tests require a live environment; report them as follow-ups when\nthey cannot be run. Do not clean up state after a failed test: preserve it for\ninspection and debugging.\n",".github/copilot-instructions.md":"# LXD Copilot Instructions\n\nLXD is a modern, secure system container and virtual machine manager.\nLXD requires the Go version listed in `doc/requirements.md` or higher and is only tested with the Golang compiler.\nSee `AGENTS.md` for the full development runbook.\n\n## Repository layout\n\n```\nlxd/        Main daemon          lxc/        Client CLI\nclient/     Go client library    shared/     Shared utilities\nlxd-agent/  VM guest agent       test/       Integration tests\ndoc/        Sphinx docs          scripts/    Utility scripts\n```\n\nKey locations: API handlers `lxd/api*.go`, device drivers `lxd/device/`, storage `lxd/storage/drivers/`, network `lxd/network/`, database `lxd/db/`, unit tests `*_test.go`, integration tests `test/suites/*.sh`.\n\n## Commit requirements\n\nSee [`COMMITS.md`](../COMMITS.md) for the full commit prefix table and signing requirements.\n\n## Code style\n\n- **No inline variable declarations in `if`** — assign on a separate line before the `if`.\n- **Check `shared/` for helpers** before reimplementing: `shared.ParseCert`, `shared.CertFingerprint`, `shared.GetRemoteCertificate`, `shared.SplitNTrimSpace`.\n- Comment all exported functions and types; end comments with a period.\n- Write table-driven unit tests where applicable.\n\n## Error messages (Go string literals only)\n\n- Gerund form: `\"Failed connecting\"` not `\"Failed to connect\"`.\n- Use `\"cannot\"` not `\"unable to\"`; no contractions (`\"does not\"` not `\"doesn't\"`).\n- US English spelling: `behavior`, `canceled`, `initialize`.\n- When changing error messages, update matching assertions in `test/suites/*.sh`.\n"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","rawUrl":"https://raw.githubusercontent.com/canonical/lxd/HEAD/AGENTS.md","title":"AI Agent Protocol & Instructions","category":"root-instruction","format":"markdown","content":"# AGENTS.md — LXD Agent Instructions\n\nLXD is a modern, secure system container and virtual machine manager written in Go.\nModule: `github.com/canonical/lxd`.\n\n## Prerequisites\n\nLXD requires the Go version listed in `doc/requirements.md` or higher and is only tested with the Golang compiler.\n- CGO native dependencies (dqlite, liblxc). Fetch them once with:\n\n  ```bash\n  make deps\n  ```\n\n  This builds the native libraries under `$(go env GOPATH)/deps` (or `vendor/` in a\n  release tarball). Set the environment variables printed by `make env` if you build\n  outside of `make`.\n\n- The `client` (lxc CLI) and some test binaries build without CGO and have no native deps.\n\n## Repository layout\n\n```\nlxd/            Main daemon\nlxc/            Client CLI\nlxd-agent/      VM guest agent\nclient/         Go client library\nshared/         Code shared across components\ntest/\n  suites/       Integration test suites (bash)\n  snap/         Snap integration test scripts (run directly)\n  local-snap.sh Snap integration test runner (sourced by test/snap/* scripts)\n  lint/         Lint scripts\n  includes/\n    snap-helpers.sh  Shared snap integration test helpers\ndoc/            Sphinx documentation\n```\n\n### Auto-generated files — do not edit manually\n\nUpdate these via the listed `make` target instead of editing by hand:\n\n| File | Command |\n|------|---------|\n| `lxd/metadata/configuration.json`, `doc/metadata.txt` | `make update-metadata` |\n| `lxd/auth/entitlements_generated.go`, `lxd/auth/drivers/openfga_model.openfga` | `make update-auth` |\n| `go.mod`, `go.sum`, `tools/go.mod`, `tools/go.sum` | `make update-gomod` |\n| `doc/rest-api.yaml` | `make update-api` |\n\n## Build\n\n```bash\n# CGO-free client only (no native deps needed)\nmake client\n\n# Full daemon (requires CGO deps)\nmake lxd\n\n# Everything\nmake\n```\n\n## Validate before committing\n\nRun these in order. Each must pass before moving to the next.\n\n```bash\n# 1. Static analysis (golangci-lint, errortype, zerolint, generated-file checks)\nmake static-analysis\n\n# 2. Unit tests\nmake check-unit\n\n# 3. Full build\nmake\n```\n\n`make static-analysis` may regenerate output (e.g. `doc/rest-api.yaml`, generated DB code,\nauth entitlements, metadata docs) and errors out if that leaves an uncommitted diff; it\nnever prompts or commits on its own (stdin is closed for the checks it runs), so it's safe\nto run from an agent session. If it reports drift, re-run `make update-api`,\n`make update-auth`, `make update-metadata`, or `make update-schema` (whichever produced the\nfile in question) to regenerate it, then stop and leave the diff for a human to review and\ncommit; these four targets never call git themselves. Do not run an individual `check-*`\ntarget (e.g. `make check-api`) or `scripts/check-and-commit.sh` directly, and do not run\nother `update-*` targets like `update-gomod`, `update-golangci`, or `update-godeps` as a\nsubstitute; unlike the four above, those call `check-and-commit.sh` directly and will\nprompt interactively to commit, which hangs an agent session with no one to answer.\n\n`make static-analysis` requires network access (it installs/updates golangci-lint,\nerrortype, zerolint, goimports, and go-swagger at versions pinned in `tools/go.mod`).\nIf you don't have network access, skip it and rely on the style rules below plus\n`make check-unit` and `make` — a maintainer or CI will run the full\n`make static-analysis` before merge.\n\n## Integration tests\n\nIntegration tests require root, a running LXD daemon, and (for some suites) MicroCeph /\nMicroOVN. See `test/README.md` for full setup instructions.\n\n```bash\n# Run a specific suite\nsudo ./test/main.sh <suite-name>\n\n# Run a snap integration suite\nsudo -E ./test/snap/cgroup latest/edge\n```\n\n## Key conventions\n\n### Commit format\n\nSee [`COMMITS.md`](COMMITS.md) for the full commit prefix table and signing requirements.\n\n### Error messages\n\n- Use gerund form: `\"Failed connecting to target\"` not `\"Failed to connect to target\"`.\n- Use `\"cannot\"` not `\"unable to\"` and not contractions (`\"does not\"` not `\"doesn't\"`).\n- US English spelling throughout (`behavior`, `color`, `initialize`).\n\n### Go code style\n\n- No inline variable declarations inside `if` conditions — assign on a separate line first.\n- Prefer early returns to reduce nesting.\n- Check `shared/` for existing helpers before implementing utilities from scratch.\n  Common helpers include `shared.ParseCert([]byte)` for PEM parsing,\n  `shared.CertFingerprint(cert)` for SHA-256 fingerprints, and\n  `shared.SplitNTrimSpace(s, sep, n, trim)` for splitting and trimming.\n\n### Additional Go style rules (enforced by `make static-analysis`)\n\n- Use `shared.IsFalse(x)` / `shared.IsTrue(x)` directly — do not write\n  `!shared.IsTrue(x)` or `!shared.IsFalse(x)`.\n- Always use the parenthesized `import (...)` block, even for a single import\n  (except `import \"C\"` for cgo).\n- Do not alias `github.com/canonical/lxd/client` as `lxd` — this collides\n  conceptually with the LXD daemon package name.\n- Prefer structured logging: `logger.Error(\"message\", logger.Ctx{\"key\": val})` over\n  `logger.Errorf(\"message: %v\", val)` — use the `f`-suffixed variants (`Debugf`,\n  `Infof`, `Warnf`, `Errorf`) only when the format string actually contains a `%` verb.\n- Add a blank line after a closing `}` of a block before the next statement, unless\n  the next line continues the same construct (e.g. `} else {` or another `case`).\n\n### Shell test style\n\n- Use `jq --exit-status` (`jq -e`) when asserting field presence or values.\n- For expected command failure: `if cmd_should_fail; then echo \"ERROR: ...\"; exit 1; fi`\n- Avoid `grep -c` for presence/absence checks; use `grep -wF` or exact CSV output instead.\n- Use `sub_test \"...\"` labels to mark meaningful test phases.\n\n## Code review\n\nUse these checks alongside `make static-analysis`, `make check-unit`, and\n`make`; `COMMITS.md` remains the source for commit prefixes and signing rules.\nReport only findings that require human action. Do not repeat issues already\nenforced by static analysis or lint checks; run the relevant check and report\nits output instead.\n\n### Go and test quality\n\n- Capitalize the first word of error messages. Preserve the gerund form,\n  `cannot`, and US English conventions listed above.\n- Prefer short variable declarations when a separate declaration and assignment\n  are unnecessary.\n- Document exported functions and types, and end doc comments with a period.\n- Prefer table-driven unit tests for homogeneous cases. Consider whether new\n  tests add enough value to justify their complexity and runtime.\n- Read each changed function in full before commenting. Flag added branching in\n  already long functions and repeated logic that should be factored out.\n\n### Cluster and network correctness\n\n- Check whether state is local or cluster-wide, and whether operations need\n  member targeting or notifications to other members.\n- Consider partial failure across members, leader-only assumptions, partitions,\n  retries and idempotency, timeouts, TLS or authentication errors, and\n  validation of untrusted network input.\n- Avoid repeated database queries inside loops or transactions. A write\n  transaction holds dqlite's cluster-wide write lock and can block other\n  writes.\n\n### API and generated files\n\n- Follow existing API conventions. A database entity with its own ID should\n  have its own URL; avoid APIs that recursively create or update multiple\n  entities without a strong justification.\n- Changes to `shared/api/` may also require updates to `doc/rest-api.yaml` and\n  `doc/api-extensions.md`. New configuration keys require `make update-metadata`.\n- Never edit generated files directly. Use the `make` targets in the generated\n  files table above.\n\n### Choosing integration tests\n\n| Changed area | Suggested test |\n|---|---|\n| `lxd/cluster/` | `group:cluster` or a `clustering_*` test |\n| `lxd/network/` | `group:network` |\n| `lxd/storage/` | `group:standalone_storage` or `group:cluster_storage` |\n| `lxd/storage/replicator/` | `group:cluster_storage` or `clustering_replicator_*` |\n| `lxd/instance/` | `group:instance` |\n| `lxd/auth/`, `lxd/identity/` | `auth` |\n| `lxc/` | `basic` or the matching subcommand test |\n| `shared/` | Search the suites for the affected consumer |\n\nIntegration tests require a live environment; report them as follow-ups when\nthey cannot be run. Do not clean up state after a failed test: preserve it for\ninspection and debugging.\n","isInternal":false,"tokens":2059,"sizeBytes":8420},{"name":"AGENTS.md","path":"test/AGENTS.md","rawUrl":"https://raw.githubusercontent.com/canonical/lxd/HEAD/test/AGENTS.md","title":"test - AI Agent Protocol & Instructions","category":"root-instruction","format":"markdown","content":"# AGENTS.md — Test Suite\n\nThis file provides agent instructions specific to the `test/` directory.\nSee `../AGENTS.md` at the repository root for the full development runbook.\nSee `README.md` in this directory for test coding conventions and environment variables.\n\n## Running tests\n\nIntegration tests require root. Use `sudo -E` to preserve environment variables:\n\n```bash\n# Run all tests\nsudo -E ./test/main.sh group:all\n\n# Run a specific group\nsudo -E ./test/main.sh group:cluster\n\n# Run against specific backends\nsudo -E LXD_BACKENDS=\"btrfs lvm\" ./test/main.sh group:standalone\n\n# Repeat tests (useful to catch races)\nsudo -E LXD_REPEAT_TESTS=10 ./test/main.sh group:standalone\n```\n\nUnit tests (no root needed):\n\n```bash\nmake check-unit\n```\n\n## Shell script style (test/*.sh)\n\n- No trailing whitespace, and no tab characters (use spaces for indentation).\n- New `test_*` functions must be registered in `test/includes/test-groups.sh`\n  (checked by `test/lint/test-tests.sh`).\n- Avoid `grep -q` in pipelines under `set -o pipefail` (can cause SIGPIPE issues);\n  avoid `grep -v` at the end of a pipeline to test for absence of a pattern — its\n  exit code doesn't reliably reflect that.\n","isInternal":false,"tokens":298,"sizeBytes":1190},{"name":"api.md","path":"doc/api.md","rawUrl":"https://raw.githubusercontent.com/canonical/lxd/HEAD/doc/api.md","title":"doc - API Interface Contract & Specifications","category":"project-spec","format":"markdown","content":"(api-specification)=\n# Main API specification\n\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../_static/swagger-ui/swagger-ui.css\" ></link>\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../_static/swagger-override.css\" ></link>\n<div id=\"swagger-ui\"></div>\n\n<script src=\"../_static/swagger-ui/swagger-ui-bundle.js\" charset=\"UTF-8\"> </script>\n<script src=\"../_static/swagger-ui/swagger-ui-standalone-preset.js\" charset=\"UTF-8\"> </script>\n<script>\nwindow.onload = function() {\n  // Begin Swagger UI call region\n  const ui = SwaggerUIBundle({\n    url: window.location.pathname +\"../rest-api.yaml\",\n    dom_id: '#swagger-ui',\n    deepLinking: true,\n    presets: [\n      SwaggerUIBundle.presets.apis,\n      SwaggerUIStandalonePreset\n    ],\n    plugins: [],\n    validatorUrl: \"none\",\n    defaultModelsExpandDepth: -1,\n    supportedSubmitMethods: []\n  })\n  // End Swagger UI call region\n\n  window.ui = ui\n}\n</script>\n","isInternal":false,"tokens":230,"sizeBytes":907},{"name":"copilot-instructions.md","path":".github/copilot-instructions.md","rawUrl":"https://raw.githubusercontent.com/canonical/lxd/HEAD/.github/copilot-instructions.md","title":"GitHub Copilot Instructions","category":"copilot-instructions","format":"markdown","content":"# LXD Copilot Instructions\n\nLXD is a modern, secure system container and virtual machine manager.\nLXD requires the Go version listed in `doc/requirements.md` or higher and is only tested with the Golang compiler.\nSee `AGENTS.md` for the full development runbook.\n\n## Repository layout\n\n```\nlxd/        Main daemon          lxc/        Client CLI\nclient/     Go client library    shared/     Shared utilities\nlxd-agent/  VM guest agent       test/       Integration tests\ndoc/        Sphinx docs          scripts/    Utility scripts\n```\n\nKey locations: API handlers `lxd/api*.go`, device drivers `lxd/device/`, storage `lxd/storage/drivers/`, network `lxd/network/`, database `lxd/db/`, unit tests `*_test.go`, integration tests `test/suites/*.sh`.\n\n## Commit requirements\n\nSee [`COMMITS.md`](../COMMITS.md) for the full commit prefix table and signing requirements.\n\n## Code style\n\n- **No inline variable declarations in `if`** — assign on a separate line before the `if`.\n- **Check `shared/` for helpers** before reimplementing: `shared.ParseCert`, `shared.CertFingerprint`, `shared.GetRemoteCertificate`, `shared.SplitNTrimSpace`.\n- Comment all exported functions and types; end comments with a period.\n- Write table-driven unit tests where applicable.\n\n## Error messages (Go string literals only)\n\n- Gerund form: `\"Failed connecting\"` not `\"Failed to connect\"`.\n- Use `\"cannot\"` not `\"unable to\"`; no contractions (`\"does not\"` not `\"doesn't\"`).\n- US English spelling: `behavior`, `canceled`, `initialize`.\n- When changing error messages, update matching assertions in `test/suites/*.sh`.\n","isInternal":false,"tokens":378,"sizeBytes":1594}],"systemPromptSnippet":"<yakaai_skills repo=\"canonical/lxd\">\n<!-- File: AGENTS.md (Tokens: ~2059 | Category: root-instruction) -->\n# AGENTS.md — LXD Agent Instructions\n\nLXD is a modern, secure system container and virtual machine manager written in Go.\nModule: `github.com/canonical/lxd`.\n\n## Prerequisites\n\nLXD requires the Go version listed in `doc/requirements.md` or higher and is only tested with the Golang compiler.\n- CGO native dependencies (dqlite, liblxc). Fetch them once with:\n\n  ```bash\n  make deps\n  ```\n\n  This builds the native libraries under `$(go env GOPATH)/deps` (or `vendor/` in a\n  release tarball). Set the environment variables printed by `make env` if you build\n  outside of `make`.\n\n- The `client` (lxc CLI) and some test binaries build without CGO and have no native deps.\n\n## Repository layout\n\n```\nlxd/            Main daemon\nlxc/            Client CLI\nlxd-agent/      VM guest agent\nclient/         Go client library\nshared/         Code shared across components\ntest/\n  suites/       Integration test suites (bash)\n  snap/         Snap integration test scripts (run directly)\n  local-snap.sh Snap integration test runner (sourced by test/snap/* scripts)\n  lint/         Lint scripts\n  includes/\n    snap-helpers.sh  Shared snap integration test helpers\ndoc/            Sphinx documentation\n```\n\n### Auto-generated files — do not edit manually\n\nUpdate these via the listed `make` target instead of editing by hand:\n\n| File | Command |\n|------|---------|\n| `lxd/metadata/configuration.json`, `doc/metadata.txt` | `make update-metadata` |\n| `lxd/auth/entitlements_generated.go`, `lxd/auth/drivers/openfga_model.openfga` | `make update-auth` |\n| `go.mod`, `go.sum`, `tools/go.mod`, `tools/go.sum` | `make update-gomod` |\n| `doc/rest-api.yaml` | `make update-api` |\n\n## Build\n\n```bash\n# CGO-free client only (no native deps needed)\nmake client\n\n# Full daemon (requires CGO deps)\nmake lxd\n\n# Everything\nmake\n```\n\n## Validate before committing\n\nRun these in order. Each must pass before moving to the next.\n\n```bash\n# 1. Static analysis (golangci-lint, errortype, zerolint, generated-file checks)\nmake static-analysis\n\n# 2. Unit tests\nmake check-unit\n\n# 3. Full build\nmake\n```\n\n`make static-analysis` may regenerate output (e.g. `doc/rest-api.yaml`, generated DB code,\nauth entitlements, metadata docs) and errors out if that leaves an uncommitted diff; it\nnever prompts or commits on its own (stdin is closed for the checks it runs), so it's safe\nto run from an agent session. If it reports drift, re-run `make update-api`,\n`make update-auth`, `make update-metadata`, or `make update-schema` (whichever produced the\nfile in question) to regenerate it, then stop and leave the diff for a human to review and\ncommit; these four targets never call git themselves. Do not run an individual `check-*`\ntarget (e.g. `make check-api`) or `scripts/check-and-commit.sh` directly, and do not run\nother `update-*` targets like `update-gomod`, `update-golangci`, or `update-godeps` as a\nsubstitute; unlike the four above, those call `check-and-commit.sh` directly and will\nprompt interactively to commit, which hangs an agent session with no one to answer.\n\n`make static-analysis` requires network access (it installs/updates golangci-lint,\nerrortype, zerolint, goimports, and go-swagger at versions pinned in `tools/go.mod`).\nIf you don't have network access, skip it and rely on the style rules below plus\n`make check-unit` and `make` — a maintainer or CI will run the full\n`make static-analysis` before merge.\n\n## Integration tests\n\nIntegration tests require root, a running LXD daemon, and (for some suites) MicroCeph /\nMicroOVN. See `test/README.md` for full setup instructions.\n\n```bash\n# Run a specific suite\nsudo ./test/main.sh <suite-name>\n\n# Run a snap integration suite\nsudo -E ./test/snap/cgroup latest/edge\n```\n\n## Key conventions\n\n### Commit format\n\nSee [`COMMITS.md`](COMMITS.md) for the full commit prefix table and signing requirements.\n\n### Error messages\n\n- Use gerund form: `\"Failed connecting to target\"` not `\"Failed to connect to target\"`.\n- Use `\"cannot\"` not `\"unable to\"` and not contractions (`\"does not\"` not `\"doesn't\"`).\n- US English spelling throughout (`behavior`, `color`, `initialize`).\n\n### Go code style\n\n- No inline variable declarations inside `if` conditions — assign on a separate line first.\n- Prefer early returns to reduce nesting.\n- Check `shared/` for existing helpers before implementing utilities from scratch.\n  Common helpers include `shared.ParseCert([]byte)` for PEM parsing,\n  `shared.CertFingerprint(cert)` for SHA-256 fingerprints, and\n  `shared.SplitNTrimSpace(s, sep, n, trim)` for splitting and trimming.\n\n### Additional Go style rules (enforced by `make static-analysis`)\n\n- Use `shared.IsFalse(x)` / `shared.IsTrue(x)` directly — do not write\n  `!shared.IsTrue(x)` or `!shared.IsFalse(x)`.\n- Always use the parenthesized `import (...)` block, even for a single import\n  (except `import \"C\"` for cgo).\n- Do not alias `github.com/canonical/lxd/client` as `lxd` — this collides\n  conceptually with the LXD daemon package name.\n- Prefer structured logging: `logger.Error(\"message\", logger.Ctx{\"key\": val})` over\n  `logger.Errorf(\"message: %v\", val)` — use the `f`-suffixed variants (`Debugf`,\n  `Infof`, `Warnf`, `Errorf`) only when the format string actually contains a `%` verb.\n- Add a blank line after a closing `}` of a block before the next statement, unless\n  the next line continues the same construct (e.g. `} else {` or another `case`).\n\n### Shell test style\n\n- Use `jq --exit-status` (`jq -e`) when asserting field presence or values.\n- For expected command failure: `if cmd_should_fail; then echo \"ERROR: ...\"; exit 1; fi`\n- Avoid `grep -c` for presence/absence checks; use `grep -wF` or exact CSV output instead.\n- Use `sub_test \"...\"` labels to mark meaningful test phases.\n\n## Code review\n\nUse these checks alongside `make static-analysis`, `make check-unit`, and\n`make`; `COMMITS.md` remains the source for commit prefixes and signing rules.\nReport only findings that require human action. Do not repeat issues already\nenforced by static analysis or lint checks; run the relevant check and report\nits output instead.\n\n### Go and test quality\n\n- Capitalize the first word of error messages. Preserve the gerund form,\n  `cannot`, and US English conventions listed above.\n- Prefer short variable declarations when a separate declaration and assignment\n  are unnecessary.\n- Document exported functions and types, and end doc comments with a period.\n- Prefer table-driven unit tests for homogeneous cases. Consider whether new\n  tests add enough value to justify their complexity and runtime.\n- Read each changed function in full before commenting. Flag added branching in\n  already long functions and repeated logic that should be factored out.\n\n### Cluster and network correctness\n\n- Check whether state is local or cluster-wide, and whether operations need\n  member targeting or notifications to other members.\n- Consider partial failure across members, leader-only assumptions, partitions,\n  retries and idempotency, timeouts, TLS or authentication errors, and\n  validation of untrusted network input.\n- Avoid repeated database queries inside loops or transactions. A write\n  transaction holds dqlite's cluster-wide write lock and can block other\n  writes.\n\n### API and generated files\n\n- Follow existing API conventions. A database entity with its own ID should\n  have its own URL; avoid APIs that recursively create or update multiple\n  entities without a strong justification.\n- Changes to `shared/api/` may also require updates to `doc/rest-api.yaml` and\n  `doc/api-extensions.md`. New configuration keys require `make update-metadata`.\n- Never edit generated files directly. Use the `make` targets in the generated\n  files table above.\n\n### Choosing integration tests\n\n| Changed area | Suggested test |\n|---|---|\n| `lxd/cluster/` | `group:cluster` or a `clustering_*` test |\n| `lxd/network/` | `group:network` |\n| `lxd/storage/` | `group:standalone_storage` or `group:cluster_storage` |\n| `lxd/storage/replicator/` | `group:cluster_storage` or `clustering_replicator_*` |\n| `lxd/instance/` | `group:instance` |\n| `lxd/auth/`, `lxd/identity/` | `auth` |\n| `lxc/` | `basic` or the matching subcommand test |\n| `shared/` | Search the suites for the affected consumer |\n\nIntegration tests require a live environment; report them as follow-ups when\nthey cannot be run. Do not clean up state after a failed test: preserve it for\ninspection and debugging.\n\n<!-- File: test/AGENTS.md (Tokens: ~298 | Category: root-instruction) -->\n# AGENTS.md — Test Suite\n\nThis file provides agent instructions specific to the `test/` directory.\nSee `../AGENTS.md` at the repository root for the full development runbook.\nSee `README.md` in this directory for test coding conventions and environment variables.\n\n## Running tests\n\nIntegration tests require root. Use `sudo -E` to preserve environment variables:\n\n```bash\n# Run all tests\nsudo -E ./test/main.sh group:all\n\n# Run a specific group\nsudo -E ./test/main.sh group:cluster\n\n# Run against specific backends\nsudo -E LXD_BACKENDS=\"btrfs lvm\" ./test/main.sh group:standalone\n\n# Repeat tests (useful to catch races)\nsudo -E LXD_REPEAT_TESTS=10 ./test/main.sh group:standalone\n```\n\nUnit tests (no root needed):\n\n```bash\nmake check-unit\n```\n\n## Shell script style (test/*.sh)\n\n- No trailing whitespace, and no tab characters (use spaces for indentation).\n- New `test_*` functions must be registered in `test/includes/test-groups.sh`\n  (checked by `test/lint/test-tests.sh`).\n- Avoid `grep -q` in pipelines under `set -o pipefail` (can cause SIGPIPE issues);\n  avoid `grep -v` at the end of a pipeline to test for absence of a pattern — its\n  exit code doesn't reliably reflect that.\n\n<!-- File: doc/api.md (Tokens: ~230 | Category: project-spec) -->\n(api-specification)=\n# Main API specification\n\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../_static/swagger-ui/swagger-ui.css\" ></link>\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../_static/swagger-override.css\" ></link>\n<div id=\"swagger-ui\"></div>\n\n<script src=\"../_static/swagger-ui/swagger-ui-bundle.js\" charset=\"UTF-8\"> </script>\n<script src=\"../_static/swagger-ui/swagger-ui-standalone-preset.js\" charset=\"UTF-8\"> </script>\n<script>\nwindow.onload = function() {\n  // Begin Swagger UI call region\n  const ui = SwaggerUIBundle({\n    url: window.location.pathname +\"../rest-api.yaml\",\n    dom_id: '#swagger-ui',\n    deepLinking: true,\n    presets: [\n      SwaggerUIBundle.presets.apis,\n      SwaggerUIStandalonePreset\n    ],\n    plugins: [],\n    validatorUrl: \"none\",\n    defaultModelsExpandDepth: -1,\n    supportedSubmitMethods: []\n  })\n  // End Swagger UI call region\n\n  window.ui = ui\n}\n</script>\n\n<!-- File: .github/copilot-instructions.md (Tokens: ~378 | Category: copilot-instructions) -->\n# LXD Copilot Instructions\n\nLXD is a modern, secure system container and virtual machine manager.\nLXD requires the Go version listed in `doc/requirements.md` or higher and is only tested with the Golang compiler.\nSee `AGENTS.md` for the full development runbook.\n\n## Repository layout\n\n```\nlxd/        Main daemon          lxc/        Client CLI\nclient/     Go client library    shared/     Shared utilities\nlxd-agent/  VM guest agent       test/       Integration tests\ndoc/        Sphinx docs          scripts/    Utility scripts\n```\n\nKey locations: API handlers `lxd/api*.go`, device drivers `lxd/device/`, storage `lxd/storage/drivers/`, network `lxd/network/`, database `lxd/db/`, unit tests `*_test.go`, integration tests `test/suites/*.sh`.\n\n## Commit requirements\n\nSee [`COMMITS.md`](../COMMITS.md) for the full commit prefix table and signing requirements.\n\n## Code style\n\n- **No inline variable declarations in `if`** — assign on a separate line before the `if`.\n- **Check `shared/` for helpers** before reimplementing: `shared.ParseCert`, `shared.CertFingerprint`, `shared.GetRemoteCertificate`, `shared.SplitNTrimSpace`.\n- Comment all exported functions and types; end comments with a period.\n- Write table-driven unit tests where applicable.\n\n## Error messages (Go string literals only)\n\n- Gerund form: `\"Failed connecting\"` not `\"Failed to connect\"`.\n- Use `\"cannot\"` not `\"unable to\"`; no contractions (`\"does not\"` not `\"doesn't\"`).\n- US English spelling: `behavior`, `canceled`, `initialize`.\n- When changing error messages, update matching assertions in `test/suites/*.sh`.\n</yakaai_skills>"}