Compare commits
156 Commits
Author | SHA1 | Date |
---|---|---|
|
66fc1cc64f | |
|
04b6c47895 | |
|
fe095fd4b3 | |
|
a2eb9b4823 | |
|
d6ba7488b2 | |
|
58b4fbdc03 | |
|
7f9559b3ac | |
|
9ed811d204 | |
|
31dce751c8 | |
|
6e59fa69eb | |
|
cd74eeb550 | |
|
5e89744b23 | |
|
196004fe46 | |
|
b7e0b93adb | |
|
e3242f37c7 | |
|
897f8ddae1 | |
|
92b9653353 | |
|
a89d6d6ef0 | |
|
6cb9178d24 | |
|
5fc3515715 | |
|
5a9541f97f | |
|
785b690989 | |
|
5ab12464fb | |
|
0b65653d80 | |
|
6294d7d1ee | |
|
136c5f75df | |
|
b02ec6036f | |
|
ef10f184b1 | |
|
3eabf12196 | |
|
7f02a36e85 | |
|
164ca27d7f | |
|
2a7c6195b4 | |
|
70fd604f0f | |
|
c9527473cf | |
|
42293a3a71 | |
|
f902cdff07 | |
|
cd904893fc | |
|
eee4f642fa | |
|
6392f961a4 | |
|
fb76d52ae9 | |
|
05bdbdea9a | |
|
0c1dfb8b00 | |
|
ff9a2eeb41 | |
|
def31691ba | |
|
04b7a6151b | |
|
0f4d9385e6 | |
|
5424f11115 | |
|
ffda1a0afa | |
|
0a975ecdf8 | |
|
2326d5fc63 | |
|
4ffa4b95d9 | |
|
49b2994ff8 | |
|
b1464afd8c | |
|
cc8608c200 | |
|
4a10ca867d | |
|
8eb63a6d2b | |
|
1be2154e2b | |
|
9b2bb83815 | |
|
4c73f653d8 | |
|
0a04e82ebe | |
|
8999d0e2b7 | |
|
347ab777b4 | |
|
6c62f33576 | |
|
4049d7adaa | |
|
fe94712e4a | |
|
d62c79f787 | |
|
441fe2edec | |
|
66e7fff1a6 | |
|
f06e2ef927 | |
|
5302f66806 | |
|
e15d76a796 | |
|
a92cec5e42 | |
|
43fbc57357 | |
|
9be037d3c8 | |
|
53a43f86e6 | |
|
7bfc237682 | |
|
9312e8decd | |
|
5022beffa7 | |
|
0aeb2e552c | |
|
242982a2b1 | |
|
34a7797dd7 | |
|
cfd827afff | |
|
02ada9374d | |
|
bce001c25d | |
|
eed5fd9092 | |
|
84cc728081 | |
|
9e6388aac3 | |
|
47b1d1f37a | |
|
56a12860b9 | |
|
fc019f08d2 | |
|
177f06c46a | |
|
204d054c97 | |
|
d88a67af73 | |
|
59a9904e83 | |
|
8a850c7d04 | |
|
abb902f171 | |
|
b41b05a79c | |
|
8460ac4527 | |
|
db872518ff | |
|
3eebbbef0b | |
|
dee6b15b4e | |
|
44e38ae256 | |
|
87d8ab1552 | |
|
610cf9fcb6 | |
|
aa8a47710e | |
|
8d2bf0a874 | |
|
7c30fa9d32 | |
|
9a57aeb763 | |
|
a07daf871e | |
|
c7273f6649 | |
|
5314673185 | |
|
f13c817218 | |
|
958a2a447e | |
|
761e48fb43 | |
|
af4b22fa6a | |
|
edc139c27d | |
|
d8f0ffb364 | |
|
870cae0a60 | |
|
086842a209 | |
|
676ff6b10f | |
|
f1f1ff11f8 | |
|
679aa134e6 | |
|
0e8ff20e37 | |
|
37019c2f86 | |
|
315b3c998e | |
|
030413d8de | |
|
62ad6ebcae | |
|
38cd495667 | |
|
fd933d0bdf | |
|
0e4b01f33b | |
|
d1cb59bdf3 | |
|
d8722f5327 | |
|
9ba5670f10 | |
|
a1ee0e5d10 | |
|
da4bf48f6f | |
|
1a97ae90c4 | |
|
746fde5df6 | |
|
5676ae7d9f | |
|
5271dfeb31 | |
|
e19b9372d8 | |
|
f68173fe59 | |
|
5e9b389cf9 | |
|
baadefdafa | |
|
880e0957ff | |
|
2829912ad1 | |
|
f2bd5ee59f | |
|
bea949018f | |
|
e4c7643aa1 | |
|
5cf00fb84d | |
|
a6e932d7de | |
|
26bea2641d | |
|
a03f28bbd4 | |
|
707da82db3 | |
|
a1e2996f54 | |
|
6d6cf814f9 | |
|
46c83179c4 |
|
@ -24,7 +24,7 @@ jobs:
|
|||
uses: actions/setup-go@v5
|
||||
|
||||
with:
|
||||
go-version: ">=1.21"
|
||||
go-version: ">=1.22"
|
||||
|
||||
- name: Build binary
|
||||
run: |
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
12
.packit.yaml
12
.packit.yaml
|
@ -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 ./"
|
||||
|
|
2
Makefile
2
Makefile
|
@ -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:
|
||||
|
|
66
README.md
66
README.md
|
@ -1,66 +0,0 @@
|
|||
## podman-tui
|
||||
|
||||

