feat: prototype for app listing

This commit is contained in:
decentral1se 2021-07-27 21:25:08 +02:00
parent cf7a8d114a
commit 0e75350985
No known key found for this signature in database
GPG Key ID: 5E2EF5A63E3718CC
3 changed files with 38 additions and 19 deletions

View File

@ -12,7 +12,7 @@ Disclaimer!: List is WIP
- [ ] `init`
- [ ] `apps`
- [ ] `abra app`
- [ ] `ls` (XXX: in progress (decentral1se))
- [x] `ls`
- [ ] `new`
- [ ] `backup`
- [ ] `deploy`

View File

@ -81,8 +81,7 @@ var appListCommand = &cli.Command{
// If type flag is set, check for it, if not, Type == ""
tableRow = []string{app.File.Server, app.Type, app.Domain}
if Status {
stackName := strings.ReplaceAll(app.Name, ".", "_")
if status, ok := statuses[stackName]; ok {
if status, ok := statuses[app.StackName()]; ok {
tableRow = append(tableRow, status)
} else {
tableRow = append(tableRow, "unknown")

View File

@ -19,6 +19,8 @@ import (
"github.com/sirupsen/logrus"
)
const dockerStackNamespace = "com.docker.stack.namespace"
var ABRA_DIR = os.ExpandEnv("$HOME/.abra")
var ABRA_SERVER_FOLDER = path.Join(ABRA_DIR, "servers")
var APPS_JSON = path.Join(ABRA_DIR, "apps.json")
@ -37,6 +39,10 @@ type App struct {
File AppFile
}
func (a App) StackName() string {
return strings.ReplaceAll(a.Name, ".", "_")
}
type ByServer []App
func (a ByServer) Len() int { return len(a) }
@ -78,7 +84,19 @@ type AppFile struct {
Server string
}
type AppFiles = map[AppName]AppFile
type AppFiles map[AppName]AppFile
func (a AppFiles) GetServers() []string {
var unique []string
servers := make(map[string]struct{})
for _, appFile := range a {
if _, ok := servers[appFile.Server]; !ok {
servers[appFile.Server] = struct{}{}
unique = append(unique, appFile.Server)
}
}
return unique
}
func LoadAppFiles(servers ...string) (AppFiles, error) {
appFiles := make(AppFiles)
@ -137,40 +155,42 @@ func GetApps(appFiles AppFiles) ([]App, error) {
}
func GetAppStatuses(appFiles AppFiles) (map[string]string, error) {
statuses := map[string]string{}
servers := make(map[string]struct{})
for _, appFile := range appFiles {
if _, ok := servers[appFile.Server]; !ok {
servers[appFile.Server] = struct{}{}
}
}
type status struct {
services []swarm.Service
err error
}
servers := appFiles.GetServers()
ch := make(chan status, len(servers))
for server, _ := range servers {
for _, server := range servers {
go func(s string) {
ctx := context.Background()
cl, err := client.NewClientWithContext(s)
if err != nil {
ch <- status{services: []swarm.Service{}, err: nil}
if strings.Contains(err.Error(), "does not exist") {
// No local context found, bail out gracefully
ch <- status{services: []swarm.Service{}, err: nil}
return
}
ch <- status{services: []swarm.Service{}, err: err}
return
}
ctx := context.Background()
filter := filters.NewArgs()
filter.Add("label", "com.docker.stack.namespace")
services, _ := cl.ServiceList(ctx, types.ServiceListOptions{Filters: filter})
filter.Add("label", dockerStackNamespace)
services, err := cl.ServiceList(ctx, types.ServiceListOptions{Filters: filter})
if err != nil {
ch <- status{services: []swarm.Service{}, err: err}
return
}
ch <- status{services: services, err: nil}
}(server)
}
statuses := map[string]string{}
for range servers {
status := <-ch
for _, service := range status.services {
name := service.Spec.Labels["com.docker.stack.namespace"]
name := service.Spec.Labels[dockerStackNamespace]
if _, ok := statuses[name]; !ok {
statuses[name] = "deployed"
}