package containers import ( "bytes" "log" "os" "os/exec" "path/filepath" "strconv" "strings" "time" "github.com/rosti-cz/node-api/apps" ) // Return bytes, inodes occupied by a directory and/or error if there is any func du(path string) (int, int, error) { space, inodes := 0, 0 // Occupied space var out bytes.Buffer var errOut bytes.Buffer command := exec.Command("/usr/bin/du", "-b", "-s", path) command.Stdout = &out command.Stderr = &errOut err := command.Run() if err != nil { log.Println(errOut.String()) return space, inodes, err } fields := strings.Fields(strings.TrimSpace(out.String())) out.Reset() errOut.Reset() if len(fields) == 2 { space, err = strconv.Atoi(fields[0]) if err != nil { return space, inodes, err } } // Occupied inodes command = exec.Command("/usr/bin/du", "--inodes", "-s", path) command.Stdout = &out command.Stderr = &errOut err = command.Run() if err != nil { log.Println(errOut.String()) return space, inodes, err } fields = strings.Fields(strings.TrimSpace(out.String())) out.Reset() errOut.Reset() if len(fields) == 2 { inodes, err = strconv.Atoi(fields[0]) if err != nil { return inodes, inodes, err } } return space, inodes, nil } // Removes content of given directory func removeDirectory(dir string) error { d, err := os.Open(dir) if err != nil { return err } defer d.Close() names, err := d.Readdirnames(-1) if err != nil { return err } for _, name := range names { err = os.RemoveAll(filepath.Join(dir, name)) if err != nil { return err } } return nil } // CPUMemoryStats returns list of applications with updated CPU and memory usage effectively. // Sample is number of seconds between two measurements of the CPU usage. More means more precise. func CPUMemoryStats(applist *[]apps.App, sample int) (*[]apps.App, error) { if sample <= 0 { sample = 1 } containers := []Container{} for _, app := range *applist { containers = append(containers, Container{App: &app}) } startMap := make(map[string]int64) endMap := make(map[string]int64) start := time.Now().UnixNano() for _, container := range containers { cpu, _, err := container.GetRawResourceStats() if err != nil { return nil, err } startMap[container.App.Name] = cpu } time.Sleep(time.Duration(sample) * time.Second) for idx, container := range containers { cpu, memory, err := container.GetRawResourceStats() if err != nil { return nil, err } endMap[container.App.Name] = cpu containers[idx].App.MemoryUsage = memory } end := time.Now().UnixNano() difference := (float64(end) - float64(start)) / float64(1000000000) updatedApps := []apps.App{} for _, container := range containers { app := *container.App app.CPUUsage = (float64(endMap[app.Name]) - float64(startMap[app.Name])) / difference / 10000000.0 updatedApps = append(updatedApps, app) } return &updatedApps, nil }