diff --git a/containers/tools.go b/containers/tools.go index 3b398cf..4897f91 100644 --- a/containers/tools.go +++ b/containers/tools.go @@ -2,10 +2,13 @@ package containers import ( "bytes" + "errors" + "fmt" "log" "os" "os/exec" "path/filepath" + "regexp" "strconv" "strings" "time" @@ -135,3 +138,33 @@ func CPUMemoryStats(applist *[]apps.App, sample int) (*[]apps.App, error) { return &updatedApps, nil } + +func getTechAndVersion(symlink string) (*TechInfo, error) { + link, err := os.Readlink(symlink) + if err != nil { + return nil, fmt.Errorf("error reading symlink: %w", err) + } + + absLink, err := filepath.Abs(link) + if err != nil { + return nil, fmt.Errorf("error getting absolute path: %w", err) + } + + dirName := filepath.Base(absLink) + parts := strings.Split(dirName, "-") + + if len(parts) < 2 { + return nil, errors.New("failed to parse language and version from symlink") + } + + re := regexp.MustCompile(`\d+\.\d+\.\d+`) + version := re.FindString(parts[1]) + if version == "" { + return nil, errors.New("failed to extract version from symlink") + } + + return &TechInfo{ + Tech: parts[0], + Version: version, + }, nil +} diff --git a/containers/types.go b/containers/types.go index c7f1ce3..a60442c 100644 --- a/containers/types.go +++ b/containers/types.go @@ -19,6 +19,12 @@ const passwordFile = "/srv/.rosti" const deployKeyType = "ed25519" const deployKeyPrefix = "rosti_deploy" +// Structure containing info about technology and its version +type TechInfo struct { + Tech string `json:"tech"` + Version string `json:"version"` +} + // Process contains info about background application usually running in supervisor type Process struct { Name string `json:"name"` @@ -558,3 +564,13 @@ func (c *Container) GetTechs() (apps.AppTechs, error) { return techs, nil } + +// Returns info about active technology +func (c *Container) GetActiveTech() (*TechInfo, error) { + info, err := getTechAndVersion(path.Join(c.volumeHostPath(), "bin", "primary_tech")) + if err != nil { + return info, err + } + + return info, nil +} diff --git a/containers/types_test.go b/containers/types_test.go new file mode 100644 index 0000000..1eb8434 --- /dev/null +++ b/containers/types_test.go @@ -0,0 +1,39 @@ +package containers + +import ( + "os" + "path/filepath" + "testing" +) + +func TestGetTechAndVersion(t *testing.T) { + // Create a temporary directory for testing + tempDir := t.TempDir() + + // Create a fake language directory with version in the temporary directory + fakeLangDir := filepath.Join(tempDir, "techs", "python-3.10.4") + err := os.MkdirAll(fakeLangDir, 0755) + if err != nil { + t.Fatalf("Failed to create fake language directory: %v", err) + } + + // Create a symlink for testing + symlink := filepath.Join(tempDir, "primary_tech") + err = os.Symlink(fakeLangDir, symlink) + if err != nil { + t.Fatalf("Failed to create symlink: %v", err) + } + + // Test parseLanguageAndVersion function + info, err := getTechAndVersion(symlink) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + + expectedLanguage := "python" + expectedVersion := "3.10.4" + if info.Tech != expectedLanguage || info.Version != expectedVersion { + t.Errorf("Expected language: %s, version: %s, but got language: %s, version: %s", + expectedLanguage, expectedVersion, info.Tech, info.Version) + } +} diff --git a/glue/main.go b/glue/main.go index d0ecb36..a4319e8 100644 --- a/glue/main.go +++ b/glue/main.go @@ -789,3 +789,18 @@ func (p *Processor) DeleteAppSnapshots() error { return nil } + +// Returns active technology in the app +func (p *Processor) GetActiveTech() (*containers.TechInfo, error) { + container, err := p.getContainer() + if err != nil { + return nil, err + } + + tech, err := container.GetActiveTech() + if err != nil { + return tech, err + } + + return tech, nil +}