// Prune will attempt to get the total size of the launchable's installs // directory to be equal to or less than the maximum specified number of // bytes. This method will preserve any directories that are pointed to // by the `current` or `last` symlinks. Installations will be removed from // oldest to newest. func (hl *Launchable) Prune(maxSize size.ByteCount) error { curTarget, err := os.Readlink(hl.CurrentDir()) if os.IsNotExist(err) { curTarget = "" } else if err != nil { return err } curTarget = filepath.Base(curTarget) lastTarget, err := os.Readlink(hl.LastDir()) if os.IsNotExist(err) { lastTarget = "" } else if err != nil { return err } lastTarget = filepath.Base(lastTarget) installs, err := ioutil.ReadDir(hl.AllInstallsDir()) if os.IsNotExist(err) { return nil } else if err != nil { return err } var totalSize size.ByteCount = 0 installSizes := map[string]size.ByteCount{} for _, i := range installs { installSize, err := hl.sizeOfInstall(i.Name()) if err != nil { return err } totalSize += size.ByteCount(installSize) installSizes[i.Name()] = installSize } oldestFirst := installsByAge(installs) sort.Sort(oldestFirst) for _, i := range oldestFirst { if totalSize <= maxSize { return nil } if i.Name() == curTarget || i.Name() == lastTarget { continue } installSize := installSizes[i.Name()] err = os.RemoveAll(filepath.Join(hl.AllInstallsDir(), i.Name())) if err != nil { return err } totalSize = totalSize - size.ByteCount(installSize) } return nil }
func TestMarshalIntegerByteCount(t *testing.T) { integeredMemory := []byte(`memory: 500`) config := Config{} err := yaml.Unmarshal(integeredMemory, &config) Assert(t).IsNil(err, "Should not have erred unmarshaling") Assert(t).AreEqual(config.Memory, size.ByteCount(500), "Should have unmarshaled the integer representation of bytes") }
func (hl *Launchable) sizeOfInstall(name string) (size.ByteCount, error) { var total int64 err := filepath.Walk(filepath.Join(hl.AllInstallsDir(), name), func(_ string, info os.FileInfo, err error) error { if !info.IsDir() { total += info.Size() } return err }) return size.ByteCount(total), err }
func (i testInstall) create(parent string) error { path := filepath.Join(parent, "installs", i.name) err := os.MkdirAll(path, 0755) if err != nil { return err } payloadPath := filepath.Join(parent, "installs", i.name, "payload") file, err := os.OpenFile(payloadPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) var soFar int64 bytesToWrite := []byte{'a'} for size.ByteCount(soFar) < i.byteCount { written, err := file.Write(bytesToWrite) if err != nil { return err } soFar += int64(written) } err = file.Close() if err != nil { return err } if i.name == "current" { err := os.Symlink(path, filepath.Join(parent, "current")) if err != nil { return err } } if i.name == "last" { err := os.Symlink(path, filepath.Join(parent, "last")) if err != nil { return err } } return os.Chtimes(path, i.modTime, i.modTime) }