mirror of
https://github.com/zrepl/zrepl.git
synced 2024-11-24 09:24:09 +01:00
79 lines
1.8 KiB
Go
79 lines
1.8 KiB
Go
package endpoint
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
"github.com/zrepl/zrepl/internal/zfs"
|
|
)
|
|
|
|
// JobID instances returned by MakeJobID() guarantee their JobID.String()
|
|
// can be used in ZFS dataset names and hold tags.
|
|
type JobID struct {
|
|
jid string
|
|
}
|
|
|
|
func MakeJobID(s string) (JobID, error) {
|
|
if len(s) == 0 {
|
|
return JobID{}, fmt.Errorf("must not be empty string")
|
|
}
|
|
|
|
if err := zfs.ComponentNamecheck(s); err != nil {
|
|
return JobID{}, errors.Wrap(err, "must be usable as a dataset path component")
|
|
}
|
|
|
|
if _, err := tentativeReplicationCursorBookmarkNameImpl("pool/ds", 0xface601d, s); err != nil {
|
|
// note that this might still fail due to total maximum name length, but we can't enforce that
|
|
return JobID{}, errors.Wrap(err, "must be usable for a tentative replication cursor bookmark")
|
|
}
|
|
|
|
if _, err := stepHoldTagImpl(s); err != nil {
|
|
return JobID{}, errors.Wrap(err, "must be usable for a step hold tag")
|
|
}
|
|
|
|
if _, err := lastReceivedHoldImpl(s); err != nil {
|
|
return JobID{}, errors.Wrap(err, "must be usable as a last-received-hold tag")
|
|
}
|
|
|
|
// FIXME replication cursor bookmark name
|
|
|
|
_, err := zfs.NewDatasetPath(s)
|
|
if err != nil {
|
|
return JobID{}, fmt.Errorf("must be usable in a ZFS dataset path: %s", err)
|
|
}
|
|
|
|
return JobID{s}, nil
|
|
}
|
|
|
|
func MustMakeJobID(s string) JobID {
|
|
jid, err := MakeJobID(s)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return jid
|
|
}
|
|
|
|
func (j JobID) expectInitialized() {
|
|
if j.jid == "" {
|
|
panic("use of uninitialized JobID")
|
|
}
|
|
}
|
|
|
|
func (j JobID) String() string {
|
|
j.expectInitialized()
|
|
return j.jid
|
|
}
|
|
|
|
var _ json.Marshaler = JobID{}
|
|
var _ json.Unmarshaler = (*JobID)(nil)
|
|
|
|
func (j JobID) MarshalJSON() ([]byte, error) { return json.Marshal(j.jid) }
|
|
|
|
func (j *JobID) UnmarshalJSON(b []byte) error {
|
|
return json.Unmarshal(b, &j.jid)
|
|
}
|
|
|
|
func (j JobID) MustValidate() { j.expectInitialized() }
|