Compare commits

...

156 Commits
v1.2.3 ... main

Author SHA1 Message Date
Navid Yaghoobi 66fc1cc64f
Merge pull request #623 from navidys/remote_connections
Fixbug invalid error when default remote connection is not defined
2025-06-15 11:52:18 +10:00
Navid Yaghoobi 04b6c47895 Bugfix invalid error when default remote connection is not defined
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2025-06-15 11:49:48 +10:00
Navid Yaghoobi fe095fd4b3
Merge pull request #622 from navidys/podman_remote_connections
Add feature to use podman remote connections config if exist
2025-06-14 20:36:28 +10:00
Navid Yaghoobi a2eb9b4823 Add feature to use podman remote connections config if exist
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2025-06-14 20:26:21 +10:00
Navid Yaghoobi d6ba7488b2
Merge pull request #621 from navidys/podman_remote_connections
Using json format for app config file
2025-06-14 10:34:51 +10:00
Navid Yaghoobi 58b4fbdc03 Using json format for app config file
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2025-06-14 10:28:38 +10:00
Navid Yaghoobi 7f9559b3ac
Merge pull request #620 from navidys/packit
packit - set rpm build for fedora-all
2025-06-11 19:27:33 +10:00
Navid Yaghoobi 9ed811d204 packit - set rpm build for fedora-all
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2025-06-11 19:19:24 +10:00
Navid Yaghoobi 31dce751c8
Merge pull request #619 from navidys/pod_create_namespace
Pod create namespace
2025-06-11 19:10:56 +10:00
Navid Yaghoobi 6e59fa69eb Added pod create namespace category
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2025-06-11 18:47:59 +10:00
Navid Yaghoobi cd74eeb550 Added pod create namespace category
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2025-06-09 20:19:27 +10:00
Navid Yaghoobi 5e89744b23
Merge pull request #618 from navidys/container_create_namespace
Added container create namespace (ipc, userns, uts, ...) category
2025-06-09 19:36:08 +10:00
Navid Yaghoobi 196004fe46 Added container create namespace (ipc, userns, uts, ...) category
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2025-06-09 19:30:43 +10:00
Navid Yaghoobi b7e0b93adb
Merge pull request #617 from navidys/bugfix_screenlock
Bugfix - connection list lock
2025-06-09 18:25:19 +10:00
Navid Yaghoobi e3242f37c7 Bugfix - connection list lock
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2025-06-09 18:17:35 +10:00
Navid Yaghoobi 897f8ddae1
Merge pull request #615 from navidys/develop
UI code cleanup + set max width for container view image name
2025-06-08 09:02:52 +10:00
Navid Yaghoobi 92b9653353 UI code cleanup + set max with for container view image name
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2025-06-08 08:54:39 +10:00
Navid Yaghoobi a89d6d6ef0
Merge pull request #613 from containers/dependabot/go_modules/golang.org/x/crypto-0.39.0
Bump golang.org/x/crypto from 0.38.0 to 0.39.0
2025-06-07 18:42:35 +10:00
Navid Yaghoobi 6cb9178d24
Merge pull request #614 from containers/dependabot/go_modules/github.com/containers/podman/v5-5.5.1
Bump github.com/containers/podman/v5 from 5.5.0 to 5.5.1
2025-06-07 16:46:53 +10:00
dependabot[bot] 5fc3515715
Bump github.com/containers/podman/v5 from 5.5.0 to 5.5.1
Bumps [github.com/containers/podman/v5](https://github.com/containers/podman) from 5.5.0 to 5.5.1.
- [Release notes](https://github.com/containers/podman/releases)
- [Changelog](https://github.com/containers/podman/blob/main/RELEASE_NOTES.md)
- [Commits](https://github.com/containers/podman/compare/v5.5.0...v5.5.1)

---
updated-dependencies:
- dependency-name: github.com/containers/podman/v5
  dependency-version: 5.5.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-06 20:07:05 +00:00
dependabot[bot] 5a9541f97f
Bump golang.org/x/crypto from 0.38.0 to 0.39.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.38.0 to 0.39.0.
- [Commits](https://github.com/golang/crypto/compare/v0.38.0...v0.39.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-version: 0.39.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-05 20:52:59 +00:00
Navid Yaghoobi 785b690989
Merge pull request #610 from navidys/bump-1.6.0
Bump 1.6.0
2025-05-28 17:45:53 +10:00
Navid Yaghoobi 5ab12464fb Bump to v1.7.0-dev
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2025-05-28 17:37:56 +10:00
Navid Yaghoobi 0b65653d80 Bump to v1.6.0
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2025-05-28 17:36:53 +10:00
Navid Yaghoobi 6294d7d1ee
Merge pull request #609 from navidys/podman-v5.5.0
Podman v5.5.0
2025-05-27 22:23:04 +10:00
Navid Yaghoobi 136c5f75df Fix golint issue
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2025-05-27 20:59:49 +10:00
Navid Yaghoobi b02ec6036f Added container create health log dest, max count and size options
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2025-05-27 20:28:22 +10:00
Navid Yaghoobi ef10f184b1 Fix bats test for network connect
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2025-05-25 12:19:16 +10:00
Navid Yaghoobi 3eabf12196 Bump github.com/containers/podman/v5 from 5.4.2 to 5.5.0
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2025-05-24 11:29:40 +10:00
Navid Yaghoobi 7f02a36e85
Merge pull request #604 from containers/dependabot/go_modules/golang.org/x/net-0.38.0
Bump golang.org/x/net from 0.36.0 to 0.38.0
2025-05-18 17:45:40 +10:00
dependabot[bot] 164ca27d7f
Bump golang.org/x/net from 0.36.0 to 0.38.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.36.0 to 0.38.0.
- [Commits](https://github.com/golang/net/compare/v0.36.0...v0.38.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-version: 0.38.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-16 23:18:22 +00:00
Navid Yaghoobi 2a7c6195b4
Merge pull request #602 from navidys/packit_epel10
packit epel10 build
2025-04-11 19:01:14 +10:00
Navid Yaghoobi 70fd604f0f packit epel10 build
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2025-04-11 18:51:57 +10:00
Navid Yaghoobi c9527473cf
Merge pull request #600 from containers/dependabot/go_modules/golang.org/x/crypto-0.37.0
Bump golang.org/x/crypto from 0.36.0 to 0.37.0
2025-04-10 12:14:59 +10:00
dependabot[bot] 42293a3a71
Bump golang.org/x/crypto from 0.36.0 to 0.37.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.36.0 to 0.37.0.
- [Commits](https://github.com/golang/crypto/compare/v0.36.0...v0.37.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-version: 0.37.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-07 21:49:06 +00:00
Navid Yaghoobi f902cdff07 Bump to v1.6.0-dev
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2025-04-06 15:04:42 +10:00
Navid Yaghoobi cd904893fc Bump to v1.5.0
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2025-04-06 15:03:08 +10:00
Navid Yaghoobi eee4f642fa
Merge pull request #598 from navidys/bump-1.5.0
Bump 1.5.0
2025-04-06 14:52:55 +10:00
Navid Yaghoobi 6392f961a4 Bump to v1.6.0-dev
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2025-04-06 14:45:10 +10:00
Navid Yaghoobi fb76d52ae9 Bump to v1.5.0
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2025-04-06 14:43:59 +10:00
Navid Yaghoobi 05bdbdea9a
Merge pull request #594 from containers/dependabot/go_modules/github.com/rs/zerolog-1.34.0
Bump github.com/rs/zerolog from 1.33.0 to 1.34.0
2025-04-06 14:19:37 +10:00
Navid Yaghoobi 0c1dfb8b00
Merge pull request #597 from containers/dependabot/go_modules/github.com/containers/podman/v5-5.4.2
Bump github.com/containers/podman/v5 from 5.4.1 to 5.4.2
2025-04-06 14:19:27 +10:00
dependabot[bot] ff9a2eeb41
Bump github.com/containers/podman/v5 from 5.4.1 to 5.4.2
Bumps [github.com/containers/podman/v5](https://github.com/containers/podman) from 5.4.1 to 5.4.2.
- [Release notes](https://github.com/containers/podman/releases)
- [Changelog](https://github.com/containers/podman/blob/v5.4.2/RELEASE_NOTES.md)
- [Commits](https://github.com/containers/podman/compare/v5.4.1...v5.4.2)

---
updated-dependencies:
- dependency-name: github.com/containers/podman/v5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-02 20:38:50 +00:00
Navid Yaghoobi def31691ba
Merge pull request #596 from containers/dependabot/go_modules/github.com/containers/buildah-1.39.4
Bump github.com/containers/buildah from 1.39.3 to 1.39.4
2025-03-30 12:10:22 +11:00
dependabot[bot] 04b7a6151b
Bump github.com/containers/buildah from 1.39.3 to 1.39.4
Bumps [github.com/containers/buildah](https://github.com/containers/buildah) from 1.39.3 to 1.39.4.
- [Release notes](https://github.com/containers/buildah/releases)
- [Changelog](https://github.com/containers/buildah/blob/v1.39.4/CHANGELOG.md)
- [Commits](https://github.com/containers/buildah/compare/v1.39.3...v1.39.4)

---
updated-dependencies:
- dependency-name: github.com/containers/buildah
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-28 20:17:00 +00:00
dependabot[bot] 0f4d9385e6
Bump github.com/rs/zerolog from 1.33.0 to 1.34.0
Bumps [github.com/rs/zerolog](https://github.com/rs/zerolog) from 1.33.0 to 1.34.0.
- [Commits](https://github.com/rs/zerolog/compare/v1.33.0...v1.34.0)

---
updated-dependencies:
- dependency-name: github.com/rs/zerolog
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-24 22:00:04 +00:00
Navid Yaghoobi 5424f11115
Merge pull request #593 from containers/dependabot/go_modules/github.com/BurntSushi/toml-1.5.0
Bump github.com/BurntSushi/toml from 1.4.0 to 1.5.0
2025-03-20 12:02:30 +11:00
dependabot[bot] ffda1a0afa
Bump github.com/BurntSushi/toml from 1.4.0 to 1.5.0
Bumps [github.com/BurntSushi/toml](https://github.com/BurntSushi/toml) from 1.4.0 to 1.5.0.
- [Release notes](https://github.com/BurntSushi/toml/releases)
- [Commits](https://github.com/BurntSushi/toml/compare/v1.4.0...v1.5.0)

---
updated-dependencies:
- dependency-name: github.com/BurntSushi/toml
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-18 20:35:42 +00:00
Navid Yaghoobi 0a975ecdf8
Merge pull request #591 from containers/dependabot/go_modules/github.com/containers/buildah-1.39.3
Bump github.com/containers/buildah from 1.39.2 to 1.39.3
2025-03-15 11:41:49 +11:00
dependabot[bot] 2326d5fc63
Bump github.com/containers/buildah from 1.39.2 to 1.39.3
Bumps [github.com/containers/buildah](https://github.com/containers/buildah) from 1.39.2 to 1.39.3.
- [Release notes](https://github.com/containers/buildah/releases)
- [Changelog](https://github.com/containers/buildah/blob/v1.39.3/CHANGELOG.md)
- [Commits](https://github.com/containers/buildah/compare/v1.39.2...v1.39.3)

---
updated-dependencies:
- dependency-name: github.com/containers/buildah
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-15 00:21:50 +00:00
Navid Yaghoobi 4ffa4b95d9
Merge pull request #588 from containers/dependabot/go_modules/github.com/containers/common-0.62.2
Bump github.com/containers/common from 0.62.0 to 0.62.2
2025-03-15 11:20:37 +11:00
Navid Yaghoobi 49b2994ff8
Merge pull request #578 from containers/dependabot/go_modules/github.com/containers/storage-1.57.2
Bump github.com/containers/storage from 1.57.1 to 1.57.2
2025-03-15 11:20:27 +11:00
Navid Yaghoobi b1464afd8c
Merge pull request #589 from containers/dependabot/go_modules/golang.org/x/net-0.36.0
Bump golang.org/x/net from 0.34.0 to 0.36.0
2025-03-15 11:10:01 +11:00
dependabot[bot] cc8608c200
Bump golang.org/x/net from 0.34.0 to 0.36.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.34.0 to 0.36.0.
- [Commits](https://github.com/golang/net/compare/v0.34.0...v0.36.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-15 00:03:54 +00:00
Navid Yaghoobi 4a10ca867d
Merge pull request #574 from containers/dependabot/go_modules/golang.org/x/crypto-0.36.0
Bump golang.org/x/crypto from 0.33.0 to 0.36.0
2025-03-15 11:02:31 +11:00
dependabot[bot] 8eb63a6d2b
Bump golang.org/x/crypto from 0.33.0 to 0.36.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.33.0 to 0.36.0.
- [Commits](https://github.com/golang/crypto/compare/v0.33.0...v0.36.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-14 23:40:21 +00:00
Navid Yaghoobi 1be2154e2b
Merge pull request #592 from navidys/go_version_update
Go update to v1.23.0 + Golangci-lint update to v1.64.4
2025-03-15 10:39:04 +11:00
Navid Yaghoobi 9b2bb83815 Go update to v1.23.0 + Golangci-lint update to v1.64.4
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2025-03-15 10:33:08 +11:00
dependabot[bot] 4c73f653d8
Bump github.com/containers/common from 0.62.0 to 0.62.2
Bumps [github.com/containers/common](https://github.com/containers/common) from 0.62.0 to 0.62.2.
- [Release notes](https://github.com/containers/common/releases)
- [Commits](https://github.com/containers/common/compare/v0.62.0...v0.62.2)

---
updated-dependencies:
- dependency-name: github.com/containers/common
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-13 06:27:36 +00:00
dependabot[bot] 0a04e82ebe
Bump github.com/containers/storage from 1.57.1 to 1.57.2
Bumps [github.com/containers/storage](https://github.com/containers/storage) from 1.57.1 to 1.57.2.
- [Release notes](https://github.com/containers/storage/releases)
- [Changelog](https://github.com/containers/storage/blob/main/docs/containers-storage-changes.md)
- [Commits](https://github.com/containers/storage/compare/v1.57.1...v1.57.2)

---
updated-dependencies:
- dependency-name: github.com/containers/storage
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-13 06:27:36 +00:00
Navid Yaghoobi 8999d0e2b7
Merge pull request #587 from containers/dependabot/go_modules/github.com/containers/podman/v5-5.4.1
Bump github.com/containers/podman/v5 from 5.4.0 to 5.4.1
2025-03-13 17:26:10 +11:00
dependabot[bot] 347ab777b4
Bump github.com/containers/podman/v5 from 5.4.0 to 5.4.1
Bumps [github.com/containers/podman/v5](https://github.com/containers/podman) from 5.4.0 to 5.4.1.
- [Release notes](https://github.com/containers/podman/releases)
- [Changelog](https://github.com/containers/podman/blob/v5.4.1/RELEASE_NOTES.md)
- [Commits](https://github.com/containers/podman/compare/v5.4.0...v5.4.1)

---
updated-dependencies:
- dependency-name: github.com/containers/podman/v5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-11 20:11:37 +00:00
Navid Yaghoobi 6c62f33576
Merge pull request #585 from navidys/ui_getitems_trimspace
UI input check trim spaces
2025-03-11 10:02:11 +11:00
Navid Yaghoobi 4049d7adaa UI input check trim spaces
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2025-03-10 19:56:28 +11:00
Navid Yaghoobi fe94712e4a
Merge pull request #584 from navidys/pod_create_resource_category
New feature - pod create resource settings category
2025-03-10 19:42:05 +11:00
Navid Yaghoobi d62c79f787 New feature - pod create resource settings category
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2025-03-10 19:28:09 +11:00
Navid Yaghoobi 441fe2edec Fix Vagrantbox hostname
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2025-03-10 11:30:25 +11:00
Navid Yaghoobi 66e7fff1a6
Merge pull request #583 from navidys/subdialog_focus
Fix view's dialogs focus issue
2025-03-08 20:31:32 +11:00
Navid Yaghoobi f06e2ef927 Fix view's dialogs focus issue
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2025-03-08 20:23:05 +11:00
Navid Yaghoobi 5302f66806
Merge pull request #582 from navidys/run_dialog_focus
Exec and run vterm container ID and name display issue fix
2025-03-08 18:41:00 +11:00
Navid Yaghoobi e15d76a796 Exec and run vterm container ID and name display issue fix
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2025-03-08 18:32:45 +11:00
Navid Yaghoobi a92cec5e42
Merge pull request #581 from navidys/podman_run_test
Added bats tests for container run cmd
2025-03-08 17:49:57 +11:00
Navid Yaghoobi 43fbc57357 Added bats tests for container run cmd
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2025-03-08 17:40:57 +11:00
Navid Yaghoobi 9be037d3c8
Merge pull request #580 from navidys/vagrantfile_update
Vagrantfile box version update to fedora/41-cloud-base
2025-03-08 17:27:19 +11:00
Navid Yaghoobi 53a43f86e6 Vagrantfile box version update to fedora/41-clous-base
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2025-03-08 17:18:22 +11:00
Navid Yaghoobi 7bfc237682
Merge pull request #579 from navidys/ui_misc_update
UI dialog size adjusmentse
2025-03-08 17:14:53 +11:00
Navid Yaghoobi 9312e8decd UI dialog size adjusmentse
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2025-03-08 17:04:15 +11:00
Navid Yaghoobi 5022beffa7
Merge pull request #577 from navidys/container_create_resource_options
New feature - container create resource settings category
2025-03-07 19:31:25 +11:00
Navid Yaghoobi 0aeb2e552c New feature - container create resource settings category
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2025-03-07 19:22:09 +11:00
Navid Yaghoobi 242982a2b1
Merge pull request #576 from navidys/subdialog_resize
View sub dialog size adjustments
2025-03-07 13:11:01 +11:00
Navid Yaghoobi 34a7797dd7 View sub dialog size adjustments
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2025-03-07 13:02:03 +11:00
Navid Yaghoobi cfd827afff
Merge pull request #573 from navidys/container_run
New feature - container run
2025-03-06 13:38:58 +11:00
Navid Yaghoobi 02ada9374d New feature - container run
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2025-03-05 19:56:32 +11:00
Navid Yaghoobi bce001c25d
Merge pull request #570 from navidys/container_exec_dialog_size
Container exec terminal size change
2025-03-02 16:13:22 +11:00
Navid Yaghoobi eed5fd9092 Container exec terminal size change
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2025-03-02 16:05:17 +11:00
Navid Yaghoobi 84cc728081
Merge pull request #569 from navidys/container_create_secret
Container create dialog secret option
2025-03-02 15:51:03 +11:00
Navid Yaghoobi 9e6388aac3 Container create dialog secret option
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2025-03-02 15:33:05 +11:00
Navid Yaghoobi 47b1d1f37a
Merge pull request #568 from navidys/dropdown_move_key
fix wrong function name
2025-03-02 12:56:19 +11:00
Navid Yaghoobi 56a12860b9 fix wrong function name
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2025-03-02 12:50:08 +11:00
Navid Yaghoobi fc019f08d2
Merge pull request #567 from navidys/bump-1.4.0
Bump 1.4.0
2025-03-01 14:25:29 +11:00
Navid Yaghoobi 177f06c46a Bump to v1.5.0-dev
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2025-03-01 14:12:17 +11:00
Navid Yaghoobi 204d054c97 Bump to v1.4.0
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2025-03-01 14:11:15 +11:00
Navid Yaghoobi d88a67af73
Merge pull request #566 from navidys/doc_update
README.md fix demo link
2025-03-01 14:03:30 +11:00
Navid Yaghoobi 59a9904e83 README.md fix demo link
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2025-03-01 14:02:04 +11:00
Navid Yaghoobi 8a850c7d04
Merge pull request #552 from Malix-Labs/patch-1
docs: enhance documentation structure and merge READMEs
2025-03-01 13:58:02 +11:00
Navid Yaghoobi abb902f171
Merge pull request #562 from containers/dependabot/go_modules/github.com/containers/buildah-1.39.1
Bump github.com/containers/buildah from 1.38.1 to 1.39.1
2025-03-01 13:57:24 +11:00
Navid Yaghoobi b41b05a79c
Merge pull request #565 from navidys/bump_x_crypto_v0.33.0
Bump golang.org/x/crypto to v0.33.0
2025-03-01 13:55:25 +11:00
Navid Yaghoobi 8460ac4527 Bump golang.org/x/crypto to v0.33.0
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2025-03-01 13:48:04 +11:00
dependabot[bot] db872518ff
Bump github.com/containers/buildah from 1.38.1 to 1.39.1
Bumps [github.com/containers/buildah](https://github.com/containers/buildah) from 1.38.1 to 1.39.1.
- [Release notes](https://github.com/containers/buildah/releases)
- [Changelog](https://github.com/containers/buildah/blob/v1.39.1/CHANGELOG.md)
- [Commits](https://github.com/containers/buildah/compare/v1.38.1...v1.39.1)

---
updated-dependencies:
- dependency-name: github.com/containers/buildah
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-01 02:42:11 +00:00
Navid Yaghoobi 3eebbbef0b
Merge pull request #559 from containers/dependabot/go_modules/github.com/spf13/cobra-1.9.1
Bump github.com/spf13/cobra from 1.8.1 to 1.9.1
2025-03-01 13:40:19 +11:00
Navid Yaghoobi dee6b15b4e
Merge pull request #561 from containers/dependabot/go_modules/github.com/go-jose/go-jose/v4-4.0.5
Bump github.com/go-jose/go-jose/v4 from 4.0.4 to 4.0.5
2025-03-01 13:39:20 +11:00
Navid Yaghoobi 44e38ae256
Merge pull request #564 from navidys/bugfix_disconnect_connect_crash
bugfix panic in system events
2025-03-01 13:39:05 +11:00
Navid Yaghoobi 87d8ab1552 bugfix panic in system events
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2025-03-01 13:33:46 +11:00
dependabot[bot] 610cf9fcb6
Bump github.com/go-jose/go-jose/v4 from 4.0.4 to 4.0.5
Bumps [github.com/go-jose/go-jose/v4](https://github.com/go-jose/go-jose) from 4.0.4 to 4.0.5.
- [Release notes](https://github.com/go-jose/go-jose/releases)
- [Changelog](https://github.com/go-jose/go-jose/blob/main/CHANGELOG.md)
- [Commits](https://github.com/go-jose/go-jose/compare/v4.0.4...v4.0.5)

---
updated-dependencies:
- dependency-name: github.com/go-jose/go-jose/v4
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-28 06:52:23 +00:00
dependabot[bot] aa8a47710e
Bump github.com/spf13/cobra from 1.8.1 to 1.9.1
Bumps [github.com/spf13/cobra](https://github.com/spf13/cobra) from 1.8.1 to 1.9.1.
- [Release notes](https://github.com/spf13/cobra/releases)
- [Commits](https://github.com/spf13/cobra/compare/v1.8.1...v1.9.1)

---
updated-dependencies:
- dependency-name: github.com/spf13/cobra
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-28 06:52:22 +00:00
Navid Yaghoobi 8d2bf0a874
Merge pull request #563 from navidys/bump_podman_5.4
Bump podman to v5.4.0
2025-02-28 17:51:00 +11:00
Navid Yaghoobi 7c30fa9d32 Bump podman to v5.4.0
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2025-02-28 17:33:33 +11:00
Malix 9a57aeb763
enhance: merge READMEs
Signed-off-by: Malix <alixbrunetcontact@gmail.com>
2025-02-27 23:09:08 +00:00
Malix a07daf871e
docs: enhance directory structure
Signed-off-by: Malix <alixbrunetcontact@gmail.com>
2025-02-27 23:08:23 +00:00
Navid Yaghoobi c7273f6649
Merge pull request #549 from containers/dependabot/go_modules/github.com/containers/podman/v5-5.3.2
Bump github.com/containers/podman/v5 from 5.3.1 to 5.3.2
2025-01-23 18:52:02 +11:00
dependabot[bot] 5314673185
Bump github.com/containers/podman/v5 from 5.3.1 to 5.3.2
Bumps [github.com/containers/podman/v5](https://github.com/containers/podman) from 5.3.1 to 5.3.2.
- [Release notes](https://github.com/containers/podman/releases)
- [Changelog](https://github.com/containers/podman/blob/v5.3.2/RELEASE_NOTES.md)
- [Commits](https://github.com/containers/podman/compare/v5.3.1...v5.3.2)

---
updated-dependencies:
- dependency-name: github.com/containers/podman/v5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-21 20:09:14 +00:00
Navid Yaghoobi f13c817218
Merge pull request #548 from navidys/packit_update
packit update epel  + centos stream
2025-01-21 19:42:03 +11:00
Navid Yaghoobi 958a2a447e packit update epel + centos stream
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2025-01-21 19:32:47 +11:00
Navid Yaghoobi 761e48fb43
Merge pull request #547 from containers/dependabot/go_modules/golang.org/x/net-0.33.0
Bump golang.org/x/net from 0.30.0 to 0.33.0
2025-01-20 07:20:22 +11:00
dependabot[bot] af4b22fa6a
Bump golang.org/x/net from 0.30.0 to 0.33.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.30.0 to 0.33.0.
- [Commits](https://github.com/golang/net/compare/v0.30.0...v0.33.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-16 23:49:24 +00:00
Navid Yaghoobi edc139c27d
Merge pull request #544 from containers/dependabot/go_modules/github.com/gdamore/tcell/v2-2.8.1
Bump github.com/gdamore/tcell/v2 from 2.7.4 to 2.8.1
2025-01-17 10:48:16 +11:00
dependabot[bot] d8f0ffb364
Bump github.com/gdamore/tcell/v2 from 2.7.4 to 2.8.1
Bumps [github.com/gdamore/tcell/v2](https://github.com/gdamore/tcell) from 2.7.4 to 2.8.1.
- [Release notes](https://github.com/gdamore/tcell/releases)
- [Changelog](https://github.com/gdamore/tcell/blob/main/CHANGESv2.md)
- [Commits](https://github.com/gdamore/tcell/compare/v2.7.4...v2.8.1)

---
updated-dependencies:
- dependency-name: github.com/gdamore/tcell/v2
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-13 20:30:52 +00:00
Navid Yaghoobi 870cae0a60
Merge pull request #542 from containers/dependabot/go_modules/golang.org/x/crypto-0.32.0
Bump golang.org/x/crypto from 0.31.0 to 0.32.0
2025-01-07 08:45:00 +11:00
dependabot[bot] 086842a209
Bump golang.org/x/crypto from 0.31.0 to 0.32.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.31.0 to 0.32.0.
- [Commits](https://github.com/golang/crypto/compare/v0.31.0...v0.32.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-06 21:00:10 +00:00
Navid Yaghoobi 676ff6b10f
Merge pull request #541 from containers/dependabot/go_modules/golang.org/x/crypto-0.31.0
Bump golang.org/x/crypto from 0.29.0 to 0.31.0
2024-12-14 16:18:28 +11:00
dependabot[bot] f1f1ff11f8
Bump golang.org/x/crypto from 0.29.0 to 0.31.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.29.0 to 0.31.0.
- [Commits](https://github.com/golang/crypto/compare/v0.29.0...v0.31.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-11 20:55:19 +00:00
Navid Yaghoobi 679aa134e6
Merge pull request #539 from navidys/bump-1.3.0
Bump 1.3.0
2024-12-01 15:59:24 +11:00
Navid Yaghoobi 0e8ff20e37 Bump to v1.4.0-dev
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2024-12-01 15:46:41 +11:00
Navid Yaghoobi 37019c2f86 Bump to v1.3.0
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2024-12-01 15:45:52 +11:00
Navid Yaghoobi 315b3c998e
Merge pull request #538 from navidys/podman_5.3.1
Bump podman to v5.3.1 + update for event reader
2024-12-01 15:38:24 +11:00
Navid Yaghoobi 030413d8de update to podman v5.3.1
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2024-12-01 15:34:30 +11:00
Navid Yaghoobi 62ad6ebcae
Merge pull request #532 from containers/dependabot/go_modules/golang.org/x/crypto-0.29.0
Bump golang.org/x/crypto from 0.28.0 to 0.29.0
2024-11-14 06:42:34 +11:00
dependabot[bot] 38cd495667
Bump golang.org/x/crypto from 0.28.0 to 0.29.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.28.0 to 0.29.0.
- [Commits](https://github.com/golang/crypto/compare/v0.28.0...v0.29.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-08 20:52:55 +00:00
Navid Yaghoobi fd933d0bdf
Merge pull request #531 from navidys/golangci_lint
golangci-lint update 1.61.0
2024-10-26 21:16:27 +11:00
Navid Yaghoobi 0e4b01f33b golangci-lint update 1.61.0
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2024-10-26 21:03:14 +11:00
Navid Yaghoobi d1cb59bdf3
Merge pull request #529 from containers/dependabot/go_modules/github.com/containers/podman/v5-5.2.5
Bump github.com/containers/podman/v5 from 5.2.4 to 5.2.5
2024-10-19 09:04:20 +11:00
dependabot[bot] d8722f5327
Bump github.com/containers/podman/v5 from 5.2.4 to 5.2.5
Bumps [github.com/containers/podman/v5](https://github.com/containers/podman) from 5.2.4 to 5.2.5.
- [Release notes](https://github.com/containers/podman/releases)
- [Changelog](https://github.com/containers/podman/blob/v5.2.5/RELEASE_NOTES.md)
- [Commits](https://github.com/containers/podman/compare/v5.2.4...v5.2.5)

---
updated-dependencies:
- dependency-name: github.com/containers/podman/v5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-18 20:46:44 +00:00
Navid Yaghoobi 9ba5670f10
Merge pull request #527 from containers/dependabot/go_modules/github.com/containers/podman/v5-5.2.4
Bump github.com/containers/podman/v5 from 5.2.3 to 5.2.4
2024-10-08 13:02:48 +11:00
dependabot[bot] a1ee0e5d10
Bump github.com/containers/podman/v5 from 5.2.3 to 5.2.4
Bumps [github.com/containers/podman/v5](https://github.com/containers/podman) from 5.2.3 to 5.2.4.
- [Release notes](https://github.com/containers/podman/releases)
- [Changelog](https://github.com/containers/podman/blob/v5.2.4/RELEASE_NOTES.md)
- [Commits](https://github.com/containers/podman/compare/v5.2.3...v5.2.4)

---
updated-dependencies:
- dependency-name: github.com/containers/podman/v5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-07 20:21:41 +00:00
Navid Yaghoobi da4bf48f6f
Merge pull request #525 from containers/dependabot/go_modules/golang.org/x/crypto-0.28.0
Bump golang.org/x/crypto from 0.27.0 to 0.28.0
2024-10-07 18:05:32 +11:00
dependabot[bot] 1a97ae90c4
Bump golang.org/x/crypto from 0.27.0 to 0.28.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.27.0 to 0.28.0.
- [Commits](https://github.com/golang/crypto/compare/v0.27.0...v0.28.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-04 20:58:00 +00:00
Navid Yaghoobi 746fde5df6
Merge pull request #519 from containers/dependabot/go_modules/golang.org/x/crypto-0.27.0
Bump golang.org/x/crypto from 0.26.0 to 0.27.0
2024-09-29 18:24:23 +10:00
dependabot[bot] 5676ae7d9f
Bump golang.org/x/crypto from 0.26.0 to 0.27.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.26.0 to 0.27.0.
- [Commits](https://github.com/golang/crypto/compare/v0.26.0...v0.27.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-27 12:40:05 +00:00
Navid Yaghoobi 5271dfeb31
Merge pull request #523 from navidys/golang_update
update golang to v1.22.6 and runc
2024-09-27 22:26:37 +10:00
Navid Yaghoobi e19b9372d8 ]# This is a combination of 2 commits.
update golang to v1.22.6 and runc

Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2024-09-27 21:37:28 +10:00
Navid Yaghoobi f68173fe59
Merge pull request #522 from containers/dependabot/go_modules/github.com/containers/podman/v5-5.2.3
Bump github.com/containers/podman/v5 from 5.2.2 to 5.2.3
2024-09-27 11:49:10 +10:00
dependabot[bot] 5e9b389cf9
Bump github.com/containers/podman/v5 from 5.2.2 to 5.2.3
Bumps [github.com/containers/podman/v5](https://github.com/containers/podman) from 5.2.2 to 5.2.3.
- [Release notes](https://github.com/containers/podman/releases)
- [Changelog](https://github.com/containers/podman/blob/v5.2.3/RELEASE_NOTES.md)
- [Commits](https://github.com/containers/podman/compare/v5.2.2...v5.2.3)

---
updated-dependencies:
- dependency-name: github.com/containers/podman/v5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-24 20:40:15 +00:00
Navid Yaghoobi baadefdafa
Merge pull request #520 from containers/dependabot/go_modules/github.com/containers/buildah-1.37.3
Bump github.com/containers/buildah from 1.37.2 to 1.37.3
2024-09-24 06:43:00 +10:00
dependabot[bot] 880e0957ff
Bump github.com/containers/buildah from 1.37.2 to 1.37.3
Bumps [github.com/containers/buildah](https://github.com/containers/buildah) from 1.37.2 to 1.37.3.
- [Release notes](https://github.com/containers/buildah/releases)
- [Changelog](https://github.com/containers/buildah/blob/v1.37.3/CHANGELOG.md)
- [Commits](https://github.com/containers/buildah/compare/v1.37.2...v1.37.3)

---
updated-dependencies:
- dependency-name: github.com/containers/buildah
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-23 20:31:55 +00:00
Navid Yaghoobi 2829912ad1
Merge pull request #521 from containers/dependabot/go_modules/github.com/containers/common-0.60.3
Bump github.com/containers/common from 0.60.2 to 0.60.3
2024-09-24 06:30:25 +10:00
dependabot[bot] f2bd5ee59f
Bump github.com/containers/common from 0.60.2 to 0.60.3
Bumps [github.com/containers/common](https://github.com/containers/common) from 0.60.2 to 0.60.3.
- [Release notes](https://github.com/containers/common/releases)
- [Commits](https://github.com/containers/common/compare/v0.60.2...v0.60.3)

---
updated-dependencies:
- dependency-name: github.com/containers/common
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-23 20:13:33 +00:00
Navid Yaghoobi bea949018f
Merge pull request #517 from containers/dependabot/go_modules/github.com/containers/podman/v5-5.2.2
Bump github.com/containers/podman/v5 from 5.2.1 to 5.2.2
2024-08-22 07:37:57 +10:00
dependabot[bot] e4c7643aa1
Bump github.com/containers/podman/v5 from 5.2.1 to 5.2.2
Bumps [github.com/containers/podman/v5](https://github.com/containers/podman) from 5.2.1 to 5.2.2.
- [Release notes](https://github.com/containers/podman/releases)
- [Changelog](https://github.com/containers/podman/blob/v5.2.2/RELEASE_NOTES.md)
- [Commits](https://github.com/containers/podman/compare/v5.2.1...v5.2.2)

---
updated-dependencies:
- dependency-name: github.com/containers/podman/v5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-21 20:27:40 +00:00
Navid Yaghoobi 5cf00fb84d
Merge pull request #515 from eulores/main
Correct spelling of 'prune'
2024-08-20 21:33:39 +10:00
Andreas a6e932d7de
Correct spelling of 'prune' 2024-08-20 12:01:28 +02:00
Navid Yaghoobi 26bea2641d
Merge pull request #513 from containers/dependabot/go_modules/github.com/containers/podman/v5-5.2.1
Bump github.com/containers/podman/v5 from 5.2.0 to 5.2.1
2024-08-15 07:35:10 +10:00
dependabot[bot] a03f28bbd4
Bump github.com/containers/podman/v5 from 5.2.0 to 5.2.1
Bumps [github.com/containers/podman/v5](https://github.com/containers/podman) from 5.2.0 to 5.2.1.
- [Release notes](https://github.com/containers/podman/releases)
- [Changelog](https://github.com/containers/podman/blob/v5.2.1/RELEASE_NOTES.md)
- [Commits](https://github.com/containers/podman/compare/v5.2.0...v5.2.1)

---
updated-dependencies:
- dependency-name: github.com/containers/podman/v5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-14 20:30:44 +00:00
Navid Yaghoobi 707da82db3
Merge pull request #510 from containers/dependabot/go_modules/golang.org/x/crypto-0.26.0
Bump golang.org/x/crypto from 0.25.0 to 0.26.0
2024-08-10 10:09:10 +10:00
dependabot[bot] a1e2996f54
Bump golang.org/x/crypto from 0.25.0 to 0.26.0
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.25.0 to 0.26.0.
- [Commits](https://github.com/golang/crypto/compare/v0.25.0...v0.26.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-06 20:48:32 +00:00
Navid Yaghoobi 6d6cf814f9
Merge pull request #508 from navidys/bump-1.2.0
Bump 1.2.0
2024-08-03 16:42:04 +10:00
Navid Yaghoobi 46c83179c4 Bump to v1.3.0-dev
Signed-off-by: Navid Yaghoobi <navidys@fedoraproject.org>
2024-08-03 16:34:48 +10:00
1881 changed files with 106171 additions and 37405 deletions

View File

@ -24,7 +24,7 @@ jobs:
uses: actions/setup-go@v5
with:
go-version: ">=1.21"
go-version: ">=1.22"
- name: Build binary
run: |

View File

@ -9,7 +9,7 @@ jobs:
steps:
- uses: actions/setup-go@v5
with:
go-version: '>=1.21'
go-version: '>=1.23'
- uses: actions/checkout@v4
- run: |
go mod tidy
@ -24,8 +24,7 @@ jobs:
steps:
- uses: actions/setup-go@v5
with:
# cannot use 1.21.X latest version since golangci-lint has an issue.
go-version: '1.21.4'
go-version: '1.23'
- uses: actions/checkout@v4
- run: |
bash hack/install_dep.sh
@ -60,7 +59,7 @@ jobs:
steps:
- uses: actions/setup-go@v5
with:
go-version: '>=1.21'
go-version: '>=1.23'
- uses: actions/checkout@v4
- run: |
make all

View File

@ -45,7 +45,7 @@ jobs:
steps:
- uses: actions/setup-go@v5
with:
go-version: '>=1.21'
go-version: '>=1.23'
- uses: actions/checkout@v4
- run: |
go mod tidy
@ -60,8 +60,7 @@ jobs:
steps:
- uses: actions/setup-go@v5
with:
# cannot use 1.21.X latest version since golangci-lint has an issue.
go-version: '1.21.4'
go-version: '1.23'
- uses: actions/checkout@v4
- run: |
bash hack/install_dep.sh
@ -87,7 +86,7 @@ jobs:
steps:
- uses: actions/setup-go@v5
with:
go-version: '>=1.21'
go-version: '>=1.23'
- uses: actions/checkout@v4
- run: |
make all

View File

@ -1,7 +1,6 @@
run:
timeout: 10m
deadline: 5m
skip-files:
- ".*_test.go"
linters:
enable-all: true
disable:
@ -10,29 +9,25 @@ linters:
- varnamelen
- gochecknoinits
- wrapcheck
- execinquery
- funlen
- depguard
- nolintlint
# generics disabled
- wastedassign
- rowserrcheck
# deprecated
- nosnakecase
- varcheck
- structcheck
- ifshort
- deadcode
- golint
- maligned
- interfacer
- scopelint
- exhaustivestruct
- gomoddirectives
- tenv
linters-settings:
# typecheck:
# enabled: false
errcheck:
check-blank: false
ignore: fmt:.*
exclude-functions:
- fmt:.*
nolintlint:
require-specific: true
issues:
exclude-files:
- ".*_test.go"

View File

@ -12,14 +12,18 @@ jobs:
- openssl-devel
- rpkg
targets:
- fedora-latest-stable
- fedora-development
- fedora-all-x86_64
- fedora-all-aarch64
- epel-9-x86_64
- epel-9-aarch64
# temporary disabled since epel10 running go v1.23.1 and we need 1.23.3
# - epel-10-x86_64
# - epel-10-aarch64
- centos-stream-9-x86_64
- centos-stream-9-aarch64
- centos-stream-10-x86_64
- centos-stream-10-aarch64
# - centos-stream-10-x86_64
# - centos-stream-10-aarch64
actions:
post-upstream-clone:
- "rpkg spec --outdir ./"

View File

@ -88,7 +88,7 @@ install.tools: .install.ginkgo .install.bats .install.pre-commit .install.codesp
.PHONY: .install.golangci-lint
.install.golangci-lint:
VERSION=1.56.2 ./hack/install_golangci.sh
VERSION=1.64.4 ./hack/install_golangci.sh
.PHONY: .install.codespell
.install.codespell:

View File

@ -1,66 +0,0 @@
## podman-tui
![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)
![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/containers/podman-tui)
![Go](https://github.com/containers/podman-tui/workflows/Go/badge.svg)
[![Go Report](https://goreportcard.com/badge/github.com/containers/podman-tui)](https://goreportcard.com/report/github.com/containers/podman-tui)
[![codecov](https://codecov.io/gh/navidys/podman-tui/branch/main/graph/badge.svg)](https://codecov.io/gh/navidys/podman-tui)
Terminal user interface for Podman environment.
![Screenshot](./docs/podman-tui.gif)
- [**Overview**](#overview)
- [**Compatibility Matrix**](#compatibility-matrix)
- [**Installation**](#installation)
- [**PreRun Checks**](#prerun-checks)
- [**Key Bindings**](#key-bindings)
- [**Code of Conduct**](#code-of-conduct)
- [**License**](#license)
## Overview
podman-tui is a terminal user interface for podman environment.
It is using [podman go bindings](https://github.com/containers/podman/tree/main/pkg/bindings) to communicate with local or remote podman machine (through SSH).
## Compatibility matrix
| Terminal User Interface | Podman |
| ----------- | ------ |
| release-1.x | v5.x.y |
| release-0.x | v4.x.y |
## Installation
Building from source (Linux, Windows and MacOS) or installing packaged versions are detailed in [install guide](install.md).
## PreRun Checks
* `podman.socket` service needs to be running on podman machine.
The recommended way to start Podman system service in production mode is via systemd socket-activation:
```shell
$ systemctl --user start podman.socket
```
See [start podman system service](https://podman.io/blogs/2020/08/10/podman-go-bindings.html) for more details.
* If the SSH key has a passphrase, then you need to set and export `CONTAINER_PASSPHRASE=<password>` variable.
```shell
$ export CONTAINER_PASSPHRASE=keypass
```
* podman-tui uses 256 colors terminal mode on `Nix` system and standard ANSI colors on `Windows` system (use "command prompt" application).
## Key Bindings
Check [podman-tui docs](./docs/README.md) for keyboard mappings.
## Code of Conduct
This project is using the [Containers Community Code of Conduct](https://github.com/containers/common/blob/main/CODE-OF-CONDUCT.md)
## License
Licensed under the [Apache 2.0](LICENSE) license.

6
Vagrantfile vendored
View File

@ -1,9 +1,9 @@
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.hostname = "fedora40"
config.vm.box = "fedora/40-cloud-base"
config.vm.box_version = "40.20240414.0"
config.vm.hostname = "fedora41"
config.vm.box = "fedora/41-cloud-base"
config.vm.box_version = "41-20241024.0"
config.vm.provision "shell", inline: "mkdir -p /home/vagrant/go"
config.vm.synced_folder ".", "/home/vagrant/go/src/podman-tui",

View File

@ -39,7 +39,7 @@ type App struct {
currentPage string
needInitUI bool
fastRefreshChan chan bool
config *config.Config
config config.Config
}
// NewApp returns new app.
@ -51,7 +51,7 @@ func NewApp(name string, version string) *App {
Application: tview.NewApplication(),
pages: tview.NewPages(),
needInitUI: false,
fastRefreshChan: make(chan bool, 10), //nolint:gomnd
fastRefreshChan: make(chan bool, 10), //nolint:mnd
}
var err error
@ -73,10 +73,10 @@ func NewApp(name string, version string) *App {
app.secrets = secrets.NewSecrets()
app.system = system.NewSystem()
app.system.SetConnectionListFunc(app.config.ServicesConnections)
app.system.SetConnectionListFunc(app.config.RemoteConnections)
app.system.SetConnectionSetDefaultFunc(func(name string) error {
err := app.config.SetDefaultService(name)
app.system.UpdateConnectionsData()
err := app.config.SetDefaultConnection(name)
app.system.UpdateData()
return err
})
@ -85,6 +85,10 @@ func NewApp(name string, version string) *App {
app.system.SetConnectionDisconnectFunc(app.health.Disconnect)
app.system.SetConnectionAddFunc(app.config.Add)
app.system.SetConnectionRemoveFunc(app.config.Remove)
app.system.SetAppFocusHandler(func() {
app.Application.SetFocus(app.system)
app.fastRefreshChan <- true
})
app.help = help.NewHelp(name, version)
@ -96,6 +100,37 @@ func NewApp(name string, version string) *App {
// its required for image build dialog.
app.images.SetFastRefreshChannel(app.fastRefreshChan)
// set app set focus
app.containers.SetAppFocusHandler(func() {
app.Application.SetFocus(app.containers)
app.fastRefreshChan <- true
})
app.pods.SetAppFocusHandler(func() {
app.Application.SetFocus(app.pods)
app.fastRefreshChan <- true
})
app.images.SetAppFocusHandler(func() {
app.Application.SetFocus(app.images)
app.fastRefreshChan <- true
})
app.volumes.SetAppFocusHandler(func() {
app.Application.SetFocus(app.volumes)
app.fastRefreshChan <- true
})
app.networks.SetAppFocusHandler(func() {
app.Application.SetFocus(app.networks)
app.fastRefreshChan <- true
})
app.secrets.SetAppFocusHandler(func() {
app.Application.SetFocus(app.secrets)
app.fastRefreshChan <- true
})
// menu items
menuItems := [][]string{
{utils.HelpScreenKey.Label(), app.help.GetTitle()},

View File

@ -13,7 +13,7 @@ func (app *App) initUI() {
app.initInfoBar()
}
app.system.UpdateConnectionsData()
app.system.UpdateData()
}
func (app *App) initInfoBar() {

View File

@ -16,9 +16,9 @@ func newMenu(menuItems [][]string) *tview.TextView {
menu.SetBackgroundColor(style.BgColor)
var menuList []string
menuList := []string{}
for i := 0; i < len(menuItems); i++ {
for i := range menuItems {
key, item := genMenuItem(menuItems[i])
if i == len(menuItems)-1 {
item += " "

View File

@ -71,7 +71,7 @@ func (app *App) refreshNotConnOK() {
app.switchToScreen(app.system.GetTitle())
}
app.system.UpdateConnectionsData()
app.system.UpdateData()
app.needInitUI = true
}

View File

@ -114,7 +114,7 @@ func (app *App) updatePageData(page string) {
switch page {
case app.system.GetTitle():
app.system.UpdateConnectionsData()
app.system.UpdateData()
case app.pods.GetTitle():
app.pods.UpdateData()
case app.containers.GetTitle():
@ -169,6 +169,6 @@ func (app *App) clearViewsData() {
func (app *App) clearInfoUIData() {
app.infoBar.UpdateBasicInfo("", "", "")
app.infoBar.UpdateSystemUsageInfo(0.00, 0.00) //nolint:gomnd
app.infoBar.UpdateSystemUsageInfo(0.00, 0.00) //nolint:mnd
app.infoBar.UpdatePodmanInfo("", "", "", "")
}

View File

@ -7,7 +7,7 @@ import (
)
const (
appVersion = "1.2.0"
appVersion = "1.7.0-dev"
)
// versionCmd represents the version command.

View File

@ -1,133 +0,0 @@
package config
import (
"fmt"
"net"
"net/url"
"os"
"regexp"
"github.com/containers/podman-tui/ui/utils"
"github.com/pkg/errors"
"github.com/rs/zerolog/log"
)
// Add adds new service connection.
func (c *Config) Add(name string, uri string, identity string) error {
log.Debug().Msgf("config: adding new service %s %s %s", name, uri, identity)
newService, err := validateNewService(name, uri, identity)
if err != nil {
return err
}
if err := c.add(name, newService); err != nil {
return err
}
if err := c.Write(); err != nil {
return err
}
return c.reload()
}
func (c *Config) add(name string, newService Service) error {
c.mu.Lock()
defer c.mu.Unlock()
for serviceName := range c.Services {
if serviceName == name {
return ErrDuplicatedServiceName
}
}
c.Services[name] = newService
return nil
}
// most of codes are from:
// https://github.com/containers/podman/blob/main/cmd/podman/system/connection/add.go.
func validateNewService(name string, dest string, identity string) (Service, error) { //nolint:cyclop
var (
service Service
serviceIdentity string
)
if name == "" {
return service, ErrEmptyServiceName
}
if dest == "" {
return service, ErrEmptyURIDestination
}
if match, err := regexp.Match("^[A-Za-z][A-Za-z0-9+.-]*://", []byte(dest)); err != nil { //nolint:mirror
return service, fmt.Errorf("%w invalid destition", err)
} else if !match {
dest = "ssh://" + dest
}
uri, err := url.Parse(dest)
if err != nil {
return service, err
}
switch uri.Scheme {
case "ssh":
if uri.User.Username() == "" {
if uri.User, err = getUserInfo(uri); err != nil {
return service, err
}
}
serviceIdentity, err = utils.ResolveHomeDir(identity)
if err != nil {
return service, err
}
if identity == "" {
return service, ErrEmptySSHIdentity
}
if uri.Port() == "" {
uri.Host = net.JoinHostPort(uri.Hostname(), "22")
}
if uri.Path == "" || uri.Path == "/" {
if uri.Path, err = getUDS(uri, serviceIdentity); err != nil {
return service, err
}
}
case "unix":
if identity != "" {
return service, fmt.Errorf("%w identity", ErrInvalidUnixSchemaOption)
}
info, err := os.Stat(uri.Path)
switch {
case errors.Is(err, os.ErrNotExist):
log.Warn().Msgf("config: %q does not exists", uri.Path)
case errors.Is(err, os.ErrPermission):
log.Warn().Msgf("config: You do not have permission to read %q", uri.Path)
case err != nil:
return service, err
case info.Mode()&os.ModeSocket == 0:
return service, fmt.Errorf("%w %q", ErrFileNotUnixSocket, uri.Path)
}
case "tcp":
if identity != "" {
return service, fmt.Errorf("%w identity", ErrInvalidTCPSchemaOption)
}
default:
return service, fmt.Errorf("%w %q", ErrInvalidURISchemaName, uri.Scheme)
}
service.Identity = serviceIdentity
service.URI = uri.String()
service.Default = false
return service, nil
}

View File

@ -1,124 +1,43 @@
package config
import (
"errors"
"os"
"sort"
"sync"
"github.com/containers/podman-tui/config/pconfig"
"github.com/containers/podman-tui/config/tconfig"
"github.com/containers/podman-tui/pdcs/registry"
"github.com/rs/zerolog/log"
)
const (
// _configPath is the path to the podman-tui/podman-tui.conf
// inside a given config directory.
_configPath = "podman-tui/podman-tui.conf"
// UserAppConfig holds the user podman-tui config path.
UserAppConfig = ".config/" + _configPath
)
var (
ErrRemotePodmanUDSReport = errors.New("remote podman failed to report its UDS socket")
ErrInvalidURISchemaName = errors.New("invalid schema name")
ErrInvalidTCPSchemaOption = errors.New("invalid option for tcp")
ErrInvalidUnixSchemaOption = errors.New("invalid option for unix")
ErrFileNotUnixSocket = errors.New("not a unix domain socket")
ErrEmptySSHIdentity = errors.New("empty identity field for SSH connection")
ErrEmptyURIDestination = errors.New("empty URI destination")
ErrEmptyServiceName = errors.New("empty service name")
ErrDuplicatedServiceName = errors.New("duplicated service name")
)
// Config contains configuration options for container tools.
type Config struct {
mu sync.Mutex
// Services specify the service destination connections
Services map[string]Service `toml:"services,omitempty"`
type Config interface {
RemoteConnections() []registry.Connection
SetDefaultConnection(name string) error
GetDefaultConnection() registry.Connection
Add(name string, uri string, identity string) error
Remove(name string) error
}
// Service represents remote service destination.
type Service struct {
// URI, required. Example: ssh://root@example.com:22/run/podman/podman.sock
URI string `toml:"uri"`
func NewConfig() (Config, error) { //nolint:ireturn
var cfg Config
// Identity file with ssh key, optional
Identity string `toml:"identity,omitempty"`
// Default if its default service, optional
Default bool `toml:"default,omitempty"`
}
// NewConfig returns new config.
func NewConfig() (*Config, error) {
log.Debug().Msgf("config: new")
path, err := configPath()
pconfig, err := pconfig.NewConfig()
if err != nil {
return nil, err
}
newConfig := &Config{}
if _, err := os.Stat(path); err == nil {
if err := newConfig.readConfigFromFile(path); err != nil {
return nil, err
}
premoteConns := pconfig.RemoteConnections()
if len(premoteConns) > 0 {
cfg = pconfig
} else {
if !os.IsNotExist(err) {
tconfig, err := tconfig.NewConfig()
if err != nil {
return nil, err
}
cfg = tconfig
}
newConfig.addLocalHostIfEmptyConfig()
defaultConn := newConfig.getDefault()
if defaultConn.URI != "" {
defaultConn := cfg.GetDefaultConnection()
if defaultConn.URI != "" && defaultConn.Name != "" {
registry.SetConnection(defaultConn)
}
return newConfig, nil
}
func (c *Config) addLocalHostIfEmptyConfig() {
if len(c.Services) > 0 {
return
}
c.Services = make(map[string]Service)
c.Services["localhost"] = Service{
URI: localNodeUnixSocket(),
Default: true,
}
}
// ServicesConnections returns list of available connections.
func (c *Config) ServicesConnections() []registry.Connection {
conn := make([]registry.Connection, 0)
c.mu.Lock()
defer c.mu.Unlock()
for name, service := range c.Services {
conn = append(conn, registry.Connection{
Name: name,
URI: service.URI,
Identity: service.Identity,
Default: service.Default,
})
}
sort.Sort(connectionListSortedName{conn})
return conn
}
type connSort []registry.Connection
func (a connSort) Len() int { return len(a) }
func (a connSort) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
type connectionListSortedName struct{ connSort }
func (a connectionListSortedName) Less(i, j int) bool {
return a.connSort[i].Name < a.connSort[j].Name
return cfg, nil
}

View File

@ -1,56 +0,0 @@
package config
import (
"github.com/containers/podman-tui/pdcs/registry"
"github.com/rs/zerolog/log"
)
// SetDefaultService sets default service name.
func (c *Config) SetDefaultService(name string) error {
log.Debug().Msgf("config: set %s as default service", name)
if err := c.setDef(name); err != nil {
return err
}
if err := c.Write(); err != nil {
return err
}
return c.reload()
}
func (c *Config) setDef(name string) error {
c.mu.Lock()
defer c.mu.Unlock()
for key := range c.Services {
dest := c.Services[key]
dest.Default = false
if key == name {
dest.Default = true
}
c.Services[key] = dest
}
return nil
}
func (c *Config) getDefault() registry.Connection {
c.mu.Lock()
defer c.mu.Unlock()
for name, service := range c.Services {
if service.Default {
return registry.Connection{
Name: name,
Identity: service.Identity,
URI: service.URI,
}
}
}
return registry.Connection{}
}

132
config/pconfig/config.go Normal file
View File

@ -0,0 +1,132 @@
package pconfig
import (
"slices"
"sort"
cconfig "github.com/containers/common/pkg/config"
"github.com/containers/podman-tui/config/utils"
"github.com/containers/podman-tui/pdcs/registry"
"github.com/containers/podman/v5/pkg/domain/entities"
"github.com/rs/zerolog/log"
)
type Config struct {
podmanOptions *entities.PodmanConfig
}
func NewConfig() (*Config, error) {
log.Debug().Msg("config: loading podman remote connections")
newConfig := &Config{}
defaultConfig, err := cconfig.New(&cconfig.Options{
SetDefault: true,
Modules: nil,
})
if err != nil {
return nil, err
}
podmanOptions := entities.PodmanConfig{ContainersConf: &cconfig.Config{}, ContainersConfDefaultsRO: defaultConfig}
newConfig.podmanOptions = &podmanOptions
return newConfig, nil
}
func (c *Config) RemoteConnections() []registry.Connection {
rconn := make([]registry.Connection, 0)
conns, err := c.podmanOptions.ContainersConfDefaultsRO.GetAllConnections()
if err != nil {
log.Err(err).Msgf("config: podman remote connection")
return nil
}
log.Debug().Msgf("connections: %v", conns)
for _, conn := range conns {
rconn = append(rconn, registry.Connection{
Name: conn.Name,
URI: conn.URI,
Identity: conn.Identity,
Default: conn.Default,
})
}
sort.Sort(utils.ConnectionListSortedName{rconn}) //nolint:govet
return rconn
}
func (c *Config) Remove(name string) error {
return cconfig.EditConnectionConfig(func(cfg *cconfig.ConnectionsFile) error {
delete(cfg.Connection.Connections, name)
if cfg.Connection.Default == name {
cfg.Connection.Default = ""
}
// If there are existing farm, remove the deleted connection that might be part of a farm
for k, v := range cfg.Farm.List {
index := slices.Index(v, name)
if index > -1 {
cfg.Farm.List[k] = append(v[:index], v[index+1:]...)
}
}
return nil
})
}
func (c *Config) Add(name string, uri string, identity string) error {
connURI, err := utils.ValidateNewConnection(name, uri, identity)
if err != nil {
return err
}
dst := cconfig.Destination{
URI: connURI,
Identity: identity,
}
return cconfig.EditConnectionConfig(func(cfg *cconfig.ConnectionsFile) error {
if cfg.Connection.Connections == nil {
cfg.Connection.Connections = map[string]cconfig.Destination{
name: dst,
}
cfg.Connection.Default = name
} else {
cfg.Connection.Connections[name] = dst
}
return nil
})
}
func (c *Config) SetDefaultConnection(name string) error {
return cconfig.EditConnectionConfig(func(cfg *cconfig.ConnectionsFile) error {
if _, found := cfg.Connection.Connections[name]; !found {
return utils.ErrConnectionNotFound
}
cfg.Connection.Default = name
return nil
})
}
func (c *Config) GetDefaultConnection() registry.Connection {
for _, conn := range c.RemoteConnections() {
if conn.Default {
return registry.Connection{
Name: conn.Name,
Identity: conn.Identity,
URI: conn.URI,
}
}
}
return registry.Connection{}
}

View File

@ -1,27 +0,0 @@
package config
import "github.com/rs/zerolog/log"
// Remove removes a service from config.
func (c *Config) Remove(name string) error {
log.Debug().Msgf("config: remove service %q", name)
c.remove(name)
if err := c.Write(); err != nil {
return err
}
return c.reload()
}
func (c *Config) remove(name string) {
c.mu.Lock()
defer c.mu.Unlock()
for serviceName := range c.Services {
if serviceName == name {
delete(c.Services, name)
}
}
}

47
config/tconfig/add.go Normal file
View File

@ -0,0 +1,47 @@
package tconfig
import (
"github.com/containers/podman-tui/config/utils"
"github.com/rs/zerolog/log"
)
// Add adds a new remote connection.
func (c *Config) Add(name string, uri string, identity string) error {
log.Debug().Msgf("config: adding new remote connection %s %s %s", name, uri, identity)
connURI, err := utils.ValidateNewConnection(name, uri, identity)
if err != nil {
return err
}
conn := RemoteConnection{
URI: connURI,
Identity: identity,
Default: false,
}
if err := c.add(name, conn); err != nil {
return err
}
if err := c.write(); err != nil {
return err
}
return c.reload()
}
func (c *Config) add(name string, conn RemoteConnection) error {
c.mu.Lock()
defer c.mu.Unlock()
for connName := range c.Connection.Connections {
if connName == name {
return ErrDuplicatedConnectionName
}
}
c.Connection.Connections[name] = conn
return nil
}

103
config/tconfig/config.go Normal file
View File

@ -0,0 +1,103 @@
package tconfig
import (
"errors"
"os"
"sort"
"sync"
"github.com/containers/podman-tui/config/utils"
"github.com/containers/podman-tui/pdcs/registry"
"github.com/rs/zerolog/log"
)
const (
// _configPath is the path to the podman-tui/podman-tui.json
// inside a given config directory.
_configPath = "podman-tui/podman-tui.json"
// UserAppConfig holds the user podman-tui config path.
UserAppConfig = ".config/" + _configPath
)
var ErrDuplicatedConnectionName = errors.New("duplicated connection name")
// Config contains configuration options for container tools.
type Config struct {
mu sync.Mutex
Connection RemoteConnections
}
type RemoteConnections struct {
Connections map[string]RemoteConnection `json:"connections"`
}
type RemoteConnection struct {
// URI, required. Example: ssh://root@example.com:22/run/podman/podman.sock
URI string `json:"uri"`
// Identity file with ssh key, optional
Identity string `json:"identity,omitempty"`
// Default if its default connection, optional
Default bool `json:"default,omitempty"`
}
// NewConfig returns new config.
func NewConfig() (*Config, error) {
path, err := utils.ConfigPath()
if err != nil {
return nil, err
}
log.Debug().Msgf("config: loading from %q", path)
newConfig := &Config{}
newConfig.Connection.Connections = make(map[string]RemoteConnection)
if _, err := os.Stat(path); err == nil {
if err := newConfig.readConfigFromFile(path); err != nil {
return nil, err
}
} else {
if !os.IsNotExist(err) {
return nil, err
}
}
newConfig.addLocalHostIfEmptyConfig()
return newConfig, nil
}
func (c *Config) addLocalHostIfEmptyConfig() {
if len(c.Connection.Connections) > 0 {
return
}
c.Connection.Connections = make(map[string]RemoteConnection)
c.Connection.Connections["localhost"] = RemoteConnection{
URI: utils.LocalNodeUnixSocket(),
Default: true,
}
}
// RemoteConnections returns list of available connections.
func (c *Config) RemoteConnections() []registry.Connection {
rconn := make([]registry.Connection, 0)
c.mu.Lock()
defer c.mu.Unlock()
for name, conn := range c.Connection.Connections {
rconn = append(rconn, registry.Connection{
Name: name,
URI: conn.URI,
Identity: conn.Identity,
Default: conn.Default,
})
}
sort.Sort(utils.ConnectionListSortedName{rconn}) //nolint:govet
return rconn
}

56
config/tconfig/default.go Normal file
View File

@ -0,0 +1,56 @@
package tconfig
import (
"github.com/containers/podman-tui/config/utils"
"github.com/containers/podman-tui/pdcs/registry"
"github.com/rs/zerolog/log"
)
// SetDefaultConnection sets default connection.
func (c *Config) SetDefaultConnection(name string) error {
log.Debug().Msgf("config: set %s as default connection", name)
if err := c.setDef(name); err != nil {
return err
}
if err := c.write(); err != nil {
return err
}
return c.reload()
}
func (c *Config) setDef(name string) error {
c.mu.Lock()
defer c.mu.Unlock()
for connName := range c.Connection.Connections {
if connName == name {
dest := c.Connection.Connections[connName]
dest.Default = true
c.Connection.Connections[connName] = dest
return nil
}
}
return utils.ErrConnectionNotFound
}
func (c *Config) GetDefaultConnection() registry.Connection {
c.mu.Lock()
defer c.mu.Unlock()
for connName, conn := range c.Connection.Connections {
if conn.Default {
return registry.Connection{
Name: connName,
Identity: conn.Identity,
URI: conn.URI,
}
}
}
return registry.Connection{}
}

View File

@ -1,10 +1,12 @@
package config
package tconfig
import (
"encoding/json"
"fmt"
"io"
"os"
"github.com/BurntSushi/toml"
"github.com/containers/podman-tui/config/utils"
"github.com/rs/zerolog/log"
)
@ -14,30 +16,23 @@ func (c *Config) readConfigFromFile(path string) error {
c.mu.Lock()
defer c.mu.Unlock()
rawConfig, err := os.ReadFile(path)
cfgFile, err := os.Open(path)
if err != nil {
return fmt.Errorf("config: %w open configuration %q", err, path)
}
cfgData, err := io.ReadAll(cfgFile)
if err != nil {
return fmt.Errorf("config: %w read configuration %q", err, path)
}
config := os.ExpandEnv(string(rawConfig))
meta, err := toml.Decode(config, c)
if err != nil {
return fmt.Errorf("config: %w decode configuration %q", err, path)
}
keys := meta.Undecoded()
if len(keys) > 0 {
log.Debug().Msgf("config: failed to decode the keys %q from %q.", keys, path)
}
return nil
return json.Unmarshal(cfgData, &c.Connection)
}
func (c *Config) reload() error {
log.Debug().Msgf("config: reload configuration")
path, err := configPath()
path, err := utils.ConfigPath()
if err != nil {
return err
}

27
config/tconfig/remove.go Normal file
View File

@ -0,0 +1,27 @@
package tconfig
import "github.com/rs/zerolog/log"
// Remove removes a connection from config.
func (c *Config) Remove(name string) error {
log.Debug().Msgf("config: remove remote connection %q", name)
c.remove(name)
if err := c.write(); err != nil {
return err
}
return c.reload()
}
func (c *Config) remove(name string) {
c.mu.Lock()
defer c.mu.Unlock()
for connName := range c.Connection.Connections {
if connName != name {
delete(c.Connection.Connections, name)
}
}
}

48
config/tconfig/write.go Normal file
View File

@ -0,0 +1,48 @@
package tconfig
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
"github.com/containers/podman-tui/config/utils"
"github.com/rs/zerolog/log"
)
// Write writes config.
func (c *Config) write() error {
var err error
c.mu.Lock()
defer c.mu.Unlock()
path, err := utils.ConfigPath()
if err != nil {
return err
}
log.Debug().Msgf("config: write configuration file %q", path)
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil { //nolint:mnd
return err
}
configFile, err := os.OpenFile(path, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0o640) //nolint:mnd
if err != nil {
return err
}
defer configFile.Close()
jsonData, err := json.Marshal(c.Connection)
if err != nil {
return fmt.Errorf("config: configuration json marshal %w", err)
}
if _, err := configFile.Write(jsonData); err != nil {
return fmt.Errorf("config: %w write configuration %q", err, path)
}
return nil
}

100
config/utils/conn.go Normal file
View File

@ -0,0 +1,100 @@
package utils
import (
"errors"
"fmt"
"net"
"net/url"
"os"
"regexp"
"github.com/containers/podman-tui/ui/utils"
"github.com/rs/zerolog/log"
)
var (
ErrInvalidURISchemaName = errors.New("invalid schema name")
ErrInvalidTCPSchemaOption = errors.New("invalid option for tcp")
ErrInvalidUnixSchemaOption = errors.New("invalid option for unix")
ErrFileNotUnixSocket = errors.New("not a unix domain socket")
ErrEmptySSHIdentity = errors.New("empty identity field for SSH connection")
ErrEmptyURIDestination = errors.New("empty URI destination")
ErrEmptyConnectionName = errors.New("empty connection name")
ErrConnectionNotFound = errors.New("connection not found")
)
func ValidateNewConnection(name string, dest string, identity string) (string, error) { //nolint:cyclop
var connIdentity string
if name == "" {
return "", ErrEmptyConnectionName
}
if dest == "" {
return "", ErrEmptyURIDestination
}
if match, err := regexp.Match("^[A-Za-z][A-Za-z0-9+.-]*://", []byte(dest)); err != nil { //nolint:mirror
return "", fmt.Errorf("%w invalid destition", err)
} else if !match {
dest = "ssh://" + dest
}
uri, err := url.Parse(dest)
if err != nil {
return "", err
}
switch uri.Scheme {
case "ssh":
if uri.User.Username() == "" {
if uri.User, err = getUserInfo(uri); err != nil {
return "", err
}
}
connIdentity, err = utils.ResolveHomeDir(identity)
if err != nil {
return "", err
}
if identity == "" {
return "", ErrEmptySSHIdentity
}
if uri.Port() == "" {
uri.Host = net.JoinHostPort(uri.Hostname(), "22")
}
if uri.Path == "" || uri.Path == "/" {
if uri.Path, err = getUDS(uri, connIdentity); err != nil {
return "", err
}
}
case "unix":
if identity != "" {
return "", fmt.Errorf("%w identity", ErrInvalidUnixSchemaOption)
}
info, err := os.Stat(uri.Path)
switch {
case errors.Is(err, os.ErrNotExist):
log.Warn().Msgf("config: %q does not exists", uri.Path)
case errors.Is(err, os.ErrPermission):
log.Warn().Msgf("config: You do not have permission to read %q", uri.Path)
case err != nil:
return "", err
case info.Mode()&os.ModeSocket == 0:
return "", fmt.Errorf("%w %q", ErrFileNotUnixSocket, uri.Path)
}
case "tcp":
if identity != "" {
return "", fmt.Errorf("%w identity", ErrInvalidTCPSchemaOption)
}
default:
return "", fmt.Errorf("%w %q", ErrInvalidURISchemaName, uri.Scheme)
}
return uri.String(), nil
}

14
config/utils/sort.go Normal file
View File

@ -0,0 +1,14 @@
package utils
import "github.com/containers/podman-tui/pdcs/registry"
type ConnSort []registry.Connection
func (a ConnSort) Len() int { return len(a) }
func (a ConnSort) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
type ConnectionListSortedName struct{ ConnSort }
func (a ConnectionListSortedName) Less(i, j int) bool {
return a.ConnSort[i].Name < a.ConnSort[j].Name
}

View File

@ -1,8 +1,9 @@
package config
package utils
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"net"
"net/url"
@ -19,7 +20,17 @@ import (
"golang.org/x/crypto/ssh/agent"
)
func configPath() (string, error) {
const (
// _configPath is the path to the podman-tui/podman-tui.json
// inside a given config directory.
_configPath = "podman-tui/podman-tui.json"
// UserAppConfig holds the user podman-tui config path.
UserAppConfig = ".config/" + _configPath
)
var ErrRemotePodmanUDSReport = errors.New("remote podman failed to report its UDS socket")
func ConfigPath() (string, error) {
if configHome := os.Getenv("XDG_CONFIG_HOME"); configHome != "" {
return filepath.Join(configHome, _configPath), nil
}
@ -32,8 +43,8 @@ func configPath() (string, error) {
return filepath.Join(home, UserAppConfig), nil
}
// localNodeUnixSocket return local node unix socket file.
func localNodeUnixSocket() string {
// LocalNodeUnixSocket return local node unix socket file.
func LocalNodeUnixSocket() string {
var (
sockDir string
socket string
@ -48,7 +59,7 @@ func localNodeUnixSocket() string {
sockDir = os.Getenv("XDG_RUNTIME_DIR")
}
socket = "unix:" + sockDir + "/podman/podman.sock"
socket = "unix:/" + sockDir + "/podman/podman.sock"
return socket
}

View File

@ -1,39 +0,0 @@
package config
import (
"os"
"path/filepath"
"github.com/BurntSushi/toml"
"github.com/rs/zerolog/log"
)
// Write writes config.
func (c *Config) Write() error {
var err error
c.mu.Lock()
defer c.mu.Unlock()
path, err := configPath()
if err != nil {
return err
}
log.Debug().Msgf("config: write configuration file %q", path)
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil { //nolint:gomnd
return err
}
configFile, err := os.OpenFile(path, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0o640) //nolint:gomnd
if err != nil {
return err
}
defer configFile.Close()
enc := toml.NewEncoder(configFile)
return enc.Encode(c)
}

View File

@ -1,4 +1,57 @@
# Documents
## podman-tui
![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)
![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/containers/podman-tui)
![Go](https://github.com/containers/podman-tui/workflows/Go/badge.svg)
[![Go Report](https://goreportcard.com/badge/github.com/containers/podman-tui)](https://goreportcard.com/report/github.com/containers/podman-tui)
[![codecov](https://codecov.io/gh/navidys/podman-tui/branch/main/graph/badge.svg)](https://codecov.io/gh/navidys/podman-tui)
Terminal user interface for Podman environment.
![Screenshot](./podman-tui.gif)
- [**Overview**](#overview)
- [**Compatibility Matrix**](#compatibility-matrix)
- [**Installation**](#installation)
- [**PreRun Checks**](#prerun-checks)
- [**Key Bindings**](#key-bindings)
- [**Code of Conduct**](#code-of-conduct)
- [**License**](#license)
## Overview
podman-tui is a terminal user interface for podman environment.
It is using [podman go bindings](https://github.com/containers/podman/tree/main/pkg/bindings) to communicate with local or remote podman machine (through SSH).
## Compatibility matrix
| Terminal User Interface | Podman |
| ----------- | ------ |
| release-1.x | v5.x.y |
| release-0.x | v4.x.y |
## Installation
Building from source (Linux, Windows and MacOS) or installing packaged versions are detailed in [install guide](install.md).
## PreRun Checks
* `podman.socket` service needs to be running on podman machine.
The recommended way to start Podman system service in production mode is via systemd socket-activation:
```shell
$ systemctl --user start podman.socket
```
See [start podman system service](https://podman.io/blogs/2020/08/10/podman-go-bindings.html) for more details.
* If the SSH key has a passphrase, then you need to set and export `CONTAINER_PASSPHRASE=<password>` variable.
```shell
$ export CONTAINER_PASSPHRASE=keypass
```
* podman-tui uses 256 colors terminal mode on `Nix` system and standard ANSI colors on `Windows` system (use "command prompt" application).
## Key Bindings
@ -27,3 +80,11 @@ podman-tui uses following keyboard keys for different actions:
| Display images screen | F6 |
| Display networks screen | F7 |
| Display secrets screen | F8 |
## Code of Conduct
This project is using the [Containers Community Code of Conduct](https://github.com/containers/common/blob/main/CODE-OF-CONDUCT.md)
## License
Licensed under the [Apache 2.0](LICENSE) license.

View File

@ -112,22 +112,27 @@ $ podman run -it --name podman-tui-app \
## Configuration Files
### podman-tui.conf
### podman-tui.json
~/.config/podman-tui/podman-tui.conf
~/.config/podman-tui/podman-tui.json
podman-tui.conf is the configuration file which specifies local and remotes podman systems connections details.
podman-tui.json is the configuration file which specifies local and remotes podman systems connections details.
```shell
[services]
[services.fc36node01]
uri = "ssh://navid@fc36node01:22/run/user/1000/podman/podman.sock"
identity = "/home/navid/.ssh/id_ed25519"
[services.fc36node02]
uri = "ssh://navid@fc36node02:22/run/user/1000/podman/podman.sock"
identity = "/home/navid/.ssh/id_ed25519"
default = true
[services.localhost]
uri = "unix://run/user/1000/podman/podman.sock"
{
"connections": {
"f42node01": {
"uri": "ssh://navid@f42node01:22/run/user/1000/podman/podman.sock",
"identity": "/home/navid/.ssh/id_ed25519"
},
"fc42node02": {
"uri": "ssh://navid@f42node02:22/run/user/1000/podman/podman.sock",
"identity": "/home/navid/.ssh/id_ed25519"
},
"localhost": {
"uri": "unix://run/user/1000/podman/podman.sock",
"default": true
}
}
}
```

164
go.mod
View File

@ -1,81 +1,83 @@
module github.com/containers/podman-tui
go 1.21.0
go 1.23.3
require (
github.com/BurntSushi/toml v1.4.0
github.com/containers/buildah v1.37.0
github.com/containers/common v0.60.0
github.com/containers/podman/v5 v5.2.0
github.com/containers/storage v1.55.0
github.com/containers/buildah v1.40.1
github.com/containers/common v0.63.1
github.com/containers/podman/v5 v5.5.1
github.com/containers/storage v1.58.0
github.com/distribution/reference v0.6.0
github.com/docker/docker v27.1.1+incompatible
github.com/docker/go-units v0.5.0
github.com/gdamore/tcell/v2 v2.7.4
github.com/gdamore/tcell/v2 v2.8.1
github.com/hashicorp/go-multierror v1.1.1
github.com/hinshun/vt10x v0.0.0-20220301184237-5011da428d02
github.com/navidys/tvxwidgets v0.4.1
github.com/onsi/ginkgo/v2 v2.19.0
github.com/onsi/gomega v1.33.1
github.com/onsi/ginkgo/v2 v2.23.4
github.com/onsi/gomega v1.37.0
github.com/pkg/errors v0.9.1
github.com/rivo/tview v0.0.0-20220307222120-9994674d60a8
github.com/rs/zerolog v1.33.0
github.com/rs/zerolog v1.34.0
github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.8.1
golang.org/x/crypto v0.25.0
github.com/spf13/cobra v1.9.1
golang.org/x/crypto v0.39.0
)
require (
dario.cat/mergo v1.0.0 // indirect
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
dario.cat/mergo v1.0.1 // indirect
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect
github.com/BurntSushi/toml v1.5.0 // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/Microsoft/hcsshim v0.12.5 // indirect
github.com/Microsoft/hcsshim v0.12.9 // indirect
github.com/VividCortex/ewma v1.2.0 // indirect
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d // indirect
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/blang/semver/v4 v4.0.0 // indirect
github.com/chzyer/readline v1.5.1 // indirect
github.com/containerd/cgroups/v3 v3.0.3 // indirect
github.com/containerd/containerd v1.7.18 // indirect
github.com/containerd/errdefs v0.1.0 // indirect
github.com/containerd/cgroups/v3 v3.0.5 // indirect
github.com/containerd/errdefs v1.0.0 // indirect
github.com/containerd/errdefs/pkg v0.3.0 // indirect
github.com/containerd/log v0.1.0 // indirect
github.com/containerd/stargz-snapshotter/estargz v0.15.1 // indirect
github.com/containers/image/v5 v5.32.0 // indirect
github.com/containerd/platforms v1.0.0-rc.1 // indirect
github.com/containerd/stargz-snapshotter/estargz v0.16.3 // indirect
github.com/containerd/typeurl/v2 v2.2.3 // indirect
github.com/containers/image/v5 v5.35.0 // indirect
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 // indirect
github.com/containers/ocicrypt v1.2.0 // indirect
github.com/containers/ocicrypt v1.2.1 // indirect
github.com/containers/psgo v1.9.0 // indirect
github.com/coreos/go-systemd/v22 v22.5.1-0.20231103132048-7d375ecc2b09 // indirect
github.com/cyberphone/json-canonicalization v0.0.0-20231217050601-ba74d44ecf5f // indirect
github.com/cyphar/filepath-securejoin v0.3.1 // indirect
github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467 // indirect
github.com/cyphar/filepath-securejoin v0.4.1 // indirect
github.com/disiqueira/gotree/v3 v3.0.2 // indirect
github.com/docker/distribution v2.8.3+incompatible // indirect
github.com/docker/docker-credential-helpers v0.8.2 // indirect
github.com/docker/docker v28.1.1+incompatible // indirect
github.com/docker/docker-credential-helpers v0.9.3 // indirect
github.com/docker/go-connections v0.5.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/gdamore/encoding v1.0.0 // indirect
github.com/go-jose/go-jose/v4 v4.0.2 // indirect
github.com/go-logr/logr v1.4.1 // indirect
github.com/fsnotify/fsnotify v1.9.0 // indirect
github.com/gdamore/encoding v1.0.1 // indirect
github.com/go-jose/go-jose/v4 v4.0.5 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/analysis v0.23.0 // indirect
github.com/go-openapi/errors v0.22.0 // indirect
github.com/go-openapi/errors v0.22.1 // indirect
github.com/go-openapi/jsonpointer v0.21.0 // indirect
github.com/go-openapi/jsonreference v0.21.0 // indirect
github.com/go-openapi/loads v0.22.0 // indirect
github.com/go-openapi/runtime v0.28.0 // indirect
github.com/go-openapi/spec v0.21.0 // indirect
github.com/go-openapi/strfmt v0.23.0 // indirect
github.com/go-openapi/swag v0.23.0 // indirect
github.com/go-openapi/swag v0.23.1 // indirect
github.com/go-openapi/validate v0.24.0 // indirect
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466 // indirect
github.com/godbus/dbus/v5 v5.1.1-0.20241109141217-c266b19b28e9 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/go-containerregistry v0.20.0 // indirect
github.com/google/go-cmp v0.7.0 // indirect
github.com/google/go-containerregistry v0.20.3 // indirect
github.com/google/go-intervals v0.0.2 // indirect
github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 // indirect
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/mux v1.8.1 // indirect
github.com/gorilla/schema v1.4.1 // indirect
@ -84,74 +86,80 @@ require (
github.com/jinzhu/copier v0.4.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.17.9 // indirect
github.com/kevinburke/ssh_config v1.2.0 // indirect
github.com/klauspost/compress v1.18.0 // indirect
github.com/klauspost/pgzip v1.2.6 // indirect
github.com/kr/fs v0.1.0 // indirect
github.com/letsencrypt/boulder v0.0.0-20240418210053-89b07f4543e0 // indirect
github.com/letsencrypt/boulder v0.0.0-20240620165639-de9c06129bec // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mailru/easyjson v0.9.0 // indirect
github.com/manifoldco/promptui v0.9.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/mattn/go-sqlite3 v1.14.22 // indirect
github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/mattn/go-sqlite3 v1.14.28 // indirect
github.com/miekg/pkcs11 v1.1.1 // indirect
github.com/mistifyio/go-zfs/v3 v3.0.1 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/moby/docker-image-spec v1.3.1 // indirect
github.com/moby/sys/capability v0.4.0 // indirect
github.com/moby/sys/mountinfo v0.7.2 // indirect
github.com/moby/sys/user v0.2.0 // indirect
github.com/moby/term v0.5.0 // indirect
github.com/moby/sys/user v0.4.0 // indirect
github.com/moby/sys/userns v0.1.0 // indirect
github.com/moby/term v0.5.2 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/nxadm/tail v1.4.11 // indirect
github.com/oklog/ulid v1.3.1 // indirect
github.com/opencontainers/cgroups v0.0.1 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.0 // indirect
github.com/opencontainers/runc v1.1.13 // indirect
github.com/opencontainers/runtime-spec v1.2.0 // indirect
github.com/opencontainers/runtime-tools v0.9.1-0.20230914150019-408c51e934dc // indirect
github.com/opencontainers/selinux v1.11.0 // indirect
github.com/opencontainers/image-spec v1.1.1 // indirect
github.com/opencontainers/runc v1.2.6 // indirect
github.com/opencontainers/runtime-spec v1.2.1 // indirect
github.com/opencontainers/runtime-tools v0.9.1-0.20250303011046-260e151b8552 // indirect
github.com/opencontainers/selinux v1.12.0 // indirect
github.com/ostreedev/ostree-go v0.0.0-20210805093236-719684c64e4f // indirect
github.com/pkg/sftp v1.13.6 // indirect
github.com/proglottis/gpgme v0.1.3 // indirect
github.com/pkg/sftp v1.13.9 // indirect
github.com/proglottis/gpgme v0.1.4 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/secure-systems-lab/go-securesystemslib v0.8.0 // indirect
github.com/sigstore/fulcio v1.4.5 // indirect
github.com/sigstore/rekor v1.3.6 // indirect
github.com/sigstore/sigstore v1.8.4 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/secure-systems-lab/go-securesystemslib v0.9.0 // indirect
github.com/sigstore/fulcio v1.6.6 // indirect
github.com/sigstore/protobuf-specs v0.4.1 // indirect
github.com/sigstore/rekor v1.3.10 // indirect
github.com/sigstore/sigstore v1.9.3 // indirect
github.com/skeema/knownhosts v1.3.1 // indirect
github.com/smallstep/pkcs7 v0.1.1 // indirect
github.com/spf13/pflag v1.0.6 // indirect
github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6 // indirect
github.com/sylabs/sif/v2 v2.18.0 // indirect
github.com/sylabs/sif/v2 v2.21.1 // indirect
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 // indirect
github.com/tchap/go-patricia/v2 v2.3.1 // indirect
github.com/tchap/go-patricia/v2 v2.3.2 // indirect
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 // indirect
github.com/ulikunitz/xz v0.5.12 // indirect
github.com/vbatts/tar-split v0.11.5 // indirect
github.com/vbauerster/mpb/v8 v8.7.4 // indirect
github.com/vbatts/tar-split v0.12.1 // indirect
github.com/vbauerster/mpb/v8 v8.9.3 // indirect
go.mongodb.org/mongo-driver v1.14.0 // indirect
go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect
go.opentelemetry.io/otel v1.24.0 // indirect
go.opentelemetry.io/otel/metric v1.24.0 // indirect
go.opentelemetry.io/otel/trace v1.24.0 // indirect
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect
golang.org/x/net v0.27.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/sys v0.22.0 // indirect
golang.org/x/term v0.22.0 // indirect
golang.org/x/text v0.16.0 // indirect
golang.org/x/time v0.5.0 // indirect
golang.org/x/tools v0.22.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 // indirect
google.golang.org/grpc v1.64.1 // indirect
google.golang.org/protobuf v1.34.2 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 // indirect
go.opentelemetry.io/otel v1.34.0 // indirect
go.opentelemetry.io/otel/metric v1.34.0 // indirect
go.opentelemetry.io/otel/trace v1.34.0 // indirect
go.uber.org/automaxprocs v1.6.0 // indirect
golang.org/x/net v0.40.0 // indirect
golang.org/x/sync v0.15.0 // indirect
golang.org/x/sys v0.33.0 // indirect
golang.org/x/term v0.32.0 // indirect
golang.org/x/text v0.26.0 // indirect
golang.org/x/time v0.11.0 // indirect
golang.org/x/tools v0.33.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250313205543-e70fdf4c4cb4 // indirect
google.golang.org/grpc v1.71.0 // indirect
google.golang.org/protobuf v1.36.6 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
tags.cncf.io/container-device-interface v0.8.0 // indirect
tags.cncf.io/container-device-interface v1.0.1 // indirect
)
replace github.com/opencontainers/runc => github.com/opencontainers/runc v1.1.1-0.20220617142545-8b9452f75cbc

439
go.sum
View File

@ -1,17 +1,17 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s=
dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
github.com/14rcole/gopopulate v0.0.0-20180821133914-b175b219e774 h1:SCbEWT58NSt7d2mcFdvxC9uyrdcTfvBbPLThhkDmXzg=
github.com/14rcole/gopopulate v0.0.0-20180821133914-b175b219e774/go.mod h1:6/0dYRLLXyJjbkIPeeGyoJ/eKOSI0eU6eTlCBYibgd0=
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg=
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
github.com/Microsoft/hcsshim v0.12.5 h1:bpTInLlDy/nDRWFVcefDZZ1+U8tS+rz3MxjKgu9boo0=
github.com/Microsoft/hcsshim v0.12.5/go.mod h1:tIUGego4G1EN5Hb6KC90aDYiUI2dqLSTTOCjVNpOgZ8=
github.com/Microsoft/hcsshim v0.12.9 h1:2zJy5KA+l0loz1HzEGqyNnjd3fyZA31ZBCGKacp6lLg=
github.com/Microsoft/hcsshim v0.12.9/go.mod h1:fJ0gkFAna6ukt0bLdKB8djt4XIJhF/vEPuoIWYVvZ8Y=
github.com/VividCortex/ewma v1.2.0 h1:f58SaIzcDXrSy3kWaHNvuJgJ3Nmz59Zji6XoJR/q1ow=
github.com/VividCortex/ewma v1.2.0/go.mod h1:nz4BbCtbLyFDeC9SUHbtcT5644juEuWfUAUnGx7j5l4=
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8=
@ -22,11 +22,11 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/logex v1.2.1 h1:XHDu3E6q+gdHgsdTPH6ImJMIp436vR6MPtH8gP05QzM=
github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ=
@ -38,42 +38,46 @@ github.com/chzyer/test v1.0.0 h1:p3BQDXSxOhOG0P9z6/hGnII4LGiEPOYBhs8asl/fC04=
github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/containerd/cgroups/v3 v3.0.3 h1:S5ByHZ/h9PMe5IOQoN7E+nMc2UcLEM/V48DGDJ9kip0=
github.com/containerd/cgroups/v3 v3.0.3/go.mod h1:8HBe7V3aWGLFPd/k03swSIsGjZhHI2WzJmticMgVuz0=
github.com/containerd/containerd v1.7.18 h1:jqjZTQNfXGoEaZdW1WwPU0RqSn1Bm2Ay/KJPUuO8nao=
github.com/containerd/containerd v1.7.18/go.mod h1:IYEk9/IO6wAPUz2bCMVUbsfXjzw5UNP5fLz4PsUygQ4=
github.com/containerd/errdefs v0.1.0 h1:m0wCRBiu1WJT/Fr+iOoQHMQS/eP5myQ8lCv4Dz5ZURM=
github.com/containerd/errdefs v0.1.0/go.mod h1:YgWiiHtLmSeBrvpw+UfPijzbLaB77mEG1WwJTDETIV0=
github.com/containerd/cgroups/v3 v3.0.5 h1:44na7Ud+VwyE7LIoJ8JTNQOa549a8543BmzaJHo6Bzo=
github.com/containerd/cgroups/v3 v3.0.5/go.mod h1:SA5DLYnXO8pTGYiAHXz94qvLQTKfVM5GEVisn4jpins=
github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI=
github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=
github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE=
github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk=
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
github.com/containerd/stargz-snapshotter/estargz v0.15.1 h1:eXJjw9RbkLFgioVaTG+G/ZW/0kEe2oEKCdS/ZxIyoCU=
github.com/containerd/stargz-snapshotter/estargz v0.15.1/go.mod h1:gr2RNwukQ/S9Nv33Lt6UC7xEx58C+LHRdoqbEKjz1Kk=
github.com/containers/buildah v1.37.0 h1:jvHwu1vIwIqnHyOSg9eef9Apdpry+5oWLrm43gdf8Rk=
github.com/containers/buildah v1.37.0/go.mod h1:MKd79tkluMf6vtH06SedhBQK5OB7E0pFVIuiTTw3dJk=
github.com/containers/common v0.60.0 h1:QMNygqiiit9LU/yqee9Dv0N0oQ+rQq41ElfdOBQtw7w=
github.com/containers/common v0.60.0/go.mod h1:dtKVe11xkV89tqzRX9s/B0ORjeB2dy5UB46aGjunMn8=
github.com/containers/image/v5 v5.32.0 h1:yjbweazPfr8xOzQ2hkkYm1A2V0jN96/kES6Gwyxj7hQ=
github.com/containers/image/v5 v5.32.0/go.mod h1:x5e0RDfGaY6bnQ13gJ2LqbfHvzssfB/y5a8HduGFxJc=
github.com/containerd/platforms v1.0.0-rc.1 h1:83KIq4yy1erSRgOVHNk1HYdPvzdJ5CnsWaRoJX4C41E=
github.com/containerd/platforms v1.0.0-rc.1/go.mod h1:J71L7B+aiM5SdIEqmd9wp6THLVRzJGXfNuWCZCllLA4=
github.com/containerd/stargz-snapshotter/estargz v0.16.3 h1:7evrXtoh1mSbGj/pfRccTampEyKpjpOnS3CyiV1Ebr8=
github.com/containerd/stargz-snapshotter/estargz v0.16.3/go.mod h1:uyr4BfYfOj3G9WBVE8cOlQmXAbPN9VEQpBBeJIuOipU=
github.com/containerd/typeurl/v2 v2.2.3 h1:yNA/94zxWdvYACdYO8zofhrTVuQY73fFU1y++dYSw40=
github.com/containerd/typeurl/v2 v2.2.3/go.mod h1:95ljDnPfD3bAbDJRugOiShd/DlAAsxGtUBhJxIn7SCk=
github.com/containers/buildah v1.40.1 h1:RW+Fbelwblzg1mJfKfyGZPS4Nbc5QtT866fJ9pYFtYo=
github.com/containers/buildah v1.40.1/go.mod h1:1UCQBc3LZrT4u5R/u7igGgUQxeDlJmn/OyYDQ9mumFk=
github.com/containers/common v0.63.1 h1:6g02gbW34PaRVH4Heb2Pk11x0SdbQ+8AfeKKeQGqYBE=
github.com/containers/common v0.63.1/go.mod h1:+3GCotSqNdIqM3sPs152VvW7m5+Mg8Kk+PExT3G9hZw=
github.com/containers/image/v5 v5.35.0 h1:T1OeyWp3GjObt47bchwD9cqiaAm/u4O4R9hIWdrdrP8=
github.com/containers/image/v5 v5.35.0/go.mod h1:8vTsgb+1gKcBL7cnjyNOInhJQfTUQjJoO2WWkKDoebM=
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 h1:Qzk5C6cYglewc+UyGf6lc8Mj2UaPTHy/iF2De0/77CA=
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY=
github.com/containers/ocicrypt v1.2.0 h1:X14EgRK3xNFvJEfI5O4Qn4T3E25ANudSOZz/sirVuPM=
github.com/containers/ocicrypt v1.2.0/go.mod h1:ZNviigQajtdlxIZGibvblVuIFBKIuUI2M0QM12SD31U=
github.com/containers/podman/v5 v5.2.0 h1:HWZLFtK4f4LJRa1mP9TPGT1nu5gnqXKQtHA2xwH+diE=
github.com/containers/podman/v5 v5.2.0/go.mod h1:tEvvwANzHLEd9B6Vf+mF76piaQtbDYrGl3YXGZkq17s=
github.com/containers/ocicrypt v1.2.1 h1:0qIOTT9DoYwcKmxSt8QJt+VzMY18onl9jUXsxpVhSmM=
github.com/containers/ocicrypt v1.2.1/go.mod h1:aD0AAqfMp0MtwqWgHM1bUwe1anx0VazI108CRrSKINQ=
github.com/containers/podman/v5 v5.5.1 h1:nFqybTuKX6kLvnQ67hScE0/ihba5k+qHFArXdopnqlI=
github.com/containers/podman/v5 v5.5.1/go.mod h1:mxncFv2XqD6ZlXZnBk4JpGmQfkx1+k7KyuBTy1d4Xfc=
github.com/containers/psgo v1.9.0 h1:eJ74jzSaCHnWt26OlKZROSyUyRcGDf+gYBdXnxrMW4g=
github.com/containers/psgo v1.9.0/go.mod h1:0YoluUm43Mz2UnBIh1P+6V6NWcbpTL5uRtXyOcH0B5A=
github.com/containers/storage v1.55.0 h1:wTWZ3YpcQf1F+dSP4KxG9iqDfpQY1otaUXjPpffuhgg=
github.com/containers/storage v1.55.0/go.mod h1:28cB81IDk+y7ok60Of6u52RbCeBRucbFOeLunhER1RQ=
github.com/containers/storage v1.58.0 h1:Q7SyyCCjqgT3wYNgRNIL8o/wUS92heIj2/cc8Sewvcc=
github.com/containers/storage v1.58.0/go.mod h1:w7Jl6oG+OpeLGLzlLyOZPkmUso40kjpzgrHUk5tyBlo=
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/coreos/go-systemd/v22 v22.5.1-0.20231103132048-7d375ecc2b09 h1:OoRAFlvDGCUqDLampLQjk0yeeSGdF9zzst/3G9IkBbc=
github.com/coreos/go-systemd/v22 v22.5.1-0.20231103132048-7d375ecc2b09/go.mod h1:m2r/smMKsKwgMSAoFKHaa68ImdCSNuKE1MxvQ64xuCQ=
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/cyberphone/json-canonicalization v0.0.0-20231217050601-ba74d44ecf5f h1:eHnXnuK47UlSTOQexbzxAZfekVz6i+LKRdj1CU5DPaM=
github.com/cyberphone/json-canonicalization v0.0.0-20231217050601-ba74d44ecf5f/go.mod h1:uzvlm1mxhHkdfqitSA92i7Se+S9ksOn3a3qmv/kyOCw=
github.com/cyphar/filepath-securejoin v0.3.1 h1:1V7cHiaW+C+39wEfpH6XlLBQo3j/PciWFrgfCLS8XrE=
github.com/cyphar/filepath-securejoin v0.3.1/go.mod h1:F7i41x/9cBF7lzCrVsYs9fuzwRZm4NQsGTBdpp6mETc=
github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467 h1:uX1JmpONuD549D73r6cgnxyUu18Zb7yHAy5AYU0Pm4Q=
github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467/go.mod h1:uzvlm1mxhHkdfqitSA92i7Se+S9ksOn3a3qmv/kyOCw=
github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s=
github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
@ -82,14 +86,14 @@ github.com/disiqueira/gotree/v3 v3.0.2 h1:ik5iuLQQoufZBNPY518dXhiO5056hyNBIK9lWh
github.com/disiqueira/gotree/v3 v3.0.2/go.mod h1:ZuyjE4+mUQZlbpkI24AmruZKhg3VHEgPLDY8Qk+uUu8=
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/docker/cli v27.1.1+incompatible h1:goaZxOqs4QKxznZjjBWKONQci/MywhtRv2oNn0GkeZE=
github.com/docker/cli v27.1.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/cli v28.0.4+incompatible h1:pBJSJeNd9QeIWPjRcV91RVJihd/TXB77q1ef64XEu4A=
github.com/docker/cli v28.0.4+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v27.1.1+incompatible h1:hO/M4MtV36kzKldqnA37IWhebRA+LnqqcqDja6kVaKY=
github.com/docker/docker v27.1.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo=
github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M=
github.com/docker/docker v28.1.1+incompatible h1:49M11BFLsVO1gxY9UX9p/zwkE/rswggs8AdFmXQw51I=
github.com/docker/docker v28.1.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8=
github.com/docker/docker-credential-helpers v0.9.3/go.mod h1:x+4Gbw9aGmChi3qTLZj8Dfn0TD20M/fuWy0E5+WDeCo=
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8=
@ -103,24 +107,25 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko=
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg=
github.com/gdamore/encoding v1.0.1 h1:YzKZckdBL6jVt2Gc+5p82qhrGiqMdG/eNs6Wy0u3Uhw=
github.com/gdamore/encoding v1.0.1/go.mod h1:0Z0cMFinngz9kS1QfMjCP8TY7em3bZYeeklsSDPivEo=
github.com/gdamore/tcell/v2 v2.4.1-0.20210905002822-f057f0a857a1/go.mod h1:Az6Jt+M5idSED2YPGtwnfJV0kXohgdCBPmHGSYc1r04=
github.com/gdamore/tcell/v2 v2.7.4 h1:sg6/UnTM9jGpZU+oFYAsDahfchWAFW8Xx2yFinNSAYU=
github.com/gdamore/tcell/v2 v2.7.4/go.mod h1:dSXtXTSK0VsW1biw65DZLZ2NKr7j0qP/0J7ONmsraWg=
github.com/go-jose/go-jose/v4 v4.0.2 h1:R3l3kkBds16bO7ZFAEEcofK0MkrAJt3jlJznWZG0nvk=
github.com/go-jose/go-jose/v4 v4.0.2/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY=
github.com/gdamore/tcell/v2 v2.8.1 h1:KPNxyqclpWpWQlPLx6Xui1pMk8S+7+R37h3g07997NU=
github.com/gdamore/tcell/v2 v2.8.1/go.mod h1:bj8ori1BG3OYMjmb3IklZVWfZUJ1UBQt9JXrOCOhGWw=
github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE=
github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-openapi/analysis v0.23.0 h1:aGday7OWupfMs+LbmLZG4k0MYXIANxcuBTYUC03zFCU=
github.com/go-openapi/analysis v0.23.0/go.mod h1:9mz9ZWaSlV8TvjQHLl2mUW2PbZtemkE8yA5v22ohupo=
github.com/go-openapi/errors v0.22.0 h1:c4xY/OLxUBSTiepAg3j/MHuAv5mJhnf53LLMWFB+u/w=
github.com/go-openapi/errors v0.22.0/go.mod h1:J3DmZScxCDufmIMsdOuDHxJbdOGC0xtUynjIx092vXE=
github.com/go-openapi/errors v0.22.1 h1:kslMRRnK7NCb/CvR1q1VWuEQCEIsBGn5GgKD9e+HYhU=
github.com/go-openapi/errors v0.22.1/go.mod h1:+n/5UdIqdVnLIJ6Q9Se8HNGUXYaY6CN8ImWzfi/Gzp0=
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ=
@ -133,24 +138,24 @@ github.com/go-openapi/spec v0.21.0 h1:LTVzPc3p/RzRnkQqLRndbAzjY0d0BCL72A6j3CdL9Z
github.com/go-openapi/spec v0.21.0/go.mod h1:78u6VdPw81XU44qEWGhtr982gJ5BWg2c0I5XwVMotYk=
github.com/go-openapi/strfmt v0.23.0 h1:nlUS6BCqcnAk0pyhi9Y+kdDVZdZMHfEKQiS4HaMgO/c=
github.com/go-openapi/strfmt v0.23.0/go.mod h1:NrtIpfKtWIygRkKVsxh7XQMDQW5HKQl6S5ik2elW+K4=
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU=
github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0=
github.com/go-openapi/validate v0.24.0 h1:LdfDKwNbpB6Vn40xhTdNZAnfLECL81w+VX3BumrGD58=
github.com/go-openapi/validate v0.24.0/go.mod h1:iyeX1sEufmv3nPbBdX3ieNviWnOZaJ1+zquzJEf2BAQ=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg=
github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U=
github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466 h1:sQspH8M4niEijh3PFscJRLDnkL547IeP7kpPe3uUhEg=
github.com/godbus/dbus/v5 v5.1.1-0.20230522191255-76236955d466/go.mod h1:ZiQxhyQ+bbbfxUKVvjfO498oPYvtYhZzycal3G/NHmU=
github.com/godbus/dbus/v5 v5.1.1-0.20241109141217-c266b19b28e9 h1:Kzr9J0S0V2PRxiX6B6xw1kWjzsIyjLO2Ibi4fNTaYBM=
github.com/godbus/dbus/v5 v5.1.1-0.20241109141217-c266b19b28e9/go.mod h1:3AAv2+hPq5rdnr5txxxRwiGjPXamgoIHgz9FPBfOp3c=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ=
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@ -170,15 +175,16 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-containerregistry v0.20.0 h1:wRqHpOeVh3DnenOrPy9xDOLdnLatiGuuNRVelR2gSbg=
github.com/google/go-containerregistry v0.20.0/go.mod h1:YCMFNQeeXeLF+dnhhWkqDItx/JSkH01j1Kis4PsjzFI=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/go-containerregistry v0.20.3 h1:oNx7IdTI936V8CQRveCjaxOiegWwvM7kqkbXTpyiovI=
github.com/google/go-containerregistry v0.20.3/go.mod h1:w00pIgBRDVUDFM6bq+Qx8lwNWK+cxgCuX1vd3PIBDNI=
github.com/google/go-intervals v0.0.2 h1:FGrVEiUnTRKR8yE04qzXYaJMtnIYqobR5QbblK3ixcM=
github.com/google/go-intervals v0.0.2/go.mod h1:MkaR3LNRfeKLPmqgJYs4E66z5InYjmCjbbr4TQlcT6Y=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg=
github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw=
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8=
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
@ -187,8 +193,8 @@ github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
github.com/gorilla/schema v1.4.1 h1:jUg5hUjCSDZpNGLuXQOgIWGdlgrIdYvgQ0wZtdK1M3E=
github.com/gorilla/schema v1.4.1/go.mod h1:Dg5SSm5PV60mhF2NFaTV1xuYYj8tV8NOPRo4FggUMnM=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1 h1:/c3QmbOGMGTOumP2iT/rCwB7b0QDGLKzqOmktBjT+Is=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.1/go.mod h1:5SN9VR2LTsRFsrEC6FHgRbTWrTHu6tqPeKxEQv15giM=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 h1:VNqngBF40hVlDloBruUehVYC3ArSgIyScOAyMRqBxRg=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1/go.mod h1:RBRO7fro65R6tjKzYgLAFo0t1QEXY1Dp+i/bvpRiqiQ=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
@ -206,10 +212,12 @@ github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8Hm
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU=
github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=
@ -218,12 +226,12 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/letsencrypt/boulder v0.0.0-20240418210053-89b07f4543e0 h1:aiPrFdHDCCvigNBCkOWj2lv9Bx5xDp210OANZEoiP0I=
github.com/letsencrypt/boulder v0.0.0-20240418210053-89b07f4543e0/go.mod h1:srVwm2N3DC/tWqQ+igZXDrmKlNRN8X/dmJ1wEZrv760=
github.com/letsencrypt/boulder v0.0.0-20240620165639-de9c06129bec h1:2tTW6cDth2TSgRbAhD7yjZzTQmcN25sDRPEeinR51yQ=
github.com/letsencrypt/boulder v0.0.0-20240620165639-de9c06129bec/go.mod h1:TmwEoGCwIti7BCeJ9hescZgRtatxRE+A72pCoPfmcfk=
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4=
github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU=
github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYthEiA=
github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
@ -233,10 +241,10 @@ github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-sqlite3 v1.14.28 h1:ThEiQrnbtumT+QMknw63Befp/ce/nUPgBPMlRFEum7A=
github.com/mattn/go-sqlite3 v1.14.28/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU=
github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
github.com/mistifyio/go-zfs/v3 v3.0.1 h1:YaoXgBePoMA12+S1u/ddkv+QqxcfiZK4prI6HPnkFiU=
@ -245,12 +253,20 @@ github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyua
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
github.com/moby/sys/atomicwriter v0.1.0 h1:kw5D/EqkBwsBFi0ss9v1VG3wIkVhzGvLklJ+w3A14Sw=
github.com/moby/sys/atomicwriter v0.1.0/go.mod h1:Ul8oqv2ZMNHOceF643P6FKPXeCmYtlQMvpizfsSoaWs=
github.com/moby/sys/capability v0.4.0 h1:4D4mI6KlNtWMCM1Z/K0i7RV1FkX+DBDHKVJpCndZoHk=
github.com/moby/sys/capability v0.4.0/go.mod h1:4g9IK291rVkms3LKCDOoYlnV8xKwoDTpIrNEE35Wq0I=
github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg=
github.com/moby/sys/mountinfo v0.7.2/go.mod h1:1YOa8w8Ih7uW0wALDUgT1dTTSBrZ+HiBLGws92L2RU4=
github.com/moby/sys/user v0.2.0 h1:OnpapJsRp25vkhw8TFG6OLJODNh/3rEwRWtJ3kakwRM=
github.com/moby/sys/user v0.2.0/go.mod h1:RYstrcWOJpVh+6qzUqp2bU3eaRpdiQeKGlKitaH0PM8=
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
github.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU=
github.com/moby/sys/sequential v0.6.0/go.mod h1:uyv8EUTrca5PnDsdMGXhZe6CCe8U/UiTWd+lL+7b/Ko=
github.com/moby/sys/user v0.4.0 h1:jhcMKit7SA80hivmFJcbB1vqmw//wU61Zdui2eQXuMs=
github.com/moby/sys/user v0.4.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs=
github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g=
github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28=
github.com/moby/term v0.5.2 h1:6qk3FJAFDs6i/q3W/pQ97SX192qKfZgGjCQqfCJkgzQ=
github.com/moby/term v0.5.2/go.mod h1:d3djjFCrjnB+fl8NJux+EJzu0msscUP+f8it8hPkFLc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@ -258,46 +274,52 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/navidys/tvxwidgets v0.4.1 h1:abITHN2R0AN1G5XYBDCeTBfR+E1FRsDKN5j1FKI8ags=
github.com/navidys/tvxwidgets v0.4.1/go.mod h1:VJRhOCt9q4cuqN1UebaWRAc0MG4pmpHMBWL3tRSoqdI=
github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY=
github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc=
github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA=
github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To=
github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk=
github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0=
github.com/onsi/ginkgo/v2 v2.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus=
github.com/onsi/ginkgo/v2 v2.23.4/go.mod h1:Bt66ApGPBFzHyR+JO10Zbt0Gsp4uWxu5mIOTusL46e8=
github.com/onsi/gomega v1.37.0 h1:CdEG8g0S133B4OswTDC/5XPSzE1OeP29QOioj2PID2Y=
github.com/onsi/gomega v1.37.0/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0=
github.com/opencontainers/cgroups v0.0.1 h1:MXjMkkFpKv6kpuirUa4USFBas573sSAY082B4CiHEVA=
github.com/opencontainers/cgroups v0.0.1/go.mod h1:s8lktyhlGUqM7OSRL5P7eAW6Wb+kWPNvt4qvVfzA5vs=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=
github.com/opencontainers/runc v1.1.1-0.20220617142545-8b9452f75cbc h1:qjkUzmFsOFbQyjObybk40mRida83j5IHRaKzLGdBbEU=
github.com/opencontainers/runc v1.1.1-0.20220617142545-8b9452f75cbc/go.mod h1:wUOQGsiKae6VzA/UvlCK3cO+pHk8F2VQHlIoITEfMM8=
github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk=
github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-tools v0.9.1-0.20230914150019-408c51e934dc h1:d2hUh5O6MRBvStV55MQ8we08t42zSTqBbscoQccWmMc=
github.com/opencontainers/runtime-tools v0.9.1-0.20230914150019-408c51e934dc/go.mod h1:8tx1helyqhUC65McMm3x7HmOex8lO2/v9zPuxmKHurs=
github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaLpt7tQ7oU=
github.com/opencontainers/selinux v1.11.0/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec=
github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=
github.com/opencontainers/runc v1.2.6 h1:P7Hqg40bsMvQGCS4S7DJYhUZOISMLJOB2iGX5COWiPk=
github.com/opencontainers/runc v1.2.6/go.mod h1:dOQeFo29xZKBNeRBI0B19mJtfHv68YgCTh1X+YphA+4=
github.com/opencontainers/runtime-spec v1.2.1 h1:S4k4ryNgEpxW1dzyqffOmhI1BHYcjzU8lpJfSlR0xww=
github.com/opencontainers/runtime-spec v1.2.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-tools v0.9.1-0.20250303011046-260e151b8552 h1:CkXngT0nixZqQUPDVfwVs3GiuhfTqCMk0V+OoHpxIvA=
github.com/opencontainers/runtime-tools v0.9.1-0.20250303011046-260e151b8552/go.mod h1:T487Kf80NeF2i0OyVXHiylg217e0buz8pQsa0T791RA=
github.com/opencontainers/selinux v1.12.0 h1:6n5JV4Cf+4y0KNXW48TLj5DwfXpvWlxXplUkdTrmPb8=
github.com/opencontainers/selinux v1.12.0/go.mod h1:BTPX+bjVbWGXw7ZZWUbdENt8w0htPSrlgOOysQaU62U=
github.com/ostreedev/ostree-go v0.0.0-20210805093236-719684c64e4f h1:/UDgs8FGMqwnHagNDPGOlts35QkhAZ8by3DR7nMih7M=
github.com/ostreedev/ostree-go v0.0.0-20210805093236-719684c64e4f/go.mod h1:J6OG6YJVEWopen4avK3VNQSnALmmjvniMmni/YFYAwc=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/sftp v1.13.6 h1:JFZT4XbOU7l77xGSpOdW+pwIMqP044IyjXX6FGyEKFo=
github.com/pkg/sftp v1.13.6/go.mod h1:tz1ryNURKu77RL+GuCzmoJYxQczL3wLNNpPWagdg4Qk=
github.com/pkg/sftp v1.13.9 h1:4NGkvGudBL7GteO3m6qnaQ4pC0Kvf0onSVc9gR3EWBw=
github.com/pkg/sftp v1.13.9/go.mod h1:OBN7bVXdstkFFN/gdnHPUb5TE8eb8G1Rp9wCItqjkkA=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/proglottis/gpgme v0.1.3 h1:Crxx0oz4LKB3QXc5Ea0J19K/3ICfy3ftr5exgUK1AU0=
github.com/proglottis/gpgme v0.1.3/go.mod h1:fPbW/EZ0LvwQtH8Hy7eixhp1eF3G39dtx7GUN+0Gmy0=
github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU=
github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k=
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
github.com/proglottis/gpgme v0.1.4 h1:3nE7YNA70o2aLjcg63tXMOhPD7bplfE5CBdV+hLAm2M=
github.com/proglottis/gpgme v0.1.4/go.mod h1:5LoXMgpE4bttgwwdv9bLs/vwqv3qV7F4glEEZ7mRKrM=
github.com/prometheus/client_golang v1.21.1 h1:DOvXXTqVzvkIewV/CDPFdejpMCGeMcbGCQ8YOmu+Ibk=
github.com/prometheus/client_golang v1.21.1/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos=
github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8=
github.com/prometheus/common v0.51.1 h1:eIjN50Bwglz6a/c3hAgSMcofL3nD+nFQkV6Dd4DsQCw=
github.com/prometheus/common v0.51.1/go.mod h1:lrWtQx+iDfn2mbH5GUzlH9TSHyfZpHkSiG1W7y3sF2Q=
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io=
github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I=
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
github.com/rivo/tview v0.0.0-20220307222120-9994674d60a8 h1:xe+mmCnDN82KhC010l3NfYlA8ZbOuzbXAzSYBa6wbMc=
@ -306,30 +328,38 @@ github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ
github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8=
github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY=
github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sebdah/goldie/v2 v2.5.3 h1:9ES/mNN+HNUbNWpVAlrzuZ7jE+Nrczbj8uFRjM7624Y=
github.com/sebdah/goldie/v2 v2.5.3/go.mod h1:oZ9fp0+se1eapSRjfYbsV/0Hqhbuu3bJVvKI/NNtssI=
github.com/secure-systems-lab/go-securesystemslib v0.8.0 h1:mr5An6X45Kb2nddcFlbmfHkLguCE9laoZCUzEEpIZXA=
github.com/secure-systems-lab/go-securesystemslib v0.8.0/go.mod h1:UH2VZVuJfCYR8WgMlCU1uFsOUU+KeyrTWcSS73NBOzU=
github.com/santhosh-tekuri/jsonschema/v6 v6.0.1 h1:PKK9DyHxif4LZo+uQSgXNqs0jj5+xZwwfKHgph2lxBw=
github.com/santhosh-tekuri/jsonschema/v6 v6.0.1/go.mod h1:JXeL+ps8p7/KNMjDQk3TCwPpBy0wYklyWTfbkIzdIFU=
github.com/sebdah/goldie/v2 v2.5.5 h1:rx1mwF95RxZ3/83sdS4Yp7t2C5TCokvWP4TBRbAyEWY=
github.com/sebdah/goldie/v2 v2.5.5/go.mod h1:oZ9fp0+se1eapSRjfYbsV/0Hqhbuu3bJVvKI/NNtssI=
github.com/secure-systems-lab/go-securesystemslib v0.9.0 h1:rf1HIbL64nUpEIZnjLZ3mcNEL9NBPB0iuVjyxvq3LZc=
github.com/secure-systems-lab/go-securesystemslib v0.9.0/go.mod h1:DVHKMcZ+V4/woA/peqr+L0joiRXbPpQ042GgJckkFgw=
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
github.com/sigstore/fulcio v1.4.5 h1:WWNnrOknD0DbruuZWCbN+86WRROpEl3Xts+WT2Ek1yc=
github.com/sigstore/fulcio v1.4.5/go.mod h1:oz3Qwlma8dWcSS/IENR/6SjbW4ipN0cxpRVfgdsjMU8=
github.com/sigstore/rekor v1.3.6 h1:QvpMMJVWAp69a3CHzdrLelqEqpTM3ByQRt5B5Kspbi8=
github.com/sigstore/rekor v1.3.6/go.mod h1:JDTSNNMdQ/PxdsS49DJkJ+pRJCO/83nbR5p3aZQteXc=
github.com/sigstore/sigstore v1.8.4 h1:g4ICNpiENFnWxjmBzBDWUn62rNFeny/P77HUC8da32w=
github.com/sigstore/sigstore v1.8.4/go.mod h1:1jIKtkTFEeISen7en+ZPWdDHazqhxco/+v9CNjc7oNg=
github.com/sigstore/fulcio v1.6.6 h1:XaMYX6TNT+8n7Npe8D94nyZ7/ERjEsNGFC+REdi/wzw=
github.com/sigstore/fulcio v1.6.6/go.mod h1:BhQ22lwaebDgIxVBEYOOqLRcN5+xOV+C9bh/GUXRhOk=
github.com/sigstore/protobuf-specs v0.4.1 h1:5SsMqZbdkcO/DNHudaxuCUEjj6x29tS2Xby1BxGU7Zc=
github.com/sigstore/protobuf-specs v0.4.1/go.mod h1:+gXR+38nIa2oEupqDdzg4qSBT0Os+sP7oYv6alWewWc=
github.com/sigstore/rekor v1.3.10 h1:/mSvRo4MZ/59ECIlARhyykAlQlkmeAQpvBPlmJtZOCU=
github.com/sigstore/rekor v1.3.10/go.mod h1:JvryKJ40O0XA48MdzYUPu0y4fyvqt0C4iSY7ri9iu3A=
github.com/sigstore/sigstore v1.9.3 h1:y2qlTj+vh+Or3ictKuR3JUFawZPdDxAjrWkeFhon0OQ=
github.com/sigstore/sigstore v1.9.3/go.mod h1:VwYkiw0G0dRtwL25KSs04hCyVFF6CYMd/qvNeYrl7EQ=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/skeema/knownhosts v1.3.1 h1:X2osQ+RAjK76shCbvhHHHVl3ZlgDm8apHEHFqRjnBY8=
github.com/skeema/knownhosts v1.3.1/go.mod h1:r7KTdC8l4uxWRyK2TpQZ/1o5HaSzh06ePQNxPwTcfiY=
github.com/smallstep/pkcs7 v0.1.1 h1:x+rPdt2W088V9Vkjho4KtoggyktZJlMduZAtRHm68LU=
github.com/smallstep/pkcs7 v0.1.1/go.mod h1:dL6j5AIz9GHjVEBTXtW+QliALcgM19RtXaTeyxI+AfA=
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6 h1:pnnLyeX7o/5aX8qUQ69P/mLojDqwda8hFOCBTmP/6hw=
github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6/go.mod h1:39R/xuhNgVhi+K0/zst4TLrJrVmbm6LVgl4A0+ZFS5M=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@ -340,22 +370,22 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/sylabs/sif/v2 v2.18.0 h1:eXugsS1qx7St2Wu/AJ21KnsQiVCpouPlTigABh+6KYI=
github.com/sylabs/sif/v2 v2.18.0/go.mod h1:GOQj7LIBqp15fjqH5i8ZEbLp8SXJi9S+xbRO+QQAdRo=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/sylabs/sif/v2 v2.21.1 h1:GZ0b5//AFAqJEChd8wHV/uSKx/l1iuGYwjR8nx+4wPI=
github.com/sylabs/sif/v2 v2.21.1/go.mod h1:YoqEGQnb5x/ItV653bawXHZJOXQaEWpGwHsSD3YePJI=
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI=
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/tchap/go-patricia/v2 v2.3.1 h1:6rQp39lgIYZ+MHmdEq4xzuk1t7OdC35z/xm0BGhTkes=
github.com/tchap/go-patricia/v2 v2.3.1/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k=
github.com/tchap/go-patricia/v2 v2.3.2 h1:xTHFutuitO2zqKAQ5rCROYgUb7Or/+IC3fts9/Yc7nM=
github.com/tchap/go-patricia/v2 v2.3.2/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k=
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 h1:e/5i7d4oYZ+C1wj2THlRK+oAhjeS/TRQwMfkIuet3w0=
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399/go.mod h1:LdwHTNJT99C5fTAzDz0ud328OgXz+gierycbcIx2fRs=
github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc=
github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/vbatts/tar-split v0.11.5 h1:3bHCTIheBm1qFTcgh9oPu+nNBtX+XJIupG/vacinCts=
github.com/vbatts/tar-split v0.11.5/go.mod h1:yZbwRsSeGjusneWgA781EKej9HF8vme8okylkAeNKLk=
github.com/vbauerster/mpb/v8 v8.7.4 h1:p4f16iMfUt3PkAC73SCzAtgtSf8TYDqEbJUT3odPrPo=
github.com/vbauerster/mpb/v8 v8.7.4/go.mod h1:r1B5k2Ljj5KJFCekfihbiqyV4VaaRTANYmvWA2btufI=
github.com/vbatts/tar-split v0.12.1 h1:CqKoORW7BUWBe7UL/iqTVvkTBOF8UvOMKOIZykxnnbo=
github.com/vbatts/tar-split v0.12.1/go.mod h1:eF6B6i6ftWQcDqEn3/iGFRFRo8cBIMSJVOpnNdfTMFA=
github.com/vbauerster/mpb/v8 v8.9.3 h1:PnMeF+sMvYv9u23l6DO6Q3+Mdj408mjLRXIzmUmU2Z8=
github.com/vbauerster/mpb/v8 v8.9.3/go.mod h1:hxS8Hz4C6ijnppDSIX6LjG8FYJSoPo9iIOcE53Zik0c=
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
@ -367,36 +397,42 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.mongodb.org/mongo-driver v1.14.0 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd80=
go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c=
go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352 h1:CCriYyAfq1Br1aIYettdHZTy8mBTIPo7We18TuO/bak=
go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk=
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw=
go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo=
go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.22.0 h1:9M3+rhx7kZCIQQhQRYaZCdNu1V73tm4TvXs2ntl98C4=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.22.0/go.mod h1:noq80iT8rrHP1SfybmPiRGc9dc5M8RPmGvtwo7Oo7tc=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0 h1:digkEZCJWobwBqMwC0cwCq8/wkkRy/OowZg5OArWZrM=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0/go.mod h1:/OpE/y70qVkndM0TrxT4KBoN3RsFZP0QaofcfYrj76I=
go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI=
go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco=
go.opentelemetry.io/otel/sdk v1.24.0 h1:YMPPDNymmQN3ZgczicBY3B6sf9n62Dlj9pWD3ucgoDw=
go.opentelemetry.io/otel/sdk v1.24.0/go.mod h1:KVrIYw6tEubO9E96HQpcmpTKDVn9gdv35HoYiQWGDFg=
go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI=
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I=
go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM=
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 h1:CV7UdSGJt/Ao6Gp4CXckLxVRRsRgDHoI8XjbL3PDl8s=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0/go.mod h1:FRmFuRJfag1IZ2dPkHnEoSFVgTVPUd2qf5Vi69hLb8I=
go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0 h1:Vh5HayB/0HHfOQA7Ctx69E/Y/DcQSMPpKANYVMQ7fBA=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0/go.mod h1:cpgtDBaqD/6ok/UG0jT15/uKjAY8mRA53diogHBg3UI=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.33.0 h1:wpMfgF8E1rkrT1Z6meFh1NDtownE9Ii3n3X2GJYjsaU=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.33.0/go.mod h1:wAy0T/dUbs468uOlkT31xjvqQgEVXv58BRFWEgn5v/0=
go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk=
go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w=
go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
go.opentelemetry.io/proto/otlp v1.4.0 h1:TA9WRvW6zMwP+Ssb6fLoUIuirti1gGbP28GcKG1jgeg=
go.opentelemetry.io/proto/otlp v1.4.0/go.mod h1:PPBWZIP98o2ElSqI35IHfu7hIhSwvc5N38Jw8pXuGFY=
go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM=
golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY=
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
@ -404,6 +440,9 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -415,10 +454,13 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY=
golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -427,8 +469,12 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8=
golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -443,35 +489,45 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220817070843-5a390386f1f2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk=
golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4=
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg=
golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0=
golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
@ -482,8 +538,10 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
golang.org/x/tools v0.33.0 h1:4qz2S3zmRxbGIhDIAgjxvFutSvH5EfnsYrRBj0UI0bc=
golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@ -493,18 +551,17 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20240311173647-c811ad7063a7 h1:ImUcDPHjTrAqNhlOkSocDLfG9rrNHH7w7uoKWPaWZ8s=
google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237 h1:RFiFrvy37/mpSpdySBDrUdipW/dHwsRwh3J3+A9VgT4=
google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237/go.mod h1:Z5Iiy3jtmioajWHDGFk7CeugTyHtPvMHA4UTmUkyalE=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 h1:NnYq6UN9ReLM9/Y01KWNOWyI5xQ9kbIms5GGJVwS/Yc=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY=
google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb h1:p31xT4yrYrSM/G4Sn2+TNUkVhFCbG9y8itM2S6Th950=
google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250313205543-e70fdf4c4cb4 h1:iK2jbkWL86DXjEx0qiHcRE9dE4/Ahua5k6V8OWFb//c=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250313205543-e70fdf4c4cb4/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc v1.64.1 h1:LKtvyfbX3UGVPFcGqJ9ItpVWW6oN/2XqTxfAnwRRXiA=
google.golang.org/grpc v1.64.1/go.mod h1:hiQF4LFZelK2WKaP6W0L92zGHtiQdZxk8CrSdvyjeP0=
google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg=
google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@ -514,8 +571,8 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
@ -524,13 +581,11 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU=
gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU=
gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q=
gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
tags.cncf.io/container-device-interface v0.8.0 h1:8bCFo/g9WODjWx3m6EYl3GfUG31eKJbaggyBDxEldRc=
tags.cncf.io/container-device-interface v0.8.0/go.mod h1:Apb7N4VdILW0EVdEMRYXIDVRZfNJZ+kmEUss2kRRQ6Y=
tags.cncf.io/container-device-interface v1.0.1 h1:KqQDr4vIlxwfYh0Ed/uJGVgX+CHAkahrgabg6Q8GYxc=
tags.cncf.io/container-device-interface v1.0.1/go.mod h1:JojJIOeW3hNbcnOH2q0NrWNha/JuHoDZcmYxAZwb2i0=

View File

@ -23,11 +23,16 @@ var ErrInvalidCreateTimeout = errors.New("invalid container create timeout value
// CreateOptions container create options.
type CreateOptions struct {
Name string
Command string
Labels []string
Image string
Remove bool
Privileged bool
Timeout string
Interactive bool
TTY bool
Detach bool
Secret []string
WorkDir string
EnvVars []string
EnvFile []string
@ -71,12 +76,39 @@ type CreateOptions struct {
HealthStartupRetries string
HealthStartupSuccess string
HealthStartupTimeout string
HealthLogDestination string
HealthMaxLogSize string
HealthMaxLogCount string
Memory string
MemoryReservation string
MemorySwap string
MemorySwappiness string
CPUs string
CPUShares string
CPUPeriod string
CPUQuota string
CPURtPeriod string
CPURtRuntime string
CPUSetCPUs string
CPUSetMems string
SHMSize string
SHMSizeSystemd string
NamespaceCgroup string
NamespacePid string
NamespaceIpc string
NamespaceUser string
NamespaceUts string
NamespaceUidmap string
NamespaceSubuidName string
NamespaceGidmap string
NamespaceSubgidName string
}
// Create creates a new container.
func Create(opts CreateOptions) ([]string, error) { //nolint:cyclop,gocognit,gocyclo
func Create(opts CreateOptions, run bool) ([]string, string, error) { //nolint:cyclop,gocognit,gocyclo,maintidx
var (
warningResponse []string
containerID string
createOptions entities.ContainerCreateOptions
)
@ -85,7 +117,7 @@ func Create(opts CreateOptions) ([]string, error) { //nolint:cyclop,gocognit,goc
conn, err := registry.GetConnection()
if err != nil {
return warningResponse, err
return warningResponse, containerID, err
}
if len(opts.Labels) > 0 {
@ -99,10 +131,10 @@ func Create(opts CreateOptions) ([]string, error) { //nolint:cyclop,gocognit,goc
if opts.Timeout != "" {
timeout, err := strconv.Atoi(opts.Timeout)
if err != nil {
return warningResponse, fmt.Errorf("%w: %s", ErrInvalidCreateTimeout, opts.Timeout)
return warningResponse, containerID, fmt.Errorf("%w: %s", ErrInvalidCreateTimeout, opts.Timeout)
}
createOptions.Timeout = uint(timeout)
createOptions.Timeout = uint(timeout) //nolint:gosec
}
createOptions.Hostname = opts.Hostname
@ -115,7 +147,7 @@ func Create(opts CreateOptions) ([]string, error) { //nolint:cyclop,gocognit,goc
createOptions.Net, err = containerNetworkOptions(opts)
if err != nil {
return warningResponse, err
return warningResponse, containerID, err
}
if opts.Pod != "" {
@ -211,31 +243,179 @@ func Create(opts CreateOptions) ([]string, error) { //nolint:cyclop,gocognit,goc
createOptions.GroupEntry = opts.GroupEntry
}
// add secrets
if len(opts.Secret) > 0 {
createOptions.Secrets = opts.Secret
}
if run {
createOptions.Interactive = opts.Interactive
createOptions.TTY = opts.TTY
}
// add healthcheck options
if err := containerHealthOptions(&createOptions, opts); err != nil {
return warningResponse, err
return warningResponse, containerID, err
}
// add resources
if opts.Memory != "" {
createOptions.Memory = opts.Memory
}
if opts.MemoryReservation != "" {
createOptions.MemoryReservation = opts.MemoryReservation
}
if opts.MemorySwap != "" {
createOptions.MemorySwap = opts.MemorySwap
}
if opts.MemorySwappiness != "" {
val, err := strconv.Atoi(opts.MemorySwappiness)
if err != nil {
return warningResponse, containerID, err
}
createOptions.MemorySwappiness = int64(val)
}
if opts.CPUs != "" {
val, err := strconv.ParseFloat(opts.CPUs, 64)
if err != nil {
return warningResponse, containerID, err
}
createOptions.CPUS = val
}
if opts.CPUShares != "" {
val, err := strconv.ParseUint(opts.CPUShares, 10, 64)
if err != nil {
return warningResponse, containerID, err
}
createOptions.CPUShares = val
}
if opts.CPUPeriod != "" {
val, err := strconv.ParseUint(opts.CPUPeriod, 10, 64)
if err != nil {
return warningResponse, containerID, err
}
createOptions.CPUPeriod = val
}
if opts.CPURtPeriod != "" {
val, err := strconv.ParseUint(opts.CPURtPeriod, 10, 64)
if err != nil {
return warningResponse, containerID, err
}
createOptions.CPURTPeriod = val
}
if opts.CPUQuota != "" {
val, err := strconv.Atoi(opts.CPUQuota)
if err != nil {
return warningResponse, containerID, err
}
createOptions.CPUQuota = int64(val)
}
if opts.CPURtRuntime != "" {
val, err := strconv.Atoi(opts.CPURtRuntime)
if err != nil {
return warningResponse, containerID, err
}
createOptions.CPURTRuntime = int64(val)
}
if opts.CPUSetCPUs != "" {
createOptions.CPUSetCPUs = opts.CPUSetCPUs
}
if opts.CPUSetMems != "" {
createOptions.CPUSetMems = opts.CPUSetMems
}
if opts.SHMSize != "" {
createOptions.ShmSize = opts.SHMSize
}
if opts.SHMSizeSystemd != "" {
createOptions.ShmSizeSystemd = opts.SHMSizeSystemd
}
// namespace options
if opts.NamespaceCgroup != "" {
createOptions.CgroupNS = opts.NamespaceCgroup
}
if opts.NamespaceIpc != "" {
createOptions.IPC = opts.NamespaceIpc
}
if opts.NamespacePid != "" {
createOptions.PID = opts.NamespacePid
}
if opts.NamespaceUser != "" {
createOptions.UserNS = opts.NamespaceUser
}
if opts.NamespaceUts != "" {
createOptions.UTS = opts.NamespaceUts
}
if opts.NamespaceUidmap != "" {
createOptions.UIDMap = []string{opts.NamespaceUidmap}
}
if opts.NamespaceSubuidName != "" {
createOptions.SubUIDName = opts.NamespaceSubuidName
}
if opts.NamespaceGidmap != "" {
createOptions.GIDMap = []string{opts.NamespaceGidmap}
}
if opts.NamespaceSubgidName != "" {
createOptions.SubGIDName = opts.NamespaceSubgidName
}
// generate spec
s := specgen.NewSpecGenerator(opts.Name, false)
if err := specgenutil.FillOutSpecGen(s, &createOptions, nil); err != nil {
return warningResponse, err
return warningResponse, containerID, err
}
// container image
s.Image = opts.Image
// command
cmd := strings.TrimSpace(opts.Command)
if cmd != "" {
s.Command = strings.Split(cmd, " ")
}
// validate spec
if err := s.Validate(); err != nil {
return warningResponse, err
return warningResponse, containerID, err
}
response, err := containers.CreateWithSpec(conn, s, &containers.CreateOptions{})
if err != nil {
return warningResponse, err
return warningResponse, containerID, err
}
warningResponse = response.Warnings
containerID = response.ID
return warningResponse, nil
return warningResponse, containerID, nil
}
func containerHealthOptions(createOptions *entities.ContainerCreateOptions, opts CreateOptions) error { //nolint:cyclop
@ -246,6 +426,7 @@ func containerHealthOptions(createOptions *entities.ContainerCreateOptions, opts
createOptions.HealthTimeout = define.DefaultHealthCheckTimeout
createOptions.StartupHCTimeout = define.DefaultHealthCheckTimeout
createOptions.HealthOnFailure = opts.HealthOnFailure
createOptions.HealthLogDestination = opts.HealthLogDestination
if opts.HealthCmd == "" {
createOptions.HealthCmd = "none"
@ -255,6 +436,26 @@ func containerHealthOptions(createOptions *entities.ContainerCreateOptions, opts
createOptions.HealthCmd = opts.HealthCmd
if opts.HealthMaxLogCount != "" {
logCount, err := strconv.ParseUint(opts.HealthMaxLogCount, 10, 32)
if err != nil {
return err
}
logCountWd := uint(logCount)
createOptions.HealthMaxLogCount = logCountWd
}
if opts.HealthMaxLogSize != "" {
logSize, err := strconv.ParseUint(opts.HealthMaxLogSize, 10, 32)
if err != nil {
return err
}
logSizeWd := uint(logSize)
createOptions.HealthMaxLogSize = logSizeWd
}
if opts.HealthInterval != "" {
createOptions.HealthInterval = opts.HealthInterval
}

View File

@ -89,7 +89,7 @@ func ResizeExecTty(id string, height int, width int) {
}
}
// Exec returns the diff of the specified container ID.
// Exec executes command in a given sessionOD.
func Exec(sessionID string, opts ExecOption) { //nolint:cyclop
log.Debug().Msgf("pdcs: podman container session (%s) exec %v", sessionID, opts)

View File

@ -10,7 +10,7 @@ import (
// Prune removes all non running containers.
func Prune() ([]string, error) {
log.Debug().Msgf("pdcs: podman container purne")
log.Debug().Msgf("pdcs: podman container prune")
var report []string

32
pdcs/containers/run.go Normal file
View File

@ -0,0 +1,32 @@
package containers
import (
"io"
"github.com/containers/podman-tui/pdcs/registry"
"github.com/containers/podman/v5/pkg/bindings/containers"
"github.com/rs/zerolog/log"
)
// RunInitAttach will init container for run and attach.
func RunInitAttach(cntID string, stdin io.Reader, stdout io.Writer, attachReady chan bool, detachKey string) error {
log.Debug().Msgf("pdcs: podman container run init attach %s", cntID)
conn, err := registry.GetConnection()
if err != nil {
return err
}
attachOptions := new(containers.AttachOptions)
attachOptions.WithDetachKeys(detachKey)
if err := containers.ContainerInit(conn, cntID, new(containers.InitOptions)); err != nil {
return err
}
if err := containers.Attach(conn, cntID, stdin, stdout, stdout, attachReady, attachOptions); err != nil {
return err
}
return nil
}

View File

@ -13,7 +13,7 @@ import (
func Top(id string) ([][]string, error) {
log.Debug().Msgf("pdcs: podman container top %s", id)
var report [][]string
report := [][]string{}
conn, err := registry.GetConnection()
if err != nil {
@ -25,7 +25,7 @@ func Top(id string) ([][]string, error) {
return report, err
}
for i := 0; i < len(response); i++ {
for i := range response {
space := regexp.MustCompile(`\s+`)
line := space.ReplaceAllString(response[i], " ")
split := strings.Split(line, " ")

View File

@ -14,7 +14,7 @@ import (
func History(id string) ([][]string, error) {
log.Debug().Msgf("pdcs: podman image history %s", id)
var report [][]string
report := [][]string{}
conn, err := registry.GetConnection()
if err != nil {
@ -26,7 +26,7 @@ func History(id string) ([][]string, error) {
return report, err
}
for i := 0; i < len(response); i++ {
for i := range response {
report = append(report, []string{
response[i].ID,
units.HumanDuration(time.Since(time.Unix(response[i].Created, 0))) + " ago",

View File

@ -47,7 +47,7 @@ func Save(imageID string, opts ImageSaveOptions) error { //nolint:cyclop
defer outputFile.Close()
cancelChan := make(chan bool, 1)
writerChan := make(chan []byte, 1024) //nolint:gomnd
writerChan := make(chan []byte, 1024) //nolint:mnd
outputWriter := channel.NewWriter(writerChan)
writeOutputFunc := func() {

View File

@ -3,8 +3,10 @@ package pods
import (
"encoding/json"
"net"
"strconv"
"github.com/containers/common/libnetwork/types"
"github.com/containers/common/pkg/config"
"github.com/containers/podman-tui/pdcs/registry"
"github.com/containers/podman-tui/pdcs/utils"
"github.com/containers/podman/v5/pkg/bindings/pods"
@ -12,33 +14,48 @@ import (
"github.com/containers/podman/v5/pkg/errorhandling"
"github.com/containers/podman/v5/pkg/specgen"
"github.com/containers/podman/v5/pkg/specgenutil"
"github.com/containers/podman/v5/pkg/util"
"github.com/pkg/errors"
"github.com/rs/zerolog/log"
)
// CreateOptions implements pods create spec options.
type CreateOptions struct {
Name string
NoHost bool
Labels map[string]string
DNSServer []string
DNSOptions []string
DNSSearchDomain []string
Infra bool
InfraCommand string
InfraImage string
Hostname string
IPAddress string
MacAddress string
AddHost []string
Network string
Publish []string
SecurityOpts []string
Name string
NoHost bool
Labels map[string]string
DNSServer []string
DNSOptions []string
DNSSearchDomain []string
Infra bool
InfraCommand string
InfraImage string
Hostname string
IPAddress string
MacAddress string
AddHost []string
Network string
Publish []string
SecurityOpts []string
Memory string
MemorySwap string
CPUs string
CPUShares string
CPUSetCPUs string
CPUSetMems string
ShmSize string
ShmSizeSystemd string
NamespaceShare []string
NamespacePid string
NamespaceUser string
NamespaceUts string
NamespaceUidmap string
NamespaceSubuidName string
NamespaceGidmap string
NamespaceSubgidName string
}
// Create creates a new pod.
func Create(opts CreateOptions) error { //nolint:cyclop
func Create(opts CreateOptions) error { //nolint:cyclop,gocognit,gocyclo
log.Debug().Msgf("pdcs: podman pod create %v", opts)
var createOptions entities.PodCreateOptions
@ -57,6 +74,88 @@ func Create(opts CreateOptions) error { //nolint:cyclop
createOptions.Name = opts.Name
createOptions.Labels = opts.Labels
createOptions.Infra = opts.Infra
// resources
if opts.Memory != "" {
infraOptions.Memory = opts.Memory
}
if opts.MemorySwap != "" {
infraOptions.MemorySwap = opts.MemorySwap
}
if opts.CPUs != "" {
val, err := strconv.ParseFloat(opts.CPUs, 64)
if err != nil {
return err
}
infraOptions.CPUS = val
}
if opts.CPUShares != "" {
val, err := strconv.ParseUint(opts.CPUShares, 10, 64)
if err != nil {
return err
}
infraOptions.CPUShares = val
}
if opts.CPUSetCPUs != "" {
infraOptions.CPUSetCPUs = opts.CPUSetCPUs
}
if opts.CPUSetMems != "" {
infraOptions.CPUSetMems = opts.CPUSetMems
}
if opts.ShmSize != "" {
infraOptions.ShmSize = opts.ShmSize
}
if opts.ShmSizeSystemd != "" {
infraOptions.ShmSizeSystemd = opts.ShmSizeSystemd
}
// namespace
if len(opts.NamespaceShare) > 0 {
createOptions.Share = opts.NamespaceShare
}
if opts.NamespacePid != "" {
createOptions.Pid = opts.NamespacePid
}
if opts.NamespaceUser != "" {
userns, err := specgen.ParseUserNamespace(opts.NamespaceUser)
if err != nil {
return err
}
createOptions.Userns = userns
}
if opts.NamespaceUts != "" {
createOptions.Uts = opts.NamespaceUts
}
if opts.NamespaceUidmap != "" {
infraOptions.UIDMap = []string{opts.NamespaceUidmap}
}
if opts.NamespaceSubuidName != "" {
infraOptions.SubUIDName = opts.NamespaceSubuidName
}
if opts.NamespaceGidmap != "" {
infraOptions.GIDMap = []string{opts.NamespaceGidmap}
}
if opts.NamespaceSubgidName != "" {
infraOptions.SubGIDName = opts.NamespaceSubgidName
}
// network options
podNetworkOptions, err := podNetworkOptions(opts)
@ -64,13 +163,16 @@ func Create(opts CreateOptions) error { //nolint:cyclop
return err
}
createOptions.Infra = opts.Infra
if createOptions.Infra {
if createOptions.Infra { //nolint:nestif
if opts.InfraImage != "" {
createOptions.InfraImage = opts.InfraImage
} else {
createOptions.InfraImage = defaultPodInfraImage()
infraImage, err := defaultPodInfraImage()
if err != nil {
return err
}
createOptions.InfraImage = infraImage
}
infraOptions.Net = podNetworkOptions
@ -140,10 +242,13 @@ func Create(opts CreateOptions) error { //nolint:cyclop
return nil
}
func defaultPodInfraImage() string {
containerConfig := util.DefaultContainerConfig()
func defaultPodInfraImage() (string, error) {
containerConfig, err := config.Default()
if err != nil {
return "", err
}
return containerConfig.Engine.InfraImage
return containerConfig.Engine.InfraImage, nil
}
func podNetworkOptions(opts CreateOptions) (*entities.NetOptions, error) { //nolint:cyclop

View File

@ -10,7 +10,7 @@ import (
// Prune removes all stop pods.
func Prune() ([]string, error) {
log.Debug().Msgf("pdcs: podman pod purne")
log.Debug().Msgf("pdcs: podman pod prune")
var report []string

View File

@ -14,7 +14,7 @@ import (
func Top(id string) ([][]string, error) {
log.Debug().Msgf("pdcs: podman pod top %s", id)
var report [][]string
report := [][]string{}
conn, err := registry.GetConnection()
if err != nil {
@ -26,7 +26,7 @@ func Top(id string) ([][]string, error) {
return report, err
}
for i := 0; i < len(response); i++ {
for i := range response {
if response[i] == "" {
continue
}

View File

@ -140,7 +140,7 @@ func (dfsum *DfSummary) Size() string {
// Reclaimable returns reclaimable value of df summary.
func (dfsum *DfSummary) Reclaimable() string {
percent := int(float64(dfsum.reclaimable)/float64(dfsum.size)) * 100 //nolint:gomnd
percent := int(float64(dfsum.reclaimable)/float64(dfsum.size)) * 100 //nolint:mnd
return fmt.Sprintf("%s (%d%%)", units.HumanSize(float64(dfsum.reclaimable)), percent)
}

View File

@ -3,15 +3,15 @@ package sysinfo
import (
"github.com/containers/podman-tui/pdcs/registry"
"github.com/containers/podman/v5/pkg/bindings/system"
"github.com/containers/podman/v5/pkg/domain/entities"
"github.com/containers/podman/v5/pkg/domain/entities/types"
)
// Events returns libpod events.
func Events(eventChan chan entities.Event, cancelChan chan bool) error {
func Events(eventChan chan types.Event, cancelChan chan bool) error {
conn, err := registry.GetConnection()
if err != nil {
return err
}
return system.Events(conn, eventChan, cancelChan, new(system.EventsOptions))
return system.Events(conn, eventChan, cancelChan, new(system.EventsOptions).WithStream(true))
}

View File

@ -39,8 +39,8 @@ func SysInfo() (*SystemInfo, error) {
info.Kernel = response.Host.Kernel
memUsed := response.Host.MemTotal - response.Host.MemFree
swapUsed := response.Host.SwapTotal - response.Host.SwapFree
info.MemUsagePC = float64(memUsed*100) / float64(response.Host.MemTotal) //nolint:gomnd
info.SwapUsagePC = float64(swapUsed*100) / float64(response.Host.SwapTotal) //nolint:gomnd
info.MemUsagePC = float64(memUsed*100) / float64(response.Host.MemTotal) //nolint:mnd
info.SwapUsagePC = float64(swapUsed*100) / float64(response.Host.SwapTotal) //nolint:mnd
info.Runtime = response.Host.OCIRuntime.Version
info.BuildahVersion = response.Host.BuildahVersion

View File

@ -12,7 +12,7 @@ import (
// SizeToStr converts size to human readable format.
func SizeToStr(size int64) string {
return units.HumanSizeWithPrecision(float64(size), 3) //nolint:gomnd
return units.HumanSizeWithPrecision(float64(size), 3) //nolint:mnd
}
// CreatedToStr converts duration to human readable format.

View File

@ -15,8 +15,8 @@
%global git0 https://%{import_path}
Name: podman-tui
Version: 1.2.0
Release: 1%{?dist}
Version: 1.7.0
Release: dev.1%{?dist}
Summary: Podman Terminal User Interface
License: ASL 2.0
URL: %{git0}
@ -60,6 +60,65 @@ install -p ./bin/%{name} %{buildroot}%{_bindir}
%{_bindir}/%{name}
%changelog
* Wed May 28 2025 Navid Yaghoobi <navidys@fedoraproject.org> 1.7.0-dev-1
* Wed May 28 2025 Navid Yaghoobi <navidys@fedoraproject.org> 1.6.0-1
- Added container create health log dest, max count and size options
- Set default values for container create/run health log options
- Fix bats test for network connect
- Running golang-lint
- Bump github.com/containers/podman/v5 from 5.4.2 to 5.5.0
- Bump github.com/containers/buildah from 1.39.4 to 1.40.0
- Bump github.com/containers/common from 0.62.3 to 0.63.0
- Bump github.com/containers/storage from 1.57.2 to 1.58.0
- Bump github.com/onsi/ginkgo/v2 from 2.22.2 to 2.23.4
- Bump github.com/onsi/gomega from 1.36.2 to 1.37.0
- Bump golang.org/x/net from 0.36.0 to 0.38.0
- Bump golang.org/x/crypto from 0.36.0 to 0.38.0
* Sun Apr 06 2025 Navid Yaghoobi <navidys@fedoraproject.org> 1.5.0-1
- Go update to v1.23.0 + Golangci-lint update to v1.64.4
- UI input check trim spaces
- New feature - pod create resource settings category
- Fix Vagrantbox hostname
- Fix view's dialogs focus issue
- Exec and run vterm container ID and name display issue fix
- Added bats tests for container run cmd
- Vagrantfile box version update to fedora/41-cloud-base
- UI dialog size adjustments
- New feature - container create resource settings category
- View sub dialog size adjustments
- New feature - container run
- Container exec terminal size change
- Container create dialog secret option
- Fix wrong function name
- Bump github.com/containers/podman/v5 to 5.4.2
- Bump github.com/rs/zerolog to 1.34.0
- Bump github.com/containers/buildah to 1.39.4
- Bump github.com/BurntSushi/toml to 1.5.0
- Bump github.com/containers/common to 0.62.3
- Bump github.com/containers/storage to 1.57.2
- Bump golang.org/x/net to 0.36.0
- Bump golang.org/x/crypto to 0.36.0
* Sat Mar 01 2025 Navid Yaghoobi <navidys@fedoraproject.org> 1.4.0-1
- Bump github.com/containers/podman/v5 to v5.4.0
- Bump github.com/containers/buildah to v1.39.1
- Bump github.com/containers/common to v0.62.0
- Bump github.com/containers/storage to v1.57.1
- Bump golang.org/x/crypto to v0.33.0
- Bump github.com/go-jose/go-jose/v4 to 4.0.5
- Bump github.com/spf13/cobra to 1.9.1
- Bugfix panic in system events
- Docs update - merge README(s)
* Sun Dec 01 2024 Navid Yaghoobi <navidys@fedoraproject.org> 1.3.0-1
- Bump github.com/containers/podman/v5 to v5.3.1
- Bump github.com/containers/buildah to v1.38.0
- Bump github.com/containers/common to v0.61.0
- Bump github.com/containers/storage to v1.56.0
- Fix event reader channel close after receiving first event
* Sat Aug 03 2024 Navid Yaghoobi <navidys@fedoraproject.org> 1.2.0-1
- New feature - secrets page
- Secret create and remove command

View File

@ -8,8 +8,7 @@ import (
"github.com/containers/podman-tui/pdcs/registry"
"github.com/containers/podman-tui/pdcs/sysinfo"
"github.com/containers/podman/v5/pkg/domain/entities"
"github.com/docker/docker/api/types/events"
"github.com/containers/podman/v5/pkg/domain/entities/types"
"github.com/rs/zerolog/log"
)
@ -18,7 +17,7 @@ var eventChannelSize = 20
type podmanEvents struct {
mu sync.Mutex
status bool
eventChan chan entities.Event
eventChan chan types.Event
eventCancelChan chan bool
cancelChan chan bool
eventBuffer []string
@ -36,28 +35,17 @@ func (engine *Engine) startEventStreamer() {
engine.sysEvents.messageBuffer = []string{}
engine.sysEvents.cancelChan = make(chan bool)
engine.sysEvents.eventCancelChan = make(chan bool)
engine.sysEvents.eventChan = make(chan entities.Event, eventChannelSize)
engine.sysEvents.eventChan = make(chan types.Event, eventChannelSize)
engine.sysEvents.mu.Unlock()
go engine.eventReader()
go engine.streamEvents()
}
go func() {
if err := sysinfo.Events(engine.sysEvents.eventChan, engine.sysEvents.eventCancelChan); err != nil {
log.Error().Msgf("health check: event streamer %v", err)
func (engine *Engine) streamEvents() {
log.Debug().Msg("health check: pdcs event steamer started")
if err := sysinfo.Events(engine.sysEvents.eventChan, engine.sysEvents.eventCancelChan); err != nil {
log.Error().Msgf("health check: pdcs event streamer %v", err)
engine.sysEvents.cancelChan <- true
engine.sysEvents.mu.Lock()
engine.sysEvents.status = false
engine.sysEvents.mu.Unlock()
log.Debug().Msgf("health check: pdcs event steamer cancel sent")
}
log.Debug().Msg("health check: pdcs event steamer stopped")
close(engine.sysEvents.eventCancelChan)
engine.sysEvents.cancelChan <- true
}
}()
}
func (engine *Engine) eventReader() {
@ -67,6 +55,11 @@ func (engine *Engine) eventReader() {
select {
case <-engine.sysEvents.cancelChan:
log.Debug().Msg("health check: event reader stopped")
engine.sysEvents.eventCancelChan <- true
engine.sysEvents.mu.Lock()
engine.sysEvents.status = false
engine.sysEvents.mu.Unlock()
close(engine.sysEvents.cancelChan)
registry.CancelContext()
@ -75,14 +68,13 @@ func (engine *Engine) eventReader() {
case event := <-engine.sysEvents.eventChan:
{
msg := engine.convertEventToHumanReadable(event.Message)
engine.addEvent(event.Message)
engine.addEventMessage(msg)
msg := engine.convertEventToHumanReadable(event)
if strings.TrimSpace(msg) != "" {
log.Debug().Msgf("health check: event reader received %s", msg)
}
engine.addEvent(event)
engine.addEventMessage(msg)
}
}
}
@ -146,7 +138,7 @@ func (engine *Engine) EventStatus() bool {
return engine.sysEvents.status
}
func (engine *Engine) addEvent(event events.Message) {
func (engine *Engine) addEvent(event types.Event) {
engine.sysEvents.mu.Lock()
engine.sysEvents.hasNewEvent = true
engine.sysEvents.eventBuffer = append(engine.sysEvents.eventBuffer, string(event.Type))
@ -154,7 +146,7 @@ func (engine *Engine) addEvent(event events.Message) {
}
// convertEventToHumanReadable returns human readable event as a formatted string.
func (engine *Engine) convertEventToHumanReadable(event events.Message) string {
func (engine *Engine) convertEventToHumanReadable(event types.Event) string {
var humanFormat string
id := event.Actor.ID

View File

@ -68,6 +68,9 @@ func (engine *Engine) Disconnect() {
}
log.Debug().Msgf("health: disconnect")
engine.sysEvents.cancelChan <- true
registry.SetConnectionStatus(registry.ConnectionStatusDisconnected)
engine.conn.setStatus(registry.ConnectionStatusDisconnected, "")
registry.UnsetConnection()

View File

@ -19,9 +19,9 @@ load helpers_tui
podman_tui_set_view "images"
podman_tui_select_image_cmd "pull"
podman_tui_send_inputs "busybox" "Enter"
sleep 8
sleep $TEST_TIMEOUT_HIGH
podman_tui_send_inputs "Down" "Enter"
sleep 12
sleep $TEST_TIMEOUT_HIGH
run_helper podman image ls busybox --format "{{ .Repository }}"
assert "$output" =~ "docker.io/library/busybox" "expected image"
@ -46,7 +46,7 @@ load helpers_tui
podman_tui_send_inputs $TEST_IMAGE_SAVE_PATH "Tab"
podman_tui_send_inputs "Space" "Tab" "Tab" "Tab" "Tab"
podman_tui_send_inputs "Enter"
sleep 6
sleep $TEST_TIMEOUT_MEDIUM
run_helper ls ${TEST_IMAGE_SAVE_PATH} 2> /dev/null
assert "$output" == "$TEST_IMAGE_SAVE_PATH" "expected $TEST_IMAGE_SAVE_PATH exists"
@ -70,7 +70,7 @@ load helpers_tui
podman_tui_send_inputs "Tab"
podman_tui_send_inputs "localhost/${TEST_NAME}_image_imported:latest"
podman_tui_send_inputs "Tab" "Tab" "Enter"
sleep 6
sleep $TEST_TIMEOUT_MEDIUM
run_helper podman image ls ${TEST_NAME}_image_imported --format "{{ .Repository }}:{{ .Tag }}"
assert "$output" =~ "localhost/${TEST_NAME}_image_imported" "expected image"
@ -96,7 +96,7 @@ load helpers_tui
podman_tui_send_inputs ${TEST_IMAGE_BUILD_REPOSITORY}
podman_tui_send_inputs "Tab" "Tab"
podman_tui_send_inputs "Enter"
sleep 8
sleep $TEST_TIMEOUT_MEDIUM
podman_tui_send_inputs "Tab" "Enter"
run_helper podman image ls ${TEST_IMAGE_BUILD_TAG} --format "{{ .Repository }}:{{ .Tag }}"
@ -113,7 +113,7 @@ load helpers_tui
podman_tui_set_view "images"
podman_tui_select_item $image_index
podman_tui_select_image_cmd "diff"
sleep 2
sleep $TEST_TIMEOUT_LOW
podman_tui_send_inputs "Tab" "Enter"
run_helper grep -w 'A /var' $PODMAN_TUI_LOG
@ -130,7 +130,7 @@ load helpers_tui
podman_tui_set_view "images"
podman_tui_select_item $image_index
podman_tui_select_image_cmd "history"
sleep 2
sleep $TEST_TIMEOUT_LOW
podman_tui_send_inputs "Tab" "Enter"
run_helper egrep -w "\[\[$image_id.*BusyBox.*" $PODMAN_TUI_LOG
@ -148,7 +148,7 @@ load helpers_tui
podman_tui_set_view "images"
podman_tui_select_item $image_index
podman_tui_select_image_cmd "inspect"
sleep 2
sleep $TEST_TIMEOUT_LOW
podman_tui_send_inputs "Enter"
run_helper sed -n '/ "RepoTags": \[/, / \],/p' $PODMAN_TUI_LOG
@ -165,7 +165,7 @@ load helpers_tui
podman_tui_select_item $busyboxIndex
podman_tui_select_image_cmd "tag"
podman_tui_send_inputs "$TEST_IMAGE_TAG_NAME" "Tab" "Tab" "Enter"
sleep 2
sleep $TEST_TIMEOUT_LOW
run_helper podman image ls $TEST_IMAGE_TAG_NAME --format "{{ .Repository }}"
assert "$output" =~ "$TEST_IMAGE_TAG_NAME" "expected tagged image $TEST_IMAGE_TAG_NAME"
@ -180,10 +180,10 @@ load helpers_tui
# press "Tab" 2 times and "Enter" to untag busybox image
podman_tui_set_view "images"
podman_tui_select_item $busybox_tagindex
sleep 1
sleep $TEST_TIMEOUT_LOW
podman_tui_select_image_cmd "untag"
podman_tui_send_inputs "Tab" "Tab" "Enter"
sleep 2
sleep $TEST_TIMEOUT_LOW
untagged_umage=$(podman image ls --format '{{ .Repository }}')
assert "$untagged_umage" !~ "$TEST_IMAGE_TAG_NAME" "expected $TEST_IMAGE_TAG_NAME not to be in the list"
@ -205,7 +205,7 @@ load helpers_tui
podman_tui_select_item $untagged_image
podman_tui_select_image_cmd "remove"
podman_tui_send_inputs "Enter"
sleep 2
sleep $TEST_TIMEOUT_LOW
podman_tui_send_inputs "Tab" "Enter"
# check if busybox image has been removed
@ -222,7 +222,7 @@ load helpers_tui
podman_tui_set_view "images"
podman_tui_select_image_cmd "prune"
podman_tui_send_inputs "Enter"
sleep 2
sleep $TEST_TIMEOUT_LOW
# check if busybox image has been removed
run_helper podman image ls --format "{{ .Repository }}" --filter "reference=busybox"

View File

@ -16,9 +16,9 @@ load helpers_tui
podman_tui_set_view "volumes"
podman_tui_select_volume_cmd "create"
podman_tui_send_inputs "$TEST_VOLUME_NAME" "Tab" "$TEST_LABEL" "Tab" "Tab" "Tab" "Tab" "Enter"
sleep 1
sleep $TEST_TIMEOUT_LOW
podman_tui_send_inputs "Tab" "Enter"
sleep 2
sleep $TEST_TIMEOUT_LOW
run_helper podman volume ls --format "{{ .Name }}" --filter "name=${TEST_VOLUME_NAME}"
assert "$output" == "$TEST_VOLUME_NAME" "expected $TEST_VOLUME_NAME to be in the list"
@ -34,9 +34,9 @@ load helpers_tui
podman_tui_set_view "volumes"
podman_tui_select_item $vol_index
podman_tui_select_volume_cmd "inspect"
sleep 1
sleep $TEST_TIMEOUT_LOW
podman_tui_send_inputs "Enter"
sleep 2
sleep $TEST_TIMEOUT_LOW
run_helper sed -n '/ "Labels": {/, / },/p' ${PODMAN_TUI_LOG}
assert "$output" =~ "\"$TEST_LABEL_NAME\": \"$TEST_LABEL_VALUE\"" "expected \"$TEST_LABEL_NAME\": \"$TEST_LABEL_VALUE\" in volume inspect"
@ -52,7 +52,7 @@ load helpers_tui
podman_tui_select_item $vol_index
podman_tui_select_volume_cmd "remove"
podman_tui_send_inputs "Enter"
sleep 2
sleep $TEST_TIMEOUT_LOW
run_helper podman volume ls --format "{{ .Name }}" --filter "name=${TEST_VOLUME_NAME}"
assert "$output" == "" "expected $TEST_VOLUME_NAME removed"
@ -68,7 +68,7 @@ load helpers_tui
podman_tui_set_view "volumes"
podman_tui_select_volume_cmd "prune"
podman_tui_send_inputs "Enter"
sleep 2
sleep $TEST_TIMEOUT_LOW
run_helper podman volume ls --format "{{ .Name }}" --filter "name=${TEST_NETWORK_NAME}"
assert "$output" =~ "" "expected at least $TEST_VOLUME_NAME image removal"

View File

@ -18,13 +18,13 @@ load helpers_tui
podman_tui_set_view "networks"
podman_tui_select_network_cmd "connect"
sleep 2
podman_tui_send_inputs "Tab" "Tab"
sleep $TEST_TIMEOUT_LOW
podman_tui_send_inputs "Tab"
podman_tui_send_inputs $TEST_NETWORK_CONNECT_ALIAS
podman_tui_send_inputs "Tab" "Tab" "Tab" "Tab"
podman_tui_send_inputs "Tab" "Enter"
sleep 2
sleep $TEST_TIMEOUT_LOW
run_helper podman container inspect $TEST_CONTAINER_NAME --format "\"{{ .NetworkSettings.Networks.$TEST_NETWORK_CONNECT }}\""
assert "$output" =~ "$TEST_NETWORK_CONNECT_ALIAS" "expected $TEST_NETWORK_CONNECT_ALIAS to be in the list of aliases"
@ -39,8 +39,8 @@ load helpers_tui
podman_tui_set_view "networks"
podman_tui_select_network_cmd "disconnect"
sleep 2
podman_tui_send_inputs "Tab" "Tab" "Tab" "Enter"
sleep $TEST_TIMEOUT_LOW
podman_tui_send_inputs "Tab" "Tab" "Enter"
run_helper podman container inspect $TEST_CONTAINER_NAME --format "{{ .NetworkSettings.Networks.$TEST_NETWORK_CONNECT }}"
assert "$output" == "<no value>" "expected $TEST_NETWORK_CONNECT_ALIAS to be removed from container"
@ -60,9 +60,9 @@ load helpers_tui
podman_tui_send_inputs "Tab"
podman_tui_send_inputs "$TEST_LABEL"
podman_tui_send_inputs "Tab" "Tab" "Tab" "Tab" "Tab" "Enter"
sleep 1
sleep $TEST_TIMEOUT_LOW
podman_tui_send_inputs "Tab" "Enter"
sleep 2
sleep $TEST_TIMEOUT_LOW
run_helper podman network ls --format "{{ .Name }}" --filter "name=${TEST_NETWORK_NAME}$"
assert "$output" == "$TEST_NETWORK_NAME" "expected $TEST_NETWORK_NAME to be in the list"
}
@ -77,9 +77,9 @@ load helpers_tui
podman_tui_set_view "networks"
podman_tui_select_item $net_index
podman_tui_select_network_cmd "inspect"
sleep 1
sleep $TEST_TIMEOUT_LOW
podman_tui_send_inputs "Enter"
sleep 2
sleep $TEST_TIMEOUT_LOW
run_helper sed -n '/ "labels": {/, / }/p' $PODMAN_TUI_LOG
assert "$output" =~ "\"$TEST_LABEL_NAME\": \"$TEST_LABEL_VALUE\"" "expected \"$TEST_LABEL_NAME\": \"$TEST_LABEL_VALUE\" in network inspect"
@ -95,7 +95,7 @@ load helpers_tui
podman_tui_select_item $net_index
podman_tui_select_network_cmd "remove"
podman_tui_send_inputs "Enter"
sleep 2
sleep $TEST_TIMEOUT_LOW
run_helper podman network ls --format "{{ .Name }}" --filter "name=${TEST_NETWORK_NAME}$"
assert "$output" == "" "expected $TEST_NETWORK_NAME removed"
@ -111,7 +111,7 @@ load helpers_tui
podman_tui_set_view "networks"
podman_tui_select_network_cmd "prune"
podman_tui_send_inputs "Enter"
sleep 2
sleep $TEST_TIMEOUT_LOW
run_helper podman network ls --format "{{ .Name }}" --filter "name=${TEST_NETWORK_NAME}$"
assert "$output" == "" "expected at least $TEST_NETWORK_NAME network removal"

View File

@ -6,7 +6,38 @@
load helpers
load helpers_tui
@test "pod create" {
@test "pod create (resource)" {
podman pod rm -f $TEST_POD_NAME || echo done
podman image pull pause:3.5 || echo done
podman_tui_set_view "pods"
podman_tui_select_pod_cmd "create"
podman_tui_send_inputs $TEST_POD_NAME "Tab" "Tab" "Tab" "Tab" "Tab"
podman_tui_send_inputs "Down" "Down" "Down" "Down" "Down" "Tab"
podman_tui_send_inputs $TEST_POD_MEMORY "Tab" $TEST_POD_SWAP
podman_tui_send_inputs "Tab" "Tab" $TEST_POD_CPU_SHARES
podman_tui_send_inputs "Tab" "Tab" $TEST_POD_CPUSET_MEM
podman_tui_send_inputs "Tab" "Tab" "Tab" "Tab"
sleep $TEST_TIMEOUT_LOW
podman_tui_send_inputs "Enter"
sleep $TEST_TIMEOUT_LOW
run_helper podman pod ls --filter="name=${TEST_POD_NAME}$" --format "{{ .Status}}"
assert $output =~ "Created" "expected $TEST_POD_NAME to be created"
pod_memory=$(podman pod inspect $TEST_POD_NAME --format "{{ json .MemoryLimit }}")
pod_memory_swap=$(podman pod inspect $TEST_POD_NAME --format "{{ json .MemorySwap }}")
pod_cpu_shares=$(podman pod inspect $TEST_POD_NAME --format "{{ json .CPUShares }}")
pod_cpu_set_mems=$(podman pod inspect $TEST_POD_NAME --format "{{ json .CPUSetMems }}")
assert "$pod_memory" =~ "$TEST_POD_MEMORY" "expected pod memory to match: $TEST_POD_MEMORY"
assert "$pod_memory_swap" =~ "$TEST_POD_SWAP" "expected pod memory swap to match: $TEST_POD_SWAP"
assert "$pod_cpu_shares" =~ "$TEST_POD_CPU_SHARES" "expected pod cpu shares to match: $TEST_POD_CPU_SHARES"
assert "$pod_cpu_set_mems" =~ "$TEST_POD_CPUSET_MEM" "expected pod cpu set mems to match: $TEST_POD_CPUSET_MEM"
}
@test "pod create (networking, security)" {
podman pod rm -f $TEST_POD_NAME || echo done
podman network rm $TEST_POD_NETWORK_NAME || echo done
podman image pull pause:3.5 || echo done
@ -35,7 +66,7 @@ load helpers_tui
podman_tui_send_inputs "Tab" "Tab" "Tab" "Tab" "Tab" "Space"
podman_tui_send_inputs "Tab" "Tab"
podman_tui_send_inputs "Enter"
sleep 4
sleep $TEST_TIMEOUT_LOW
run_helper podman pod ls --filter="name=${TEST_POD_NAME}$" --format "{{ .Status}}"
assert $output =~ "Created" "expected $TEST_POD_NAME to be created"
@ -54,7 +85,7 @@ load helpers_tui
podman_tui_set_view "pods"
podman_tui_select_item $pod_index
podman_tui_select_pod_cmd "start"
sleep 2
sleep $TEST_TIMEOUT_LOW
run_helper podman pod ls --filter="name=${TEST_POD_NAME}$" --format "{{ .Status}}"
assert $output =~ "Running" "expected $TEST_POD_NAME running"
@ -69,7 +100,7 @@ load helpers_tui
podman_tui_set_view "pods"
podman_tui_select_item $pod_index
podman_tui_select_pod_cmd "pause"
sleep 2
sleep $TEST_TIMEOUT_LOW
run_helper podman pod ls --filter="name=${TEST_POD_NAME}$" --format "{{ .Status}}"
assert $output =~ "Paused" "expected $TEST_POD_NAME running"
@ -84,7 +115,7 @@ load helpers_tui
podman_tui_set_view "pods"
podman_tui_select_item $pod_index
podman_tui_select_pod_cmd "unpause"
sleep 2
sleep $TEST_TIMEOUT_LOW
run_helper podman pod ls --filter="name=${TEST_POD_NAME}$" --format "{{ .Status}}"
assert $output =~ "Running" "expected $TEST_POD_NAME running"
@ -99,7 +130,7 @@ load helpers_tui
podman_tui_set_view "pods"
podman_tui_select_item $pod_index
podman_tui_select_pod_cmd "stop"
sleep 2
sleep $TEST_TIMEOUT_LOW
run_helper podman pod ls --filter="name=${TEST_POD_NAME}$" --format "{{ .Status}}"
assert $output =~ "Exited" "expected $TEST_POD_NAME exited"
@ -114,7 +145,7 @@ load helpers_tui
podman_tui_set_view "pods"
podman_tui_select_item $pod_index
podman_tui_select_pod_cmd "restart"
sleep 2
sleep $TEST_TIMEOUT_LOW
run_helper podman pod ls --filter="name=${TEST_POD_NAME}$" --format "{{ .Status}}"
assert $output =~ "Running" "expected $TEST_POD_NAME exited"
@ -129,7 +160,7 @@ load helpers_tui
podman_tui_set_view "pods"
podman_tui_select_item $pod_index
podman_tui_select_pod_cmd "kill"
sleep 2
sleep $TEST_TIMEOUT_LOW
run_helper podman pod ls --filter="name=${TEST_POD_NAME}$" --format "{{ .Status}}"
assert $output =~ "Exited" "expected $TEST_POD_NAME exited"
@ -145,7 +176,7 @@ load helpers_tui
podman_tui_set_view "pods"
podman_tui_select_item $pod_index
podman_tui_select_pod_cmd "inspect"
sleep 2
sleep $TEST_TIMEOUT_LOW
podman_tui_send_inputs "Enter"
run_helper sed -n '/ "Labels": {/, / },/p' $PODMAN_TUI_LOG
@ -164,7 +195,7 @@ load helpers_tui
podman_tui_select_pod_cmd "remove"
podman_tui_send_inputs "Enter"
podman_tui_send_inputs "Enter"
sleep 2
sleep $TEST_TIMEOUT_LOW
run_helper podman pod ls --format "{{ .Name }}" --filter "name=${TEST_POD_NAME}$"
assert "$output" == "" "expected $TEST_POD_NAME pod removal"
@ -174,7 +205,7 @@ load helpers_tui
podman pod create --name $TEST_POD_NAME --label $TEST_LABEL || echo done
podman pod start $TEST_POD_NAME || echo done
podman pod stop $TEST_POD_NAME || echo done
sleep 2
sleep $TEST_TIMEOUT_LOW
# switch to pods view
# select prune command from pod commands dialog
@ -182,7 +213,7 @@ load helpers_tui
podman_tui_set_view "pods"
podman_tui_select_pod_cmd "prune"
podman_tui_send_inputs "Enter"
sleep 3
sleep $TEST_TIMEOUT_LOW
run_helper podman pod ls --format "{{ .Name }}" --filter "name=${TEST_POD_NAME}$"
assert "$output" == "" "expected at least $TEST_POD_NAME pod removal"

View File

@ -6,6 +6,39 @@
load helpers
load helpers_tui
@test "container run" {
podman container rm -f $TEST_CONTAINER_NAME || echo done
buysbox_image=$(podman image ls --sort repository --format "{{ .Repository }}" --filter "reference=docker.io/library/busybox")
if [ "${buysbox_image}" == "" ] ; then
podman image pull docker.io/library/busybox
fi
image_index=$(podman image ls --sort repository --noheading | nl -v 1 | grep 'busybox ' | awk '{print $1}')
podman_tui_set_view "containers"
podman_tui_select_container_cmd "run"
podman_tui_send_inputs $TEST_CONTAINER_NAME "Tab" "$TEST_CONTAINER_RUN_CMD" "Tab"
podman_tui_send_inputs "Down"
podman_tui_select_item $image_index
podman_tui_send_inputs "Enter"
podman_tui_send_inputs "Tab" "Tab" "Tab" "Tab" "Space"
podman_tui_send_inputs "Tab" "Tab" "Space"
podman_tui_send_inputs "Tab" "Space"
podman_tui_send_inputs "Tab" "Space"
sleep $TEST_TIMEOUT_LOW
podman_tui_send_inputs "Tab" "Tab" "Tab" "Enter"
sleep $TEST_TIMEOUT_HIGH
cnt_status=$(podman container inspect $TEST_CONTAINER_NAME --format "{{ json .State.Status }}")
assert "$cnt_status" =~ "running" "expected container status to match: running"
podman container stop $TEST_CONTAINER_NAME
run_helper podman container ls --all --filter "name=${TEST_CONTAINER_NAME}$" --noheading
assert "$output" == "" "expected $TEST_CONTAINER_NAME to be removed"
}
@test "container create (privileged, timeout, remove)" {
podman container rm -f $TEST_CONTAINER_NAME || echo done
@ -25,15 +58,15 @@ load helpers_tui
# select image from dropdown widget
# select privileged
# set timeout to 10
podman_tui_send_inputs $TEST_CONTAINER_NAME "Tab"
podman_tui_send_inputs $TEST_CONTAINER_NAME "Tab" "Tab"
podman_tui_send_inputs "Down"
podman_tui_select_item $image_index
podman_tui_send_inputs "Enter" "Tab" "Tab" "Tab"
podman_tui_send_inputs "Space" "Tab" "Space" "Tab" "$TEST_CONTAINER_TIMEOUT"
podman_tui_send_inputs "Tab" "Tab"
sleep 2
podman_tui_send_inputs "Tab" "Tab" "Tab"
sleep $TEST_TIMEOUT_LOW
podman_tui_send_inputs "Enter"
sleep 3
sleep $TEST_TIMEOUT_LOW
cnt_status=$(podman container inspect $TEST_CONTAINER_NAME --format "{{ json .State.Status }}")
cnt_annotations=$(podman container inspect $TEST_CONTAINER_NAME --format "{{ json .Config.Annotations }}")
@ -62,11 +95,11 @@ load helpers_tui
# fillout name field
# select image from dropdown widget
podman_tui_send_inputs $TEST_CONTAINER_NAME "Tab"
podman_tui_send_inputs $TEST_CONTAINER_NAME "Tab" "Tab"
podman_tui_send_inputs "Down"
podman_tui_select_item $image_index
podman_tui_send_inputs "Enter" "Tab" "Tab" "Tab" "Tab" "Tab" "Tab" "Tab" "Tab"
sleep 2
podman_tui_send_inputs "Enter" "Tab" "Tab" "Tab" "Tab" "Tab" "Tab" "Tab" "Tab" "Tab"
sleep $TEST_TIMEOUT_LOW
# switch to environmen page
podman_tui_send_inputs "Down" "Tab"
@ -75,9 +108,9 @@ load helpers_tui
podman_tui_send_inputs "Tab" "Tab" "Tab" "Tab" "Tab" "Tab"
podman_tui_send_inputs "$TEST_CONTAINER_UMASK"
podman_tui_send_inputs "Tab" "Tab"
sleep 2
sleep $TEST_TIMEOUT_LOW
podman_tui_send_inputs "Enter"
sleep 3
sleep $TEST_TIMEOUT_LOW
cnt_workdir=$(podman container inspect $TEST_CONTAINER_NAME --format "{{ json .Config.WorkingDir }}")
cnt_vars=$(podman container inspect $TEST_CONTAINER_NAME --format "{{ json .Config.Env }}")
@ -89,6 +122,63 @@ load helpers_tui
assert "$cnt_vars" =~ "$TEST_CONTAINER_ENV2" "expected container env to match: $TEST_CONTAINER_ENV2"
}
@test "container create (resource page)" {
podman container rm -f $TEST_CONTAINER_NAME || echo done
buysbox_image=$(podman image ls --sort repository --format "{{ .Repository }}" --filter "reference=docker.io/library/busybox")
if [ "${buysbox_image}" == "" ] ; then
podman image pull docker.io/library/busybox
fi
image_index=$(podman image ls --sort repository --noheading | nl -v 1 | grep 'busybox ' | awk '{print $1}')
# switch to containers view
# select create command from container commands dialog
podman_tui_set_view "containers"
podman_tui_select_container_cmd "create"
# fillout name field
# select image from dropdown widget
podman_tui_send_inputs $TEST_CONTAINER_NAME "Tab" "Tab"
podman_tui_send_inputs "Down"
podman_tui_select_item $image_index
podman_tui_send_inputs "Enter" "Tab" "Tab" "Tab" "Tab" "Tab" "Tab" "Tab" "Tab" "Tab"
sleep $TEST_TIMEOUT_LOW
# switch to environmen page
podman_tui_send_inputs "Down" "Down" "Down" "Down" "Down" "Down" "Down" "Down" "Down" "Tab"
podman_tui_send_inputs "$TEST_CONTAINER_MEMORY" "Tab" "$TEST_CONTAINER_MEMORY_RESERV" "Tab"
podman_tui_send_inputs "$TEST_CONTAINER_MEMORY_SWAP" "Tab" "$TEST_CONTAINER_MEMORY_SWAPPINESS"
podman_tui_send_inputs "Tab" "Tab" "$TEST_CONTAINER_CPU_SHARES"
podman_tui_send_inputs "Tab" "$TEST_CONTAINER_CPU_PERIOD"
podman_tui_send_inputs "Tab" "Tab" "$TEST_CONTAINER_CPU_QUOTA"
podman_tui_send_inputs "Tab" "Tab" "Tab" "Tab"
podman_tui_send_inputs "$TEST_CONTAINER_SHM_SIZE" "Tab"
podman_tui_send_inputs "$TEST_CONTAINER_SHM_SIZE_SYSTYEMD"
sleep $TEST_TIMEOUT_LOW
podman_tui_send_inputs "Tab" "Tab"
podman_tui_send_inputs "Enter"
sleep $TEST_TIMEOUT_LOW
cnt_memory=$(podman container inspect $TEST_CONTAINER_NAME --format "{{ json .HostConfig.Memory }}")
cnt_memory_reserv=$(podman container inspect $TEST_CONTAINER_NAME --format "{{ json .HostConfig.MemoryReservation }}")
cnt_memory_swap=$(podman container inspect $TEST_CONTAINER_NAME --format "{{ json .HostConfig.MemorySwap }}")
cnt_memory_swappiness=$(podman container inspect $TEST_CONTAINER_NAME --format "{{ json .HostConfig.MemorySwappiness }}")
cnt_cpu_shares=$(podman container inspect $TEST_CONTAINER_NAME --format "{{ json .HostConfig.CpuShares }}")
cnt_cpu_period=$(podman container inspect $TEST_CONTAINER_NAME --format "{{ json .HostConfig.CpuPeriod }}")
cnt_cpu_quota=$(podman container inspect $TEST_CONTAINER_NAME --format "{{ json .HostConfig.CpuQuota }}")
cnt_shm_size=$(podman container inspect $TEST_CONTAINER_NAME --format "{{ json .HostConfig.ShmSize }}")
assert "$cnt_memory" =~ "$TEST_CONTAINER_MEMORY" "expected container memory to match: $TEST_CONTAINER_MEMORY"
assert "$cnt_memory_reserv" =~ "$TEST_CONTAINER_MEMORY_RESERV" "expected container memory reservation to match: $TEST_CONTAINER_MEMORY_RESERV"
assert "$cnt_memory_swap" =~ "$TEST_CONTAINER_MEMORY_SWAP" "expected container memory swap to match: $TEST_CONTAINER_MEMORY_SWAP"
assert "$cnt_memory_swappiness" =~ "$TEST_CONTAINER_MEMORY_SWAPPINESS" "expected container memory swappiness to match: $TEST_CONTAINER_MEMORY_SWAPPINESS"
assert "$cnt_cpu_shares" =~ "$TEST_CONTAINER_CPU_SHARES" "expected container cpu shares to match: $TEST_CONTAINER_CPU_SHARES"
assert "$cnt_cpu_period" =~ "$TEST_CONTAINER_CPU_PERIOD" "expected container cpu period to match: $TEST_CONTAINER_CPU_PERIOD"
assert "$cnt_cpu_quota" =~ "$TEST_CONTAINER_CPU_QUOTA" "expected container cpu quota to match: $TEST_CONTAINER_CPU_QUOTA"
assert "$cnt_shm_size" =~ "$TEST_CONTAINER_SHM_SIZE" "expected container shm size to match: $TEST_CONTAINER_SHM_SIZE"
}
@test "container create (pod, network, volume, security options, health)" {
httpd_image=$(podman image ls --sort repository --format "{{ .Repository }}" --filter "reference=docker.io/library/httpd")
if [ "${httpd_image}" == "" ] ; then
@ -106,7 +196,7 @@ load helpers_tui
podman network create $TEST_CONTAINER_NETWORK_NAME || echo done
podman volume create $TEST_CONTAINER_VOLUME_NAME || echo done
podman pod create --name $TEST_CONTAINER_POD_NAME --network $TEST_CONTAINER_NETWORK_NAME --publish $TEST_CONTAINER_PORT || echo done
sleep 2
sleep $TEST_TIMEOUT_LOW
# get required pod, image, network and volume index for number of KeyDown stroke
pod_index=$(podman pod ls --sort name --format "{{ .Name }}" | nl -v 1 | grep "$TEST_CONTAINER_POD_NAME" | awk '{print $1}')
@ -123,32 +213,28 @@ load helpers_tui
# select image from dropdown widget
# select pod from dropdown widget
# fillout label field
podman_tui_send_inputs $TEST_CONTAINER_NAME "Tab"
podman_tui_send_inputs $TEST_CONTAINER_NAME "Tab" "Tab"
podman_tui_send_inputs "Down"
podman_tui_select_item $image_index
podman_tui_send_inputs "Enter" "Tab"
podman_tui_send_inputs "Down"
podman_tui_select_item $pod_index
podman_tui_send_inputs "Enter" "Tab"
podman_tui_send_inputs $TEST_LABEL "Tab" "Tab" "Tab" "Tab" "Tab"
sleep 1
podman_tui_send_inputs $TEST_LABEL "Tab" "Tab" "Tab" "Tab" "Tab" "Tab"
sleep $TEST_TIMEOUT_LOW
podman_tui_send_inputs "Tab"
sleep 1
sleep $TEST_TIMEOUT_LOW
# switch to "health check" create view
podman_tui_send_inputs "Down" "Down" "Down" "Down" "Tab"
podman_tui_send_inputs $TEST_CONTAINER_HEALTH_CMD "Tab" "Tab"
podman_tui_send_inputs $TEST_CONTAINER_HEALTH_CMD "Tab" "Tab" "Tab" "Tab" "Tab"
podman_tui_send_inputs "Enter" "Down" "Down" "Enter"
podman_tui_send_inputs "Tab" "Tab" "Tab"
podman_tui_send_inputs $TEST_CONTAINER_HEALTH_INTERVAL
podman_tui_send_inputs "Tab" "Tab"
podman_tui_send_inputs $TEST_CONTAINER_HEALTH_RETRIES
podman_tui_send_inputs "Tab" "Tab"
podman_tui_send_inputs $TEST_CONTAINER_HEALTH_TIMEOUT
podman_tui_send_inputs "Tab" "Tab" "Tab"
sleep 1
podman_tui_send_inputs "Tab" "Tab" "Tab" "Tab"
sleep $TEST_TIMEOUT_LOW
podman_tui_send_inputs "Tab"
sleep 1
sleep $TEST_TIMEOUT_LOW
# switch to "security options" create view
podman_tui_send_inputs "Down" "Down" "Down" "Tab"
@ -161,11 +247,11 @@ load helpers_tui
podman_tui_send_inputs "${TEST_CONTAINER_VOLUME_NAME}:${TEST_CONTAINER_VOLUME_MOUNT_POINT}:rw"
podman_tui_send_inputs "Tab" "Tab"
podman_tui_send_inputs "type=bind,src=${TEST_CONTAINER_MOUNT_SOURCE},dst=${TEST_CONTAINER_MOUNT_DEST}"
sleep 1
sleep $TEST_TIMEOUT_LOW
# go to "Create" button and press Enter
podman_tui_send_inputs "Tab" "Tab" "Enter"
sleep 2
sleep $TEST_TIMEOUT_LOW
# get created container information
container_information=$(podman container ls --all --pod --filter "name=${TEST_CONTAINER_NAME}$" --format \
@ -222,7 +308,7 @@ load helpers_tui
podman_tui_send_inputs Tab Tab Tab Tab
podman_tui_send_inputs Tab Tab Tab Tab
podman_tui_send_inputs Enter
sleep 10
sleep $TEST_TIMEOUT_HIGH
run_helper podman image ls ${TEST_CONTAINER_COMMIT_IMAGE_NAME} --format "{{ .Repository }}"
assert "$output" =~ "localhost/${TEST_CONTAINER_COMMIT_IMAGE_NAME}" "expected image"
}
@ -236,7 +322,7 @@ load helpers_tui
podman_tui_set_view "containers"
podman_tui_select_item $container_index
podman_tui_select_container_cmd "start"
sleep 2
sleep $TEST_TIMEOUT_LOW
run_helper podman container ls --all --filter="name=${TEST_CONTAINER_NAME}$" --format "{{ .Status }}"
assert "$output" =~ "Up" "expected $TEST_CONTAINER_NAME to be up"
@ -265,7 +351,7 @@ load helpers_tui
podman_tui_send_inputs "Tab" "Tab" "Tab" "Tab"
podman_tui_send_inputs "Tab" "Tab" "Enter"
sleep 10
sleep $TEST_TIMEOUT_HIGH
run_helper ls ~/${TEST_CONTAINER_CHECKPOINT_NAME}_dump.tar 2>/dev/null || echo -e '\c'
assert "$output" == "/root/${TEST_CONTAINER_CHECKPOINT_NAME}_dump.tar" "expected tar file to be created"
@ -288,7 +374,7 @@ load helpers_tui
podman_tui_send_inputs "Tab" "Tab" "Tab" "Tab"
podman_tui_send_inputs "Tab" "Tab" "Enter"
sleep 8
sleep $TEST_TIMEOUT_HIGH
run_helper podman container ls --all --format "{{ .Names }}"
assert "$output" =~ "${TEST_CONTAINER_CHECKPOINT_NAME}_restore" "expected container to be restored"
}
@ -312,10 +398,10 @@ load helpers_tui
podman_tui_send_inputs "Tab" "Space" "Tab"
podman_tui_send_inputs "Tab" "Tab" "Tab" "Tab" "Tab" "Tab" "Tab" "Tab"
podman_tui_send_inputs "Enter"
sleep 1
sleep $TEST_TIMEOUT_LOW
podman_tui_send_inputs "echo Space test Space > Space a.txt" "Enter"
podman_tui_send_inputs "Tab" "Enter"
sleep 2
sleep $TEST_TIMEOUT_LOW
run_helper podman container exec $TEST_CONTAINER_NAME cat a.txt
@ -331,7 +417,7 @@ load helpers_tui
podman_tui_set_view "containers"
podman_tui_select_item $container_index
podman_tui_select_container_cmd "inspect"
sleep 2
sleep $TEST_TIMEOUT_LOW
run_helper sed -n '/ "Labels": {/, / },/p' $PODMAN_TUI_LOG
@ -347,7 +433,7 @@ load helpers_tui
podman_tui_set_view "containers"
podman_tui_select_item $container_index
podman_tui_select_container_cmd "diff"
sleep 6
sleep $TEST_TIMEOUT_MEDIUM
run_helper grep -w "/etc" $PODMAN_TUI_LOG
assert "$output" =~ '/etc' "expected '/etc' in the logs"
@ -362,7 +448,7 @@ load helpers_tui
podman_tui_set_view "containers"
podman_tui_select_item $container_index
podman_tui_select_container_cmd "top"
sleep 2
sleep $TEST_TIMEOUT_LOW
run_helper grep -w "USER PID PPID" $PODMAN_TUI_LOG
assert "$output" =~ 'USER PID PPID' "expected 'USER PID PPID' in the logs"
@ -377,7 +463,7 @@ load helpers_tui
podman_tui_set_view "containers"
podman_tui_select_item $container_index
podman_tui_select_container_cmd "port"
sleep 2
sleep $TEST_TIMEOUT_LOW
container_ports=$(podman container ls --all --filter="name=${TEST_CONTAINER_NAME}$" --format "{{ .Ports }}")
run_helper grep -w "$container_ports" $PODMAN_TUI_LOG
@ -393,7 +479,7 @@ load helpers_tui
podman_tui_set_view "containers"
podman_tui_select_item $container_index
podman_tui_select_container_cmd "pause"
sleep 2
sleep $TEST_TIMEOUT_LOW
run_helper podman container ls --all --filter="name=${TEST_CONTAINER_NAME}$" --format "{{ .Status }}"
assert "$output" =~ "Paused" "expected $TEST_CONTAINER_NAME to be paused"
@ -408,7 +494,7 @@ load helpers_tui
podman_tui_set_view "containers"
podman_tui_select_item $container_index
podman_tui_select_container_cmd "unpause"
sleep 2
sleep $TEST_TIMEOUT_LOW
run_helper podman container ls --all --filter="name=${TEST_CONTAINER_NAME}$" --format "{{ .Status }}"
assert "$output" =~ "Up" "expected $TEST_CONTAINER_NAME to be Up"
@ -423,7 +509,7 @@ load helpers_tui
podman_tui_set_view "containers"
podman_tui_select_item $container_index
podman_tui_select_container_cmd "stop"
sleep 2
sleep $TEST_TIMEOUT_LOW
run_helper podman container ls --all --filter="name=${TEST_CONTAINER_NAME}$" --format "{{ .Status }}"
assert "$output" =~ "Exited" "expected $TEST_CONTAINER_NAME to be Up"
@ -439,7 +525,7 @@ load helpers_tui
podman_tui_set_view "containers"
podman_tui_select_item $container_index
podman_tui_select_container_cmd "kill"
sleep 2
sleep $TEST_TIMEOUT_LOW
run_helper podman container ls --all --filter="name=${TEST_CONTAINER_NAME}$" --format "{{ .Status }}"
assert "$output" =~ "Exited" "expected $TEST_CONTAINER_NAME to be killed"
@ -455,7 +541,7 @@ load helpers_tui
podman_tui_select_item $container_index
podman_tui_select_container_cmd "remove"
podman_tui_send_inputs "Enter"
sleep 2
sleep $TEST_TIMEOUT_LOW
run_helper podman container ls --all --filter "name=${TEST_CONTAINER_NAME}$" --noheading
assert "$output" == "" "expected $TEST_CONTAINER_NAME to be removed"
@ -474,7 +560,7 @@ load helpers_tui
podman_tui_select_container_cmd "rename"
podman_tui_send_inputs ${TEST_CONTAINER_NAME}_renamed
podman_tui_send_inputs "Tab" "Tab" "Enter"
sleep 2
sleep $TEST_TIMEOUT_LOW
run_helper podman container ls --all --filter "name=${TEST_CONTAINER_NAME}_renamed$" --format "{{ .Names }}"
assert "$output" == "${TEST_CONTAINER_NAME}_renamed" "expected ${TEST_CONTAINER_NAME}_renamed to be in the list"
@ -492,7 +578,7 @@ load helpers_tui
podman_tui_select_item $container_index
podman_tui_select_container_cmd "prune"
podman_tui_send_inputs "Enter"
sleep 10
sleep $TEST_TIMEOUT_MEDIUM
run_helper podman container ls --all --filter "name=${TEST_CONTAINER_NAME}$" --noheading
assert "$output" == "" "expected $TEST_CONTAINER_NAME to be removed"

View File

@ -18,11 +18,10 @@ load helpers_tui
podman_tui_send_inputs "Tab"
podman_tui_send_inputs $TEST_SYSTEM_CONN_URI
podman_tui_send_inputs "Tab" "Tab" "Tab" "Enter"
sleep 1
sleep $TEST_TIMEOUT_LOW
run_helper tail -2 $PODMAN_TUI_CONFIG_FILE
assert "$output" =~ "[services.${TEST_SYSTEM_CONN_NAME}]" "expected [services.${TEST_SYSTEM_CONN_NAME}] in ${PODMAN_TUI_CONFIG_FILE}"
assert "$output" =~ "uri = \"unix://run/podman/podman.sock\"" "expected ${TEST_SYSTEM_CONN_URI} in ${PODMAN_TUI_CONFIG_FILE}"
run_helper jq ".connections.${TEST_SYSTEM_CONN_NAME}.uri" ${PODMAN_TUI_CONFIG_FILE}
assert "$output" == "\"$TEST_SYSTEM_CONN_URI\"" "expected ${TEST_SYSTEM_CONN_URI} in ${PODMAN_TUI_CONFIG_FILE}"
}
@test "system set default" {
@ -32,12 +31,13 @@ load helpers_tui
podman_tui_set_view "system"
podman_tui_select_item 1
podman_tui_select_system_cmd "default"
sleep 1
sleep $TEST_TIMEOUT_LOW
run_helper tail -3 $PODMAN_TUI_CONFIG_FILE
assert "$output" =~ "[services.${TEST_SYSTEM_CONN_NAME}]" "expected [services.${TEST_SYSTEM_CONN_NAME}] in ${PODMAN_TUI_CONFIG_FILE}"
assert "$output" =~ "uri = \"unix://run/podman/podman.sock\"" "expected ${TEST_SYSTEM_CONN_URI} in ${PODMAN_TUI_CONFIG_FILE}"
assert "$output" =~ "default = true" "expected 'default = true' in ${PODMAN_TUI_CONFIG_FILE}"
run_helper jq ".connections.${TEST_SYSTEN_CONN_LOCAL}.uri" ${PODMAN_TUI_CONFIG_FILE}
assert "$output" == "\"$TEST_SYSTEM_CONN_URI\"" "expected ${TEST_SYSTEM_CONN_URI} in ${PODMAN_TUI_CONFIG_FILE}"
run_helper jq ".connections.${TEST_SYSTEN_CONN_LOCAL}.default" ${PODMAN_TUI_CONFIG_FILE}
assert "$output" == "true" "expected 'default = true' in ${PODMAN_TUI_CONFIG_FILE}"
}
@test "system remove" {
@ -49,10 +49,10 @@ load helpers_tui
podman_tui_select_item 1
podman_tui_select_system_cmd "remove"
podman_tui_send_inputs "Enter"
sleep 1
sleep $TEST_TIMEOUT_LOW
run_helper tail -3 $PODMAN_TUI_CONFIG_FILE
assert "$output" !~ "services.${TEST_SYSTEM_CONN_NAME}" "expected [services.${TEST_SYSTEM_CONN_NAME}] not in ${PODMAN_TUI_CONFIG_FILE}"
run_helper jq ".connections.${TEST_SYSTEN_CONN_LOCAL}" ${PODMAN_TUI_CONFIG_FILE}
assert "$output" == "null" "expected ${TEST_SYSTEN_CONN_LOCAL} connection to be removed from in ${PODMAN_TUI_CONFIG_FILE}"
}
@test "system disconnect" {
@ -60,7 +60,7 @@ load helpers_tui
# select "disconnect" command
podman_tui_set_view "system"
podman_tui_select_system_cmd "disconnect"
sleep 2
sleep $TEST_TIMEOUT_LOW
run_helper tmux capture-pane -pS 0 -E 0
assert "$output" =~ "DISCONNECTED" "expected DISCONNECTED connection status"
@ -74,13 +74,13 @@ load helpers_tui
# select "disconnect" command
podman_tui_set_view "system"
podman_tui_select_system_cmd "disconnect"
sleep 2
sleep $TEST_TIMEOUT_LOW
run_helper tmux capture-pane -pS 0 -E 0
assert "$output" =~ "DISCONNECTED" "expected DISCONNECTED connection status"
# select "connect" command
podman_tui_select_system_cmd "connect"
sleep 3
sleep $TEST_TIMEOUT_LOW
run_helper tmux capture-pane -pS 0 -E 0
assert "$output" =~ "STATUS_OK" "expected STATUS_OK connection status"

View File

@ -5,7 +5,7 @@ PODMAN_TUI=${PODMAN_TUI:-./bin/podman-tui}
PODMAN_TUI_DEBUG="$PODMAN_TUI -d"
PODMAN_TUI_LOG="podman-tui.log"
PODMAN_TUI_CONFIG_DIR="/root/.config/podman-tui"
PODMAN_TUI_CONFIG_FILE="${PODMAN_TUI_CONFIG_DIR}/podman-tui.conf"
PODMAN_TUI_CONFIG_FILE="${PODMAN_TUI_CONFIG_DIR}/podman-tui.json"
TMUX_SESSION="podman_tui_test"
@ -13,12 +13,7 @@ function setup() {
# setup config file
[ ! -d "${PODMAN_TUI_CONFIG_DIR}" ] && mkdir -p ${PODMAN_TUI_CONFIG_DIR}
cat > ${PODMAN_TUI_CONFIG_FILE} << EOF
[services]
[services.localhost]
uri = "unix://run/podman/podman.sock"
default = true
[services.localhost_test]
uri = "unix://run/podman/podman.sock"
{"connections":{"localhost":{"uri":"unix://run/podman/podman.sock","default":true},"localhost_test":{"uri":"unix://run/podman/podman.sock"}}}
EOF
# start podman socket

View File

@ -11,9 +11,9 @@ TEST_POD_NETWORK_NAME="${TEST_NAME}_pod01_net"
TEST_CONTAINER_NAME="${TEST_NAME}_cnt01"
TEST_CONTAINER_CHECKPOINT_NAME="${TEST_NAME}_checkpoint"
TEST_CONTAINER_HEALTH_CMD="date"
TEST_CONTAINER_HEALTH_INTERVAL="60s"
TEST_CONTAINER_HEALTH_TIMEOUT="60s"
TEST_CONTAINER_HEALTH_RETRIES="6"
TEST_CONTAINER_HEALTH_INTERVAL="30s"
TEST_CONTAINER_HEALTH_TIMEOUT="30s"
TEST_CONTAINER_HEALTH_RETRIES="3"
TEST_CONTAINER_HEALTH_ONFAILURE="restart"
TEST_CONTAINER_POD_NAME="${TEST_NAME}_cnt01_pod"
TEST_CONTAINER_NETWORK_NAME="${TEST_NAME}_cnt01_net"
@ -28,15 +28,33 @@ TEST_CONTAINER_WORKDIR="/${TEST_NAME}_workdir"
TEST_CONTAINER_ENV1="key1=value1"
TEST_CONTAINER_ENV2="key2=value2"
TEST_CONTAINER_UMASK="0777"
TEST_CONTAINER_RUN_CMD="/bin/sh"
TEST_LABEL_NAME="test"
TEST_LABEL_VALUE="$TEST_NAME"
TEST_LABEL="${TEST_LABEL_NAME}=${TEST_LABEL_VALUE}"
TEST_SYSTEN_CONN_LOCAL="localhost_test"
TEST_SYSTEM_CONN_NAME="localhost_test_tui"
TEST_SYSTEM_CONN_URI="unix://run/podman/podman.sock"
TEST_IMAGE_BUILD_CONTEXT_DIR="$(realpath .)/test/testdata/"
TEST_IMAGE_BUILD_TAG="${TEST_NAME}_image:latest"
TEST_IMAGE_BUILD_REPOSITORY="localhost"
TEST_IMAGE_SAVE_PATH="/tmp/${TEST_NAME}_image_save.tar"
TEST_CONTAINER_MEMORY=100
TEST_CONTAINER_MEMORY_RESERV=80
TEST_CONTAINER_MEMORY_SWAP=150
TEST_CONTAINER_MEMORY_SWAPPINESS=50
TEST_CONTAINER_CPU_SHARES=10
TEST_CONTAINER_CPU_PERIOD=20
TEST_CONTAINER_CPU_QUOTA=10
TEST_CONTAINER_SHM_SIZE=120
TEST_CONTAINER_SHM_SIZE_SYSTYEMD=150
TEST_POD_MEMORY=20
TEST_POD_SWAP=30
TEST_POD_CPUSET_MEM=40
TEST_POD_CPU_SHARES=50
TEST_TIMEOUT_HIGH=15
TEST_TIMEOUT_MEDIUM=10
TEST_TIMEOUT_LOW=5
################
# podman_tui_set_view # switches to different podman-tui views
@ -237,16 +255,18 @@ function podman_tui_select_container_cmd() {
menu_index=14;;
"remove")
menu_index=15;;
"start")
"run")
menu_index=16;;
"stat")
"start")
menu_index=17;;
"stop")
"stat")
menu_index=18;;
"top")
"stop")
menu_index=19;;
"unpause")
"top")
menu_index=20;;
"unpause")
menu_index=21;;
esac
podman_tui_select_menu $menu_index

View File

@ -190,13 +190,13 @@ func NewContainerCheckpointDialog() *ContainerCheckpointDialog {
optionsLayoutRow01.AddItem(dialog.export, 1, 0, true)
optionsLayoutRow02 := tview.NewFlex().SetDirection(tview.FlexColumn)
optionsLayoutRow02.AddItem(dialog.fileLock, labelWidth+2, 0, true) //nolint:gomnd
optionsLayoutRow02.AddItem(dialog.fileLock, labelWidth+2, 0, true) //nolint:mnd
optionsLayoutRow02.AddItem(dialog.ignoreRootFS, 0, 1, true)
optionsLayoutRow02.AddItem(dialog.tcpEstablished, 0, 1, true)
optionsLayoutRow02.AddItem(dialog.preCheckpoint, 0, 1, true)
optionsLayoutRow03 := tview.NewFlex().SetDirection(tview.FlexColumn)
optionsLayoutRow03.AddItem(dialog.printStats, labelWidth+2, 1, true) //nolint:gomnd
optionsLayoutRow03.AddItem(dialog.printStats, labelWidth+2, 1, true) //nolint:mnd
optionsLayoutRow03.AddItem(dialog.keep, 0, 1, true)
optionsLayoutRow03.AddItem(dialog.leaveRunning, 0, 1, true)
optionsLayoutRow03.AddItem(dialog.withPrevious, 0, 1, true)
@ -433,13 +433,13 @@ func (d *ContainerCheckpointDialog) InputHandler() func(event *tcell.EventKey, s
// SetRect set rects for this primitive.
func (d *ContainerCheckpointDialog) SetRect(x, y, width, height int) {
if width > cntCheckpointDialogMaxWidth {
emptySpace := (width - cntCheckpointDialogMaxWidth) / 2 //nolint:gomnd
emptySpace := (width - cntCheckpointDialogMaxWidth) / 2 //nolint:mnd
x += emptySpace
width = cntCheckpointDialogMaxWidth
}
if height > cntCheckpointDialogMaxHeight {
emptySpace := (height - cntCheckpointDialogMaxHeight) / 2 //nolint:gomnd
emptySpace := (height - cntCheckpointDialogMaxHeight) / 2 //nolint:mnd
y += emptySpace
height = cntCheckpointDialogMaxHeight
}
@ -474,7 +474,7 @@ func (d *ContainerCheckpointDialog) SetCheckpointFunc(handler func()) *Container
// SetCancelFunc sets form cancel button selected function.
func (d *ContainerCheckpointDialog) SetCancelFunc(handler func()) *ContainerCheckpointDialog {
d.cancelHandler = handler
cancelButton := d.form.GetButton(d.form.GetButtonCount() - 2) //nolint:gomnd
cancelButton := d.form.GetButton(d.form.GetButtonCount() - 2) //nolint:mnd
cancelButton.SetSelectedFunc(handler)

View File

@ -74,7 +74,7 @@ func NewContainerCommitDialog() *ContainerCommitDialog {
cntInfoLabel := "CONTAINER ID:" //nolint:goconst
dialog.cntInfo.SetBackgroundColor(style.DialogBgColor)
dialog.cntInfo.SetLabel("[::b]" + cntInfoLabel) //nolint:goconst
dialog.cntInfo.SetLabel("[::b]" + cntInfoLabel)
dialog.cntInfo.SetLabelWidth(len(cntInfoLabel) + 1)
dialog.cntInfo.SetFieldBackgroundColor(style.DialogBgColor)
dialog.cntInfo.SetLabelStyle(tcell.StyleDefault.
@ -154,7 +154,7 @@ func NewContainerCommitDialog() *ContainerCommitDialog {
iaLayout := tview.NewFlex().SetDirection(tview.FlexColumn)
iaLayout.SetBackgroundColor(style.DialogBgColor)
iaLayout.AddItem(dialog.image, 0, 1, true)
iaLayout.AddItem(utils.EmptyBoxSpace(style.DialogBgColor), 2, 0, false) //nolint:gomnd
iaLayout.AddItem(utils.EmptyBoxSpace(style.DialogBgColor), 2, 0, false) //nolint:mnd
iaLayout.AddItem(dialog.author, 0, 1, true)
// dropdown and checkbox layout row
@ -388,13 +388,13 @@ func (d *ContainerCommitDialog) setFocusElement() {
// SetRect set rects for this primitive.
func (d *ContainerCommitDialog) SetRect(x, y, width, height int) {
if width > cntCommitDialogMaxWidth {
emptySpace := (width - cntCommitDialogMaxWidth) / 2 //nolint:gomnd
emptySpace := (width - cntCommitDialogMaxWidth) / 2 //nolint:mnd
x += emptySpace
width = cntCommitDialogMaxWidth
}
if height > cntCommitDialogMaxHeight {
emptySpace := (height - cntCommitDialogMaxHeight) / 2 //nolint:gomnd
emptySpace := (height - cntCommitDialogMaxHeight) / 2 //nolint:mnd
y += emptySpace
height = cntCommitDialogMaxHeight
}
@ -429,7 +429,7 @@ func (d *ContainerCommitDialog) SetCommitFunc(handler func()) *ContainerCommitDi
// SetCancelFunc sets form cancel button selected function.
func (d *ContainerCommitDialog) SetCancelFunc(handler func()) *ContainerCommitDialog {
d.cancelHandler = handler
cancelButton := d.form.GetButton(d.form.GetButtonCount() - 2) //nolint:gomnd
cancelButton := d.form.GetButton(d.form.GetButtonCount() - 2) //nolint:mnd
cancelButton.SetSelectedFunc(handler)

File diff suppressed because it is too large Load Diff

View File

@ -16,7 +16,7 @@ var _ = Describe("container create", Ordered, func() {
BeforeAll(func() {
createDialogApp = tview.NewApplication()
createDialog = NewContainerCreateDialog()
createDialog = NewContainerCreateDialog(ContainerCreateOnlyDialogMode)
createDialogScreen = tcell.NewSimulationScreen("UTF-8")
err := createDialogScreen.Init()
if err != nil {
@ -52,7 +52,7 @@ var _ = Describe("container create", Ordered, func() {
createDialogApp.Draw()
Expect(createDialog.dropdownHasFocus()).To(Equal(true))
createDialog.focusElement = createcontainerPodFieldFocis
createDialog.focusElement = createcontainerPodFieldFocus
createDialogApp.SetFocus(createDialog)
createDialogApp.Draw()
Expect(createDialog.dropdownHasFocus()).To(Equal(true))
@ -89,7 +89,7 @@ var _ = Describe("container create", Ordered, func() {
createFunc := func() {
createAction = createWants
}
createDialog.SetCreateFunc(createFunc)
createDialog.SetHandlerFunc(createFunc)
createDialog.focusElement = createContainerFormFocus
createDialogApp.SetFocus(createDialog)
createDialogApp.Draw()
@ -210,6 +210,11 @@ var _ = Describe("container create", Ordered, func() {
It("setContainerInfoPageNextFocus", func() {
createDialog.focusElement = createContainerNameFieldFocus
createDialogApp.SetFocus(createDialog)
createDialogApp.Draw()
createDialog.setContainerInfoPageNextFocus()
Expect(createDialog.focusElement).To(Equal(createContainerCommandFieldFocus))
createDialogApp.SetFocus(createDialog)
createDialogApp.Draw()
createDialog.setContainerInfoPageNextFocus()
@ -218,7 +223,7 @@ var _ = Describe("container create", Ordered, func() {
createDialogApp.SetFocus(createDialog)
createDialogApp.Draw()
createDialog.setContainerInfoPageNextFocus()
Expect(createDialog.focusElement).To(Equal(createcontainerPodFieldFocis))
Expect(createDialog.focusElement).To(Equal(createcontainerPodFieldFocus))
createDialogApp.SetFocus(createDialog)
createDialogApp.Draw()
@ -240,6 +245,11 @@ var _ = Describe("container create", Ordered, func() {
createDialog.setContainerInfoPageNextFocus()
Expect(createDialog.focusElement).To(Equal(createContainerTimeoutFieldFocus))
createDialogApp.SetFocus(createDialog)
createDialogApp.Draw()
createDialog.setContainerInfoPageNextFocus()
Expect(createDialog.focusElement).To(Equal(createContainerSecretFieldFocus))
createDialogApp.SetFocus(createDialog)
createDialogApp.Draw()
createDialog.setContainerInfoPageNextFocus()
@ -289,6 +299,74 @@ var _ = Describe("container create", Ordered, func() {
Expect(createDialog.focusElement).To(Equal(createContainerFormFocus))
})
It("setResourceSettingsPageNextFocus", func() {
createDialog.focusElement = createContainerMemoryFieldFocus
createDialogApp.SetFocus(createDialog)
createDialogApp.Draw()
createDialog.setResourceSettingsPageNextFocus()
Expect(createDialog.focusElement).To(Equal(createContainerMemoryReservatoinFieldFocus))
createDialogApp.SetFocus(createDialog)
createDialogApp.Draw()
createDialog.setResourceSettingsPageNextFocus()
Expect(createDialog.focusElement).To(Equal(createContainerMemorySwapFieldFocus))
createDialogApp.SetFocus(createDialog)
createDialogApp.Draw()
createDialog.setResourceSettingsPageNextFocus()
Expect(createDialog.focusElement).To(Equal(createcontainerMemorySwappinessFieldFocus))
createDialogApp.SetFocus(createDialog)
createDialogApp.Draw()
createDialog.setResourceSettingsPageNextFocus()
Expect(createDialog.focusElement).To(Equal(createContainerCPUsFieldFocus))
createDialogApp.SetFocus(createDialog)
createDialogApp.Draw()
createDialog.setResourceSettingsPageNextFocus()
Expect(createDialog.focusElement).To(Equal(createContainerCPUSharesFieldFocus))
createDialogApp.SetFocus(createDialog)
createDialogApp.Draw()
createDialog.setResourceSettingsPageNextFocus()
Expect(createDialog.focusElement).To(Equal(createContainerCPUPeriodFieldFocus))
createDialogApp.SetFocus(createDialog)
createDialogApp.Draw()
createDialog.setResourceSettingsPageNextFocus()
Expect(createDialog.focusElement).To(Equal(createContainerCPURtPeriodFieldFocus))
createDialogApp.SetFocus(createDialog)
createDialogApp.Draw()
createDialog.setResourceSettingsPageNextFocus()
Expect(createDialog.focusElement).To(Equal(createContainerCPUQuotaFieldFocus))
createDialogApp.SetFocus(createDialog)
createDialogApp.Draw()
createDialog.setResourceSettingsPageNextFocus()
Expect(createDialog.focusElement).To(Equal(createContainerCPURtRuntimeFeildFocus))
createDialogApp.SetFocus(createDialog)
createDialogApp.Draw()
createDialog.setResourceSettingsPageNextFocus()
Expect(createDialog.focusElement).To(Equal(createContainerCPUSetCPUsFieldFocus))
createDialogApp.SetFocus(createDialog)
createDialogApp.Draw()
createDialog.setResourceSettingsPageNextFocus()
Expect(createDialog.focusElement).To(Equal(createContainerCPUSetMemsFieldFocus))
createDialogApp.SetFocus(createDialog)
createDialogApp.Draw()
createDialog.setResourceSettingsPageNextFocus()
Expect(createDialog.focusElement).To(Equal(createContainerShmSizeFieldFocus))
createDialogApp.SetFocus(createDialog)
createDialogApp.Draw()
createDialog.setResourceSettingsPageNextFocus()
Expect(createDialog.focusElement).To(Equal(createContainerShmSizeSystemdFieldFocus))
})
It("hide", func() {
createDialog.Hide()
Expect(createDialog.IsDisplay()).To(Equal(false))

View File

@ -189,7 +189,7 @@ func NewContainerExecDialog() *ContainerExecDialog {
mLayout.AddItem(dialog.command, 1, 0, true)
// interactive, tty, privileged and detach
checkBoxWidth := execDialogLabelWidth + 4 //nolint:gomnd
checkBoxWidth := execDialogLabelWidth + 4 //nolint:mnd
labelPaddings := 5
checkBoxLayout := tview.NewFlex().SetDirection(tview.FlexColumn)
@ -578,7 +578,7 @@ func (d *ContainerExecDialog) SetRect(x, y, width, height int) {
if width > execDialogMaxWidth {
wEmptySpace := width - execDialogMaxWidth
if wEmptySpace > 0 {
dX = x + (wEmptySpace / 2) //nolint:gomnd
dX = x + (wEmptySpace / 2) //nolint:mnd
}
dWidth = execDialogMaxWidth
@ -591,7 +591,7 @@ func (d *ContainerExecDialog) SetRect(x, y, width, height int) {
hEmptySpace := height - execDialogMaxHeight
if hEmptySpace > 0 {
dY = y + (hEmptySpace / 2) //nolint:gomnd
dY = y + (hEmptySpace / 2) //nolint:mnd
}
dHeight = execDialogMaxHeight
@ -618,7 +618,7 @@ func (d *ContainerExecDialog) Draw(screen tcell.Screen) {
// SetCancelFunc sets form cancel button selected function.
func (d *ContainerExecDialog) SetCancelFunc(handler func()) *ContainerExecDialog {
d.cancelHandler = handler
cancelButton := d.form.GetButton(d.form.GetButtonCount() - 2) //nolint:gomnd
cancelButton := d.form.GetButton(d.form.GetButtonCount() - 2) //nolint:mnd
cancelButton.SetSelectedFunc(handler)

View File

@ -39,10 +39,10 @@ const (
cntRestoreDialogMaxWidth = cntRestoreDialogLabelWidth +
cntRestoreDialogChkGroupColTwoWidth +
cntRestoreDialogChkGroupColThreeWidth +
cntRestoreDialogChkGroupColFourWidth + (6 * cntRestoreDialogPadding) //nolint:gomnd
cntRestoreDialogChkGroupColFourWidth + (6 * cntRestoreDialogPadding) //nolint:mnd
cntRestoreDialogMaxHeight = 17
cntRestoreDialogSingleFieldWidth = cntRestoreDialogMaxWidth -
cntRestoreDialogLabelWidth - (2 * cntRestoreDialogPadding) //nolint:gomnd
cntRestoreDialogLabelWidth - (2 * cntRestoreDialogPadding) //nolint:mnd
)
// ContainerRestoreDialog implements container restore dialog primitive.
@ -414,13 +414,13 @@ func (d *ContainerRestoreDialog) InputHandler() func(event *tcell.EventKey, setF
// SetRect set rects for this primitive.
func (d *ContainerRestoreDialog) SetRect(x, y, width, height int) {
if width > cntRestoreDialogMaxWidth {
emptySpace := (width - cntRestoreDialogMaxWidth) / 2 //nolint:gomnd
emptySpace := (width - cntRestoreDialogMaxWidth) / 2 //nolint:mnd
x += emptySpace
width = cntRestoreDialogMaxWidth
}
if height > cntRestoreDialogMaxHeight {
emptySpace := (height - cntRestoreDialogMaxHeight) / 2 //nolint:gomnd
emptySpace := (height - cntRestoreDialogMaxHeight) / 2 //nolint:mnd
y += emptySpace
height = cntRestoreDialogMaxHeight
}
@ -455,7 +455,7 @@ func (d *ContainerRestoreDialog) SetRestoreFunc(handler func()) *ContainerRestor
// SetCancelFunc sets form cancel button selected function.
func (d *ContainerRestoreDialog) SetCancelFunc(handler func()) *ContainerRestoreDialog {
d.cancelHandler = handler
cancelButton := d.form.GetButton(d.form.GetButtonCount() - 2) //nolint:gomnd
cancelButton := d.form.GetButton(d.form.GetButtonCount() - 2) //nolint:mnd
cancelButton.SetSelectedFunc(handler)
@ -497,7 +497,7 @@ func (d *ContainerRestoreDialog) SetContainers(cnts [][]string) {
emptyOptions := fmt.Sprintf("%*s", cntRestoreDialogSingleFieldWidth, " ")
cntOptions := []string{emptyOptions}
for i := 0; i < len(cnts); i++ {
for i := range cnts {
cntInfo := fmt.Sprintf("%s (%s)", utils.GetIDWithLimit(cnts[i][0]), cnts[i][1])
cntInfoOption := fmt.Sprintf("%-*s", cntRestoreDialogSingleFieldWidth, cntInfo)
cntOptions = append(cntOptions, cntInfoOption)
@ -511,7 +511,7 @@ func (d *ContainerRestoreDialog) SetPods(pods [][]string) {
emptyOptions := fmt.Sprintf("%*s", cntRestoreDialogSingleFieldWidth, " ")
podOptions := []string{emptyOptions}
for i := 0; i < len(pods); i++ {
for i := range pods {
podInfo := fmt.Sprintf("%s (%s)", utils.GetIDWithLimit(pods[i][0]), pods[i][1])
podInfoOption := fmt.Sprintf("%-*s", cntRestoreDialogSingleFieldWidth, podInfo)
podOptions = append(podOptions, podInfoOption)

View File

@ -36,8 +36,8 @@ func NewContainerStatsDialog() *ContainerStatsDialog {
statsDialog := ContainerStatsDialog{
Box: tview.NewBox(),
containerInfo: tview.NewInputField(),
maxHeight: 14, //nolint:gomnd
maxWidth: 92, //nolint:gomnd
maxHeight: 14, //nolint:mnd
maxWidth: 92, //nolint:mnd
}
// table
@ -178,18 +178,18 @@ func (d *ContainerStatsDialog) Draw(screen tcell.Screen) {
func (d *ContainerStatsDialog) SetRect(x, y, width, height int) {
dX := x + dialogs.DialogPadding
dY := y + dialogs.DialogPadding - 1
dWidth := width - (2 * dialogs.DialogPadding) //nolint:gomnd
dHeight := height - (2 * (dialogs.DialogPadding - 1)) //nolint:gomnd
dWidth := width - (2 * dialogs.DialogPadding) //nolint:mnd
dHeight := height - (2 * (dialogs.DialogPadding - 1)) //nolint:mnd
if dHeight > d.maxHeight {
emptySpace := dHeight - d.maxHeight
dY += (emptySpace / 2) //nolint:gomnd
dY += (emptySpace / 2) //nolint:mnd
dHeight = d.maxHeight
}
if dWidth > d.maxWidth {
emptySpace := dWidth - d.maxWidth
dX += (emptySpace / 2) //nolint:gomnd
dX += (emptySpace / 2) //nolint:mnd
dWidth = d.maxWidth
}
@ -281,28 +281,28 @@ var (
col: 1,
}
containerBlockInputCell = tableCell{
row: 2, //nolint:gomnd
row: 2, //nolint:mnd
col: 1,
}
containerBlockOutputCell = tableCell{
row: 3, //nolint:gomnd
row: 3, //nolint:mnd
col: 1,
}
containerPidsCell = tableCell{
row: 0,
col: 3, //nolint:gomnd
col: 3, //nolint:mnd
}
containerCPUPercCell = tableCell{
row: 1,
col: 3, //nolint:gomnd
col: 3, //nolint:mnd
}
containerNetInputCell = tableCell{
row: 2, //nolint:gomnd
col: 3, //nolint:gomnd
row: 2, //nolint:mnd
col: 3, //nolint:mnd
}
containerNetOutputCell = tableCell{
row: 3, //nolint:gomnd
col: 3, //nolint:gomnd
row: 3, //nolint:mnd
col: 3, //nolint:mnd
}
)
@ -322,7 +322,7 @@ func (d *ContainerStatsDialog) initTableUI() {
d.table.SetCell(containerMemPercCell.row, containerMemPercCell.col-1,
tview.NewTableCell("memory %:").SetTextColor(headerFgColor))
d.table.SetCell(containerMemPercCell.row, containerMemPercCell.col, tview.NewTableCell(""))
d.setContainerMemPerc(0.00) //nolint:gomnd
d.setContainerMemPerc(0.00) //nolint:mnd
d.table.SetCell(containerBlockInputCell.row, containerBlockInputCell.col-1,
tview.NewTableCell("block input:").SetTextColor(headerFgColor))
@ -340,7 +340,7 @@ func (d *ContainerStatsDialog) initTableUI() {
d.table.SetCell(containerCPUPercCell.row, containerCPUPercCell.col-1,
tview.NewTableCell("cpu %:").SetTextColor(headerFgColor))
d.table.SetCell(containerCPUPercCell.row, containerCPUPercCell.col, tview.NewTableCell(""))
d.setContainerCPUPerc(0.00) //nolint:gomnd
d.setContainerCPUPerc(0.00) //nolint:mnd
d.table.SetCell(containerNetInputCell.row, containerNetInputCell.col-1,
tview.NewTableCell("net input:").SetTextColor(headerFgColor))

View File

@ -6,6 +6,7 @@ import (
"fmt"
"io"
"strings"
"sync"
"github.com/containers/podman-tui/pdcs/containers"
"github.com/containers/podman-tui/ui/dialogs"
@ -55,6 +56,8 @@ type VtermDialog struct { //nolint:revive
init bool
ttyWidth int
ttyHeight int
alreadyDetached bool
alreadyDetachedLock sync.Mutex
cancelHandler func()
fastRefreshHandler func()
}
@ -74,7 +77,8 @@ func NewVtermDialog() *VtermDialog {
tcell.KeyCtrlP, tcell.KeyCtrlQ, tcell.KeyCtrlP,
},
},
display: false,
display: false,
alreadyDetached: false,
}
dialog.initLayoutUI()
@ -118,7 +122,7 @@ func (d *VtermDialog) initLayoutUI() {
layout.SetBackgroundColor(bgColor)
layout.SetBorder(false)
layout.AddItem(d.containerInfo, 1, 0, true)
layout.AddItem(utils.EmptyBoxSpace(bgColor), 1, 0, true)
// layout.AddItem(utils.EmptyBoxSpace(bgColor), 1, 0, true)
layout.AddItem(d.termScreen, 0, 1, true)
termLayout.SetBackgroundColor(bgColor)
@ -132,14 +136,14 @@ func (d *VtermDialog) initLayoutUI() {
d.layout.SetBorder(true)
d.layout.SetBorderColor(borderColor)
d.layout.SetBackgroundColor(bgColor)
d.layout.SetTitle("CONTAINER TERMINAL")
// d.layout.SetTitle("CONTAINER TERMINAL")
d.layout.AddItem(termLayout, 0, 1, true)
d.layout.AddItem(d.form, dialogs.DialogFormHeight, 0, true)
}
func (d *VtermDialog) initChannelsCommon() {
d.sessionOutputDoneChan = make(chan bool, 2) //nolint:gomnd
d.sessionOutputDoneChan = make(chan bool, 2) //nolint:mnd
d.vtTerminal = vt10x.New()
sessionStdinPipeIn, sessionStdinPipeOut := io.Pipe()
d.sessionStdin = bufio.NewReader(sessionStdinPipeIn)
@ -157,7 +161,7 @@ func (d *VtermDialog) InitAttachChannels() (io.Reader, io.Writer) {
d.initChannelsCommon()
c := make(chan []byte, 1000) //nolint:gomnd
c := make(chan []byte, 1000) //nolint:mnd
d.sessionStdout = NewWriter(c)
d.init = true
@ -173,7 +177,7 @@ func (d *VtermDialog) InitExecChannels() (*bufio.Reader, channel.WriteCloser) {
d.initChannelsCommon()
c := make(chan []byte, 1000) //nolint:gomnd
c := make(chan []byte, 1000) //nolint:mnd
d.execSessionStdout = channel.NewWriter(c)
@ -200,9 +204,29 @@ func (d *VtermDialog) Display() {
go d.startVTBuffer()
}
d.SetAlreadyDetach(false)
d.display = true
}
func (d *VtermDialog) SetAlreadyDetach(detached bool) {
d.alreadyDetachedLock.Lock()
defer d.alreadyDetachedLock.Unlock()
d.alreadyDetached = detached
}
func (d *VtermDialog) IsAlreadyDetach() bool {
var alreadyDetached bool
d.alreadyDetachedLock.Lock()
alreadyDetached = d.alreadyDetached
d.alreadyDetachedLock.Unlock()
return alreadyDetached
}
// IsDisplay returns true if primitive is shown onto the screen.
func (d *VtermDialog) IsDisplay() bool {
return d.display
@ -220,7 +244,9 @@ func (d *VtermDialog) Hide() {
d.sessionMode = sessionModeNone
d.sendDetachToSession()
if !d.IsAlreadyDetach() {
d.sendDetachToSession()
}
if d.sessionMode == sessionModeExec {
d.execSessionStdout.Close()
@ -294,7 +320,9 @@ func (d *VtermDialog) InputHandler() func(event *tcell.EventKey, setFocus func(p
if handler := d.termScreen.InputHandler(); handler != nil {
handler(event, setFocus)
d.writeToSession(event)
if !d.IsAlreadyDetach() {
d.writeToSession(event)
}
return
}
@ -314,8 +342,8 @@ func (d *VtermDialog) InputHandler() func(event *tcell.EventKey, setFocus func(p
func (d *VtermDialog) SetRect(x, y, width, height int) {
dX := x + 1
dY := y + 1
dWidth := width - 2 //nolint:gomnd
dHeight := height - 2 //nolint:gomnd
dWidth := width - 2 //nolint:mnd
dHeight := height - 2 //nolint:mnd
d.Box.SetRect(dX, dY, dWidth, dHeight)
}
@ -341,8 +369,8 @@ func (d *VtermDialog) Draw(screen tcell.Screen) {
}
// set terminal background
for trow := 0; trow < height; trow++ {
for tcol := 0; tcol < width; tcol++ {
for trow := range height {
for tcol := range width {
tview.PrintJoinedSemigraphics(screen, x+tcol, y+trow, rune(0), terminalStyle)
}
}
@ -350,7 +378,7 @@ func (d *VtermDialog) Draw(screen tcell.Screen) {
content, cursor := d.vtContent()
contentLines := strings.Split(content, "\n")
for row := 0; row < len(contentLines); row++ {
for row := range contentLines {
tview.PrintSimple(screen, contentLines[row], x, y+row)
}
@ -391,8 +419,12 @@ func (d *VtermDialog) SetCancelFunc(handler func()) *VtermDialog {
// SetContainerInfo sets container's ID and NAME to the terminal header.
func (d *VtermDialog) SetContainerInfo(id string, name string) {
d.containerID = id
containerInfo := id[0:12]
if name != "" {
containerInfo = fmt.Sprintf("%s (%s)", containerInfo, name)
}
containerInfo := fmt.Sprintf("%12s (%s)", id, name)
d.containerInfo.SetText(containerInfo)
}
@ -404,7 +436,7 @@ func (d *VtermDialog) SetSessionID(id string) {
id = id[0:utils.IDLength]
}
sessionIDLabel := fmt.Sprintf("SESSION (%s)", id)
sessionIDLabel := fmt.Sprintf("TERMINAL SESSION (%s)", id)
d.termScreen.SetTitle(sessionIDLabel)
}
@ -422,23 +454,23 @@ func (d *VtermDialog) SetFastRefreshHandler(handler func()) {
func (d *VtermDialog) writeToSession(event *tcell.EventKey) {
switch event.Key() { //nolint:exhaustive
case tcell.KeyUp:
d.sessionStdinWriter.WriteRune(rune(27)) //nolint:errcheck,gomnd
d.sessionStdinWriter.WriteRune(rune(91)) //nolint:errcheck,gomnd
d.sessionStdinWriter.WriteRune(rune(65)) //nolint:errcheck,gomnd
d.sessionStdinWriter.WriteRune(rune(27)) //nolint:errcheck,mnd
d.sessionStdinWriter.WriteRune(rune(91)) //nolint:errcheck,mnd
d.sessionStdinWriter.WriteRune(rune(65)) //nolint:errcheck,mnd
case tcell.KeyDown:
d.sessionStdinWriter.WriteRune(rune(27)) //nolint:errcheck,gomnd
d.sessionStdinWriter.WriteRune(rune(91)) //nolint:errcheck,gomnd
d.sessionStdinWriter.WriteRune(rune(66)) //nolint:errcheck,gomnd
d.sessionStdinWriter.WriteRune(rune(27)) //nolint:errcheck,mnd
d.sessionStdinWriter.WriteRune(rune(91)) //nolint:errcheck,mnd
d.sessionStdinWriter.WriteRune(rune(66)) //nolint:errcheck,mnd
case tcell.KeyRight:
d.sessionStdinWriter.WriteRune(rune(27)) //nolint:errcheck,gomnd
d.sessionStdinWriter.WriteRune(rune(91)) //nolint:errcheck,gomnd
d.sessionStdinWriter.WriteRune(rune(67)) //nolint:errcheck,gomnd
d.sessionStdinWriter.WriteRune(rune(27)) //nolint:errcheck,mnd
d.sessionStdinWriter.WriteRune(rune(91)) //nolint:errcheck,mnd
d.sessionStdinWriter.WriteRune(rune(67)) //nolint:errcheck,mnd
case tcell.KeyLeft:
d.sessionStdinWriter.WriteRune(rune(27)) //nolint:errcheck,gomnd
d.sessionStdinWriter.WriteRune(rune(91)) //nolint:errcheck,gomnd
d.sessionStdinWriter.WriteRune(rune(68)) //nolint:errcheck,gomnd
d.sessionStdinWriter.WriteRune(rune(27)) //nolint:errcheck,mnd
d.sessionStdinWriter.WriteRune(rune(91)) //nolint:errcheck,mnd
d.sessionStdinWriter.WriteRune(rune(68)) //nolint:errcheck,mnd
case tcell.KeyEsc:
d.sessionStdinWriter.WriteRune(rune(27)) //nolint:errcheck,gomnd
d.sessionStdinWriter.WriteRune(rune(27)) //nolint:errcheck,mnd
default:
d.sessionStdinWriter.WriteRune(event.Rune()) //nolint:errcheck
}
@ -451,7 +483,7 @@ func (d *VtermDialog) sendDetachToSession() {
keys := d.detachKeys.keys()
for i := 0; i < len(keys); i++ {
for i := range keys {
d.sessionStdinWriter.WriteRune(rune(keys[i])) //nolint:errcheck
}

View File

@ -46,6 +46,8 @@ func (cnt *Containers) runCommand(cmd string) { //nolint:cyclop
cnt.port()
case "rm":
cnt.rm()
case "run":
cnt.runDialog.Display()
case "start":
cnt.start()
case "stats":
@ -90,6 +92,7 @@ func (cnt *Containers) attach() {
cnt.progressDialog.Hide()
cnt.displayError(title, err)
cnt.appFocusHandler()
return
}
@ -101,6 +104,7 @@ func (cnt *Containers) attach() {
cnt.progressDialog.Hide()
cnt.terminalDialog.SetContainerInfo(cntID, cntName)
cnt.terminalDialog.Display()
cnt.appFocusHandler()
}
}
@ -128,6 +132,7 @@ func (cnt *Containers) preHealthcheck() {
title := fmt.Sprintf("CONTAINER (%s) HEALTHCHECK ERROR", cntID)
cnt.displayError(title, err)
cnt.appFocusHandler()
return
}
@ -137,6 +142,7 @@ func (cnt *Containers) preHealthcheck() {
cnt.messageDialog.SetTitle("podman container healthcheck")
cnt.messageDialog.SetText(dialogs.MessageContainerInfo, headerLabel, report)
cnt.messageDialog.Display()
cnt.appFocusHandler()
}
go cntHealthCheck()
@ -205,6 +211,7 @@ func (cnt *Containers) restore() {
cnt.progressDialog.Hide()
cnt.displayError(title, err)
cnt.appFocusHandler()
return
}
@ -215,6 +222,7 @@ func (cnt *Containers) restore() {
cnt.messageDialog.SetTitle("podman container restore")
cnt.messageDialog.SetText(dialogs.MessageContainerInfo, headerLabel, report)
cnt.messageDialog.Display()
cnt.appFocusHandler()
}
go restore()
@ -246,6 +254,7 @@ func (cnt *Containers) checkpoint() {
cnt.progressDialog.Hide()
cnt.displayError(title, err)
cnt.appFocusHandler()
return
}
@ -256,6 +265,7 @@ func (cnt *Containers) checkpoint() {
cnt.messageDialog.SetTitle("podman container checkpoint")
cnt.messageDialog.SetText(dialogs.MessageContainerInfo, headerLabel, report)
cnt.messageDialog.Display()
cnt.appFocusHandler()
}
go checkpoint()
@ -289,6 +299,7 @@ func (cnt *Containers) commit() {
title := fmt.Sprintf("CONTAINER (%s) COMMIT ERROR", cnt.selectedID)
cnt.displayError(title, err)
cnt.appFocusHandler()
return
}
@ -299,6 +310,7 @@ func (cnt *Containers) commit() {
cnt.messageDialog.SetTitle("podman container commit")
cnt.messageDialog.SetText(dialogs.MessageContainerInfo, headerLabel, response)
cnt.messageDialog.Display()
cnt.appFocusHandler()
}
go cntCommit()
@ -362,8 +374,8 @@ func (cnt *Containers) exec() {
cntID, cntName := cnt.getSelectedItem()
_, _, width, height := cnt.table.GetInnerRect()
width = width - (2 * dialogs.DialogPadding) - 6 //nolint:gomnd
height = height - (2 * (dialogs.DialogPadding - 1)) - 2*dialogs.DialogFormHeight - 4 //nolint:gomnd
width = width - (2 * dialogs.DialogPadding) - 6 //nolint:mnd
height = height - (2 * (dialogs.DialogPadding - 1)) - 2*dialogs.DialogFormHeight - 4 //nolint:mnd
execOpts := cnt.execDialog.ContainerExecOptions()
execOpts.TtyWidth = width
@ -386,6 +398,7 @@ func (cnt *Containers) exec() {
prepareAndExec := func() {
cnt.terminalDialog.SetSessionID(execSessionID)
containers.Exec(execSessionID, execOpts)
cnt.terminalDialog.SetAlreadyDetach(true)
}
go prepareAndExec()
@ -393,9 +406,147 @@ func (cnt *Containers) exec() {
cnt.terminalDialog.Display()
}
func (cnt *Containers) run() {
runOpts := cnt.runDialog.ContainerCreateOptions()
if runOpts.Image == "" {
cnt.displayError("CONTAINER RUN ERROR", errEmptyContainerImageName)
return
}
cnt.progressDialog.SetTitle("container run in progress")
cnt.progressDialog.Display()
if runOpts.Detach {
cnt.runDetach(runOpts)
return
}
cnt.runAttach(runOpts)
}
func (cnt *Containers) runDetach(runOpts containers.CreateOptions) {
go func() {
warnings, cntID, err := containers.Create(runOpts, true)
if err != nil {
cnt.progressDialog.Hide()
cnt.displayError("CONTAINER RUN ERROR", err)
cnt.appFocusHandler()
return
}
if len(warnings) > 0 {
cnt.progressDialog.Hide()
headerLabel := fmt.Sprintf("%s (%s)", "", runOpts.Name)
cnt.messageDialog.SetTitle("CONTAINER RUN WARNINGS")
cnt.messageDialog.SetText(dialogs.MessageContainerInfo, headerLabel, strings.Join(warnings, "\n"))
cnt.messageDialog.Display()
cnt.appFocusHandler()
return
}
if err := containers.Start(cntID); err != nil {
cnt.progressDialog.Hide()
cnt.displayError("CONTAINER RUN ERROR", err)
cnt.appFocusHandler()
return
}
cnt.progressDialog.Hide()
}()
}
func (cnt *Containers) runAttach(runOpts containers.CreateOptions) {
runStatusChan := make(chan bool)
attachReady := make(chan bool)
runIDChan := make(chan string)
stdin, stdout := cnt.terminalDialog.InitAttachChannels()
detachKeys := cnt.terminalDialog.DetachKeys()
run := func() {
warnings, cntID, err := containers.Create(runOpts, true)
if err != nil {
runStatusChan <- false
cnt.displayError("CONTAINER RUN ERROR", err)
cnt.appFocusHandler()
return
}
if len(warnings) > 0 {
runStatusChan <- false
headerLabel := fmt.Sprintf("%s (%s)", "", runOpts.Name)
cnt.messageDialog.SetTitle("CONTAINER RUN WARNINGS")
cnt.messageDialog.SetText(dialogs.MessageContainerInfo, headerLabel, strings.Join(warnings, "\n"))
cnt.messageDialog.Display()
cnt.appFocusHandler()
return
}
runIDChan <- cntID
err = containers.RunInitAttach(cntID, stdin, stdout, attachReady, detachKeys)
if err != nil {
attachReady <- false
cnt.displayError("CONTAINER RUN ERROR", err)
cnt.appFocusHandler()
return
}
runStatusChan <- true
}
waitForAttach := func() {
cntID := ""
for {
select {
case <-runStatusChan:
cnt.terminalDialog.SetAlreadyDetach(true)
cnt.progressDialog.Hide()
return
case id := <-runIDChan:
cntID = id
case isReady := <-attachReady:
cnt.progressDialog.Hide()
if isReady {
if err := containers.Start(cntID); err != nil {
cnt.displayError("CONTAINER RUN ERROR", err)
cnt.appFocusHandler()
return
}
cnt.terminalDialog.SetContainerInfo(cntID, "")
cnt.terminalDialog.Display()
cnt.appFocusHandler()
}
}
}
}
go waitForAttach()
go run()
}
func (cnt *Containers) create() {
createOpts := cnt.createDialog.ContainerCreateOptions()
if createOpts.Name == "" || createOpts.Image == "" {
if createOpts.Image == "" {
cnt.displayError("CONTAINER CREATE ERROR", errEmptyContainerImageName)
return
@ -405,12 +556,13 @@ func (cnt *Containers) create() {
cnt.progressDialog.Display()
create := func() {
warnings, err := containers.Create(createOpts)
warnings, _, err := containers.Create(createOpts, false)
cnt.progressDialog.Hide()
if err != nil {
cnt.displayError("CONTAINER CREATE ERROR", err)
cnt.appFocusHandler()
return
}
@ -421,6 +573,7 @@ func (cnt *Containers) create() {
cnt.messageDialog.SetTitle("CONTAINER CREATE WARNINGS")
cnt.messageDialog.SetText(dialogs.MessageContainerInfo, headerLabel, strings.Join(warnings, "\n"))
cnt.messageDialog.Display()
cnt.appFocusHandler()
}
}
@ -446,7 +599,7 @@ func (cnt *Containers) diff() {
cnt.messageDialog.SetTitle("podman container diff")
cnt.messageDialog.SetText(dialogs.MessageContainerInfo, headerLabel, strings.Join(data, "\n"))
cnt.messageDialog.Display()
cnt.messageDialog.DisplayFullSize()
}
func (cnt *Containers) inspect() {
@ -468,7 +621,7 @@ func (cnt *Containers) inspect() {
cnt.messageDialog.SetTitle("podman container inspect")
cnt.messageDialog.SetText(dialogs.MessageContainerInfo, headerLabel, data)
cnt.messageDialog.Display()
cnt.messageDialog.DisplayFullSize()
}
func (cnt *Containers) kill() {
@ -489,6 +642,7 @@ func (cnt *Containers) kill() {
if err != nil {
title := fmt.Sprintf("CONTAINER (%s) KILL ERROR", cnt.selectedID)
cnt.displayError(title, err)
cnt.appFocusHandler()
return
}
@ -517,6 +671,7 @@ func (cnt *Containers) logs() {
title := fmt.Sprintf("CONTAINER (%s) DISPLAY LOG ERROR", cntID)
cnt.displayError(title, err)
cnt.appFocusHandler()
return
}
@ -530,7 +685,8 @@ func (cnt *Containers) logs() {
cnt.messageDialog.SetTitle("podman container logs")
cnt.messageDialog.SetText(dialogs.MessageContainerInfo, headerLabel, cntLogs)
cnt.messageDialog.TextScrollToEnd()
cnt.messageDialog.Display()
cnt.messageDialog.DisplayFullSize()
cnt.appFocusHandler()
}
go getLogs()
@ -554,6 +710,7 @@ func (cnt *Containers) pause() {
if err != nil {
title := fmt.Sprintf("CONTAINER (%s) PAUSE ERROR", cnt.selectedID)
cnt.displayError(title, err)
cnt.appFocusHandler()
return
}
@ -595,7 +752,7 @@ func (cnt *Containers) cprune() {
}
func (cnt *Containers) prune() {
cnt.progressDialog.SetTitle("container purne in progress")
cnt.progressDialog.SetTitle("container prune in progress")
cnt.progressDialog.Display()
prune := func() {
@ -605,6 +762,7 @@ func (cnt *Containers) prune() {
if err != nil {
cnt.displayError("CONTAINER PRUNE ERROR", err)
cnt.appFocusHandler()
return
}
@ -657,6 +815,7 @@ func (cnt *Containers) renameContainer(id string, newName string) {
if err != nil {
title := fmt.Sprintf("CONTAINER (%s) RENAME ERROR", cnt.selectedID)
cnt.displayError(title, err)
cnt.appFocusHandler()
return
}
@ -700,6 +859,7 @@ func (cnt *Containers) remove() {
title := fmt.Sprintf("CONTAINER (%s) REMOVE ERROR", cnt.selectedID)
cnt.displayError(title, err)
cnt.appFocusHandler()
return
}
@ -708,6 +868,7 @@ func (cnt *Containers) remove() {
title := fmt.Sprintf("CONTAINER (%s) REMOVE ERROR", cnt.selectedID)
cnt.displayError(title, fmt.Errorf("%v", errData)) //nolint:goerr113
cnt.appFocusHandler()
}
}
@ -733,6 +894,7 @@ func (cnt *Containers) start() {
title := fmt.Sprintf("CONTAINER (%s) START ERROR", cnt.selectedID)
cnt.displayError(title, err)
cnt.appFocusHandler()
return
}
@ -759,6 +921,7 @@ func (cnt *Containers) stop() {
title := fmt.Sprintf("CONTAINER (%s) STOP ERROR", cnt.selectedID)
cnt.displayError(title, err)
cnt.appFocusHandler()
return
}
@ -808,6 +971,7 @@ func (cnt *Containers) unpause() {
title := fmt.Sprintf("CONTAINER (%s) UNPAUSE ERROR", cnt.selectedID)
cnt.displayError(title, err)
cnt.appFocusHandler()
return
}

View File

@ -43,7 +43,7 @@ var (
errNoContainerStart = errors.New("there is no container to start")
errNoContainerStop = errors.New("there is no container to stop")
errNoContainerTop = errors.New("there is no container to display top")
errEmptyContainerImageName = errors.New("empty container name or image name")
errEmptyContainerImageName = errors.New("empty container image name")
)
// Containers implements the containers page primitive.
@ -60,6 +60,7 @@ type Containers struct {
progressDialog *dialogs.ProgressDialog
topDialog *dialogs.TopDialog
createDialog *cntdialogs.ContainerCreateDialog
runDialog *cntdialogs.ContainerCreateDialog
execDialog *cntdialogs.ContainerExecDialog
terminalDialog *vterm.VtermDialog
statsDialog *cntdialogs.ContainerStatsDialog
@ -71,6 +72,7 @@ type Containers struct {
selectedName string
confirmData string
fastRefreshChan chan bool
appFocusHandler func()
}
type containerListReport struct {
@ -90,7 +92,8 @@ func NewContainers() *Containers {
progressDialog: dialogs.NewProgressDialog(),
confirmDialog: dialogs.NewConfirmDialog(),
topDialog: dialogs.NewTopDialog(),
createDialog: cntdialogs.NewContainerCreateDialog(),
createDialog: cntdialogs.NewContainerCreateDialog(cntdialogs.ContainerCreateOnlyDialogMode),
runDialog: cntdialogs.NewContainerCreateDialog(cntdialogs.ContainerCreateAndRunDialogMode),
execDialog: cntdialogs.NewContainerExecDialog(),
terminalDialog: vterm.NewVtermDialog(),
statsDialog: cntdialogs.NewContainerStatsDialog(),
@ -117,6 +120,7 @@ func NewContainers() *Containers {
{"rename", "rename the selected container"},
{"restore", "restores a container from a checkpoint"},
{"rm", "remove the selected container"},
{"run", "runs a command in a new container from the given image"},
{"start", "start the selected containers"},
{"stats", "display container resource usage statistics"},
{"stop", "stop the selected containers"},
@ -131,7 +135,7 @@ func NewContainers() *Containers {
containers.table.SetBackgroundColor(style.BgColor)
containers.table.SetBorder(true)
for i := 0; i < len(containers.headers); i++ {
for i := range containers.headers {
containers.table.SetCell(0, i,
tview.NewTableCell(fmt.Sprintf("[black::b]%s", strings.ToUpper(containers.headers[i]))). //nolint:perfsprint
SetExpansion(1).
@ -180,11 +184,21 @@ func NewContainers() *Containers {
containers.createDialog.Hide()
})
containers.createDialog.SetCreateFunc(func() {
containers.createDialog.SetHandlerFunc(func() {
containers.createDialog.Hide()
containers.create()
})
// set run dialog functions
containers.runDialog.SetCancelFunc(func() {
containers.runDialog.Hide()
})
containers.runDialog.SetHandlerFunc(func() {
containers.runDialog.Hide()
containers.run()
})
// set exec dialog functions
containers.execDialog.SetCancelFunc(containers.execDialog.Hide)
containers.execDialog.SetExecFunc(containers.exec)
@ -213,6 +227,11 @@ func NewContainers() *Containers {
return containers
}
// SetAppFocusHandler sets application focus handler.
func (cnt *Containers) SetAppFocusHandler(handler func()) {
cnt.appFocusHandler = handler
}
// GetTitle returns primitive title.
func (cnt *Containers) GetTitle() string {
return cnt.title
@ -248,11 +267,11 @@ func (cnt *Containers) HasFocus() bool { //nolint:cyclop
return true
}
if cnt.Box.HasFocus() || cnt.terminalDialog.HasFocus() {
if cnt.runDialog.HasFocus() || cnt.terminalDialog.HasFocus() {
return true
}
return false
return cnt.Box.HasFocus()
}
// SubDialogHasFocus returns whether or not sub dialog primitive has focus.
@ -285,7 +304,7 @@ func (cnt *Containers) SubDialogHasFocus() bool { //nolint:cyclop
return true
}
return false
return cnt.runDialog.HasFocus()
}
// Focus is called when this primitive receives focus.
@ -339,6 +358,13 @@ func (cnt *Containers) Focus(delegate func(p tview.Primitive)) { //nolint:cyclop
return
}
// run dialog
if cnt.runDialog.IsDisplay() {
delegate(cnt.runDialog)
return
}
// exec dialog
if cnt.execDialog.IsDisplay() {
delegate(cnt.execDialog)
@ -440,6 +466,10 @@ func (cnt *Containers) HideAllDialogs() { //nolint:cyclop
cnt.createDialog.Hide()
}
if cnt.runDialog.IsDisplay() {
cnt.runDialog.Hide()
}
if cnt.execDialog.IsDisplay() {
cnt.execDialog.Hide()
}

View File

@ -26,14 +26,16 @@ func (cnt *Containers) UpdateData() {
}
cnt.containersList.mu.Lock()
defer cnt.containersList.mu.Unlock()
cnt.containersList.report = cntList
cnt.containersList.mu.Unlock()
}
func (cnt *Containers) getData() []entities.ListContainer {
cnt.containersList.mu.Lock()
defer cnt.containersList.mu.Unlock()
data := cnt.containersList.report
cnt.containersList.mu.Unlock()
return data
}
@ -41,15 +43,16 @@ func (cnt *Containers) getData() []entities.ListContainer {
// ClearData clears table data.
func (cnt *Containers) ClearData() {
cnt.containersList.mu.Lock()
defer cnt.containersList.mu.Unlock()
cnt.containersList.report = nil
cnt.containersList.mu.Unlock()
cnt.table.Clear()
expand := 1
fgColor := style.PageHeaderFgColor
bgColor := style.PageHeaderBgColor
for i := 0; i < len(cnt.headers); i++ {
for i := range cnt.headers {
cnt.table.SetCell(0, i,
tview.NewTableCell(fmt.Sprintf("[::b]%s", strings.ToUpper(cnt.headers[i]))). //nolint:perfsprint
SetExpansion(expand).

View File

@ -6,17 +6,17 @@ import (
// Draw draws this primitive onto the screen.
func (cnt *Containers) Draw(screen tcell.Screen) { //nolint:cyclop
cnt.refresh()
cnt.Box.DrawForSubclass(screen, cnt)
cnt.Box.SetBorder(false)
x, y, width, height := cnt.GetInnerRect()
cntViewX, cntViewY, cntViewW, cntViewH := cnt.GetInnerRect()
cnt.table.SetRect(x, y, width, height)
cnt.refresh(cntViewW)
cnt.table.SetRect(cntViewX, cntViewY, cntViewW, cntViewH)
cnt.table.SetBorder(true)
cnt.table.Draw(screen)
x, y, width, height = cnt.table.GetInnerRect()
x, y, width, height := cnt.table.GetInnerRect()
// error dialog
if cnt.errorDialog.IsDisplay() {
@ -49,9 +49,23 @@ func (cnt *Containers) Draw(screen tcell.Screen) { //nolint:cyclop
return
}
// run dialog
if cnt.runDialog.IsDisplay() {
cnt.runDialog.SetRect(x, y, width, height)
cnt.runDialog.Draw(screen)
return
}
// message dialog
if cnt.messageDialog.IsDisplay() {
cnt.messageDialog.SetRect(x, y, width, height+1)
if cnt.messageDialog.IsDisplayFullSize() {
cnt.messageDialog.SetRect(cntViewX, cntViewY, cntViewW, cntViewH)
} else {
cnt.messageDialog.SetRect(x, y, width, height+1)
}
cnt.messageDialog.Draw(screen)
return
@ -121,7 +135,7 @@ func (cnt *Containers) Draw(screen tcell.Screen) { //nolint:cyclop
// terminal dialog
if cnt.terminalDialog.IsDisplay() {
cnt.terminalDialog.SetRect(x, y, width, height)
cnt.terminalDialog.SetRect(cntViewX, cntViewY, cntViewW, cntViewH)
cnt.terminalDialog.Draw(screen)
return

View File

@ -44,6 +44,13 @@ func (cnt *Containers) InputHandler() func(event *tcell.EventKey, setFocus func(
}
}
// run dialog handler
if cnt.runDialog.HasFocus() {
if runDialogHandler := cnt.runDialog.InputHandler(); runDialogHandler != nil {
runDialogHandler(event, setFocus)
}
}
// exec dialog handler
if cnt.execDialog.HasFocus() {
if execDialogHandler := cnt.execDialog.InputHandler(); execDialogHandler != nil {

View File

@ -12,13 +12,15 @@ import (
"github.com/rivo/tview"
)
func (cnt *Containers) refresh() {
func (cnt *Containers) refresh(maxWidth int) {
imageColMaxWidth := maxWidth / 5 //nolint:mnd
cnt.table.Clear()
expand := 1
alignment := tview.AlignLeft
for i := 0; i < len(cnt.headers); i++ {
for i := range cnt.headers {
cnt.table.SetCell(0, i,
tview.NewTableCell(fmt.Sprintf("[::b]%s", strings.ToUpper(cnt.headers[i]))). //nolint:perfsprint
SetExpansion(expand).
@ -33,7 +35,7 @@ func (cnt *Containers) refresh() {
cnt.table.SetTitle(fmt.Sprintf("[::b]%s[%d]", strings.ToUpper(cnt.title), len(cntList)))
for i := 0; i < len(cntList); i++ {
for i := range cntList {
cntID := cntList[i].ID
if len(cntID) > utils.IDLength {
cntID = cntID[:utils.IDLength]
@ -72,6 +74,7 @@ func (cnt *Containers) refresh() {
// image name column
cnt.table.SetCell(rowIndex, viewContainersImageColIndex,
tview.NewTableCell(cntImage).
SetMaxWidth(imageColMaxWidth).
SetTextColor(cellTextColor).
SetExpansion(expand).
SetAlign(alignment))

View File

@ -69,7 +69,7 @@ func NewCommandDialog(options [][]string) *CommandDialog {
col1Width := 0
col2Width := 0
for i := 0; i < len(options); i++ {
for i := range options {
cmdsTable.SetCell(i+1, 0,
tview.NewTableCell(options[i][0]).
SetAlign(tview.AlignLeft).
@ -88,7 +88,7 @@ func NewCommandDialog(options [][]string) *CommandDialog {
}
}
cmdWidth = col1Width + col2Width + 2 //nolint:gomnd
cmdWidth = col1Width + col2Width + 2 //nolint:mnd
cmdsTable.SetFixed(1, 1)
cmdsTable.SetSelectable(true, false)
@ -254,8 +254,8 @@ func (cmd *CommandDialog) SetCancelFunc(handler func()) *CommandDialog {
// SetRect set rects for this primitive.
func (cmd *CommandDialog) SetRect(x, y, width, height int) {
ws := (width - cmd.width) / 2 //nolint:gomnd
hs := ((height - cmd.height) / 2) //nolint:gomnd
ws := (width - cmd.width) / 2 //nolint:mnd
hs := ((height - cmd.height) / 2) //nolint:mnd
dy := y + hs
bWidth := cmd.width

View File

@ -107,8 +107,8 @@ func (d *ConfirmDialog) HasFocus() bool {
func (d *ConfirmDialog) SetRect(x, y, width, height int) {
d.x = x + DialogPadding
d.y = y + DialogPadding
d.width = width - (2 * DialogPadding) //nolint:gomnd
d.height = height - (2 * DialogPadding) //nolint:gomnd
d.width = width - (2 * DialogPadding) //nolint:mnd
d.height = height - (2 * DialogPadding) //nolint:mnd
d.setRect()
}
@ -118,30 +118,30 @@ func (d *ConfirmDialog) setRect() {
messageHeight := len(strings.Split(d.message, "\n"))
messageWidth := getMessageWidth(d.message)
layoutHeight := messageHeight + 2 //nolint:gomnd
layoutHeight := messageHeight + 2 //nolint:mnd
if maxHeight > layoutHeight+DialogFormHeight {
d.height = layoutHeight + DialogFormHeight + 2 //nolint:gomnd
d.height = layoutHeight + DialogFormHeight + 2 //nolint:mnd
} else {
d.height = maxHeight
layoutHeight = d.height - DialogFormHeight - 2 //nolint:gomnd
layoutHeight = d.height - DialogFormHeight - 2 //nolint:mnd
}
if maxHeight > d.height {
emptyHeight := (maxHeight - d.height) / 2 //nolint:gomnd
emptyHeight := (maxHeight - d.height) / 2 //nolint:mnd
d.y += emptyHeight
}
if d.width > DialogMinWidth {
if messageWidth < DialogMinWidth {
d.width = DialogMinWidth + 2 //nolint:gomnd
d.width = DialogMinWidth + 4 //nolint:mnd
} else if messageWidth < d.width {
d.width = messageWidth + 2 //nolint:gomnd
d.width = messageWidth + 6 //nolint:mnd
}
}
if maxWidth > d.width {
emptyWidth := (maxWidth - d.width) / 2 //nolint:gomnd
emptyWidth := (maxWidth - d.width) / 2 //nolint:mnd
d.x += emptyWidth
}
@ -192,7 +192,7 @@ func (d *ConfirmDialog) InputHandler() func(event *tcell.EventKey, setFocus func
// SetCancelFunc sets form cancel button selected function.
func (d *ConfirmDialog) SetCancelFunc(handler func()) *ConfirmDialog {
d.cancelHandler = handler
cancelButton := d.form.GetButton(d.form.GetButtonCount() - 2) //nolint:gomnd
cancelButton := d.form.GetButton(d.form.GetButtonCount() - 2) //nolint:mnd
cancelButton.SetSelectedFunc(handler)
return d

View File

@ -102,7 +102,7 @@ func (d *SimpleInputDialog) setLayout(haveDesc bool) {
if !haveDesc {
descHeight = 1
d.height = siDialogHeight - 3 //nolint:gomnd
d.height = siDialogHeight - 3 //nolint:mnd
} else {
d.height = siDialogHeight
}
@ -174,7 +174,7 @@ func (d *SimpleInputDialog) SetInputText(text string) {
// SetLabel sets input fields label message.
func (d *SimpleInputDialog) SetLabel(text string) {
width := len(text) + 2 //nolint:gomnd
width := len(text) + 2 //nolint:mnd
d.inputWidth = siDialogInputWidth - width
d.input.SetFieldWidth(d.inputWidth)
@ -261,8 +261,8 @@ func (d *SimpleInputDialog) InputHandler() func(event *tcell.EventKey, setFocus
// SetRect set rects for this primitive.
func (d *SimpleInputDialog) SetRect(x, y, width, height int) {
ws := (width - siDialogWidth) / 2 //nolint:gomnd
hs := ((height - d.height) / 2) //nolint:gomnd
ws := (width - siDialogWidth) / 2 //nolint:mnd
hs := ((height - d.height) / 2) //nolint:mnd
dy := y + hs
bWidth := siDialogWidth
@ -311,7 +311,7 @@ func (d *SimpleInputDialog) SetSelectedFunc(handler func()) *SimpleInputDialog {
// SetCancelFunc sets form cancel button selected function.
func (d *SimpleInputDialog) SetCancelFunc(handler func()) *SimpleInputDialog {
d.cancelHandler = handler
cancelButton := d.form.GetButton(d.form.GetButtonCount() - 2) //nolint:gomnd
cancelButton := d.form.GetButton(d.form.GetButtonCount() - 2) //nolint:mnd
cancelButton.SetSelectedFunc(handler)
return d

View File

@ -13,13 +13,14 @@ import (
// MessageDialog is a simaple message dialog primitive.
type MessageDialog struct {
*tview.Box
layout *tview.Flex
infoType *tview.InputField
textview *tview.TextView
form *tview.Form
display bool
message string
cancelHandler func()
layout *tview.Flex
infoType *tview.InputField
textview *tview.TextView
form *tview.Form
display bool
displayFullSize bool
message string
cancelHandler func()
}
type messageInfo int
@ -38,10 +39,11 @@ const (
// NewMessageDialog returns new message dialog primitive.
func NewMessageDialog(text string) *MessageDialog {
dialog := &MessageDialog{
Box: tview.NewBox(),
infoType: tview.NewInputField(),
display: false,
message: text,
Box: tview.NewBox(),
infoType: tview.NewInputField(),
display: false,
displayFullSize: false,
message: text,
}
dialog.infoType.SetBackgroundColor(style.DialogBgColor)
@ -65,7 +67,6 @@ func NewMessageDialog(text string) *MessageDialog {
tlayout.AddItem(utils.EmptyBoxSpace(style.DialogBgColor), 1, 0, false)
tlayout.AddItem(tview.NewFlex().SetDirection(tview.FlexRow).
AddItem(dialog.infoType, 1, 0, false).
AddItem(utils.EmptyBoxSpace(style.DialogBgColor), 1, 0, false).
AddItem(dialog.textview, 0, 1, true),
0, 1, true)
tlayout.AddItem(utils.EmptyBoxSpace(style.DialogBgColor), 1, 0, false)
@ -78,7 +79,6 @@ func NewMessageDialog(text string) *MessageDialog {
dialog.form.SetButtonBackgroundColor(style.ButtonBgColor)
dialog.layout = tview.NewFlex().SetDirection(tview.FlexRow)
dialog.layout.AddItem(utils.EmptyBoxSpace(style.DialogBgColor), 1, 0, true)
dialog.layout.AddItem(tlayout, 0, 1, true)
dialog.layout.AddItem(dialog.form, DialogFormHeight, 0, true)
dialog.layout.SetBorder(true)
@ -91,6 +91,13 @@ func NewMessageDialog(text string) *MessageDialog {
// Display displays this primitive.
func (d *MessageDialog) Display() {
d.display = true
d.displayFullSize = false
}
// DisplayFullSize displays this primitive in full size.
func (d *MessageDialog) DisplayFullSize() {
d.display = true
d.displayFullSize = true
}
// IsDisplay returns true if primitive is shown.
@ -98,6 +105,11 @@ func (d *MessageDialog) IsDisplay() bool {
return d.display
}
// IsDisplayFullSize returns true if primitive is shown in full size.
func (d *MessageDialog) IsDisplayFullSize() bool {
return d.displayFullSize
}
// Hide stops displaying this primitive.
func (d *MessageDialog) Hide() {
d.message = ""
@ -169,37 +181,48 @@ func (d *MessageDialog) HasFocus() bool {
// SetRect set rects for this primitive.
func (d *MessageDialog) SetRect(x, y, width, height int) {
if d.displayFullSize {
dX := x + 1
dY := y + 1
dWidth := width - 2 //nolint:mnd
dHeight := height - 2 //nolint:mnd
d.Box.SetRect(dX, dY, dWidth, dHeight)
return
}
messageHeight := 0
if d.message != "" {
messageHeight = len(strings.Split(d.message, "\n")) + 3 //nolint:gomnd
messageHeight = len(strings.Split(d.message, "\n")) + 3 //nolint:mnd
}
messageWidth := getMessageWidth(d.message)
headerWidth := len(d.infoType.GetText()) + len(d.infoType.GetLabel()) + 4 //nolint:gomnd
headerWidth := len(d.infoType.GetText()) + len(d.infoType.GetLabel()) + 4 //nolint:mnd
if messageWidth < headerWidth {
messageWidth = headerWidth
}
dWidth := width - (2 * DialogPadding) //nolint:gomnd
if messageWidth+4 < dWidth {
dWidth = messageWidth + 4 //nolint:gomnd
dWidth := width - (2 * DialogPadding) //nolint:mnd
if messageWidth+6 < dWidth {
dWidth = messageWidth + 6 //nolint:mnd
}
if DialogMinWidth < width && dWidth < DialogMinWidth {
dWidth = DialogMinWidth
}
emptySpace := (width - dWidth) / 2 //nolint:gomnd
emptySpace := (width - dWidth) / 2 //nolint:mnd
dX := x + emptySpace
dHeight := messageHeight + DialogFormHeight + DialogPadding + 1
dHeight := messageHeight + DialogFormHeight + DialogPadding
if dHeight > height {
dHeight = height - DialogPadding - 1
}
textviewHeight := dHeight - DialogFormHeight - 2 //nolint:gomnd
hs := ((height - dHeight) / 2) //nolint:gomnd
textviewHeight := dHeight - DialogFormHeight - 2 //nolint:mnd
hs := ((height - dHeight) / 2) //nolint:mnd
dY := y + hs
d.Box.SetRect(dX, dY, dWidth, dHeight)

View File

@ -62,9 +62,9 @@ var _ = Describe("message dialog", Ordered, func() {
height := 20
// wants
wWants := 40
hWants := 11
xWants := 5 // 0 + (50-40)/2
yWants := 4 // 0 + (20-8)/2 - 2
hWants := 10
xWants := 5
yWants := 5
messageDialog.SetRect(x, y, width, height)
x1, y1, w1, h1 := messageDialog.Box.GetRect()

View File

@ -60,13 +60,13 @@ func (d *ProgressDialog) SetRect(x, y, width, height int) {
if d.width > prgMinWidth {
d.width = prgMinWidth
spaceWidth := (width - d.width) / 2 //nolint:gomnd
spaceWidth := (width - d.width) / 2 //nolint:mnd
d.x = x + spaceWidth
}
if height > 3 { //nolint:gomnd
if height > 3 { //nolint:mnd
d.height = 3
spaceHeight := (height - d.height) / 2 //nolint:gomnd
spaceHeight := (height - d.height) / 2 //nolint:mnd
d.y = y + spaceHeight
}
@ -104,11 +104,11 @@ func (d *ProgressDialog) InputHandler() func(event *tcell.EventKey, setFocus fun
})
}
func (d *ProgressDialog) tickStr(max int) string {
func (d *ProgressDialog) tickStr(maxCount int) string {
barColor := style.GetColorHex(style.PrgBarColor)
counter := d.counterValue
if counter < max-4 {
if counter < maxCount-4 {
d.counterValue++
} else {
d.counterValue = 0
@ -119,14 +119,14 @@ func (d *ProgressDialog) tickStr(max int) string {
prgEndStr := ""
prgStr := ""
for i := 0; i < d.counterValue; i++ {
for range d.counterValue {
prgHeadStr += fmt.Sprintf("[black::]%s", prgCell) //nolint:perfsprint
hWidth++
}
prgStr = prgCell + prgCell + prgCell + prgCell
for i := 0; i < max+hWidth+4; i++ {
for range maxCount + hWidth + 4 {
prgEndStr += fmt.Sprintf("[black::]%s", prgCell) //nolint:perfsprint
}

View File

@ -143,16 +143,16 @@ func (d *TopDialog) InputHandler() func(event *tcell.EventKey, setFocus func(p t
// SetRect set rects for this primitive.
func (d *TopDialog) SetRect(x, y, width, height int) {
dX := x + DialogPadding
dWidth := width - (2 * DialogPadding) //nolint:gomnd
dHeight := len(d.results) + DialogFormHeight + 6 //nolint:gomnd
dWidth := width - (2 * DialogPadding) //nolint:mnd
dHeight := len(d.results) + DialogFormHeight + 6 //nolint:mnd
if dHeight > height {
dHeight = height
}
tableHeight := dHeight - DialogFormHeight - 2 //nolint:gomnd
tableHeight := dHeight - DialogFormHeight - 2 //nolint:mnd
hs := ((height - dHeight) / 2) //nolint:gomnd
hs := ((height - dHeight) / 2) //nolint:mnd
dY := y + hs
d.Box.SetRect(dX, dY, dWidth, dHeight)
@ -161,9 +161,9 @@ func (d *TopDialog) SetRect(x, y, width, height int) {
cWidth := d.getCommandWidth()
for i := 0; i < d.table.GetRowCount(); i++ {
for i := range d.table.GetRowCount() {
cell := d.table.GetCell(i, viewTopCommandColIndex)
cell.SetMaxWidth(cWidth / 2) //nolint:gomnd
cell.SetMaxWidth(cWidth / 2) //nolint:mnd
d.table.SetCell(i, viewTopCommandColIndex, cell)
}
}
@ -195,7 +195,7 @@ func (d *TopDialog) initTable() {
d.table.SetFixed(1, 1)
d.table.SetSelectable(true, false)
for i := 0; i < len(d.tableHeaders); i++ {
for i := range d.tableHeaders {
d.table.SetCell(0, i,
tview.NewTableCell(fmt.Sprintf("[%s::b]%s", style.GetColorHex(fgColor), strings.ToUpper(d.tableHeaders[i]))).
SetExpansion(0).
@ -226,7 +226,7 @@ func (d *TopDialog) UpdateResults(infoType topInfo, id string, name string, data
rowIndex := 1
expand := 1
if len(data) < 2 { //nolint:gomnd
if len(data) < 2 { //nolint:mnd
return
}
@ -322,7 +322,7 @@ func (d *TopDialog) getCommandWidth() int {
}
}
commandWidth = width - usedWidth*2 + 8 //nolint:gomnd
commandWidth = width - usedWidth*2 + 8 //nolint:mnd
if commandWidth <= 0 {
commandWidth = 0
}

View File

@ -54,9 +54,9 @@ func NewHelp(appName string, appVersion string) *Help {
rowIndex := 0
colIndex := 0
needInit := true
maxRowIndex := len(utils.UIKeysBindings)/2 + 1 //nolint:gomnd
maxRowIndex := len(utils.UIKeysBindings)/2 + 1 //nolint:mnd
for i := 0; i < len(utils.UIKeysBindings); i++ {
for i := range utils.UIKeysBindings {
if i >= maxRowIndex {
if needInit {
colIndex = 2
@ -82,7 +82,7 @@ func NewHelp(appName string, appVersion string) *Help {
// appinfo and appkeys layout
mlayout := tview.NewFlex().SetDirection(tview.FlexRow)
mlayout.AddItem(appinfo, 2, 0, false) //nolint:gomnd
mlayout.AddItem(appinfo, 2, 0, false) //nolint:mnd
mlayout.AddItem(utils.EmptyBoxSpace(bgColor), 1, 0, false)
mlayout.AddItem(keyinfo, 0, 1, false)
mlayout.AddItem(utils.EmptyBoxSpace(bgColor), 1, 0, false)
@ -117,7 +117,7 @@ func (help *Help) Focus(delegate func(p tview.Primitive)) {
// Draw draws this primitive onto the screen.
func (help *Help) Draw(screen tcell.Screen) {
x, y, width, height := help.Box.GetInnerRect()
if height <= 3 { //nolint:gomnd
if height <= 3 { //nolint:mnd
return
}

View File

@ -77,6 +77,7 @@ func (img *Images) build() {
if err != nil {
img.displayError("IMAGE BUILD ERROR", err)
img.appFocusHandler()
return
}
@ -84,6 +85,7 @@ func (img *Images) build() {
img.messageDialog.SetTitle("podman image build")
img.messageDialog.SetText(dialogs.MessageImageInfo, report, "")
img.messageDialog.Display()
img.appFocusHandler()
}
go buildFunc()
@ -108,7 +110,9 @@ func (img *Images) diff() {
if err != nil {
title := fmt.Sprintf("IMAGE (%s) DIFF ERROR", imageID)
img.displayError(title, err)
img.appFocusHandler()
return
}
@ -117,7 +121,8 @@ func (img *Images) diff() {
img.messageDialog.SetTitle("podman image diff")
img.messageDialog.SetText(dialogs.MessageImageInfo, headerLabel, strings.Join(data, "\n"))
img.messageDialog.Display()
img.messageDialog.DisplayFullSize()
img.appFocusHandler()
}
go diff()
@ -160,6 +165,7 @@ func (img *Images) imageImport() {
if err != nil {
img.displayError("IMAGE IMPORT ERROR", err)
img.appFocusHandler()
return
}
@ -167,6 +173,7 @@ func (img *Images) imageImport() {
img.messageDialog.SetTitle("podman image import")
img.messageDialog.SetText(dialogs.MessageImageInfo, newImageID, "")
img.messageDialog.Display()
img.appFocusHandler()
}
go importFunc()
@ -192,7 +199,7 @@ func (img *Images) inspect() {
img.messageDialog.SetTitle("podman image inspect")
img.messageDialog.SetText(dialogs.MessageImageInfo, headerLabel, data)
img.messageDialog.Display()
img.messageDialog.DisplayFullSize()
}
func (img *Images) cprune() {
@ -203,7 +210,7 @@ func (img *Images) cprune() {
}
func (img *Images) prune() {
img.progressDialog.SetTitle("image purne in progress")
img.progressDialog.SetTitle("image prune in progress")
img.progressDialog.Display()
prune := func() {
@ -213,6 +220,7 @@ func (img *Images) prune() {
if err != nil {
img.displayError("IMAGE PRUNE ERROR", err)
img.appFocusHandler()
return
}
@ -243,7 +251,9 @@ func (img *Images) push() {
if err := images.Push(img.selectedID, pushOptions); err != nil {
img.progressDialog.Hide()
title := fmt.Sprintf("IMAGE (%s) PUSH ERROR", img.selectedID)
img.displayError(title, err)
img.appFocusHandler()
return
}
@ -285,13 +295,16 @@ func (img *Images) remove() {
if err != nil {
title := fmt.Sprintf("IMAGE (%s) REMOVE ERROR", imageID)
img.displayError(title, err)
img.appFocusHandler()
} else {
headerLabel := fmt.Sprintf("%12s (%s)", imageID, imageName)
img.messageDialog.SetTitle("podman image remove")
img.messageDialog.SetText(dialogs.MessageImageInfo, headerLabel, strings.Join(data, "\n"))
img.messageDialog.Display()
img.appFocusHandler()
}
}
@ -330,7 +343,9 @@ func (img *Images) save() {
if err != nil {
title := fmt.Sprintf("IMAGE (%s) SAVE ERROR", img.selectedID)
img.displayError(title, err)
img.appFocusHandler()
return
}
@ -348,7 +363,9 @@ func (img *Images) search(term string) {
result, err := images.Search(term)
if err != nil {
title := fmt.Sprintf("IMAGE (%s) SEARCH ERROR", img.selectedID)
img.displayError(title, err)
img.appFocusHandler()
}
img.searchDialog.UpdateResults(result)
@ -423,7 +440,9 @@ func (img *Images) tree() {
tree, err := images.Tree(imageID)
if err != nil {
title := fmt.Sprintf("IMAGE (%s) TREE ERROR", imageID)
img.displayError(title, err)
img.appFocusHandler()
return
}
@ -434,6 +453,7 @@ func (img *Images) tree() {
img.messageDialog.SetTitle("podman image tree")
img.messageDialog.SetText(dialogs.MessageImageInfo, headerLabel, tree)
img.messageDialog.Display()
img.appFocusHandler()
}
img.progressDialog.SetTitle("image tree in progress")
@ -459,7 +479,9 @@ func (img *Images) pull(image string) {
err := images.Pull(name)
if err != nil {
title := fmt.Sprintf("IMAGE (%s) PULL ERROR", img.selectedID)
img.displayError(title, err)
img.appFocusHandler()
}
img.progressDialog.Hide()

View File

@ -22,14 +22,16 @@ func (img *Images) UpdateData() {
}
img.imagesList.mu.Lock()
defer img.imagesList.mu.Unlock()
img.imagesList.report = images
img.imagesList.mu.Unlock()
}
func (img *Images) getData() []images.ImageListReporter {
img.imagesList.mu.Lock()
defer img.imagesList.mu.Unlock()
data := img.imagesList.report
img.imagesList.mu.Unlock()
return data
}
@ -37,15 +39,17 @@ func (img *Images) getData() []images.ImageListReporter {
// ClearData clears table data.
func (img *Images) ClearData() {
img.imagesList.mu.Lock()
defer img.imagesList.mu.Unlock()
img.imagesList.report = nil
img.imagesList.mu.Unlock()
img.table.Clear()
expand := 1
fgColor := style.PageHeaderFgColor
bgColor := style.PageHeaderBgColor
for i := 0; i < len(img.headers); i++ {
for i := range img.headers {
img.table.SetCell(0, i,
tview.NewTableCell(fmt.Sprintf("[::b]%s", strings.ToUpper(img.headers[i]))). //nolint:perfsprint
SetExpansion(expand).

View File

@ -6,17 +6,17 @@ import (
// Draw draws this primitive onto the screen.
func (img *Images) Draw(screen tcell.Screen) { //nolint:cyclop
img.refresh()
img.Box.DrawForSubclass(screen, img)
img.Box.SetBorder(false)
x, y, width, height := img.GetInnerRect()
imagewViewX, imagewViewY, imagewViewW, imagewViewH := img.GetInnerRect()
img.table.SetRect(x, y, width, height)
img.refresh(imagewViewW)
img.table.SetRect(imagewViewX, imagewViewY, imagewViewW, imagewViewH)
img.table.SetBorder(true)
img.table.Draw(screen)
x, y, width, height = img.table.GetInnerRect()
x, y, width, height := img.table.GetInnerRect()
// error dialog
if img.errorDialog.IsDisplay() {
@ -44,7 +44,12 @@ func (img *Images) Draw(screen tcell.Screen) { //nolint:cyclop
// message dialog
if img.messageDialog.IsDisplay() {
img.messageDialog.SetRect(x, y, width, height+1)
if img.messageDialog.IsDisplayFullSize() {
img.messageDialog.SetRect(imagewViewX, imagewViewY, imagewViewW, imagewViewH)
} else {
img.messageDialog.SetRect(x, y, width, height+1)
}
img.messageDialog.Draw(screen)
return
@ -60,7 +65,7 @@ func (img *Images) Draw(screen tcell.Screen) { //nolint:cyclop
// search dialog
if img.searchDialog.IsDisplay() {
img.searchDialog.SetRect(x, y, width, height)
img.searchDialog.SetRect(imagewViewX, imagewViewY, imagewViewW, imagewViewH)
img.searchDialog.Draw(screen)
}
@ -72,7 +77,7 @@ func (img *Images) Draw(screen tcell.Screen) { //nolint:cyclop
// history dialog
if img.historyDialog.IsDisplay() {
img.historyDialog.SetRect(x, y, width, height)
img.historyDialog.SetRect(imagewViewX, imagewViewY, imagewViewW, imagewViewH)
img.historyDialog.Draw(screen)
return

View File

@ -58,6 +58,7 @@ type Images struct {
selectedName string
confirmData string
fastRefreshChan chan bool
appFocusHandler func()
}
type imageListReport struct {
@ -108,7 +109,7 @@ func NewImages() *Images {
imgTable.SetTitleColor(style.FgColor)
imgTable.SetBorder(true)
for i := 0; i < len(images.headers); i++ {
for i := range images.headers {
imgTable.SetCell(0, i,
tview.NewTableCell(fmt.Sprintf("[black::b]%s", strings.ToUpper(images.headers[i]))). //nolint:perfsprint
SetExpansion(1).
@ -207,6 +208,11 @@ func NewImages() *Images {
return images
}
// SetAppFocusHandler sets application focus handler.
func (img *Images) SetAppFocusHandler(handler func()) {
img.appFocusHandler = handler
}
// GetTitle returns primitive title.
func (img *Images) GetTitle() string {
return img.title
@ -371,7 +377,7 @@ func (img *Images) getSelectedItem() (string, string) {
imageRepo := img.table.GetCell(row, 0).Text
imageTag := img.table.GetCell(row, 1).Text
imageName := imageRepo + ":" + imageTag
imageID := img.table.GetCell(row, 2).Text //nolint:gomnd
imageID := img.table.GetCell(row, 2).Text //nolint:mnd
return imageID, imageName
}

View File

@ -508,7 +508,7 @@ func (d *ImageBuildDialog) setupLayout() {
// layers setup page
secondRowLayout := tview.NewFlex().SetDirection(tview.FlexColumn)
secondRowLayout.SetBackgroundColor(bgColor)
secondRowLayout.AddItem(d.formatField, 0, 2, true) //nolint:gomnd
secondRowLayout.AddItem(d.formatField, 0, 2, true) //nolint:mnd
secondRowLayout.AddItem(d.SquashField, 0, 1, true)
secondRowLayout.AddItem(d.layersField, 0, 1, true)
secondRowLayout.AddItem(d.noCacheField, 0, 1, true)
@ -516,7 +516,7 @@ func (d *ImageBuildDialog) setupLayout() {
cntRmRowLayout := tview.NewFlex().SetDirection(tview.FlexColumn)
cntRmRowLayout.SetBackgroundColor(bgColor)
cntRmRowLayout.AddItem(d.forceRemoveCntField, 0, 1, true)
cntRmRowLayout.AddItem(d.removeCntField, 0, 2, true) //nolint:gomnd
cntRmRowLayout.AddItem(d.removeCntField, 0, 2, true) //nolint:mnd
// build setup page
d.buildInfoPage.SetDirection(tview.FlexRow)
@ -594,7 +594,7 @@ func (d *ImageBuildDialog) setupLayout() {
// add it to layout.
_, layoutWidth := utils.AlignStringListWidth(d.categoryLabels)
layout := tview.NewFlex().SetDirection(tview.FlexColumn)
layout.AddItem(d.categories, layoutWidth+6, 0, true) //nolint:gomnd
layout.AddItem(d.categories, layoutWidth+6, 0, true) //nolint:mnd
layout.AddItem(d.categoryPages, 0, 1, true)
layout.SetBackgroundColor(bgColor)
@ -901,13 +901,13 @@ func (d *ImageBuildDialog) InputHandler() func(event *tcell.EventKey, setFocus f
// SetRect set rects for this primitive.
func (d *ImageBuildDialog) SetRect(x, y, width, height int) {
if width > buildDialogMaxWidth {
emptySpace := (width - buildDialogMaxWidth) / 2 //nolint:gomnd
emptySpace := (width - buildDialogMaxWidth) / 2 //nolint:mnd
x += emptySpace
width = buildDialogMaxWidth
}
if height > buildDialogHeight {
emptySpace := (height - buildDialogHeight) / 2 //nolint:gomnd
emptySpace := (height - buildDialogHeight) / 2 //nolint:mnd
y += emptySpace
height = buildDialogHeight
}
@ -930,7 +930,7 @@ func (d *ImageBuildDialog) Draw(screen tcell.Screen) {
// SetCancelFunc sets form cancel button selected function.
func (d *ImageBuildDialog) SetCancelFunc(handler func()) *ImageBuildDialog {
d.cancelHandler = handler
cancelButton := d.form.GetButton(d.form.GetButtonCount() - 2) //nolint:gomnd
cancelButton := d.form.GetButton(d.form.GetButtonCount() - 2) //nolint:mnd
cancelButton.SetSelectedFunc(handler)
return d
@ -1002,11 +1002,11 @@ func (d *ImageBuildDialog) setActiveCategory(index int) {
d.activePageIndex = index
d.categories.Clear()
var ctgList []string
ctgList := []string{}
alignedList, _ := utils.AlignStringListWidth(d.categoryLabels)
for i := 0; i < len(alignedList); i++ {
for i := range alignedList {
if i == index {
ctgList = append(ctgList, fmt.Sprintf("[%s:%s:b]-> %s ", ctgFgColor, ctgBgColor, alignedList[i]))
@ -1246,7 +1246,7 @@ func (d *ImageBuildDialog) ImageBuildOptions() (images.ImageBuildOptions, error)
// basic info page
// Containerfiles
for _, cntFile := range strings.Split(d.containerFilePath.GetText(), " ") {
for _, cntFile := range strings.Split(strings.TrimSpace(d.containerFilePath.GetText()), " ") {
if cntFile != "" {
cFile, err := utils.ResolveHomeDir(cntFile)
if err != nil {
@ -1262,14 +1262,14 @@ func (d *ImageBuildDialog) ImageBuildOptions() (images.ImageBuildOptions, error)
BuildOptions: entities.BuildOptions{},
}
dir, err := utils.ResolveHomeDir(d.contextDirectoryPath.GetText())
dir, err := utils.ResolveHomeDir(strings.TrimSpace(d.contextDirectoryPath.GetText()))
if err != nil {
return images.ImageBuildOptions{}, fmt.Errorf("cannot resolve home directory %w", err)
}
opts.BuildOptions.ContextDirectory = dir
opts.BuildOptions.AdditionalTags = append(opts.BuildOptions.AdditionalTags, d.tagField.GetText())
opts.BuildOptions.Registry = d.registryField.GetText()
opts.BuildOptions.AdditionalTags = append(opts.BuildOptions.AdditionalTags, strings.TrimSpace(d.tagField.GetText()))
opts.BuildOptions.Registry = strings.TrimSpace(d.registryField.GetText())
_, pullOption := d.pullPolicyField.GetCurrentOption()
switch pullOption {
@ -1329,7 +1329,7 @@ func (d *ImageBuildDialog) ImageBuildOptions() (images.ImageBuildOptions, error)
return images.ImageBuildOptions{}, fmt.Errorf("invalid CPU period value %q %w", cpuPeriodVal, err)
}
cpuPeriod = uint64(period)
cpuPeriod = uint64(period) //nolint:gosec
}
cpuQuotaVal := d.cpuQuataField.GetText()
@ -1349,7 +1349,7 @@ func (d *ImageBuildDialog) ImageBuildOptions() (images.ImageBuildOptions, error)
return images.ImageBuildOptions{}, fmt.Errorf("invalid CPU quota value %q %w", cpuSharesVal, err)
}
cpuShares = uint64(shares)
cpuShares = uint64(shares) //nolint:gosec
}
cpuSetCpusVal := d.cpuSetCpusField.GetText()

View File

@ -63,7 +63,7 @@ func NewImageBuildProgressDialog() *ImageBuildProgressDialog {
buildPrgDialog.layout.SetBorder(true)
buildPrgDialog.layout.SetBorderColor(style.DialogBorderColor)
buildPrgDialog.layout.SetTitle("PODMAN IMAGE BUILD")
buildPrgDialog.layout.AddItem(buildPrgDialog.progressBar, 3, 0, false) //nolint:gomnd
buildPrgDialog.layout.AddItem(buildPrgDialog.progressBar, 3, 0, false) //nolint:mnd
outputLayout := tview.NewFlex().SetDirection(tview.FlexColumn)
outputLayout.AddItem(utils.EmptyBoxSpace(outputBgColor), 1, 0, false)
@ -78,7 +78,7 @@ func NewImageBuildProgressDialog() *ImageBuildProgressDialog {
func (d *ImageBuildProgressDialog) Display() {
d.display = true
d.cancelChan = make(chan bool)
d.writerChan = make(chan []byte, 100) //nolint:gomnd
d.writerChan = make(chan []byte, 100) //nolint:mnd
go d.outputReaderLoop()
}
@ -121,13 +121,13 @@ func (d *ImageBuildProgressDialog) InputHandler() func(event *tcell.EventKey, se
// SetRect set rects for this primitive.
func (d *ImageBuildProgressDialog) SetRect(x, y, width, height int) {
if width > buildPrgDialogMaxWidth {
emptySpace := (width - buildPrgDialogMaxWidth) / 2 //nolint:gomnd
emptySpace := (width - buildPrgDialogMaxWidth) / 2 //nolint:mnd
x += emptySpace
width = buildPrgDialogMaxWidth
}
if height > buildPrgDialogHeight {
emptySpace := (height - buildPrgDialogHeight) / 2 //nolint:gomnd
emptySpace := (height - buildPrgDialogHeight) / 2 //nolint:mnd
y += emptySpace
height = buildPrgDialogHeight
}

View File

@ -146,29 +146,21 @@ func (d *ImageHistoryDialog) InputHandler() func(event *tcell.EventKey, setFocus
// SetRect set rects for this primitive.
func (d *ImageHistoryDialog) SetRect(x, y, width, height int) {
dX := x + dialogs.DialogPadding
dWidth := width - (2 * dialogs.DialogPadding) //nolint:gomnd
dHeight := len(d.results) + dialogs.DialogFormHeight + 5 //nolint:gomnd
if dHeight > height {
dHeight = height
}
tableHeight := dHeight - dialogs.DialogFormHeight - 2 //nolint:gomnd
hs := ((height - dHeight) / 2) //nolint:gomnd
dY := y + hs
dX := x + 1
dY := y + 1
dWidth := width - 2 //nolint:mnd
dHeight := height - 2 //nolint:mnd
d.Box.SetRect(dX, dY, dWidth, dHeight)
// set table height size
d.layout.ResizeItem(d.table, tableHeight, 0)
d.layout.ResizeItem(d.table, dHeight, 0)
cWidth := d.getCreatedByWidth()
for i := 0; i < d.table.GetRowCount(); i++ {
cell := d.table.GetCell(i, 2) //nolint:gomnd
cell.SetMaxWidth(cWidth / 2) //nolint:gomnd
d.table.SetCell(i, 2, cell) //nolint:gomnd
for i := range d.table.GetRowCount() {
cell := d.table.GetCell(i, 2) //nolint:mnd
cell.SetMaxWidth(cWidth / 2) //nolint:mnd
d.table.SetCell(i, 2, cell) //nolint:mnd
}
}
@ -201,7 +193,7 @@ func (d *ImageHistoryDialog) initTable() {
d.table.SetFixed(1, 1)
d.table.SetSelectable(true, false)
for i := 0; i < len(d.tableHeaders); i++ {
for i := range d.tableHeaders {
d.table.SetCell(0, i,
tview.NewTableCell(fmt.Sprintf("[%s::b]%s", style.GetColorHex(fgColor), strings.ToUpper(d.tableHeaders[i]))).
SetExpansion(1).
@ -221,7 +213,7 @@ func (d *ImageHistoryDialog) UpdateResults(data [][]string) {
rowIndex := 1
expand := 0
for i := 0; i < len(data); i++ {
for i := range data {
id := data[i][0]
if len(id) > utils.IDLength {
id = id[0:utils.IDLength]
@ -311,7 +303,7 @@ func (d *ImageHistoryDialog) getCreatedByWidth() int {
}
usedWidth := idWidth + createdWidth + sizeWidth + commentWidth
createdByWidth = width - usedWidth*2 + 8 //nolint:gomnd
createdByWidth = width - usedWidth*2 + 8 //nolint:mnd
if createdByWidth <= 0 {
createdByWidth = 0

View File

@ -251,13 +251,13 @@ func (d *ImageImportDialog) InputHandler() func(event *tcell.EventKey, setFocus
// SetRect set rects for this primitive.
func (d *ImageImportDialog) SetRect(x, y, width, height int) {
if width > imageImportDialogMaxWidth {
emptySpace := (width - imageImportDialogMaxWidth) / 2 //nolint:gomnd
emptySpace := (width - imageImportDialogMaxWidth) / 2 //nolint:mnd
x += emptySpace
width = imageImportDialogMaxWidth
}
if height > imageImportDialogMaxHeight {
emptySpace := (height - imageImportDialogMaxHeight) / 2 //nolint:gomnd
emptySpace := (height - imageImportDialogMaxHeight) / 2 //nolint:mnd
y += emptySpace
height = imageImportDialogMaxHeight
}
@ -302,7 +302,7 @@ func (d *ImageImportDialog) SetImportFunc(handler func()) *ImageImportDialog {
// SetCancelFunc sets form cancel button selected function.
func (d *ImageImportDialog) SetCancelFunc(handler func()) *ImageImportDialog {
d.cancelHandler = handler
cancelButton := d.form.GetButton(d.form.GetButtonCount() - 2) //nolint:gomnd
cancelButton := d.form.GetButton(d.form.GetButtonCount() - 2) //nolint:mnd
cancelButton.SetSelectedFunc(handler)
return d
@ -319,7 +319,7 @@ func (d *ImageImportDialog) ImageImportOptions() (images.ImageImportOptions, err
commit = strings.TrimSpace(d.commitMessage.GetText())
reference = strings.TrimSpace(d.reference.GetText())
change = strings.Split(d.change.GetText(), " ")
change = strings.Split(strings.TrimSpace(d.change.GetText()), " ")
opts := images.ImageImportOptions{
Change: change,

View File

@ -154,15 +154,15 @@ func NewImagePushDialog() *ImagePushDialog {
// dropdowns and checkbox row layour
dcLayout := tview.NewFlex().SetDirection(tview.FlexColumn)
dcLayout.AddItem(dialog.compress, labelWidth+1, 1, true)
dcLayout.AddItem(utils.EmptyBoxSpace(bgColor), 2, 0, false) //nolint:gomnd
dcLayout.AddItem(dialog.format, len(formatLabel)+5, 0, true) //nolint:gomnd
dcLayout.AddItem(utils.EmptyBoxSpace(bgColor), 2, 0, false) //nolint:gomnd
dcLayout.AddItem(utils.EmptyBoxSpace(bgColor), 2, 0, false) //nolint:mnd
dcLayout.AddItem(dialog.format, len(formatLabel)+5, 0, true) //nolint:mnd
dcLayout.AddItem(utils.EmptyBoxSpace(bgColor), 2, 0, false) //nolint:mnd
dcLayout.AddItem(dialog.skipTLSVerify, 0, 1, true)
// username and password row layout
userPassLayout := tview.NewFlex().SetDirection(tview.FlexColumn)
userPassLayout.AddItem(dialog.username, 0, 1, true)
userPassLayout.AddItem(utils.EmptyBoxSpace(bgColor), 3, 0, false) //nolint:gomnd
userPassLayout.AddItem(utils.EmptyBoxSpace(bgColor), 3, 0, false) //nolint:mnd
userPassLayout.AddItem(dialog.password, 0, 1, true)
layout := tview.NewFlex().SetDirection(tview.FlexRow)
@ -390,13 +390,13 @@ func (d *ImagePushDialog) setFocusElement() {
// SetRect set rects for this primitive.
func (d *ImagePushDialog) SetRect(x, y, width, height int) {
if width > imagePushDialogMaxWidth {
emptySpace := (width - imagePushDialogMaxWidth) / 2 //nolint:gomnd
emptySpace := (width - imagePushDialogMaxWidth) / 2 //nolint:mnd
x += emptySpace
width = imagePushDialogMaxWidth
}
if height > imagePushDialogMaxHeight {
emptySpace := (height - imagePushDialogMaxHeight) / 2 //nolint:gomnd
emptySpace := (height - imagePushDialogMaxHeight) / 2 //nolint:mnd
y += emptySpace
height = imagePushDialogMaxHeight
}
@ -429,7 +429,7 @@ func (d *ImagePushDialog) SetPushFunc(handler func()) *ImagePushDialog {
// SetCancelFunc sets form cancel button selected function.
func (d *ImagePushDialog) SetCancelFunc(handler func()) *ImagePushDialog {
d.cancelHandler = handler
cancelButton := d.form.GetButton(d.form.GetButtonCount() - 2) //nolint:gomnd
cancelButton := d.form.GetButton(d.form.GetButtonCount() - 2) //nolint:mnd
cancelButton.SetSelectedFunc(handler)
return d

View File

@ -124,7 +124,7 @@ func NewImageSaveDialog() *ImageSaveDialog {
compressRow := tview.NewFlex().SetDirection(tview.FlexColumn)
compressRow.SetBackgroundColor(bgColor)
compressRow.AddItem(dialog.compress, 0, 1, true)
compressRow.AddItem(dialog.ociAcceptUncompressed, 0, 3, true) //nolint:gomnd
compressRow.AddItem(dialog.ociAcceptUncompressed, 0, 3, true) //nolint:mnd
optionsLayout := tview.NewFlex().SetDirection(tview.FlexRow)
optionsLayout.AddItem(utils.EmptyBoxSpace(bgColor), 1, 0, false)
@ -287,13 +287,13 @@ func (d *ImageSaveDialog) InputHandler() func(event *tcell.EventKey, setFocus fu
// SetRect set rects for this primitive.
func (d *ImageSaveDialog) SetRect(x, y, width, height int) {
if width > imageSaveDialogMaxWidth {
emptySpace := (width - imageSaveDialogMaxWidth) / 2 //nolint:gomnd
emptySpace := (width - imageSaveDialogMaxWidth) / 2 //nolint:mnd
x += emptySpace
width = imageSaveDialogMaxWidth
}
if height > imageSaveDialogMaxHeight {
emptySpace := (height - imageSaveDialogMaxHeight) / 2 //nolint:gomnd
emptySpace := (height - imageSaveDialogMaxHeight) / 2 //nolint:mnd
y += emptySpace
height = imageSaveDialogMaxHeight
}
@ -339,7 +339,7 @@ func (d *ImageSaveDialog) SetSaveFunc(handler func()) *ImageSaveDialog {
// SetCancelFunc sets form cancel button selected function.
func (d *ImageSaveDialog) SetCancelFunc(handler func()) *ImageSaveDialog {
d.cancelHandler = handler
cancelButton := d.form.GetButton(d.form.GetButtonCount() - 2) //nolint:gomnd
cancelButton := d.form.GetButton(d.form.GetButtonCount() - 2) //nolint:mnd
cancelButton.SetSelectedFunc(handler)

View File

@ -87,7 +87,7 @@ func NewImageSearchDialog() *ImageSearchDialog {
dialog.searchLayout = tview.NewFlex().SetDirection(tview.FlexColumn)
dialog.searchLayout.AddItem(utils.EmptyBoxSpace(bgColor), 1, 0, true)
dialog.searchLayout.AddItem(dialog.input, searchFieldMaxSize+searchInpuLabelWidth, 10, true) //nolint:gomnd
dialog.searchLayout.AddItem(dialog.input, searchFieldMaxSize+searchInpuLabelWidth, 10, true) //nolint:mnd
dialog.searchLayout.AddItem(utils.EmptyBoxSpace(bgColor), 1, 0, true)
dialog.searchLayout.AddItem(dialog.searchButton, searchButtonWidth, 0, true)
dialog.searchLayout.SetBackgroundColor(bgColor)
@ -309,11 +309,11 @@ func (d *ImageSearchDialog) SetRect(x, y, width, height int) {
paddingY := 1
dX := x + paddingX
dY := y + paddingY
dWidth := width - (2 * paddingX) //nolint:gomnd
dHeight := height - (2 * paddingY) //nolint:gomnd
dWidth := width - (2 * paddingX) //nolint:mnd
dHeight := height - (2 * paddingY) //nolint:mnd
// set search input field size
iwidth := dWidth - searchInpuLabelWidth - searchButtonWidth - 5 //nolint:gomnd
iwidth := dWidth - searchInpuLabelWidth - searchButtonWidth - 5 //nolint:mnd
if iwidth > searchFieldMaxSize {
iwidth = searchFieldMaxSize
}
@ -322,7 +322,7 @@ func (d *ImageSearchDialog) SetRect(x, y, width, height int) {
d.searchLayout.ResizeItem(d.input, iwidth+searchInpuLabelWidth, 0)
// set table height size
d.layout.ResizeItem(d.searchResult, dHeight-dialogs.DialogFormHeight-5, 0) //nolint:gomnd
d.layout.ResizeItem(d.searchResult, dHeight-dialogs.DialogFormHeight-5, 0) //nolint:mnd
d.Box.SetRect(dX, dY, dWidth, dHeight)
}
@ -391,7 +391,7 @@ func (d *ImageSearchDialog) InputHandler() func(event *tcell.EventKey, setFocus
// SetCancelFunc sets form cancel button selected function.
func (d *ImageSearchDialog) SetCancelFunc(handler func()) *ImageSearchDialog {
d.cancelHandler = handler
cancelButton := d.form.GetButton(d.form.GetButtonCount() - 2) //nolint:gomnd
cancelButton := d.form.GetButton(d.form.GetButtonCount() - 2) //nolint:mnd
cancelButton.SetSelectedFunc(handler)
return d
@ -413,7 +413,7 @@ func (d *ImageSearchDialog) SetPullFunc(handler func()) *ImageSearchDialog {
// GetSearchText returns search input field text.
func (d *ImageSearchDialog) GetSearchText() string {
return d.input.GetText()
return strings.TrimSpace(d.input.GetText())
}
// GetSelectedItem returns selected image name from search result table.
@ -441,7 +441,7 @@ func (d *ImageSearchDialog) UpdateResults(data [][]string) {
rowIndex := 1
expand := 1
for i := 0; i < len(data); i++ {
for i := range data {
index := data[i][searchResultIndexIndex]
name := data[i][searchResultNameIndex]
desc := data[i][searchResultDescIndex]

View File

@ -10,13 +10,13 @@ import (
"github.com/rivo/tview"
)
func (img *Images) refresh() {
func (img *Images) refresh(_ int) {
img.table.Clear()
expand := 1
alignment := tview.AlignLeft
for i := 0; i < len(img.headers); i++ {
for i := range img.headers {
img.table.SetCell(0, i,
tview.NewTableCell(fmt.Sprintf("[::b]%s", strings.ToUpper(img.headers[i]))). //nolint:perfsprint
SetExpansion(expand).
@ -31,7 +31,7 @@ func (img *Images) refresh() {
img.table.SetTitle(fmt.Sprintf("[::b]%s[%d]", strings.ToUpper(img.title), len(images)))
for i := 0; i < len(images); i++ {
for i := range images {
repo := images[i].Repository
tag := images[i].Tag
imgID := images[i].ID

View File

@ -43,7 +43,7 @@ func NewInfoBar() *InfoBar {
}
// empty column
for i := 0; i < 5; i++ {
for i := range 5 {
table.SetCell(i, 0, emptyCell())
}
@ -84,7 +84,7 @@ func NewInfoBar() *InfoBar {
table.SetCell(swapCellRow, dataCol2Index, tview.NewTableCell(utils.ProgressUsageString(defaultPerc)))
// empty column
for i := 0; i < dataCol4Index; i++ {
for i := range dataCol4Index {
table.SetCell(i, totalRows, emptyCell())
}

View File

@ -50,6 +50,7 @@ func (nets *Networks) cconnect() {
if err != nil {
nets.progressDialog.Hide()
nets.displayError("NETWORK CONNECT ERROR", err)
nets.appFocusHandler()
return
}
@ -60,6 +61,7 @@ func (nets *Networks) cconnect() {
nets.connectDialog.SetContainers(cntListReport)
nets.progressDialog.Hide()
nets.connectDialog.Display()
nets.appFocusHandler()
}
go initData()
@ -76,6 +78,7 @@ func (nets *Networks) connect() {
if err := networks.Connect(connectOptions); err != nil {
nets.progressDialog.Hide()
nets.displayError("NETWORK CONNECT ERROR", err)
nets.appFocusHandler()
return
}
@ -101,6 +104,7 @@ func (nets *Networks) cdisconnect() {
if err != nil {
nets.progressDialog.Hide()
nets.displayError("NETWORK DISCONNECT ERROR", err)
nets.appFocusHandler()
return
}
@ -111,6 +115,7 @@ func (nets *Networks) cdisconnect() {
nets.disconnectDialog.SetContainers(cntListReport)
nets.progressDialog.Hide()
nets.disconnectDialog.Display()
nets.appFocusHandler()
}
go initData()
@ -127,6 +132,7 @@ func (nets *Networks) disconnect() {
if err := networks.Disconnect(networkName, containerID); err != nil {
nets.progressDialog.Hide()
nets.displayError("NETWORK DISCONNECT ERROR", err)
nets.appFocusHandler()
return
}
@ -170,7 +176,7 @@ func (nets *Networks) inspect() {
nets.messageDialog.SetTitle("podman network inspect")
nets.messageDialog.SetText(dialogs.MessageNetworkInfo, headerLabel, data)
nets.messageDialog.Display()
nets.messageDialog.DisplayFullSize()
}
func (nets *Networks) cprune() {
@ -183,13 +189,14 @@ func (nets *Networks) cprune() {
}
func (nets *Networks) prune() {
nets.progressDialog.SetTitle("network purne in progress")
nets.progressDialog.SetTitle("network prune in progress")
nets.progressDialog.Display()
prune := func() {
if err := networks.Prune(); err != nil {
nets.progressDialog.Hide()
nets.displayError("NETWORK PRUNE ERROR", err)
nets.appFocusHandler()
return
}
@ -233,7 +240,9 @@ func (nets *Networks) remove() {
if err != nil {
title := fmt.Sprintf("NETWORK (%s) REMOVE ERROR", nets.selectedID)
nets.displayError(title, err)
nets.appFocusHandler()
return
}

61
ui/networks/data.go Normal file
View File

@ -0,0 +1,61 @@
package networks
import (
"fmt"
"strings"
"github.com/containers/podman-tui/pdcs/networks"
"github.com/containers/podman-tui/ui/style"
"github.com/rivo/tview"
"github.com/rs/zerolog/log"
)
// UpdateData retrieves networks list data.
func (nets *Networks) UpdateData() {
netList, err := networks.List()
if err != nil {
log.Error().Msgf("view: networks update %v", err)
nets.errorDialog.SetText(fmt.Sprintf("%v", err))
nets.errorDialog.Display()
}
nets.networkList.mu.Lock()
defer nets.networkList.mu.Unlock()
nets.networkList.report = netList
}
func (nets *Networks) getData() [][]string {
nets.networkList.mu.Lock()
defer nets.networkList.mu.Unlock()
data := nets.networkList.report
return data
}
// ClearData clears table data.
func (nets *Networks) ClearData() {
nets.networkList.mu.Lock()
defer nets.networkList.mu.Unlock()
nets.networkList.report = nil
nets.table.Clear()
expand := 1
fgColor := style.PageHeaderFgColor
bgColor := style.PageHeaderBgColor
for i := range nets.headers {
nets.table.SetCell(0, i,
tview.NewTableCell(fmt.Sprintf("[::b]%s", strings.ToUpper(nets.headers[i]))). //nolint:perfsprint
SetExpansion(expand).
SetBackgroundColor(bgColor).
SetTextColor(fgColor).
SetAlign(tview.AlignLeft).
SetSelectable(false))
}
nets.table.SetTitle(fmt.Sprintf("[::b]%s[0]", strings.ToUpper(nets.title)))
}

View File

@ -9,14 +9,15 @@ func (nets *Networks) Draw(screen tcell.Screen) {
nets.Box.DrawForSubclass(screen, nets)
nets.Box.SetBorder(false)
x, y, width, height := nets.GetInnerRect()
netViewX, netViewY, netViewW, netViewH := nets.GetInnerRect()
nets.table.SetRect(x, y, width, height)
nets.table.SetRect(netViewX, netViewY, netViewW, netViewH)
nets.refresh(netViewW)
nets.table.SetBorder(true)
nets.table.Draw(screen)
x, y, width, height = nets.table.GetInnerRect()
x, y, width, height := nets.table.GetInnerRect()
// error dialog
if nets.errorDialog.IsDisplay() {
@ -60,7 +61,12 @@ func (nets *Networks) Draw(screen tcell.Screen) {
// message dialog
if nets.messageDialog.IsDisplay() {
nets.messageDialog.SetRect(x, y, width, height+1)
if nets.messageDialog.IsDisplayFullSize() {
nets.messageDialog.SetRect(netViewX, netViewY, netViewW, netViewH)
} else {
nets.messageDialog.SetRect(x, y, width, height+1)
}
nets.messageDialog.Draw(screen)
return

View File

@ -302,13 +302,13 @@ func (d *NetworkConnectDialog) InputHandler() func(event *tcell.EventKey, setFoc
// SetRect set rects for this primitive.
func (d *NetworkConnectDialog) SetRect(x, y, width, height int) {
if width > netConnectDialogMaxWidth {
emptySpace := (width - netConnectDialogMaxWidth) / 2 //nolint:gomnd
emptySpace := (width - netConnectDialogMaxWidth) / 2 //nolint:mnd
x += emptySpace
width = netConnectDialogMaxWidth
}
if height > netConnectDialogMaxHeight {
emptySpace := (height - netConnectDialogMaxHeight) / 2 //nolint:gomnd
emptySpace := (height - netConnectDialogMaxHeight) / 2 //nolint:mnd
y += emptySpace
height = netConnectDialogMaxHeight
}
@ -343,7 +343,7 @@ func (d *NetworkConnectDialog) SetConnectFunc(handler func()) *NetworkConnectDia
// SetCancelFunc sets form cancel button selected function.
func (d *NetworkConnectDialog) SetCancelFunc(handler func()) *NetworkConnectDialog {
d.cancelHandler = handler
cancelButton := d.form.GetButton(d.form.GetButtonCount() - 2) //nolint:gomnd
cancelButton := d.form.GetButton(d.form.GetButtonCount() - 2) //nolint:mnd
cancelButton.SetSelectedFunc(handler)
@ -393,10 +393,10 @@ func (d *NetworkConnectDialog) GetConnectOptions() networks.NetworkConnect {
container := strings.Split(selectedCnt, " ")[0]
connectOptions.Container = container
connectOptions.Network = d.networkName
connectOptions.IPv4 = d.ipv4.GetText()
connectOptions.IPv6 = d.ipv6.GetText()
connectOptions.MacAddress = d.macAddr.GetText()
connectOptions.Aliases = strings.Split(d.aliases.GetText(), " ")
connectOptions.IPv4 = strings.TrimSpace(d.ipv4.GetText())
connectOptions.IPv6 = strings.TrimSpace(d.ipv6.GetText())
connectOptions.MacAddress = strings.TrimSpace(d.macAddr.GetText())
connectOptions.Aliases = strings.Split(strings.TrimSpace(d.aliases.GetText()), " ")
return connectOptions
}

Some files were not shown because too many files have changed in this diff Show More