Skip to content

Commit

Permalink
running golangci-lint on config package
Browse files Browse the repository at this point in the history
Signed-off-by: Navid Yaghoobi <[email protected]>
  • Loading branch information
navidys committed Nov 25, 2023
1 parent ce5905b commit b94bfa9
Show file tree
Hide file tree
Showing 8 changed files with 154 additions and 66 deletions.
2 changes: 0 additions & 2 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ run:
- ".*_test.go"
skip-dirs:
- app
# - cmd
- config
- ui/containers
- ui/dialogs
- ui/images
Expand Down
41 changes: 28 additions & 13 deletions config/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,50 +12,59 @@ import (
"github.com/rs/zerolog/log"
)

// Add adds new service connection
// 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 fmt.Errorf("duplicated service 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) {
// https://github.com/containers/podman/blob/main/cmd/podman/system/connection/add.go.
func validateNewService(name string, dest string, identity string) (Service, error) { //nolint:gocognit,cyclop
var (
service Service
serviceIdentity string
)

if name == "" {
return service, fmt.Errorf("empty service name %q", name)
return service, ErrEmptyServiceName
}

if dest == "" {
return service, fmt.Errorf("empty URI %q", dest)
return service, ErrEmptyURIDestination
}

if match, err := regexp.Match("^[A-Za-z][A-Za-z0-9+.-]*://", []byte(dest)); err != nil {
return service, fmt.Errorf("%v invalid destition", err)
return service, fmt.Errorf("%w invalid destition", err)
} else if !match {
dest = "ssh://" + dest
}
Expand All @@ -64,33 +73,40 @@ func validateNewService(name string, dest string, identity string) (Service, err
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, fmt.Errorf("%q empty identity field for SSH connection", 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("identity option not supported for unix scheme")
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)
Expand All @@ -99,15 +115,14 @@ func validateNewService(name string, dest string, identity string) (Service, err
case err != nil:
return service, err
case info.Mode()&os.ModeSocket == 0:
return service, fmt.Errorf("%q exists and is not a unix domain socket", uri.Path)
return service, fmt.Errorf("%w %q", ErrFileNotUnixSocket, uri.Path)
}

case "tcp":
if identity != "" {
return service, fmt.Errorf("identity option not supported for tcp scheme")
return service, fmt.Errorf("%w identity", ErrInvalidTCPSchemaOption)
}
default:
return service, fmt.Errorf("%q invalid schema name", uri.Scheme)
return service, fmt.Errorf("%w %q", ErrInvalidURISchemaName, uri.Scheme)
}

service.Identity = serviceIdentity
Expand Down
46 changes: 29 additions & 17 deletions config/config.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package config

import (
"errors"
"os"
"sort"
"sync"
Expand All @@ -13,18 +14,30 @@ 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 holds the user podman-tui config path.
UserAppConfig = ".config/" + _configPath
)

// Config contains configuration options for container tools
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"`
}

// Service represents remote service destination
// Service represents remote service destination.
type Service struct {
// URI, required. Example: ssh://[email protected]:22/run/podman/podman.sock
URI string `toml:"uri"`
Expand All @@ -36,9 +49,10 @@ type Service struct {
Default bool `toml:"default,omitempty"`
}

// NewConfig returns new config
// NewConfig returns new config.
func NewConfig() (*Config, error) {
log.Debug().Msgf("config: new")

path, err := configPath()
if err != nil {
return nil, err
Expand All @@ -54,9 +68,8 @@ func NewConfig() (*Config, error) {
return nil, err
}
}
if err := newConfig.addLocalHostIfEmptyConfig(); err != nil {
return nil, err
}

newConfig.addLocalHostIfEmptyConfig()

defaultConn := newConfig.getDefault()
if defaultConn.URI != "" {
Expand All @@ -66,28 +79,25 @@ func NewConfig() (*Config, error) {
return newConfig, nil
}

func (c *Config) addLocalHostIfEmptyConfig() error {
func (c *Config) addLocalHostIfEmptyConfig() {
if len(c.Services) > 0 {
return nil
}
localSocket, err := localNodeUnixSocket()
if err != nil {
return err
return
}

c.Services = make(map[string]Service)
c.Services["localhost"] = Service{
URI: localSocket,
URI: localNodeUnixSocket(),
Default: true,
}
return nil
}

// ServicesConnections returns list of available connections
// ServicesConnections returns list of available connections.
func (c *Config) ServicesConnections() []registry.Connection {
var conn []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,
Expand All @@ -96,7 +106,9 @@ func (c *Config) ServicesConnections() []registry.Connection {
Default: service.Default,
})
}

sort.Sort(connectionListSortedName{conn})

return conn
}

Expand Down
8 changes: 8 additions & 0 deletions config/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,33 +8,40 @@ import (
// 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{
Expand All @@ -44,5 +51,6 @@ func (c *Config) getDefault() registry.Connection {
}
}
}

return registry.Connection{}
}
9 changes: 8 additions & 1 deletion config/read.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,34 @@ import (

func (c *Config) readConfigFromFile(path string) error {
log.Debug().Msgf("config: reading configuration file %q", path)

c.mu.Lock()
defer c.mu.Unlock()

meta, err := toml.DecodeFile(path, c)
if err != nil {
return fmt.Errorf("config: %v decode configuration %q", err, path)
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
}

func (c *Config) reload() error {
log.Debug().Msgf("config: reload configuration")

path, err := configPath()
if err != nil {
return err
}

if err := c.readConfigFromFile(path); err != nil {
return err
}

return nil
}
7 changes: 5 additions & 2 deletions config/remove.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,26 @@ package config

import "github.com/rs/zerolog/log"

// Remove removes a service from config
// 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)
}
}

}
Loading

0 comments on commit b94bfa9

Please sign in to comment.