|
||||

|
||||

|
||||
[](https://goreportcard.com/report/github.com/containers/podman-tui)
|
||||
[](https://codecov.io/gh/navidys/podman-tui)
|
||||
|
||||
Terminal user interface for Podman environment.
|
||||
|
||||

|
||||
|
||||
- [**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.
|
|
@ -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",
|
||||
|
|
45
app/app.go
45
app/app.go
|
@ -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()},
|
||||
|
|
|
@ -13,7 +13,7 @@ func (app *App) initUI() {
|
|||
app.initInfoBar()
|
||||
}
|
||||
|
||||
app.system.UpdateConnectionsData()
|
||||
app.system.UpdateData()
|
||||
}
|
||||
|
||||
func (app *App) initInfoBar() {
|
||||
|
|
|
@ -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 += " "
|
||||
|
|
|
@ -71,7 +71,7 @@ func (app *App) refreshNotConnOK() {
|
|||
app.switchToScreen(app.system.GetTitle())
|
||||
}
|
||||
|
||||
app.system.UpdateConnectionsData()
|
||||
app.system.UpdateData()
|
||||
|
||||
app.needInitUI = true
|
||||
}
|
||||
|
|
|
@ -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("", "", "", "")
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
appVersion = "1.2.0"
|
||||
appVersion = "1.7.0-dev"
|
||||
)
|
||||
|
||||
// versionCmd represents the version command.
|
||||
|
|
133
config/add.go
133
config/add.go
|
@ -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
|
||||
}
|
123
config/config.go
123
config/config.go
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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{}
|
||||
}
|
|
@ -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{}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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{}
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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)
|
||||
}
|
|
@ -1,4 +1,57 @@
|
|||
# Documents
|
||||
## podman-tui
|
||||
|
||||

|
||||

|
||||

|
||||
[](https://goreportcard.com/report/github.com/containers/podman-tui)
|
||||
[](https://codecov.io/gh/navidys/podman-tui)
|
||||
|
||||
Terminal user interface for Podman environment.
|
||||
|
||||

|
||||
|
||||
- [**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.
|
||||
|
|
|
@ -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
164
go.mod
|
@ -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
439
go.sum
|
@ -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=
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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, " ")
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
|
@ -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))
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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).
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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).
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)))
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue