diff --git a/Makefile b/Makefile index 21a2f80..97b4d7d 100644 --- a/Makefile +++ b/Makefile @@ -19,3 +19,8 @@ minio: -e MINIO_ROOT_USER=test \ -e MINIO_ROOT_PASSWORD=testtest \ minio/minio server /data --console-address ":9001" + +.PHONY: clean +clean: + -podman stop rosti-snapshots + -podman rm rosti-snapshots diff --git a/apps/types.go b/apps/types.go index 2dcab54..b3f2b02 100644 --- a/apps/types.go +++ b/apps/types.go @@ -84,6 +84,10 @@ type App struct { // Disk usage in inodes DiskUsageInodes int `json:"disk_usage_inodes"` + // this is gathered in docker package and has to be assembled externally + Techs AppTechs `json:"techs,omitempty" gorm:"-"` // list of available technologies in the image + PrimaryTech AppTech `json:"primary_tech,omitempty" gorm:"-"` // Technology that was selected as primary in the environment + // This is not store in the database but used in create request when the app suppose to be created from an existing snapshot Snapshot string `json:"snapshot" gorm:"-"` } @@ -119,3 +123,12 @@ func (a *App) Validate() []string { return errors } + +// AppTechs is list of technologies available in the app +type AppTechs []AppTech + +// AppTech holds info about one technology in the app +type AppTech struct { + Name string + Version string +} diff --git a/docker/types.go b/docker/types.go index c5cb851..756366e 100644 --- a/docker/types.go +++ b/docker/types.go @@ -1,6 +1,7 @@ package docker import ( + "errors" "log" "path" "strings" @@ -277,3 +278,59 @@ func (c *Container) GetProcessList() (*[]Process, error) { return &processes, nil } + +// GetPrimaryTech returns primary tech configured in the container. +func (c *Container) GetPrimaryTech() (apps.AppTech, error) { + tech := apps.AppTech{} + + driver := c.getDriver() + + stdouterr, err := driver.Exec(c.App.Name, []string{"readlink", "/srv/bin/primary_tech"}, "", []string{}, true) + if err != nil { + return tech, err + } + + if len(string(*stdouterr)) > 0 { + parts := strings.Split(string(*stdouterr), "/") + if len(parts) == 5 { + rawTech := parts[3] + techParts := strings.Split(rawTech, "-") + if len(techParts) != 2 { + return tech, errors.New("wrong number of tech parts") + } + return apps.AppTech{ + Name: techParts[0], + Version: techParts[1], + }, nil + } + } + + return tech, errors.New("wrong number of path parts") +} + +// GetTechs returns all techs available in the container +func (c *Container) GetTechs() (apps.AppTechs, error) { + techs := apps.AppTechs{} + + driver := c.getDriver() + + stdouterr, err := driver.Exec(c.App.Name, []string{"ls", "/opt/techs"}, "", []string{}, true) + if err != nil { + return techs, err + } + + techsRaw := strings.Split(string(*stdouterr), "\n") + for _, techRaw := range techsRaw { + techParts := strings.Split(techRaw, "-") + if len(techParts) == 2 { + techs = append(techs, apps.AppTech{ + Name: techParts[0], + Version: techParts[1], + }) + } else { + return techs, errors.New("one of the tech has wrong number of parts") + } + } + + return techs, nil +} diff --git a/handlers_nats.go b/handlers_nats.go index 8d6ede4..fb6da33 100644 --- a/handlers_nats.go +++ b/handlers_nats.go @@ -140,6 +140,31 @@ func getEventHandler(m *nats.Msg, message *RequestMessage) error { return errorReplyFormater(m, "backend error", err) } + // Gather runtime info about the container + container := docker.Container{ + App: app, + } + + status, err := container.Status() + if err != nil { + log.Printf("backend error: %v\n", err) + return errorReplyFormater(m, "backend error", err) + } + if status == "running" { + var err error + app.Techs, err = container.GetTechs() + if err != nil { + log.Printf("backend error: %v\n", err) + return errorReplyFormater(m, "backend error", err) + } + app.PrimaryTech, err = container.GetPrimaryTech() + if err != nil { + log.Printf("backend error: %v\n", err) + return errorReplyFormater(m, "backend error", err) + } + } + + // Assembling reply message reply := ReplyMessage{ AppName: app.Name, Payload: app, diff --git a/stats.go b/stats.go index 227cebd..d93ab66 100644 --- a/stats.go +++ b/stats.go @@ -40,7 +40,7 @@ func updateUsage(name string) error { return err } -// Updates only container's state +// Updates only container's state. Check current status of the container and saves it into the database. func updateState(name string) error { processor := apps.AppsProcessor{ DB: common.GetDBConnection(),