endpoint: refactor, fix stale holds on initial replication, holds release subcmds
- endpoint abstractions now share an interface `Abstraction`
- pkg endpoint now has a query facitilty (`ListAbstractions`) which is
used to find on-disk
- step holds and bookmarks
- replication cursors (v1, v2)
- last-received-holds
- the `zrepl holds list` command consumes endpoint.ListAbstractions
- the new `zrepl holds release-{all,stale}` commands can be used
to remove abstractions of package endpoint
Co-authored-by: InsanePrawn <insane.prawny@gmail.com>
supersedes #282
fixes #280
fixes #278
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
package endpoint
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/zrepl/zrepl/zfs"
|
||||
)
|
||||
|
||||
// returns the short name (no fs# prefix)
|
||||
func makeJobAndGuidBookmarkName(prefix string, fs string, guid uint64, jobid string) (string, error) {
|
||||
bmname := fmt.Sprintf(prefix+"_G_%016x_J_%s", guid, jobid)
|
||||
if err := zfs.EntityNamecheck(fmt.Sprintf("%s#%s", fs, bmname), zfs.EntityTypeBookmark); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return bmname, nil
|
||||
}
|
||||
|
||||
var jobAndGuidBookmarkRE = regexp.MustCompile(`(.+)_G_([0-9a-f]{16})_J_(.+)$`)
|
||||
|
||||
func parseJobAndGuidBookmarkName(fullname string, prefix string) (guid uint64, jobID JobID, _ error) {
|
||||
|
||||
if len(prefix) == 0 {
|
||||
panic("prefix must not be empty")
|
||||
}
|
||||
|
||||
if err := zfs.EntityNamecheck(fullname, zfs.EntityTypeBookmark); err != nil {
|
||||
return 0, JobID{}, err
|
||||
}
|
||||
|
||||
_, _, name, err := zfs.DecomposeVersionString(fullname)
|
||||
if err != nil {
|
||||
return 0, JobID{}, errors.Wrap(err, "decompose bookmark name")
|
||||
}
|
||||
|
||||
match := jobAndGuidBookmarkRE.FindStringSubmatch(name)
|
||||
if match == nil {
|
||||
return 0, JobID{}, errors.Errorf("bookmark name does not match regex %q", jobAndGuidBookmarkRE.String())
|
||||
}
|
||||
if match[1] != prefix {
|
||||
return 0, JobID{}, errors.Errorf("prefix component does not match: expected %q, got %q", prefix, match[1])
|
||||
}
|
||||
|
||||
guid, err = strconv.ParseUint(match[2], 16, 64)
|
||||
if err != nil {
|
||||
return 0, JobID{}, errors.Wrapf(err, "parse guid component: %q", match[2])
|
||||
}
|
||||
|
||||
jobID, err = MakeJobID(match[3])
|
||||
if err != nil {
|
||||
return 0, JobID{}, errors.Wrapf(err, "parse jobid component: %q", match[3])
|
||||
}
|
||||
|
||||
return guid, jobID, nil
|
||||
}
|
||||
Reference in New Issue
Block a user