예제 #1
0
파일: restore.go 프로젝트: maruel/dumbcas
func (c *restoreRun) main(a DumbcasApplication, nodeArg string) error {
	if err := c.Parse(a, true); err != nil {
		return err
	}

	// Load the Node and process it.
	// Do it serially for now, assuming that it is I/O bound on magnetic disks.
	// For a network CAS, it would be good to implement concurrent fetches.

	f, err := c.nodes.Open(nodeArg)
	if err != nil {
		return err
	}
	defer func() {
		_ = f.Close()
	}()
	node := &dumbcaslib.Node{}
	if err := dumbcaslib.LoadReaderAsJSON(f, node); err != nil {
		return err
	}

	entry, err := dumbcaslib.LoadEntry(c.cas, node.Entry)
	if err != nil {
		return err
	}
	// TODO(maruel): Progress bar.
	count, err := restoreEntry(a.GetLog(), c.cas, entry, c.Out)
	fmt.Fprintf(a.GetOut(), "Restored %d files in %s\n", count, c.Out)
	return err
}
예제 #2
0
파일: info.go 프로젝트: maruel/dumbcas
func (c *infoRun) main(a DumbcasApplication, nodeArg string) error {
	if err := c.Parse(a, true); err != nil {
		return err
	}

	// Load the Node and process it.
	f, err := c.nodes.Open(nodeArg)
	if err != nil {
		return err
	}
	defer func() {
		_ = f.Close()
	}()
	node := &dumbcaslib.Node{}
	if err := dumbcaslib.LoadReaderAsJSON(f, node); err != nil {
		return err
	}

	entry, err := dumbcaslib.LoadEntry(c.cas, node.Entry)
	if err != nil {
		return err
	}

	count := printEntry(a.GetOut(), entry, "")
	fmt.Fprintf(a.GetOut(), "Total %d\n", count)
	return nil
}
예제 #3
0
파일: gc.go 프로젝트: maruel/dumbcas
func (c *gcRun) main(a DumbcasApplication) error {
	if err := c.Parse(a, false); err != nil {
		return err
	}

	entries := map[string]bool{}
	for item := range c.cas.Enumerate() {
		if item.Error != nil {
			// TODO(maruel): Leaks channel.
			c.cas.SetFsckBit()
			return fmt.Errorf("Failed enumerating the CAS table %s", item.Error)
		}
		entries[item.Item] = false
	}
	a.GetLog().Printf("Found %d entries", len(entries))

	// Load all the nodes.
	for item := range c.nodes.Enumerate() {
		if item.Error != nil {
			// TODO(maruel): Leaks channel.
			return item.Error
		}
		f, err := c.nodes.Open(item.Item)
		if err != nil {
			// TODO(maruel): Leaks channel.
			c.cas.SetFsckBit()
			return fmt.Errorf("Failed opening node %s: %s", item.Item, err)
		}
		defer func() {
			_ = f.Close()
		}()
		node := &dumbcaslib.Node{}
		if err := dumbcaslib.LoadReaderAsJSON(f, node); err != nil {
			// TODO(maruel): Leaks channel.
			c.cas.SetFsckBit()
			return fmt.Errorf("Failed opening node %s: %s", item.Item, err)
		}

		entries[node.Entry] = true
		entry, err := dumbcaslib.LoadEntry(c.cas, node.Entry)
		if err != nil {
			return err
		}
		tagRecurse(entries, entry)
	}

	orphans := []string{}
	for entry, tagged := range entries {
		if !tagged {
			orphans = append(orphans, entry)
		}
	}
	a.GetLog().Printf("Found %d orphan", len(orphans))
	for _, orphan := range orphans {
		if err := c.cas.Remove(orphan); err != nil {
			c.cas.SetFsckBit()
			return fmt.Errorf("Internal error while removing %s: %s", orphan, err)
		}
	}
	return nil
}