completed phase 5

This commit is contained in:
christophe-duc 2026-01-07 13:23:48 -04:00
parent b24ed8cc71
commit 38f28b1209
20 changed files with 158 additions and 151 deletions

View file

@ -65,23 +65,23 @@ logs:
since: '60m' # set to '' to show all logs
tail: '' # set to 200 to show last 200 lines of logs
commandTemplates:
dockerCompose: docker compose # Determines the Docker Compose command to run, referred to as .DockerCompose in commandTemplates
restartService: '{{ .DockerCompose }} restart {{ .Service.Name }}'
up: '{{ .DockerCompose }} up -d'
down: '{{ .DockerCompose }} down'
downWithVolumes: '{{ .DockerCompose }} down --volumes'
upService: '{{ .DockerCompose }} up -d {{ .Service.Name }}'
startService: '{{ .DockerCompose }} start {{ .Service.Name }}'
stopService: '{{ .DockerCompose }} stop {{ .Service.Name }}'
serviceLogs: '{{ .DockerCompose }} logs --since=60m --follow {{ .Service.Name }}'
viewServiceLogs: '{{ .DockerCompose }} logs --follow {{ .Service.Name }}'
rebuildService: '{{ .DockerCompose }} up -d --build {{ .Service.Name }}'
recreateService: '{{ .DockerCompose }} up -d --force-recreate {{ .Service.Name }}'
allLogs: '{{ .DockerCompose }} logs --tail=300 --follow'
viewAlLogs: '{{ .DockerCompose }} logs'
dockerComposeConfig: '{{ .DockerCompose }} config'
checkDockerComposeConfig: '{{ .DockerCompose }} config --quiet'
serviceTop: '{{ .DockerCompose }} top {{ .Service.Name }}'
podmanCompose: podman-compose # Determines the compose command to run, referred to as .PodmanCompose in commandTemplates
restartService: '{{ .PodmanCompose }} restart {{ .Service.Name }}'
up: '{{ .PodmanCompose }} up -d'
down: '{{ .PodmanCompose }} down'
downWithVolumes: '{{ .PodmanCompose }} down --volumes'
upService: '{{ .PodmanCompose }} up -d {{ .Service.Name }}'
startService: '{{ .PodmanCompose }} start {{ .Service.Name }}'
stopService: '{{ .PodmanCompose }} stop {{ .Service.Name }}'
serviceLogs: '{{ .PodmanCompose }} logs --since=60m --follow {{ .Service.Name }}'
viewServiceLogs: '{{ .PodmanCompose }} logs --follow {{ .Service.Name }}'
rebuildService: '{{ .PodmanCompose }} up -d --build {{ .Service.Name }}'
recreateService: '{{ .PodmanCompose }} up -d --force-recreate {{ .Service.Name }}'
allLogs: '{{ .PodmanCompose }} logs --tail=300 --follow'
viewAlLogs: '{{ .PodmanCompose }} logs'
composeConfig: '{{ .PodmanCompose }} config'
checkComposeConfig: '{{ .PodmanCompose }} config --quiet'
serviceTop: '{{ .PodmanCompose }} top {{ .Service.Name }}'
oS:
openCommand: open {{filename}}
openLinkCommand: open {{link}}
@ -124,12 +124,12 @@ customCommands:
containers:
- name: bash
attach: true
command: 'docker exec -it {{ .Container.ID }} bash'
command: 'podman exec -it {{ .Container.ID }} bash'
serviceNames: []
```
You may use the following go templates (such as `{{ .Container.ID }}` above) in your commands:
- `{{ .DockerCompose }}`: the docker compose command (default: `docker-compose`)
- `{{ .PodmanCompose }}`: the compose command (default: `podman-compose`)
- [`{{ .Container }}`](https://pkg.go.dev/github.com/christophe-duc/lazypodman@v0.20.0/pkg/commands#Container) and its fields. For example: `{{ .Container.Container.ImageID }}`
- [`{{ .Service }}`](https://pkg.go.dev/github.com/christophe-duc/lazypodman@v0.20.0/pkg/commands#Service) and its fields. For example: `{{ .Service.Name }}`

View file

@ -31,7 +31,7 @@ type PodmanCommand struct {
Tr *i18n.TranslationSet
Config *config.AppConfig
Runtime ContainerRuntime
InDockerComposeProject bool
InComposeProject bool
ErrorChan chan error
ContainerMutex deadlock.Mutex
ServiceMutex deadlock.Mutex
@ -49,7 +49,7 @@ type LimitedPodmanCommand interface {
// CommandObject is what we pass to our template resolvers when we are running a custom command.
// We do not guarantee that all fields will be populated: just the ones that make sense for the current context
type CommandObject struct {
DockerCompose string
PodmanCompose string
Service *Service
Container *Container
Image *Image
@ -59,7 +59,7 @@ type CommandObject struct {
// NewCommandObject takes a command object and returns a default command object with the passed command object merged in
func (c *PodmanCommand) NewCommandObject(obj CommandObject) CommandObject {
defaultObj := CommandObject{DockerCompose: c.Config.UserConfig.CommandTemplates.DockerCompose}
defaultObj := CommandObject{PodmanCompose: c.Config.UserConfig.CommandTemplates.PodmanCompose}
_ = mergo.Merge(&defaultObj, obj)
return defaultObj
}
@ -112,23 +112,23 @@ func NewPodmanCommand(log *logrus.Entry, osCommand *OSCommand, tr *i18n.Translat
Log: log,
OSCommand: osCommand,
Tr: tr,
Config: config,
Runtime: runtime,
ErrorChan: errorChan,
InDockerComposeProject: true,
Closers: closers,
Config: config,
Runtime: runtime,
ErrorChan: errorChan,
InComposeProject: true,
Closers: closers,
}
podmanCommand.setComposeCommand(config)
err = osCommand.RunCommand(
utils.ApplyTemplate(
config.UserConfig.CommandTemplates.CheckDockerComposeConfig,
config.UserConfig.CommandTemplates.CheckComposeConfig,
podmanCommand.NewCommandObject(CommandObject{}),
),
)
if err != nil {
podmanCommand.InDockerComposeProject = false
podmanCommand.InComposeProject = false
log.Warn(err.Error())
}
@ -138,31 +138,31 @@ func NewPodmanCommand(log *logrus.Entry, osCommand *OSCommand, tr *i18n.Translat
// setComposeCommand detects and sets the appropriate compose command
func (c *PodmanCommand) setComposeCommand(config *config.AppConfig) {
// If user has explicitly set a compose command, respect it
if config.UserConfig.CommandTemplates.DockerCompose != "docker compose" &&
config.UserConfig.CommandTemplates.DockerCompose != "" {
if config.UserConfig.CommandTemplates.PodmanCompose != "podman-compose" &&
config.UserConfig.CommandTemplates.PodmanCompose != "" {
return
}
// Try podman-compose first
if err := c.OSCommand.RunCommand("podman-compose version"); err == nil {
config.UserConfig.CommandTemplates.DockerCompose = "podman-compose"
config.UserConfig.CommandTemplates.PodmanCompose = "podman-compose"
return
}
// Try podman compose (built-in, if available)
if err := c.OSCommand.RunCommand("podman compose version"); err == nil {
config.UserConfig.CommandTemplates.DockerCompose = "podman compose"
config.UserConfig.CommandTemplates.PodmanCompose = "podman compose"
return
}
// Fall back to docker-compose for compatibility
if err := c.OSCommand.RunCommand("docker-compose version"); err == nil {
config.UserConfig.CommandTemplates.DockerCompose = "docker-compose"
config.UserConfig.CommandTemplates.PodmanCompose = "docker-compose"
return
}
// Default to podman-compose
config.UserConfig.CommandTemplates.DockerCompose = "podman-compose"
config.UserConfig.CommandTemplates.PodmanCompose = "podman-compose"
}
func (c *PodmanCommand) Close() error {
@ -448,11 +448,11 @@ func (c *PodmanCommand) GetContainers(existingContainers []*Container) ([]*Conta
// GetServices gets services
func (c *PodmanCommand) GetServices() ([]*Service, error) {
if !c.InDockerComposeProject {
if !c.InComposeProject {
return nil, nil
}
composeCommand := c.Config.UserConfig.CommandTemplates.DockerCompose
composeCommand := c.Config.UserConfig.CommandTemplates.PodmanCompose
output, err := c.OSCommand.RunCommandWithOutput(fmt.Sprintf("%s config --services", composeCommand))
if err != nil {
return nil, err
@ -520,11 +520,11 @@ func (c *PodmanCommand) ViewAllLogs() (*exec.Cmd, error) {
return cmd, nil
}
// DockerComposeConfig returns the result of 'compose config'
func (c *PodmanCommand) DockerComposeConfig() string {
// ComposeConfig returns the result of 'compose config'
func (c *PodmanCommand) ComposeConfig() string {
output, err := c.OSCommand.RunCommandWithOutput(
utils.ApplyTemplate(
c.OSCommand.Config.UserConfig.CommandTemplates.DockerComposeConfig,
c.OSCommand.Config.UserConfig.CommandTemplates.ComposeConfig,
c.NewCommandObject(CommandObject{}),
),
)

View file

@ -42,26 +42,33 @@ func NewSSHHandler(oSCommand CmdKiller) *SSHHandler {
}
}
// HandleSSHDockerHost overrides the DOCKER_HOST environment variable
// to point towards a local unix socket tunneled over SSH to the specified ssh host.
// HandleSSHDockerHost overrides the CONTAINER_HOST (or DOCKER_HOST for compatibility)
// environment variable to point towards a local unix socket tunneled over SSH.
func (self *SSHHandler) HandleSSHDockerHost() (io.Closer, error) {
const key = "DOCKER_HOST"
// Check CONTAINER_HOST first (Podman standard), then DOCKER_HOST for compatibility
key := "CONTAINER_HOST"
hostValue := self.getenv(key)
if hostValue == "" {
key = "DOCKER_HOST"
hostValue = self.getenv(key)
}
ctx := context.Background()
u, err := url.Parse(self.getenv(key))
u, err := url.Parse(hostValue)
if err != nil {
// if no or an invalid docker host is specified, continue nominally
// if no or an invalid container host is specified, continue nominally
return noopCloser{}, nil
}
// if the docker host scheme is "ssh", forward the docker socket before creating the client
// if the container host scheme is "ssh", forward the socket before creating the client
if u.Scheme == "ssh" {
tunnel, err := self.createDockerHostTunnel(ctx, u.Host)
if err != nil {
return noopCloser{}, fmt.Errorf("tunnel ssh docker host: %w", err)
return noopCloser{}, fmt.Errorf("tunnel ssh container host: %w", err)
}
err = self.setenv(key, tunnel.socketPath)
if err != nil {
return noopCloser{}, fmt.Errorf("override DOCKER_HOST to tunneled socket: %w", err)
return noopCloser{}, fmt.Errorf("override %s to tunneled socket: %w", key, err)
}
return tunnel, nil
@ -90,15 +97,15 @@ func (self *SSHHandler) createDockerHostTunnel(ctx context.Context, remoteHost s
if err != nil {
return nil, fmt.Errorf("create ssh tunnel tmp file: %w", err)
}
localSocket := path.Join(socketDir, "dockerhost.sock")
localSocket := path.Join(socketDir, "podman.sock")
cmd, err := self.tunnelSSH(ctx, remoteHost, localSocket)
if err != nil {
return nil, fmt.Errorf("tunnel docker host over ssh: %w", err)
return nil, fmt.Errorf("tunnel container host over ssh: %w", err)
}
// set a reasonable timeout, then wait for the socket to dial successfully
// before attempting to create a new docker client
// before attempting to create a new container client
const socketTunnelTimeout = 8 * time.Second
ctx, cancel := context.WithTimeout(ctx, socketTunnelTimeout)
defer cancel()
@ -108,7 +115,7 @@ func (self *SSHHandler) createDockerHostTunnel(ctx context.Context, remoteHost s
return nil, fmt.Errorf("ssh tunneled socket never became available: %w", err)
}
// construct the new DOCKER_HOST url with the proper scheme
// construct the new CONTAINER_HOST url with the proper scheme
newDockerHostURL := url.URL{Scheme: "unix", Path: localSocket}
return &tunneledDockerHost{
socketPath: newDockerHostURL.String(),
@ -149,7 +156,7 @@ func (self *SSHHandler) tryDial(ctx context.Context, socketPath string) error {
}
func (self *SSHHandler) tunnelSSH(ctx context.Context, host, localSocket string) (*exec.Cmd, error) {
cmd := exec.CommandContext(ctx, "ssh", "-L", localSocket+":/var/run/docker.sock", host, "-N")
cmd := exec.CommandContext(ctx, "ssh", "-L", localSocket+":/run/podman/podman.sock", host, "-N")
self.oSCommand.PrepareForChildren(cmd)
err := self.startCmd(cmd)
if err != nil {

View file

@ -41,7 +41,7 @@ type UserConfig struct {
// CustomCommands determines what shows up in your custom commands menu when
// you press 'c'. You can use go templates to access three items on the
// struct: the DockerCompose command (defaulted to 'docker-compose'), the
// struct: the DockerCompose command (defaulted to 'podman-compose'), the
// Service if present, and the Container if present. The struct types for
// those are found in the commands package
CustomCommands CustomCommands `yaml:"customCommands,omitempty"`
@ -166,14 +166,15 @@ type CommandTemplatesConfig struct {
// downs and removes volumes
DownWithVolumes string `yaml:"downWithVolumes,omitempty"`
// DockerCompose is for your docker-compose command. You may want to combine a
// few different docker-compose.yml files together, in which case you can set
// this to "docker compose -f foo/docker-compose.yml -f
// bah/docker-compose.yml". The reason that the other docker-compose command
// templates all start with {{ .DockerCompose }} is so that they can make use
// PodmanCompose is for your compose command. You may want to combine a
// few different compose.yml files together, in which case you can set
// this to "podman-compose -f foo/docker-compose.yml -f
// bah/docker-compose.yml". The reason that the other compose command
// templates all start with {{ .PodmanCompose }} is so that they can make use
// of whatever you've set in this value rather than you having to copy and
// paste it to all the other commands
DockerCompose string `yaml:"dockerCompose,omitempty"`
// paste it to all the other commands. Auto-detected in order: podman-compose,
// podman compose, docker-compose.
PodmanCompose string `yaml:"podmanCompose,omitempty"`
// StopService is the command for stopping a service
StopService string `yaml:"stopService,omitempty"`
@ -191,7 +192,7 @@ type CommandTemplatesConfig struct {
ViewServiceLogs string `yaml:"viewServiceLogs,omitempty"`
// RebuildService is the command for rebuilding a service. Defaults to
// something along the lines of `{{ .DockerCompose }} up --build {{
// something along the lines of `{{ .PodmanCompose }} up --build {{
// .Service.Name }}`
RebuildService string `yaml:"rebuildService,omitempty"`
@ -207,16 +208,16 @@ type CommandTemplatesConfig struct {
// ViewAllLogs is the command we use when you want to see all logs in a subprocess with no filtering
ViewAllLogs string `yaml:"viewAlLogs,omitempty"`
// DockerComposeConfig is the command for viewing the config of your docker
// compose. It basically prints out the yaml from your docker-compose.yml
// ComposeConfig is the command for viewing the config of your compose
// project. It basically prints out the yaml from your docker-compose.yml
// file(s)
DockerComposeConfig string `yaml:"dockerComposeConfig,omitempty"`
ComposeConfig string `yaml:"composeConfig,omitempty"`
// CheckDockerComposeConfig is what we use to check whether we are in a
// docker-compose context. If the command returns an error then we clearly
// aren't in a docker-compose config and we then just hide the services panel
// CheckComposeConfig is what we use to check whether we are in a
// compose context. If the command returns an error then we clearly
// aren't in a compose config and we then just hide the services panel
// and only show containers
CheckDockerComposeConfig string `yaml:"checkDockerComposeConfig,omitempty"`
CheckComposeConfig string `yaml:"checkComposeConfig,omitempty"`
// ServiceTop is the command for viewing the processes under a given service
ServiceTop string `yaml:"serviceTop,omitempty"`
@ -326,7 +327,7 @@ type CustomCommand struct {
Shell bool `yaml:"shell"`
// Command is the command we want to run. We can use the go templates here as
// well. One example might be `{{ .DockerCompose }} exec {{ .Service.Name }}
// well. One example might be `{{ .PodmanCompose }} exec {{ .Service.Name }}
// /bin/sh`
Command string `yaml:"command"`
@ -385,23 +386,23 @@ func GetDefaultConfig() UserConfig {
Tail: "",
},
CommandTemplates: CommandTemplatesConfig{
DockerCompose: "docker compose",
RestartService: "{{ .DockerCompose }} restart {{ .Service.Name }}",
StartService: "{{ .DockerCompose }} start {{ .Service.Name }}",
Up: "{{ .DockerCompose }} up -d",
Down: "{{ .DockerCompose }} down",
DownWithVolumes: "{{ .DockerCompose }} down --volumes",
UpService: "{{ .DockerCompose }} up -d {{ .Service.Name }}",
RebuildService: "{{ .DockerCompose }} up -d --build {{ .Service.Name }}",
RecreateService: "{{ .DockerCompose }} up -d --force-recreate {{ .Service.Name }}",
StopService: "{{ .DockerCompose }} stop {{ .Service.Name }}",
ServiceLogs: "{{ .DockerCompose }} logs --since=60m --follow {{ .Service.Name }}",
ViewServiceLogs: "{{ .DockerCompose }} logs --follow {{ .Service.Name }}",
AllLogs: "{{ .DockerCompose }} logs --tail=300 --follow",
ViewAllLogs: "{{ .DockerCompose }} logs",
DockerComposeConfig: "{{ .DockerCompose }} config",
CheckDockerComposeConfig: "{{ .DockerCompose }} config --quiet",
ServiceTop: "{{ .DockerCompose }} top {{ .Service.Name }}",
PodmanCompose: "podman-compose",
RestartService: "{{ .PodmanCompose }} restart {{ .Service.Name }}",
StartService: "{{ .PodmanCompose }} start {{ .Service.Name }}",
Up: "{{ .PodmanCompose }} up -d",
Down: "{{ .PodmanCompose }} down",
DownWithVolumes: "{{ .PodmanCompose }} down --volumes",
UpService: "{{ .PodmanCompose }} up -d {{ .Service.Name }}",
RebuildService: "{{ .PodmanCompose }} up -d --build {{ .Service.Name }}",
RecreateService: "{{ .PodmanCompose }} up -d --force-recreate {{ .Service.Name }}",
StopService: "{{ .PodmanCompose }} stop {{ .Service.Name }}",
ServiceLogs: "{{ .PodmanCompose }} logs --since=60m --follow {{ .Service.Name }}",
ViewServiceLogs: "{{ .PodmanCompose }} logs --follow {{ .Service.Name }}",
AllLogs: "{{ .PodmanCompose }} logs --tail=300 --follow",
ViewAllLogs: "{{ .PodmanCompose }} logs",
ComposeConfig: "{{ .PodmanCompose }} config",
CheckComposeConfig: "{{ .PodmanCompose }} config --quiet",
ServiceTop: "{{ .PodmanCompose }} top {{ .Service.Name }}",
},
CustomCommands: CustomCommands{
Containers: []CustomCommand{},
@ -413,42 +414,42 @@ func GetDefaultConfig() UserConfig {
Services: []CustomCommand{
{
Name: "up",
Command: "{{ .DockerCompose }} up -d",
Command: "{{ .PodmanCompose }} up -d",
},
{
Name: "up (attached)",
Command: "{{ .DockerCompose }} up",
Command: "{{ .PodmanCompose }} up",
Attach: true,
},
{
Name: "stop",
Command: "{{ .DockerCompose }} stop",
Command: "{{ .PodmanCompose }} stop",
},
{
Name: "pull",
Command: "{{ .DockerCompose }} pull",
Command: "{{ .PodmanCompose }} pull",
Attach: true,
},
{
Name: "build",
Command: "{{ .DockerCompose }} build --parallel --force-rm",
Command: "{{ .PodmanCompose }} build --parallel --force-rm",
Attach: true,
},
{
Name: "down",
Command: "{{ .DockerCompose }} down",
Command: "{{ .PodmanCompose }} down",
},
{
Name: "down with volumes",
Command: "{{ .DockerCompose }} down --volumes",
Command: "{{ .PodmanCompose }} down --volumes",
},
{
Name: "down with images",
Command: "{{ .DockerCompose }} down --rmi all",
Command: "{{ .PodmanCompose }} down --rmi all",
},
{
Name: "down with volumes and images",
Command: "{{ .DockerCompose }} down --volumes --rmi all",
Command: "{{ .PodmanCompose }} down --volumes --rmi all",
},
},
Containers: []CustomCommand{},
@ -502,9 +503,9 @@ func NewAppConfig(name, version, commit, date string, buildSource string, debugg
return nil, err
}
// Pass compose files as individual -f flags to docker compose
// Pass compose files as individual -f flags to compose command
if len(composeFiles) > 0 {
userConfig.CommandTemplates.DockerCompose += " -f " + strings.Join(composeFiles, " -f ")
userConfig.CommandTemplates.PodmanCompose += " -f " + strings.Join(composeFiles, " -f ")
}
appConfig := &AppConfig{

View file

@ -7,43 +7,43 @@ import (
"github.com/jesseduffield/yaml"
)
func TestDockerComposeCommandNoFiles(t *testing.T) {
func TestPodmanComposeCommandNoFiles(t *testing.T) {
composeFiles := []string{}
conf, err := NewAppConfig("name", "version", "commit", "date", "buildSource", false, composeFiles, "projectDir")
if err != nil {
t.Fatalf("Unexpected error: %s", err)
}
actual := conf.UserConfig.CommandTemplates.DockerCompose
expected := "docker compose"
actual := conf.UserConfig.CommandTemplates.PodmanCompose
expected := "podman-compose"
if actual != expected {
t.Fatalf("Expected %s but got %s", expected, actual)
}
}
func TestDockerComposeCommandSingleFile(t *testing.T) {
func TestPodmanComposeCommandSingleFile(t *testing.T) {
composeFiles := []string{"one.yml"}
conf, err := NewAppConfig("name", "version", "commit", "date", "buildSource", false, composeFiles, "projectDir")
if err != nil {
t.Fatalf("Unexpected error: %s", err)
}
actual := conf.UserConfig.CommandTemplates.DockerCompose
expected := "docker compose -f one.yml"
actual := conf.UserConfig.CommandTemplates.PodmanCompose
expected := "podman-compose -f one.yml"
if actual != expected {
t.Fatalf("Expected %s but got %s", expected, actual)
}
}
func TestDockerComposeCommandMultipleFiles(t *testing.T) {
func TestPodmanComposeCommandMultipleFiles(t *testing.T) {
composeFiles := []string{"one.yml", "two.yml", "three.yml"}
conf, err := NewAppConfig("name", "version", "commit", "date", "buildSource", false, composeFiles, "projectDir")
if err != nil {
t.Fatalf("Unexpected error: %s", err)
}
actual := conf.UserConfig.CommandTemplates.DockerCompose
expected := "docker compose -f one.yml -f two.yml -f three.yml"
actual := conf.UserConfig.CommandTemplates.PodmanCompose
expected := "podman-compose -f one.yml -f two.yml -f three.yml"
if actual != expected {
t.Fatalf("Expected %s but got %s", expected, actual)
}

View file

@ -282,7 +282,7 @@ func (gui *Gui) refreshContainersAndServices() error {
}
func (gui *Gui) renderContainersAndServices() error {
if gui.PodmanCommand.InDockerComposeProject {
if gui.PodmanCommand.InComposeProject {
if err := gui.Panels.Services.RerenderList(); err != nil {
return err
}
@ -449,7 +449,7 @@ func (gui *Gui) containerExecShell(container *commands.Container) error {
})
// TODO: use SDK
resolvedCommand := utils.ApplyTemplate("docker exec -it {{ .Container.ID }} /bin/sh -c 'eval $(grep ^$(id -un): /etc/passwd | cut -d : -f 7-)'", commandObject)
resolvedCommand := utils.ApplyTemplate("podman exec -it {{ .Container.ID }} /bin/sh -c 'eval $(grep ^$(id -un): /etc/passwd | cut -d : -f 7-)'", commandObject)
// attach and return the subprocess error
cmd := gui.OSCommand.ExecutableFromString(resolvedCommand)
return gui.runSubprocess(cmd)

View file

@ -445,7 +445,7 @@ func (gui *Gui) ShouldRefresh(key string) bool {
}
func (gui *Gui) initiallyFocusedViewName() string {
if gui.PodmanCommand.InDockerComposeProject {
if gui.PodmanCommand.InComposeProject {
return "services"
}
return "containers"

View file

@ -23,7 +23,7 @@ func (gui *Gui) getProjectPanel() *panels.SideListPanel[*commands.Project] {
return &panels.SideListPanel[*commands.Project]{
ContextState: &panels.ContextState[*commands.Project]{
GetMainTabs: func() []panels.MainTab[*commands.Project] {
if gui.PodmanCommand.InDockerComposeProject {
if gui.PodmanCommand.InComposeProject {
return []panels.MainTab[*commands.Project]{
{
Key: "logs",
@ -32,8 +32,8 @@ func (gui *Gui) getProjectPanel() *panels.SideListPanel[*commands.Project] {
},
{
Key: "config",
Title: gui.Tr.DockerComposeConfigTitle,
Render: gui.renderDockerComposeConfig,
Title: gui.Tr.ComposeConfigTitle,
Render: gui.renderComposeConfig,
},
{
Key: "credits",
@ -79,7 +79,7 @@ func (gui *Gui) refreshProject() error {
func (gui *Gui) getProjectName() string {
projectName := path.Base(gui.Config.ProjectDir)
if gui.PodmanCommand.InDockerComposeProject {
if gui.PodmanCommand.InComposeProject {
for _, service := range gui.Panels.Services.List.GetAllItems() {
container := service.Container
if container != nil && container.DetailsLoaded() {
@ -144,9 +144,9 @@ func (gui *Gui) renderAllLogs(_project *commands.Project) tasks.TaskFunc {
})
}
func (gui *Gui) renderDockerComposeConfig(_project *commands.Project) tasks.TaskFunc {
func (gui *Gui) renderComposeConfig(_project *commands.Project) tasks.TaskFunc {
return gui.NewSimpleRenderStringTask(func() string {
return utils.ColoredYamlString(gui.PodmanCommand.DockerComposeConfig())
return utils.ColoredYamlString(gui.PodmanCommand.ComposeConfig())
})
}

View file

@ -78,7 +78,7 @@ func (gui *Gui) getServicesPanel() *panels.SideListPanel[*commands.Service] {
return presentation.GetServiceDisplayStrings(&gui.Config.UserConfig.Gui, service)
},
Hide: func() bool {
return !gui.PodmanCommand.InDockerComposeProject
return !gui.PodmanCommand.InComposeProject
},
}
}
@ -148,7 +148,7 @@ func (gui *Gui) handleServiceRemoveMenu(g *gocui.Gui, v *gocui.View) error {
return nil
}
composeCommand := gui.Config.UserConfig.CommandTemplates.DockerCompose
composeCommand := gui.Config.UserConfig.CommandTemplates.PodmanCompose
options := []*commandOption{
{

View file

@ -4,7 +4,6 @@ import (
"sort"
"testing"
"github.com/docker/docker/api/types/container"
"github.com/christophe-duc/lazypodman/pkg/commands"
"github.com/stretchr/testify/assert"
)
@ -14,28 +13,28 @@ func sampleContainers() []*commands.Container {
{
ID: "1",
Name: "1",
Container: container.Summary{
Summary: commands.ContainerSummary{
State: "exited",
},
},
{
ID: "2",
Name: "2",
Container: container.Summary{
Summary: commands.ContainerSummary{
State: "running",
},
},
{
ID: "3",
Name: "3",
Container: container.Summary{
Summary: commands.ContainerSummary{
State: "running",
},
},
{
ID: "4",
Name: "4",
Container: container.Summary{
Summary: commands.ContainerSummary{
State: "created",
},
},
@ -47,28 +46,28 @@ func expectedPerStatusContainers() []*commands.Container {
{
ID: "2",
Name: "2",
Container: container.Summary{
Summary: commands.ContainerSummary{
State: "running",
},
},
{
ID: "3",
Name: "3",
Container: container.Summary{
Summary: commands.ContainerSummary{
State: "running",
},
},
{
ID: "1",
Name: "1",
Container: container.Summary{
Summary: commands.ContainerSummary{
State: "exited",
},
},
{
ID: "4",
Name: "4",
Container: container.Summary{
Summary: commands.ContainerSummary{
State: "created",
},
},
@ -80,28 +79,28 @@ func expectedLegacySortedContainers() []*commands.Container {
{
ID: "1",
Name: "1",
Container: container.Summary{
Summary: commands.ContainerSummary{
State: "exited",
},
},
{
ID: "2",
Name: "2",
Container: container.Summary{
Summary: commands.ContainerSummary{
State: "running",
},
},
{
ID: "3",
Name: "3",
Container: container.Summary{
Summary: commands.ContainerSummary{
State: "running",
},
},
{
ID: "4",
Name: "4",
Container: container.Summary{
Summary: commands.ContainerSummary{
State: "created",
},
},
@ -110,8 +109,8 @@ func expectedLegacySortedContainers() []*commands.Container {
func assertEqualContainers(t *testing.T, left *commands.Container, right *commands.Container) {
t.Helper()
assert.Equal(t, left.Container.State, right.Container.State)
assert.Equal(t, left.Container.ID, right.Container.ID)
assert.Equal(t, left.Summary.State, right.Summary.State)
assert.Equal(t, left.Summary.ID, right.Summary.ID)
assert.Equal(t, left.Name, right.Name)
}

View file

@ -128,7 +128,7 @@ func (gui *Gui) createAllViews() error {
gui.Views.Containers.Highlight = true
gui.Views.Containers.SelBgColor = selectedLineBgColor
if gui.Config.UserConfig.Gui.ShowAllContainers || !gui.PodmanCommand.InDockerComposeProject {
if gui.Config.UserConfig.Gui.ShowAllContainers || !gui.PodmanCommand.InComposeProject {
gui.Views.Containers.Title = gui.Tr.ContainersTitle
} else {
gui.Views.Containers.Title = gui.Tr.StandaloneContainersTitle

View file

@ -95,7 +95,7 @@ func chineseSet() TranslationSet {
LogsTitle: "日志",
ConfigTitle: "配置",
EnvTitle: "环境变量",
DockerComposeConfigTitle: "Docker-Compose配置",
ComposeConfigTitle: "Compose配置",
TopTitle: "系统资源管理",
StatsTitle: "统计信息",
CreditsTitle: "关于我们",
@ -113,7 +113,7 @@ func chineseSet() TranslationSet {
NoServices: "没有服务",
ConfirmQuit: "您确定要退出吗?",
ConfirmUpProject: "您确定要“up”的docker compose项目吗",
ConfirmUpProject: "您确定要启动您的compose项目吗",
MustForceToRemoveContainer: "您无法删除正在运行的容器,除非您强制执行。您想强制执行吗?",
NotEnoughSpace: "空间不足,无法渲染面板",
ConfirmPruneImages: "您确定要删除所有未使用的镜像吗?",

View file

@ -68,7 +68,7 @@ func dutchSet() TranslationSet {
LogsTitle: "Logs",
ConfigTitle: "Config",
EnvTitle: "Env",
DockerComposeConfigTitle: "Docker-Compose Configuratie",
ComposeConfigTitle: "Compose Configuratie",
TopTitle: "Top",
StatsTitle: "Stats",
CreditsTitle: "Over",

View file

@ -110,10 +110,10 @@ type TranslationSet struct {
OpenInBrowser string
SortContainersByState string
LogsTitle string
ConfigTitle string
EnvTitle string
DockerComposeConfigTitle string
LogsTitle string
ConfigTitle string
EnvTitle string
ComposeConfigTitle string
StatsTitle string
CreditsTitle string
ContainerConfigTitle string
@ -232,7 +232,7 @@ func englishSet() TranslationSet {
LogsTitle: "Logs",
ConfigTitle: "Config",
EnvTitle: "Env",
DockerComposeConfigTitle: "Docker-Compose Config",
ComposeConfigTitle: "Compose Config",
TopTitle: "Top",
StatsTitle: "Stats",
CreditsTitle: "About",
@ -250,7 +250,7 @@ func englishSet() TranslationSet {
NoServices: "No services",
ConfirmQuit: "Are you sure you want to quit?",
ConfirmUpProject: "Are you sure you want to 'up' your docker compose project?",
ConfirmUpProject: "Are you sure you want to 'up' your compose project?",
MustForceToRemoveContainer: "You cannot remove a running container unless you force it. Do you want to force it?",
NotEnoughSpace: "Not enough space to render panels",
ConfirmPruneImages: "Are you sure you want to prune all unused images?",

View file

@ -85,7 +85,7 @@ func frenchSet() TranslationSet {
LogsTitle: "Journaux",
ConfigTitle: "Config",
EnvTitle: "Env",
DockerComposeConfigTitle: "Config Docker-Compose",
ComposeConfigTitle: "Config Compose",
TopTitle: "Top",
StatsTitle: "Statistiques",
CreditsTitle: "À propos",

View file

@ -67,7 +67,7 @@ func germanSet() TranslationSet {
LogsTitle: "Protokoll",
ConfigTitle: "Konfiguration",
EnvTitle: "Env",
DockerComposeConfigTitle: "Docker-Compose Konfiguration",
ComposeConfigTitle: "Compose Konfiguration",
TopTitle: "Top",
StatsTitle: "Statistiken",
CreditsTitle: "Über Uns",

View file

@ -67,7 +67,7 @@ func polishSet() TranslationSet {
LogsTitle: "Logi",
ConfigTitle: "Konfiguracja",
EnvTitle: "Env",
DockerComposeConfigTitle: "Konfiguracja docker-compose",
ComposeConfigTitle: "Konfiguracja compose",
TopTitle: "Top",
StatsTitle: "Staty",
CreditsTitle: "O",

View file

@ -95,7 +95,7 @@ func portugueseSet() TranslationSet {
LogsTitle: "Registros",
ConfigTitle: "Config",
EnvTitle: "Env",
DockerComposeConfigTitle: "Docker-Compose Config",
ComposeConfigTitle: "Compose Config",
TopTitle: "Topo",
StatsTitle: "Estatísticas",
CreditsTitle: "Sobre",
@ -113,7 +113,7 @@ func portugueseSet() TranslationSet {
NoServices: "Sem serviços",
ConfirmQuit: "Tem certeza que deseja sair?",
ConfirmUpProject: "Tem certeza que deseja 'iniciar' seu projeto docker compose?",
ConfirmUpProject: "Tem certeza que deseja 'iniciar' seu projeto compose?",
MustForceToRemoveContainer: "Você não pode remover um contêiner em execução a menos que o force. Deseja forçar?",
NotEnoughSpace: "Sem espaço suficiente para renderizar os painéis",
ConfirmPruneImages: "Tem certeza que deseja eliminar todas as imagens não utilizadas?",

View file

@ -90,7 +90,7 @@ func spanishSet() TranslationSet {
LogsTitle: "Logs",
ConfigTitle: "Configuración",
EnvTitle: "Variables de entorno",
DockerComposeConfigTitle: "Docker-Compose Config",
ComposeConfigTitle: "Compose Config",
TopTitle: "Top",
StatsTitle: "Estadísticas",
CreditsTitle: "Acerca",
@ -108,7 +108,7 @@ func spanishSet() TranslationSet {
NoServices: "Sin servicios",
ConfirmQuit: "¿Realmente quieres salir?",
ConfirmUpProject: "¿Realmente quieres levantar tu proyecto docker compose?",
ConfirmUpProject: "¿Realmente quieres levantar tu proyecto compose?",
MustForceToRemoveContainer: "No puedes borrar un contenedor en ejecución a menos de que lo fuerces, ¿quieres hacerlo?",
NotEnoughSpace: "No hay suficiente espacio para renderizar los paneles",
ConfirmPruneImages: "¿Realmente quieres limpiar todas tus imágenes?",

View file

@ -67,7 +67,7 @@ func turkishSet() TranslationSet {
LogsTitle: "Kayitlar",
ConfigTitle: "Ayarlar",
EnvTitle: "Env",
DockerComposeConfigTitle: "Docker-Compose Ayar",
ComposeConfigTitle: "Compose Ayar",
TopTitle: "Top",
StatsTitle: "Durumlar",
CreditsTitle: "Hakkinda",