mirror of
https://github.com/garethgeorge/backrest.git
synced 2025-12-17 11:05:38 +00:00
feat: implement repo, edit, and supporting RPCs
This commit is contained in:
@@ -10,7 +10,9 @@ import (
|
||||
"syscall"
|
||||
|
||||
"github.com/garethgeorge/resticui/internal/api"
|
||||
"github.com/garethgeorge/resticui/static"
|
||||
"github.com/garethgeorge/resticui/internal/config"
|
||||
"github.com/garethgeorge/resticui/internal/orchestrator"
|
||||
static "github.com/garethgeorge/resticui/webui"
|
||||
"go.uber.org/zap"
|
||||
|
||||
_ "embed"
|
||||
@@ -21,6 +23,10 @@ func main() {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
go onterm(cancel)
|
||||
|
||||
if _, err := config.Default.Get(); err != nil {
|
||||
zap.S().Fatalf("Error loading config: %v", err)
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
|
||||
// Configure the HTTP mux
|
||||
@@ -32,11 +38,13 @@ func main() {
|
||||
Handler: mux,
|
||||
}
|
||||
|
||||
orchestrator := orchestrator.NewOrchestrator(config.Default)
|
||||
|
||||
// Serve the API
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
err := api.ServeAPI(ctx, mux)
|
||||
err := api.ServeAPI(ctx, orchestrator, mux)
|
||||
if err != nil {
|
||||
zap.S().Fatal("Error serving API", zap.Error(err))
|
||||
}
|
||||
|
||||
@@ -25,7 +25,10 @@ type Config struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Version int32 `protobuf:"varint,1,opt,name=version,proto3" json:"version,omitempty"`
|
||||
// modification number, used for read-modify-write consistency in the UI. Incremented on every write.
|
||||
Modno int32 `protobuf:"varint,1,opt,name=modno,proto3" json:"modno,omitempty"`
|
||||
// override the hostname tagged on backups. If provided it will be used in addition to tags to group backups.
|
||||
HostOverride string `protobuf:"bytes,2,opt,name=host_override,proto3" json:"host_override,omitempty"`
|
||||
Repos []*Repo `protobuf:"bytes,3,rep,name=repos,proto3" json:"repos,omitempty"`
|
||||
Plans []*Plan `protobuf:"bytes,4,rep,name=plans,proto3" json:"plans,omitempty"`
|
||||
}
|
||||
@@ -62,13 +65,20 @@ func (*Config) Descriptor() ([]byte, []int) {
|
||||
return file_v1_config_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *Config) GetVersion() int32 {
|
||||
func (x *Config) GetModno() int32 {
|
||||
if x != nil {
|
||||
return x.Version
|
||||
return x.Modno
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *Config) GetHostOverride() string {
|
||||
if x != nil {
|
||||
return x.HostOverride
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *Config) GetRepos() []*Repo {
|
||||
if x != nil {
|
||||
return x.Repos
|
||||
@@ -83,61 +93,6 @@ func (x *Config) GetPlans() []*Plan {
|
||||
return nil
|
||||
}
|
||||
|
||||
type User struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` // plaintext password
|
||||
}
|
||||
|
||||
func (x *User) Reset() {
|
||||
*x = User{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_v1_config_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *User) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*User) ProtoMessage() {}
|
||||
|
||||
func (x *User) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_v1_config_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use User.ProtoReflect.Descriptor instead.
|
||||
func (*User) Descriptor() ([]byte, []int) {
|
||||
return file_v1_config_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *User) GetName() string {
|
||||
if x != nil {
|
||||
return x.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *User) GetPassword() string {
|
||||
if x != nil {
|
||||
return x.Password
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type Repo struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@@ -153,7 +108,7 @@ type Repo struct {
|
||||
func (x *Repo) Reset() {
|
||||
*x = Repo{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_v1_config_proto_msgTypes[2]
|
||||
mi := &file_v1_config_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -166,7 +121,7 @@ func (x *Repo) String() string {
|
||||
func (*Repo) ProtoMessage() {}
|
||||
|
||||
func (x *Repo) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_v1_config_proto_msgTypes[2]
|
||||
mi := &file_v1_config_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -179,7 +134,7 @@ func (x *Repo) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use Repo.ProtoReflect.Descriptor instead.
|
||||
func (*Repo) Descriptor() ([]byte, []int) {
|
||||
return file_v1_config_proto_rawDescGZIP(), []int{2}
|
||||
return file_v1_config_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *Repo) GetId() string {
|
||||
@@ -233,7 +188,7 @@ type Plan struct {
|
||||
func (x *Plan) Reset() {
|
||||
*x = Plan{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_v1_config_proto_msgTypes[3]
|
||||
mi := &file_v1_config_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -246,7 +201,7 @@ func (x *Plan) String() string {
|
||||
func (*Plan) ProtoMessage() {}
|
||||
|
||||
func (x *Plan) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_v1_config_proto_msgTypes[3]
|
||||
mi := &file_v1_config_proto_msgTypes[2]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -259,7 +214,7 @@ func (x *Plan) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use Plan.ProtoReflect.Descriptor instead.
|
||||
func (*Plan) Descriptor() ([]byte, []int) {
|
||||
return file_v1_config_proto_rawDescGZIP(), []int{3}
|
||||
return file_v1_config_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *Plan) GetId() string {
|
||||
@@ -323,7 +278,7 @@ type RetentionPolicy struct {
|
||||
func (x *RetentionPolicy) Reset() {
|
||||
*x = RetentionPolicy{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_v1_config_proto_msgTypes[4]
|
||||
mi := &file_v1_config_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -336,7 +291,7 @@ func (x *RetentionPolicy) String() string {
|
||||
func (*RetentionPolicy) ProtoMessage() {}
|
||||
|
||||
func (x *RetentionPolicy) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_v1_config_proto_msgTypes[4]
|
||||
mi := &file_v1_config_proto_msgTypes[3]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -349,7 +304,7 @@ func (x *RetentionPolicy) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use RetentionPolicy.ProtoReflect.Descriptor instead.
|
||||
func (*RetentionPolicy) Descriptor() ([]byte, []int) {
|
||||
return file_v1_config_proto_rawDescGZIP(), []int{4}
|
||||
return file_v1_config_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *RetentionPolicy) GetMaxUnusedLimit() string {
|
||||
@@ -412,57 +367,55 @@ var File_v1_config_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_v1_config_proto_rawDesc = []byte{
|
||||
0x0a, 0x0f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x12, 0x02, 0x76, 0x31, 0x22, 0x62, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12,
|
||||
0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05,
|
||||
0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x05, 0x72, 0x65, 0x70,
|
||||
0x6f, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65,
|
||||
0x70, 0x6f, 0x52, 0x05, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x12, 0x1e, 0x0a, 0x05, 0x70, 0x6c, 0x61,
|
||||
0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6c,
|
||||
0x61, 0x6e, 0x52, 0x05, 0x70, 0x6c, 0x61, 0x6e, 0x73, 0x22, 0x36, 0x0a, 0x04, 0x55, 0x73, 0x65,
|
||||
0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72,
|
||||
0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72,
|
||||
0x64, 0x22, 0x6c, 0x0a, 0x04, 0x52, 0x65, 0x70, 0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x69,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x69, 0x12, 0x1a, 0x0a, 0x08, 0x70,
|
||||
0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70,
|
||||
0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, 0x76, 0x18, 0x04,
|
||||
0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x65, 0x6e, 0x76, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61,
|
||||
0x67, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x22,
|
||||
0xa3, 0x01, 0x0a, 0x04, 0x50, 0x6c, 0x61, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x70, 0x6f,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x12, 0x14, 0x0a, 0x05,
|
||||
0x70, 0x61, 0x74, 0x68, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x70, 0x61, 0x74,
|
||||
0x68, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x73, 0x18, 0x05,
|
||||
0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x73, 0x12, 0x12,
|
||||
0x0a, 0x04, 0x63, 0x72, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x72,
|
||||
0x6f, 0x6e, 0x12, 0x31, 0x0a, 0x09, 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x18,
|
||||
0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x74, 0x65, 0x6e,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x09, 0x72, 0x65, 0x74, 0x65,
|
||||
0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xb2, 0x02, 0x0a, 0x0f, 0x52, 0x65, 0x74, 0x65, 0x6e, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x28, 0x0a, 0x10, 0x6d, 0x61, 0x78,
|
||||
0x5f, 0x75, 0x6e, 0x75, 0x73, 0x65, 0x64, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x0e, 0x6d, 0x61, 0x78, 0x55, 0x6e, 0x75, 0x73, 0x65, 0x64, 0x4c, 0x69,
|
||||
0x6d, 0x69, 0x74, 0x12, 0x1e, 0x0a, 0x0b, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x6c, 0x61, 0x73, 0x74,
|
||||
0x5f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x6b, 0x65, 0x65, 0x70, 0x4c, 0x61,
|
||||
0x73, 0x74, 0x4e, 0x12, 0x1f, 0x0a, 0x0b, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x68, 0x6f, 0x75, 0x72,
|
||||
0x6c, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x6b, 0x65, 0x65, 0x70, 0x48, 0x6f,
|
||||
0x75, 0x72, 0x6c, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x64, 0x61, 0x69,
|
||||
0x6c, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x6b, 0x65, 0x65, 0x70, 0x44, 0x61,
|
||||
0x69, 0x6c, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x77, 0x65, 0x65, 0x6b,
|
||||
0x6c, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x6b, 0x65, 0x65, 0x70, 0x57, 0x65,
|
||||
0x65, 0x6b, 0x6c, 0x79, 0x12, 0x21, 0x0a, 0x0c, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x6d, 0x6f, 0x6e,
|
||||
0x74, 0x68, 0x6c, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x6b, 0x65, 0x65, 0x70,
|
||||
0x4d, 0x6f, 0x6e, 0x74, 0x68, 0x6c, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x6b, 0x65, 0x65, 0x70, 0x5f,
|
||||
0x79, 0x65, 0x61, 0x72, 0x6c, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x6b, 0x65,
|
||||
0x65, 0x70, 0x59, 0x65, 0x61, 0x72, 0x6c, 0x79, 0x12, 0x30, 0x0a, 0x14, 0x6b, 0x65, 0x65, 0x70,
|
||||
0x5f, 0x77, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x6b, 0x65, 0x65, 0x70, 0x57, 0x69, 0x74, 0x68,
|
||||
0x69, 0x6e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69,
|
||||
0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x61, 0x72, 0x65, 0x74, 0x68, 0x67,
|
||||
0x65, 0x6f, 0x72, 0x67, 0x65, 0x2f, 0x72, 0x65, 0x73, 0x74, 0x69, 0x63, 0x75, 0x69, 0x2f, 0x67,
|
||||
0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x33,
|
||||
0x6f, 0x12, 0x02, 0x76, 0x31, 0x22, 0x84, 0x01, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
|
||||
0x12, 0x14, 0x0a, 0x05, 0x6d, 0x6f, 0x64, 0x6e, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52,
|
||||
0x05, 0x6d, 0x6f, 0x64, 0x6e, 0x6f, 0x12, 0x24, 0x0a, 0x0d, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x6f,
|
||||
0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x68,
|
||||
0x6f, 0x73, 0x74, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x12, 0x1e, 0x0a, 0x05,
|
||||
0x72, 0x65, 0x70, 0x6f, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x76, 0x31,
|
||||
0x2e, 0x52, 0x65, 0x70, 0x6f, 0x52, 0x05, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x12, 0x1e, 0x0a, 0x05,
|
||||
0x70, 0x6c, 0x61, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x08, 0x2e, 0x76, 0x31,
|
||||
0x2e, 0x50, 0x6c, 0x61, 0x6e, 0x52, 0x05, 0x70, 0x6c, 0x61, 0x6e, 0x73, 0x22, 0x6c, 0x0a, 0x04,
|
||||
0x52, 0x65, 0x70, 0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x03, 0x75, 0x72, 0x69, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f,
|
||||
0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f,
|
||||
0x72, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, 0x76, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52,
|
||||
0x03, 0x65, 0x6e, 0x76, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x05, 0x20,
|
||||
0x03, 0x28, 0x09, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x22, 0xa3, 0x01, 0x0a, 0x04, 0x50,
|
||||
0x6c, 0x61, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x68, 0x73,
|
||||
0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x70, 0x61, 0x74, 0x68, 0x73, 0x12, 0x1a, 0x0a,
|
||||
0x08, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52,
|
||||
0x08, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x72, 0x6f,
|
||||
0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x72, 0x6f, 0x6e, 0x12, 0x31, 0x0a,
|
||||
0x09, 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x13, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x50,
|
||||
0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x09, 0x72, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x22, 0xb2, 0x02, 0x0a, 0x0f, 0x52, 0x65, 0x74, 0x65, 0x6e, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f,
|
||||
0x6c, 0x69, 0x63, 0x79, 0x12, 0x28, 0x0a, 0x10, 0x6d, 0x61, 0x78, 0x5f, 0x75, 0x6e, 0x75, 0x73,
|
||||
0x65, 0x64, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e,
|
||||
0x6d, 0x61, 0x78, 0x55, 0x6e, 0x75, 0x73, 0x65, 0x64, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x1e,
|
||||
0x0a, 0x0b, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x6e, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x05, 0x52, 0x09, 0x6b, 0x65, 0x65, 0x70, 0x4c, 0x61, 0x73, 0x74, 0x4e, 0x12, 0x1f,
|
||||
0x0a, 0x0b, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x68, 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x18, 0x03, 0x20,
|
||||
0x01, 0x28, 0x05, 0x52, 0x0a, 0x6b, 0x65, 0x65, 0x70, 0x48, 0x6f, 0x75, 0x72, 0x6c, 0x79, 0x12,
|
||||
0x1d, 0x0a, 0x0a, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x64, 0x61, 0x69, 0x6c, 0x79, 0x18, 0x04, 0x20,
|
||||
0x01, 0x28, 0x05, 0x52, 0x09, 0x6b, 0x65, 0x65, 0x70, 0x44, 0x61, 0x69, 0x6c, 0x79, 0x12, 0x1f,
|
||||
0x0a, 0x0b, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x77, 0x65, 0x65, 0x6b, 0x6c, 0x79, 0x18, 0x05, 0x20,
|
||||
0x01, 0x28, 0x05, 0x52, 0x0a, 0x6b, 0x65, 0x65, 0x70, 0x57, 0x65, 0x65, 0x6b, 0x6c, 0x79, 0x12,
|
||||
0x21, 0x0a, 0x0c, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x6c, 0x79, 0x18,
|
||||
0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x6b, 0x65, 0x65, 0x70, 0x4d, 0x6f, 0x6e, 0x74, 0x68,
|
||||
0x6c, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x79, 0x65, 0x61, 0x72, 0x6c,
|
||||
0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x6b, 0x65, 0x65, 0x70, 0x59, 0x65, 0x61,
|
||||
0x72, 0x6c, 0x79, 0x12, 0x30, 0x0a, 0x14, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x77, 0x69, 0x74, 0x68,
|
||||
0x69, 0x6e, 0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x12, 0x6b, 0x65, 0x65, 0x70, 0x57, 0x69, 0x74, 0x68, 0x69, 0x6e, 0x44, 0x75, 0x72,
|
||||
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
|
||||
0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x61, 0x72, 0x65, 0x74, 0x68, 0x67, 0x65, 0x6f, 0x72, 0x67, 0x65,
|
||||
0x2f, 0x72, 0x65, 0x73, 0x74, 0x69, 0x63, 0x75, 0x69, 0x2f, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -477,18 +430,17 @@ func file_v1_config_proto_rawDescGZIP() []byte {
|
||||
return file_v1_config_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_v1_config_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
|
||||
var file_v1_config_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
|
||||
var file_v1_config_proto_goTypes = []interface{}{
|
||||
(*Config)(nil), // 0: v1.Config
|
||||
(*User)(nil), // 1: v1.User
|
||||
(*Repo)(nil), // 2: v1.Repo
|
||||
(*Plan)(nil), // 3: v1.Plan
|
||||
(*RetentionPolicy)(nil), // 4: v1.RetentionPolicy
|
||||
(*Repo)(nil), // 1: v1.Repo
|
||||
(*Plan)(nil), // 2: v1.Plan
|
||||
(*RetentionPolicy)(nil), // 3: v1.RetentionPolicy
|
||||
}
|
||||
var file_v1_config_proto_depIdxs = []int32{
|
||||
2, // 0: v1.Config.repos:type_name -> v1.Repo
|
||||
3, // 1: v1.Config.plans:type_name -> v1.Plan
|
||||
4, // 2: v1.Plan.retention:type_name -> v1.RetentionPolicy
|
||||
1, // 0: v1.Config.repos:type_name -> v1.Repo
|
||||
2, // 1: v1.Config.plans:type_name -> v1.Plan
|
||||
3, // 2: v1.Plan.retention:type_name -> v1.RetentionPolicy
|
||||
3, // [3:3] is the sub-list for method output_type
|
||||
3, // [3:3] is the sub-list for method input_type
|
||||
3, // [3:3] is the sub-list for extension type_name
|
||||
@@ -515,18 +467,6 @@ func file_v1_config_proto_init() {
|
||||
}
|
||||
}
|
||||
file_v1_config_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*User); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_v1_config_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Repo); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -538,7 +478,7 @@ func file_v1_config_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_v1_config_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_v1_config_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*Plan); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -550,7 +490,7 @@ func file_v1_config_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_v1_config_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_v1_config_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*RetentionPolicy); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -569,7 +509,7 @@ func file_v1_config_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_v1_config_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 5,
|
||||
NumMessages: 4,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
|
||||
@@ -155,7 +155,7 @@ type Event_Log struct {
|
||||
}
|
||||
|
||||
type Event_BackupStatusChange struct {
|
||||
BackupStatusChange *BackupStatusEvent `protobuf:"bytes,4,opt,name=backup_status_change,json=backup_status,proto3,oneof"`
|
||||
BackupStatusChange *BackupStatusEvent `protobuf:"bytes,4,opt,name=backup_status_change,json=backupStatusChange,proto3,oneof"`
|
||||
}
|
||||
|
||||
func (*Event_Log) isEvent_Event() {}
|
||||
@@ -276,33 +276,33 @@ var File_v1_events_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_v1_events_proto_rawDesc = []byte{
|
||||
0x0a, 0x0f, 0x76, 0x31, 0x2f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x12, 0x02, 0x76, 0x31, 0x22, 0x96, 0x01, 0x0a, 0x05, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12,
|
||||
0x6f, 0x12, 0x02, 0x76, 0x31, 0x22, 0x9b, 0x01, 0x0a, 0x05, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12,
|
||||
0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x20, 0x0a,
|
||||
0x03, 0x6c, 0x6f, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x76, 0x31, 0x2e,
|
||||
0x4c, 0x6f, 0x67, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x03, 0x6c, 0x6f, 0x67, 0x12,
|
||||
0x44, 0x0a, 0x14, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73,
|
||||
0x49, 0x0a, 0x14, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73,
|
||||
0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e,
|
||||
0x76, 0x31, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x45,
|
||||
0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0d, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x5f, 0x73,
|
||||
0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x24,
|
||||
0x0a, 0x08, 0x4c, 0x6f, 0x67, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65,
|
||||
0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73,
|
||||
0x73, 0x61, 0x67, 0x65, 0x22, 0x65, 0x0a, 0x11, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x53, 0x74,
|
||||
0x61, 0x74, 0x75, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6c, 0x61,
|
||||
0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x6c, 0x61, 0x6e, 0x12, 0x22, 0x0a,
|
||||
0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0a, 0x2e,
|
||||
0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75,
|
||||
0x73, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01,
|
||||
0x28, 0x0d, 0x52, 0x07, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x2a, 0x3f, 0x0a, 0x06, 0x53,
|
||||
0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e,
|
||||
0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x49, 0x4e, 0x5f, 0x50, 0x52, 0x4f, 0x47, 0x52, 0x45, 0x53,
|
||||
0x53, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x55, 0x43, 0x43, 0x45, 0x53, 0x53, 0x10, 0x02,
|
||||
0x12, 0x0a, 0x0a, 0x06, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x03, 0x42, 0x2e, 0x5a, 0x2c,
|
||||
0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x61, 0x72, 0x65, 0x74,
|
||||
0x68, 0x67, 0x65, 0x6f, 0x72, 0x67, 0x65, 0x2f, 0x72, 0x65, 0x73, 0x74, 0x69, 0x63, 0x75, 0x69,
|
||||
0x2f, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x33,
|
||||
0x76, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x12, 0x62, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x53, 0x74,
|
||||
0x61, 0x74, 0x75, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x76,
|
||||
0x65, 0x6e, 0x74, 0x22, 0x24, 0x0a, 0x08, 0x4c, 0x6f, 0x67, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12,
|
||||
0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x65, 0x0a, 0x11, 0x42, 0x61, 0x63,
|
||||
0x6b, 0x75, 0x70, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x12,
|
||||
0x0a, 0x04, 0x70, 0x6c, 0x61, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x6c,
|
||||
0x61, 0x6e, 0x12, 0x22, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x0e, 0x32, 0x0a, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06,
|
||||
0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e,
|
||||
0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74,
|
||||
0x2a, 0x3f, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e,
|
||||
0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x49, 0x4e, 0x5f, 0x50, 0x52,
|
||||
0x4f, 0x47, 0x52, 0x45, 0x53, 0x53, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x55, 0x43, 0x43,
|
||||
0x45, 0x53, 0x53, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10,
|
||||
0x03, 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
|
||||
0x67, 0x61, 0x72, 0x65, 0x74, 0x68, 0x67, 0x65, 0x6f, 0x72, 0x67, 0x65, 0x2f, 0x72, 0x65, 0x73,
|
||||
0x74, 0x69, 0x63, 0x75, 0x69, 0x2f, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76,
|
||||
0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
||||
@@ -26,7 +26,7 @@ type ResticSnapshot struct {
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
UnixTimeMs int64 `protobuf:"varint,2,opt,name=unix_time_ms,json=time,proto3" json:"unix_time_ms,omitempty"`
|
||||
UnixTimeMs int64 `protobuf:"varint,2,opt,name=unix_time_ms,json=unixTimeMs,proto3" json:"unix_time_ms,omitempty"`
|
||||
Hostname string `protobuf:"bytes,3,opt,name=hostname,proto3" json:"hostname,omitempty"`
|
||||
Username string `protobuf:"bytes,4,opt,name=username,proto3" json:"username,omitempty"`
|
||||
Tree string `protobuf:"bytes,5,opt,name=tree,proto3" json:"tree,omitempty"` // tree hash
|
||||
@@ -123,6 +123,53 @@ func (x *ResticSnapshot) GetTags() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
type ResticSnapshotList struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Snapshots []*ResticSnapshot `protobuf:"bytes,1,rep,name=snapshots,proto3" json:"snapshots,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ResticSnapshotList) Reset() {
|
||||
*x = ResticSnapshotList{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_v1_restic_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ResticSnapshotList) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ResticSnapshotList) ProtoMessage() {}
|
||||
|
||||
func (x *ResticSnapshotList) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_v1_restic_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ResticSnapshotList.ProtoReflect.Descriptor instead.
|
||||
func (*ResticSnapshotList) Descriptor() ([]byte, []int) {
|
||||
return file_v1_restic_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *ResticSnapshotList) GetSnapshots() []*ResticSnapshot {
|
||||
if x != nil {
|
||||
return x.Snapshots
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type BackupProgressEntry struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@@ -138,7 +185,7 @@ type BackupProgressEntry struct {
|
||||
func (x *BackupProgressEntry) Reset() {
|
||||
*x = BackupProgressEntry{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_v1_restic_proto_msgTypes[1]
|
||||
mi := &file_v1_restic_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -151,7 +198,7 @@ func (x *BackupProgressEntry) String() string {
|
||||
func (*BackupProgressEntry) ProtoMessage() {}
|
||||
|
||||
func (x *BackupProgressEntry) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_v1_restic_proto_msgTypes[1]
|
||||
mi := &file_v1_restic_proto_msgTypes[2]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -164,7 +211,7 @@ func (x *BackupProgressEntry) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use BackupProgressEntry.ProtoReflect.Descriptor instead.
|
||||
func (*BackupProgressEntry) Descriptor() ([]byte, []int) {
|
||||
return file_v1_restic_proto_rawDescGZIP(), []int{1}
|
||||
return file_v1_restic_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (m *BackupProgressEntry) GetEntry() isBackupProgressEntry_Entry {
|
||||
@@ -209,17 +256,17 @@ type BackupProgressStatusEntry struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
PercentDone float64 `protobuf:"fixed64,1,opt,name=percent_done,json=percent,proto3" json:"percent_done,omitempty"` // 0.0 - 1.0
|
||||
TotalFiles int64 `protobuf:"varint,2,opt,name=total_files,proto3" json:"total_files,omitempty"`
|
||||
TotalBytes int64 `protobuf:"varint,3,opt,name=total_bytes,proto3" json:"total_bytes,omitempty"`
|
||||
FilesDone int64 `protobuf:"varint,4,opt,name=files_done,proto3" json:"files_done,omitempty"`
|
||||
BytesDone int64 `protobuf:"varint,5,opt,name=bytes_done,proto3" json:"bytes_done,omitempty"`
|
||||
PercentDone float64 `protobuf:"fixed64,1,opt,name=percent_done,json=percentDone,proto3" json:"percent_done,omitempty"` // 0.0 - 1.0
|
||||
TotalFiles int64 `protobuf:"varint,2,opt,name=total_files,json=totalFiles,proto3" json:"total_files,omitempty"`
|
||||
TotalBytes int64 `protobuf:"varint,3,opt,name=total_bytes,json=totalBytes,proto3" json:"total_bytes,omitempty"`
|
||||
FilesDone int64 `protobuf:"varint,4,opt,name=files_done,json=filesDone,proto3" json:"files_done,omitempty"`
|
||||
BytesDone int64 `protobuf:"varint,5,opt,name=bytes_done,json=bytesDone,proto3" json:"bytes_done,omitempty"`
|
||||
}
|
||||
|
||||
func (x *BackupProgressStatusEntry) Reset() {
|
||||
*x = BackupProgressStatusEntry{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_v1_restic_proto_msgTypes[2]
|
||||
mi := &file_v1_restic_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -232,7 +279,7 @@ func (x *BackupProgressStatusEntry) String() string {
|
||||
func (*BackupProgressStatusEntry) ProtoMessage() {}
|
||||
|
||||
func (x *BackupProgressStatusEntry) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_v1_restic_proto_msgTypes[2]
|
||||
mi := &file_v1_restic_proto_msgTypes[3]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -245,7 +292,7 @@ func (x *BackupProgressStatusEntry) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use BackupProgressStatusEntry.ProtoReflect.Descriptor instead.
|
||||
func (*BackupProgressStatusEntry) Descriptor() ([]byte, []int) {
|
||||
return file_v1_restic_proto_rawDescGZIP(), []int{2}
|
||||
return file_v1_restic_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *BackupProgressStatusEntry) GetPercentDone() float64 {
|
||||
@@ -288,25 +335,25 @@ type BackupProgressSummary struct {
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
FilesNew int64 `protobuf:"varint,1,opt,name=files_new,proto3" json:"files_new,omitempty"`
|
||||
FilesChanged int64 `protobuf:"varint,2,opt,name=files_changed,proto3" json:"files_changed,omitempty"`
|
||||
FilesUnmodified int64 `protobuf:"varint,3,opt,name=files_unmodified,proto3" json:"files_unmodified,omitempty"`
|
||||
DirsNew int64 `protobuf:"varint,4,opt,name=dirs_new,proto3" json:"dirs_new,omitempty"`
|
||||
DirsChanged int64 `protobuf:"varint,5,opt,name=dirs_changed,proto3" json:"dirs_changed,omitempty"`
|
||||
DirsUnmodified int64 `protobuf:"varint,6,opt,name=dirs_unmodified,proto3" json:"dirs_unmodified,omitempty"`
|
||||
DataBlobs int64 `protobuf:"varint,7,opt,name=data_blobs,proto3" json:"data_blobs,omitempty"`
|
||||
TreeBlobs int64 `protobuf:"varint,8,opt,name=tree_blobs,proto3" json:"tree_blobs,omitempty"`
|
||||
DataAdded int64 `protobuf:"varint,9,opt,name=data_added,proto3" json:"data_added,omitempty"`
|
||||
TotalFilesProcessed int64 `protobuf:"varint,10,opt,name=total_files_processed,proto3" json:"total_files_processed,omitempty"`
|
||||
TotalBytesProcessed int64 `protobuf:"varint,11,opt,name=total_bytes_processed,proto3" json:"total_bytes_processed,omitempty"`
|
||||
TotalDuration int64 `protobuf:"varint,12,opt,name=total_duration,proto3" json:"total_duration,omitempty"`
|
||||
SnapshotId string `protobuf:"bytes,13,opt,name=snapshot_id,proto3" json:"snapshot_id,omitempty"`
|
||||
FilesNew int64 `protobuf:"varint,1,opt,name=files_new,json=filesNew,proto3" json:"files_new,omitempty"`
|
||||
FilesChanged int64 `protobuf:"varint,2,opt,name=files_changed,json=filesChanged,proto3" json:"files_changed,omitempty"`
|
||||
FilesUnmodified int64 `protobuf:"varint,3,opt,name=files_unmodified,json=filesUnmodified,proto3" json:"files_unmodified,omitempty"`
|
||||
DirsNew int64 `protobuf:"varint,4,opt,name=dirs_new,json=dirsNew,proto3" json:"dirs_new,omitempty"`
|
||||
DirsChanged int64 `protobuf:"varint,5,opt,name=dirs_changed,json=dirsChanged,proto3" json:"dirs_changed,omitempty"`
|
||||
DirsUnmodified int64 `protobuf:"varint,6,opt,name=dirs_unmodified,json=dirsUnmodified,proto3" json:"dirs_unmodified,omitempty"`
|
||||
DataBlobs int64 `protobuf:"varint,7,opt,name=data_blobs,json=dataBlobs,proto3" json:"data_blobs,omitempty"`
|
||||
TreeBlobs int64 `protobuf:"varint,8,opt,name=tree_blobs,json=treeBlobs,proto3" json:"tree_blobs,omitempty"`
|
||||
DataAdded int64 `protobuf:"varint,9,opt,name=data_added,json=dataAdded,proto3" json:"data_added,omitempty"`
|
||||
TotalFilesProcessed int64 `protobuf:"varint,10,opt,name=total_files_processed,json=totalFilesProcessed,proto3" json:"total_files_processed,omitempty"`
|
||||
TotalBytesProcessed int64 `protobuf:"varint,11,opt,name=total_bytes_processed,json=totalBytesProcessed,proto3" json:"total_bytes_processed,omitempty"`
|
||||
TotalDuration int64 `protobuf:"varint,12,opt,name=total_duration,json=totalDuration,proto3" json:"total_duration,omitempty"`
|
||||
SnapshotId string `protobuf:"bytes,13,opt,name=snapshot_id,json=snapshotId,proto3" json:"snapshot_id,omitempty"`
|
||||
}
|
||||
|
||||
func (x *BackupProgressSummary) Reset() {
|
||||
*x = BackupProgressSummary{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_v1_restic_proto_msgTypes[3]
|
||||
mi := &file_v1_restic_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -319,7 +366,7 @@ func (x *BackupProgressSummary) String() string {
|
||||
func (*BackupProgressSummary) ProtoMessage() {}
|
||||
|
||||
func (x *BackupProgressSummary) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_v1_restic_proto_msgTypes[3]
|
||||
mi := &file_v1_restic_proto_msgTypes[4]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -332,7 +379,7 @@ func (x *BackupProgressSummary) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use BackupProgressSummary.ProtoReflect.Descriptor instead.
|
||||
func (*BackupProgressSummary) Descriptor() ([]byte, []int) {
|
||||
return file_v1_restic_proto_rawDescGZIP(), []int{3}
|
||||
return file_v1_restic_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
func (x *BackupProgressSummary) GetFilesNew() int64 {
|
||||
@@ -430,77 +477,81 @@ var File_v1_restic_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_v1_restic_proto_rawDesc = []byte{
|
||||
0x0a, 0x0f, 0x76, 0x31, 0x2f, 0x72, 0x65, 0x73, 0x74, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x12, 0x02, 0x76, 0x31, 0x22, 0xca, 0x01, 0x0a, 0x0e, 0x52, 0x65, 0x73, 0x74, 0x69, 0x63,
|
||||
0x6f, 0x12, 0x02, 0x76, 0x31, 0x22, 0xd0, 0x01, 0x0a, 0x0e, 0x52, 0x65, 0x73, 0x74, 0x69, 0x63,
|
||||
0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x0c, 0x75, 0x6e, 0x69, 0x78,
|
||||
0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04,
|
||||
0x74, 0x69, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65,
|
||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65,
|
||||
0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04,
|
||||
0x74, 0x72, 0x65, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x72, 0x65, 0x65,
|
||||
0x12, 0x16, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x68,
|
||||
0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x70, 0x61, 0x74, 0x68, 0x73, 0x12, 0x12,
|
||||
0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x74, 0x61,
|
||||
0x67, 0x73, 0x22, 0x8e, 0x01, 0x0a, 0x13, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x50, 0x72, 0x6f,
|
||||
0x67, 0x72, 0x65, 0x73, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x37, 0x0a, 0x06, 0x73, 0x74,
|
||||
0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x76, 0x31, 0x2e,
|
||||
0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74,
|
||||
0x61, 0x74, 0x75, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x48, 0x00, 0x52, 0x06, 0x73, 0x74, 0x61,
|
||||
0x74, 0x75, 0x73, 0x12, 0x35, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70,
|
||||
0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x48,
|
||||
0x00, 0x52, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x6e,
|
||||
0x74, 0x72, 0x79, 0x22, 0xbe, 0x01, 0x0a, 0x19, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x50, 0x72,
|
||||
0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x45, 0x6e, 0x74, 0x72,
|
||||
0x79, 0x12, 0x1d, 0x0a, 0x0c, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x5f, 0x64, 0x6f, 0x6e,
|
||||
0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x07, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74,
|
||||
0x12, 0x20, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x66, 0x69, 0x6c,
|
||||
0x65, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x62, 0x79, 0x74, 0x65,
|
||||
0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x62,
|
||||
0x79, 0x74, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5f, 0x64, 0x6f,
|
||||
0x6e, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5f,
|
||||
0x64, 0x6f, 0x6e, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x64, 0x6f,
|
||||
0x6e, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f,
|
||||
0x64, 0x6f, 0x6e, 0x65, 0x22, 0x87, 0x04, 0x0a, 0x15, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x50,
|
||||
0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x1c,
|
||||
0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5f, 0x6e, 0x65, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x03, 0x52, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5f, 0x6e, 0x65, 0x77, 0x12, 0x24, 0x0a, 0x0d,
|
||||
0x66, 0x69, 0x6c, 0x65, 0x73, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x03, 0x52, 0x0d, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67,
|
||||
0x65, 0x64, 0x12, 0x2a, 0x0a, 0x10, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5f, 0x75, 0x6e, 0x6d, 0x6f,
|
||||
0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x10, 0x66, 0x69,
|
||||
0x6c, 0x65, 0x73, 0x5f, 0x75, 0x6e, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, 0x1a,
|
||||
0x0a, 0x08, 0x64, 0x69, 0x72, 0x73, 0x5f, 0x6e, 0x65, 0x77, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03,
|
||||
0x52, 0x08, 0x64, 0x69, 0x72, 0x73, 0x5f, 0x6e, 0x65, 0x77, 0x12, 0x22, 0x0a, 0x0c, 0x64, 0x69,
|
||||
0x72, 0x73, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03,
|
||||
0x52, 0x0c, 0x64, 0x69, 0x72, 0x73, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, 0x28,
|
||||
0x0a, 0x0f, 0x64, 0x69, 0x72, 0x73, 0x5f, 0x75, 0x6e, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65,
|
||||
0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x64, 0x69, 0x72, 0x73, 0x5f, 0x75, 0x6e,
|
||||
0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x61, 0x74, 0x61,
|
||||
0x5f, 0x62, 0x6c, 0x6f, 0x62, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x64, 0x61,
|
||||
0x74, 0x61, 0x5f, 0x62, 0x6c, 0x6f, 0x62, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x74, 0x72, 0x65, 0x65,
|
||||
0x5f, 0x62, 0x6c, 0x6f, 0x62, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x74, 0x72,
|
||||
0x65, 0x65, 0x5f, 0x62, 0x6c, 0x6f, 0x62, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x64, 0x61, 0x74, 0x61,
|
||||
0x5f, 0x61, 0x64, 0x64, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x64, 0x61,
|
||||
0x74, 0x61, 0x5f, 0x61, 0x64, 0x64, 0x65, 0x64, 0x12, 0x34, 0x0a, 0x15, 0x74, 0x6f, 0x74, 0x61,
|
||||
0x6c, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65,
|
||||
0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x66,
|
||||
0x69, 0x6c, 0x65, 0x73, 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x12, 0x34,
|
||||
0x0a, 0x15, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x70, 0x72,
|
||||
0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x03, 0x52, 0x15, 0x74,
|
||||
0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65,
|
||||
0x73, 0x73, 0x65, 0x64, 0x12, 0x26, 0x0a, 0x0e, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x64, 0x75,
|
||||
0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x74, 0x6f,
|
||||
0x74, 0x61, 0x6c, 0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x0b,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x20, 0x0a, 0x0c, 0x75, 0x6e, 0x69, 0x78,
|
||||
0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a,
|
||||
0x75, 0x6e, 0x69, 0x78, 0x54, 0x69, 0x6d, 0x65, 0x4d, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x6f,
|
||||
0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f,
|
||||
0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61,
|
||||
0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61,
|
||||
0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x72, 0x65, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x04, 0x74, 0x72, 0x65, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74,
|
||||
0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x14,
|
||||
0x0a, 0x05, 0x70, 0x61, 0x74, 0x68, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x70,
|
||||
0x61, 0x74, 0x68, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, 0x67, 0x73, 0x18, 0x08, 0x20, 0x03,
|
||||
0x28, 0x09, 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x22, 0x46, 0x0a, 0x12, 0x52, 0x65, 0x73, 0x74,
|
||||
0x69, 0x63, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x30,
|
||||
0x0a, 0x09, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28,
|
||||
0x0b, 0x32, 0x12, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x69, 0x63, 0x53, 0x6e, 0x61,
|
||||
0x70, 0x73, 0x68, 0x6f, 0x74, 0x52, 0x09, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73,
|
||||
0x22, 0x8e, 0x01, 0x0a, 0x13, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x50, 0x72, 0x6f, 0x67, 0x72,
|
||||
0x65, 0x73, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x37, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74,
|
||||
0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61,
|
||||
0x63, 0x6b, 0x75, 0x70, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x61, 0x74,
|
||||
0x75, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x48, 0x00, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75,
|
||||
0x73, 0x12, 0x35, 0x0a, 0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x0b, 0x32, 0x19, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x50, 0x72,
|
||||
0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x48, 0x00, 0x52,
|
||||
0x07, 0x73, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x42, 0x07, 0x0a, 0x05, 0x65, 0x6e, 0x74, 0x72,
|
||||
0x79, 0x22, 0xbe, 0x01, 0x0a, 0x19, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x50, 0x72, 0x6f, 0x67,
|
||||
0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12,
|
||||
0x21, 0x0a, 0x0c, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x5f, 0x64, 0x6f, 0x6e, 0x65, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0b, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x44, 0x6f,
|
||||
0x6e, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x66, 0x69, 0x6c, 0x65,
|
||||
0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x46, 0x69,
|
||||
0x6c, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x62, 0x79, 0x74,
|
||||
0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x42,
|
||||
0x79, 0x74, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5f, 0x64, 0x6f,
|
||||
0x6e, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x44,
|
||||
0x6f, 0x6e, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x64, 0x6f, 0x6e,
|
||||
0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x62, 0x79, 0x74, 0x65, 0x73, 0x44, 0x6f,
|
||||
0x6e, 0x65, 0x22, 0xf8, 0x03, 0x0a, 0x15, 0x42, 0x61, 0x63, 0x6b, 0x75, 0x70, 0x50, 0x72, 0x6f,
|
||||
0x67, 0x72, 0x65, 0x73, 0x73, 0x53, 0x75, 0x6d, 0x6d, 0x61, 0x72, 0x79, 0x12, 0x1b, 0x0a, 0x09,
|
||||
0x66, 0x69, 0x6c, 0x65, 0x73, 0x5f, 0x6e, 0x65, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52,
|
||||
0x08, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x4e, 0x65, 0x77, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x69, 0x6c,
|
||||
0x65, 0x73, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03,
|
||||
0x52, 0x0c, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, 0x29,
|
||||
0x0a, 0x10, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5f, 0x75, 0x6e, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69,
|
||||
0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x55,
|
||||
0x6e, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x64, 0x69, 0x72,
|
||||
0x73, 0x5f, 0x6e, 0x65, 0x77, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x64, 0x69, 0x72,
|
||||
0x73, 0x4e, 0x65, 0x77, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x69, 0x72, 0x73, 0x5f, 0x63, 0x68, 0x61,
|
||||
0x6e, 0x67, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x64, 0x69, 0x72, 0x73,
|
||||
0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x64, 0x69, 0x72, 0x73, 0x5f,
|
||||
0x75, 0x6e, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03,
|
||||
0x52, 0x0e, 0x64, 0x69, 0x72, 0x73, 0x55, 0x6e, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64,
|
||||
0x12, 0x1d, 0x0a, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x62, 0x6c, 0x6f, 0x62, 0x73, 0x18, 0x07,
|
||||
0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x64, 0x61, 0x74, 0x61, 0x42, 0x6c, 0x6f, 0x62, 0x73, 0x12,
|
||||
0x1d, 0x0a, 0x0a, 0x74, 0x72, 0x65, 0x65, 0x5f, 0x62, 0x6c, 0x6f, 0x62, 0x73, 0x18, 0x08, 0x20,
|
||||
0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x72, 0x65, 0x65, 0x42, 0x6c, 0x6f, 0x62, 0x73, 0x12, 0x1d,
|
||||
0x0a, 0x0a, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x61, 0x64, 0x64, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01,
|
||||
0x28, 0x03, 0x52, 0x09, 0x64, 0x61, 0x74, 0x61, 0x41, 0x64, 0x64, 0x65, 0x64, 0x12, 0x32, 0x0a,
|
||||
0x15, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x5f, 0x70, 0x72, 0x6f,
|
||||
0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x13, 0x74, 0x6f,
|
||||
0x74, 0x61, 0x6c, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65,
|
||||
0x64, 0x12, 0x32, 0x0a, 0x15, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73,
|
||||
0x5f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x03,
|
||||
0x52, 0x13, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x42, 0x79, 0x74, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x63,
|
||||
0x65, 0x73, 0x73, 0x65, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x64,
|
||||
0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x74,
|
||||
0x6f, 0x74, 0x61, 0x6c, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b,
|
||||
0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x0d, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x0b, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x69, 0x64, 0x42, 0x2e,
|
||||
0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x61, 0x72,
|
||||
0x65, 0x74, 0x68, 0x67, 0x65, 0x6f, 0x72, 0x67, 0x65, 0x2f, 0x72, 0x65, 0x73, 0x74, 0x69, 0x63,
|
||||
0x75, 0x69, 0x2f, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x31, 0x62, 0x06,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x09, 0x52, 0x0a, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x49, 0x64, 0x42, 0x2e, 0x5a,
|
||||
0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x61, 0x72, 0x65,
|
||||
0x74, 0x68, 0x67, 0x65, 0x6f, 0x72, 0x67, 0x65, 0x2f, 0x72, 0x65, 0x73, 0x74, 0x69, 0x63, 0x75,
|
||||
0x69, 0x2f, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -515,21 +566,23 @@ func file_v1_restic_proto_rawDescGZIP() []byte {
|
||||
return file_v1_restic_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_v1_restic_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
|
||||
var file_v1_restic_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
|
||||
var file_v1_restic_proto_goTypes = []interface{}{
|
||||
(*ResticSnapshot)(nil), // 0: v1.ResticSnapshot
|
||||
(*BackupProgressEntry)(nil), // 1: v1.BackupProgressEntry
|
||||
(*BackupProgressStatusEntry)(nil), // 2: v1.BackupProgressStatusEntry
|
||||
(*BackupProgressSummary)(nil), // 3: v1.BackupProgressSummary
|
||||
(*ResticSnapshotList)(nil), // 1: v1.ResticSnapshotList
|
||||
(*BackupProgressEntry)(nil), // 2: v1.BackupProgressEntry
|
||||
(*BackupProgressStatusEntry)(nil), // 3: v1.BackupProgressStatusEntry
|
||||
(*BackupProgressSummary)(nil), // 4: v1.BackupProgressSummary
|
||||
}
|
||||
var file_v1_restic_proto_depIdxs = []int32{
|
||||
2, // 0: v1.BackupProgressEntry.status:type_name -> v1.BackupProgressStatusEntry
|
||||
3, // 1: v1.BackupProgressEntry.summary:type_name -> v1.BackupProgressSummary
|
||||
2, // [2:2] is the sub-list for method output_type
|
||||
2, // [2:2] is the sub-list for method input_type
|
||||
2, // [2:2] is the sub-list for extension type_name
|
||||
2, // [2:2] is the sub-list for extension extendee
|
||||
0, // [0:2] is the sub-list for field type_name
|
||||
0, // 0: v1.ResticSnapshotList.snapshots:type_name -> v1.ResticSnapshot
|
||||
3, // 1: v1.BackupProgressEntry.status:type_name -> v1.BackupProgressStatusEntry
|
||||
4, // 2: v1.BackupProgressEntry.summary:type_name -> v1.BackupProgressSummary
|
||||
3, // [3:3] is the sub-list for method output_type
|
||||
3, // [3:3] is the sub-list for method input_type
|
||||
3, // [3:3] is the sub-list for extension type_name
|
||||
3, // [3:3] is the sub-list for extension extendee
|
||||
0, // [0:3] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_v1_restic_proto_init() }
|
||||
@@ -551,7 +604,7 @@ func file_v1_restic_proto_init() {
|
||||
}
|
||||
}
|
||||
file_v1_restic_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*BackupProgressEntry); i {
|
||||
switch v := v.(*ResticSnapshotList); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
@@ -563,7 +616,7 @@ func file_v1_restic_proto_init() {
|
||||
}
|
||||
}
|
||||
file_v1_restic_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*BackupProgressStatusEntry); i {
|
||||
switch v := v.(*BackupProgressEntry); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
@@ -575,6 +628,18 @@ func file_v1_restic_proto_init() {
|
||||
}
|
||||
}
|
||||
file_v1_restic_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*BackupProgressStatusEntry); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_v1_restic_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*BackupProgressSummary); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -587,7 +652,7 @@ func file_v1_restic_proto_init() {
|
||||
}
|
||||
}
|
||||
}
|
||||
file_v1_restic_proto_msgTypes[1].OneofWrappers = []interface{}{
|
||||
file_v1_restic_proto_msgTypes[2].OneofWrappers = []interface{}{
|
||||
(*BackupProgressEntry_Status)(nil),
|
||||
(*BackupProgressEntry_Summary)(nil),
|
||||
}
|
||||
@@ -597,7 +662,7 @@ func file_v1_restic_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_v1_restic_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 4,
|
||||
NumMessages: 5,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
emptypb "google.golang.org/protobuf/types/known/emptypb"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -22,67 +23,151 @@ const (
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
type ListSnapshotsRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
RepoId string `protobuf:"bytes,1,opt,name=repo_id,json=repoId,proto3" json:"repo_id,omitempty"`
|
||||
PlanId string `protobuf:"bytes,2,opt,name=plan_id,json=planId,proto3" json:"plan_id,omitempty"`
|
||||
}
|
||||
|
||||
func (x *ListSnapshotsRequest) Reset() {
|
||||
*x = ListSnapshotsRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_v1_service_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *ListSnapshotsRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*ListSnapshotsRequest) ProtoMessage() {}
|
||||
|
||||
func (x *ListSnapshotsRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_v1_service_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use ListSnapshotsRequest.ProtoReflect.Descriptor instead.
|
||||
func (*ListSnapshotsRequest) Descriptor() ([]byte, []int) {
|
||||
return file_v1_service_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *ListSnapshotsRequest) GetRepoId() string {
|
||||
if x != nil {
|
||||
return x.RepoId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *ListSnapshotsRequest) GetPlanId() string {
|
||||
if x != nil {
|
||||
return x.PlanId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var File_v1_service_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_v1_service_proto_rawDesc = []byte{
|
||||
0x0a, 0x10, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x12, 0x02, 0x76, 0x31, 0x1a, 0x0f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69,
|
||||
0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0f, 0x76, 0x31, 0x2f, 0x65, 0x76, 0x65, 0x6e,
|
||||
0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x11, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f,
|
||||
0x76, 0x61, 0x6c, 0x75, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f,
|
||||
0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70,
|
||||
0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
|
||||
0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0xeb, 0x02, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x74, 0x69,
|
||||
0x63, 0x55, 0x49, 0x12, 0x43, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
|
||||
0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
|
||||
0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0a, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f,
|
||||
0x6e, 0x66, 0x69, 0x67, 0x22, 0x12, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0c, 0x12, 0x0a, 0x2f, 0x76,
|
||||
0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3a, 0x0a, 0x09, 0x53, 0x65, 0x74, 0x43,
|
||||
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x0a, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69,
|
||||
0x67, 0x1a, 0x0a, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x15, 0x82,
|
||||
0xd3, 0xe4, 0x93, 0x02, 0x0f, 0x3a, 0x01, 0x2a, 0x22, 0x0a, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f,
|
||||
0x6e, 0x66, 0x69, 0x67, 0x12, 0x3b, 0x0a, 0x07, 0x41, 0x64, 0x64, 0x52, 0x65, 0x70, 0x6f, 0x12,
|
||||
0x08, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x1a, 0x0a, 0x2e, 0x76, 0x31, 0x2e, 0x43,
|
||||
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x1a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x14, 0x3a, 0x01, 0x2a,
|
||||
0x22, 0x0f, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x72, 0x65, 0x70,
|
||||
0x6f, 0x12, 0x44, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x16,
|
||||
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
|
||||
0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x09, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x76, 0x65, 0x6e,
|
||||
0x74, 0x22, 0x12, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0c, 0x12, 0x0a, 0x2f, 0x76, 0x31, 0x2f, 0x65,
|
||||
0x76, 0x65, 0x6e, 0x74, 0x73, 0x30, 0x01, 0x12, 0x5b, 0x0a, 0x10, 0x50, 0x61, 0x74, 0x68, 0x41,
|
||||
0x75, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x12, 0x2e, 0x74, 0x79,
|
||||
0x70, 0x65, 0x73, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a,
|
||||
0x11, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4c, 0x69,
|
||||
0x73, 0x74, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x3a, 0x01, 0x2a, 0x22, 0x15, 0x2f,
|
||||
0x76, 0x31, 0x2f, 0x61, 0x75, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x2f,
|
||||
0x70, 0x61, 0x74, 0x68, 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
|
||||
0x6f, 0x6d, 0x2f, 0x67, 0x61, 0x72, 0x65, 0x74, 0x68, 0x67, 0x65, 0x6f, 0x72, 0x67, 0x65, 0x2f,
|
||||
0x72, 0x65, 0x73, 0x74, 0x69, 0x63, 0x75, 0x69, 0x2f, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0f, 0x76, 0x31, 0x2f, 0x72, 0x65, 0x73,
|
||||
0x74, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x11, 0x74, 0x79, 0x70, 0x65, 0x73,
|
||||
0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f,
|
||||
0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d,
|
||||
0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
|
||||
0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x48, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x53,
|
||||
0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
|
||||
0x17, 0x0a, 0x07, 0x72, 0x65, 0x70, 0x6f, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x06, 0x72, 0x65, 0x70, 0x6f, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x70, 0x6c, 0x61, 0x6e,
|
||||
0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x6c, 0x61, 0x6e, 0x49,
|
||||
0x64, 0x32, 0xc8, 0x03, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x74, 0x69, 0x63, 0x55, 0x49, 0x12, 0x43,
|
||||
0x0a, 0x09, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x16, 0x2e, 0x67, 0x6f,
|
||||
0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d,
|
||||
0x70, 0x74, 0x79, 0x1a, 0x0a, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22,
|
||||
0x12, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0c, 0x12, 0x0a, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e,
|
||||
0x66, 0x69, 0x67, 0x12, 0x3a, 0x0a, 0x09, 0x53, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
|
||||
0x12, 0x0a, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x0a, 0x2e, 0x76,
|
||||
0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x15, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0f,
|
||||
0x3a, 0x01, 0x2a, 0x22, 0x0a, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12,
|
||||
0x3b, 0x0a, 0x07, 0x41, 0x64, 0x64, 0x52, 0x65, 0x70, 0x6f, 0x12, 0x08, 0x2e, 0x76, 0x31, 0x2e,
|
||||
0x52, 0x65, 0x70, 0x6f, 0x1a, 0x0a, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
|
||||
0x22, 0x1a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x14, 0x3a, 0x01, 0x2a, 0x22, 0x0f, 0x2f, 0x76, 0x31,
|
||||
0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x12, 0x44, 0x0a, 0x09,
|
||||
0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
|
||||
0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74,
|
||||
0x79, 0x1a, 0x09, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x22, 0x12, 0x82, 0xd3,
|
||||
0xe4, 0x93, 0x02, 0x0c, 0x12, 0x0a, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73,
|
||||
0x30, 0x01, 0x12, 0x5b, 0x0a, 0x0d, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68,
|
||||
0x6f, 0x74, 0x73, 0x12, 0x18, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x6e, 0x61,
|
||||
0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e,
|
||||
0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x69, 0x63, 0x53, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f,
|
||||
0x74, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x3a, 0x01, 0x2a,
|
||||
0x22, 0x0d, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x73, 0x12,
|
||||
0x5b, 0x0a, 0x10, 0x50, 0x61, 0x74, 0x68, 0x41, 0x75, 0x74, 0x6f, 0x63, 0x6f, 0x6d, 0x70, 0x6c,
|
||||
0x65, 0x74, 0x65, 0x12, 0x12, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x74, 0x72, 0x69,
|
||||
0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x11, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e,
|
||||
0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93,
|
||||
0x02, 0x1a, 0x3a, 0x01, 0x2a, 0x22, 0x15, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x75, 0x74, 0x6f, 0x63,
|
||||
0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x2f, 0x70, 0x61, 0x74, 0x68, 0x42, 0x2e, 0x5a, 0x2c,
|
||||
0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x61, 0x72, 0x65, 0x74,
|
||||
0x68, 0x67, 0x65, 0x6f, 0x72, 0x67, 0x65, 0x2f, 0x72, 0x65, 0x73, 0x74, 0x69, 0x63, 0x75, 0x69,
|
||||
0x2f, 0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_v1_service_proto_rawDescOnce sync.Once
|
||||
file_v1_service_proto_rawDescData = file_v1_service_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_v1_service_proto_rawDescGZIP() []byte {
|
||||
file_v1_service_proto_rawDescOnce.Do(func() {
|
||||
file_v1_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_v1_service_proto_rawDescData)
|
||||
})
|
||||
return file_v1_service_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_v1_service_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
|
||||
var file_v1_service_proto_goTypes = []interface{}{
|
||||
(*emptypb.Empty)(nil), // 0: google.protobuf.Empty
|
||||
(*Config)(nil), // 1: v1.Config
|
||||
(*Repo)(nil), // 2: v1.Repo
|
||||
(*types.StringValue)(nil), // 3: types.StringValue
|
||||
(*Event)(nil), // 4: v1.Event
|
||||
(*types.StringList)(nil), // 5: types.StringList
|
||||
(*ListSnapshotsRequest)(nil), // 0: v1.ListSnapshotsRequest
|
||||
(*emptypb.Empty)(nil), // 1: google.protobuf.Empty
|
||||
(*Config)(nil), // 2: v1.Config
|
||||
(*Repo)(nil), // 3: v1.Repo
|
||||
(*types.StringValue)(nil), // 4: types.StringValue
|
||||
(*Event)(nil), // 5: v1.Event
|
||||
(*ResticSnapshotList)(nil), // 6: v1.ResticSnapshotList
|
||||
(*types.StringList)(nil), // 7: types.StringList
|
||||
}
|
||||
var file_v1_service_proto_depIdxs = []int32{
|
||||
0, // 0: v1.ResticUI.GetConfig:input_type -> google.protobuf.Empty
|
||||
1, // 1: v1.ResticUI.SetConfig:input_type -> v1.Config
|
||||
2, // 2: v1.ResticUI.AddRepo:input_type -> v1.Repo
|
||||
0, // 3: v1.ResticUI.GetEvents:input_type -> google.protobuf.Empty
|
||||
3, // 4: v1.ResticUI.PathAutocomplete:input_type -> types.StringValue
|
||||
1, // 5: v1.ResticUI.GetConfig:output_type -> v1.Config
|
||||
1, // 6: v1.ResticUI.SetConfig:output_type -> v1.Config
|
||||
1, // 7: v1.ResticUI.AddRepo:output_type -> v1.Config
|
||||
4, // 8: v1.ResticUI.GetEvents:output_type -> v1.Event
|
||||
5, // 9: v1.ResticUI.PathAutocomplete:output_type -> types.StringList
|
||||
5, // [5:10] is the sub-list for method output_type
|
||||
0, // [0:5] is the sub-list for method input_type
|
||||
1, // 0: v1.ResticUI.GetConfig:input_type -> google.protobuf.Empty
|
||||
2, // 1: v1.ResticUI.SetConfig:input_type -> v1.Config
|
||||
3, // 2: v1.ResticUI.AddRepo:input_type -> v1.Repo
|
||||
1, // 3: v1.ResticUI.GetEvents:input_type -> google.protobuf.Empty
|
||||
0, // 4: v1.ResticUI.ListSnapshots:input_type -> v1.ListSnapshotsRequest
|
||||
4, // 5: v1.ResticUI.PathAutocomplete:input_type -> types.StringValue
|
||||
2, // 6: v1.ResticUI.GetConfig:output_type -> v1.Config
|
||||
2, // 7: v1.ResticUI.SetConfig:output_type -> v1.Config
|
||||
2, // 8: v1.ResticUI.AddRepo:output_type -> v1.Config
|
||||
5, // 9: v1.ResticUI.GetEvents:output_type -> v1.Event
|
||||
6, // 10: v1.ResticUI.ListSnapshots:output_type -> v1.ResticSnapshotList
|
||||
7, // 11: v1.ResticUI.PathAutocomplete:output_type -> types.StringList
|
||||
6, // [6:12] is the sub-list for method output_type
|
||||
0, // [0:6] is the sub-list for method input_type
|
||||
0, // [0:0] is the sub-list for extension type_name
|
||||
0, // [0:0] is the sub-list for extension extendee
|
||||
0, // [0:0] is the sub-list for field type_name
|
||||
@@ -95,18 +180,34 @@ func file_v1_service_proto_init() {
|
||||
}
|
||||
file_v1_config_proto_init()
|
||||
file_v1_events_proto_init()
|
||||
file_v1_restic_proto_init()
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_v1_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*ListSnapshotsRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_v1_service_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 0,
|
||||
NumMessages: 1,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
GoTypes: file_v1_service_proto_goTypes,
|
||||
DependencyIndexes: file_v1_service_proto_depIdxs,
|
||||
MessageInfos: file_v1_service_proto_msgTypes,
|
||||
}.Build()
|
||||
File_v1_service_proto = out.File
|
||||
file_v1_service_proto_rawDesc = nil
|
||||
|
||||
@@ -136,6 +136,40 @@ func request_ResticUI_GetEvents_0(ctx context.Context, marshaler runtime.Marshal
|
||||
|
||||
}
|
||||
|
||||
func request_ResticUI_ListSnapshots_0(ctx context.Context, marshaler runtime.Marshaler, client ResticUIClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq ListSnapshotsRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
newReader, berr := utilities.IOReaderFactory(req.Body)
|
||||
if berr != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
|
||||
}
|
||||
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := client.ListSnapshots(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func local_request_ResticUI_ListSnapshots_0(ctx context.Context, marshaler runtime.Marshaler, server ResticUIServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq ListSnapshotsRequest
|
||||
var metadata runtime.ServerMetadata
|
||||
|
||||
newReader, berr := utilities.IOReaderFactory(req.Body)
|
||||
if berr != nil {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
|
||||
}
|
||||
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
|
||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||
}
|
||||
|
||||
msg, err := server.ListSnapshots(ctx, &protoReq)
|
||||
return msg, metadata, err
|
||||
|
||||
}
|
||||
|
||||
func request_ResticUI_PathAutocomplete_0(ctx context.Context, marshaler runtime.Marshaler, client ResticUIClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||
var protoReq types.StringValue
|
||||
var metadata runtime.ServerMetadata
|
||||
@@ -258,6 +292,31 @@ func RegisterResticUIHandlerServer(ctx context.Context, mux *runtime.ServeMux, s
|
||||
return
|
||||
})
|
||||
|
||||
mux.Handle("POST", pattern_ResticUI_ListSnapshots_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
var stream runtime.ServerTransportStream
|
||||
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
var err error
|
||||
var annotatedContext context.Context
|
||||
annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/v1.ResticUI/ListSnapshots", runtime.WithHTTPPathPattern("/v1/snapshots"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := local_request_ResticUI_ListSnapshots_0(annotatedContext, inboundMarshaler, server, req, pathParams)
|
||||
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_ResticUI_ListSnapshots_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("POST", pattern_ResticUI_PathAutocomplete_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
@@ -412,6 +471,28 @@ func RegisterResticUIHandlerClient(ctx context.Context, mux *runtime.ServeMux, c
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("POST", pattern_ResticUI_ListSnapshots_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||
var err error
|
||||
var annotatedContext context.Context
|
||||
annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/v1.ResticUI/ListSnapshots", runtime.WithHTTPPathPattern("/v1/snapshots"))
|
||||
if err != nil {
|
||||
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
resp, md, err := request_ResticUI_ListSnapshots_0(annotatedContext, inboundMarshaler, client, req, pathParams)
|
||||
annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
|
||||
if err != nil {
|
||||
runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
|
||||
return
|
||||
}
|
||||
|
||||
forward_ResticUI_ListSnapshots_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||
|
||||
})
|
||||
|
||||
mux.Handle("POST", pattern_ResticUI_PathAutocomplete_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
defer cancel()
|
||||
@@ -446,6 +527,8 @@ var (
|
||||
|
||||
pattern_ResticUI_GetEvents_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "events"}, ""))
|
||||
|
||||
pattern_ResticUI_ListSnapshots_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "snapshots"}, ""))
|
||||
|
||||
pattern_ResticUI_PathAutocomplete_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "autocomplete", "path"}, ""))
|
||||
)
|
||||
|
||||
@@ -458,5 +541,7 @@ var (
|
||||
|
||||
forward_ResticUI_GetEvents_0 = runtime.ForwardResponseStream
|
||||
|
||||
forward_ResticUI_ListSnapshots_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_ResticUI_PathAutocomplete_0 = runtime.ForwardResponseMessage
|
||||
)
|
||||
|
||||
@@ -25,6 +25,7 @@ const (
|
||||
ResticUI_SetConfig_FullMethodName = "/v1.ResticUI/SetConfig"
|
||||
ResticUI_AddRepo_FullMethodName = "/v1.ResticUI/AddRepo"
|
||||
ResticUI_GetEvents_FullMethodName = "/v1.ResticUI/GetEvents"
|
||||
ResticUI_ListSnapshots_FullMethodName = "/v1.ResticUI/ListSnapshots"
|
||||
ResticUI_PathAutocomplete_FullMethodName = "/v1.ResticUI/PathAutocomplete"
|
||||
)
|
||||
|
||||
@@ -36,6 +37,7 @@ type ResticUIClient interface {
|
||||
SetConfig(ctx context.Context, in *Config, opts ...grpc.CallOption) (*Config, error)
|
||||
AddRepo(ctx context.Context, in *Repo, opts ...grpc.CallOption) (*Config, error)
|
||||
GetEvents(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (ResticUI_GetEventsClient, error)
|
||||
ListSnapshots(ctx context.Context, in *ListSnapshotsRequest, opts ...grpc.CallOption) (*ResticSnapshotList, error)
|
||||
PathAutocomplete(ctx context.Context, in *types.StringValue, opts ...grpc.CallOption) (*types.StringList, error)
|
||||
}
|
||||
|
||||
@@ -106,6 +108,15 @@ func (x *resticUIGetEventsClient) Recv() (*Event, error) {
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (c *resticUIClient) ListSnapshots(ctx context.Context, in *ListSnapshotsRequest, opts ...grpc.CallOption) (*ResticSnapshotList, error) {
|
||||
out := new(ResticSnapshotList)
|
||||
err := c.cc.Invoke(ctx, ResticUI_ListSnapshots_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *resticUIClient) PathAutocomplete(ctx context.Context, in *types.StringValue, opts ...grpc.CallOption) (*types.StringList, error) {
|
||||
out := new(types.StringList)
|
||||
err := c.cc.Invoke(ctx, ResticUI_PathAutocomplete_FullMethodName, in, out, opts...)
|
||||
@@ -123,6 +134,7 @@ type ResticUIServer interface {
|
||||
SetConfig(context.Context, *Config) (*Config, error)
|
||||
AddRepo(context.Context, *Repo) (*Config, error)
|
||||
GetEvents(*emptypb.Empty, ResticUI_GetEventsServer) error
|
||||
ListSnapshots(context.Context, *ListSnapshotsRequest) (*ResticSnapshotList, error)
|
||||
PathAutocomplete(context.Context, *types.StringValue) (*types.StringList, error)
|
||||
mustEmbedUnimplementedResticUIServer()
|
||||
}
|
||||
@@ -143,6 +155,9 @@ func (UnimplementedResticUIServer) AddRepo(context.Context, *Repo) (*Config, err
|
||||
func (UnimplementedResticUIServer) GetEvents(*emptypb.Empty, ResticUI_GetEventsServer) error {
|
||||
return status.Errorf(codes.Unimplemented, "method GetEvents not implemented")
|
||||
}
|
||||
func (UnimplementedResticUIServer) ListSnapshots(context.Context, *ListSnapshotsRequest) (*ResticSnapshotList, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method ListSnapshots not implemented")
|
||||
}
|
||||
func (UnimplementedResticUIServer) PathAutocomplete(context.Context, *types.StringValue) (*types.StringList, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method PathAutocomplete not implemented")
|
||||
}
|
||||
@@ -234,6 +249,24 @@ func (x *resticUIGetEventsServer) Send(m *Event) error {
|
||||
return x.ServerStream.SendMsg(m)
|
||||
}
|
||||
|
||||
func _ResticUI_ListSnapshots_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ListSnapshotsRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ResticUIServer).ListSnapshots(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ResticUI_ListSnapshots_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ResticUIServer).ListSnapshots(ctx, req.(*ListSnapshotsRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _ResticUI_PathAutocomplete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(types.StringValue)
|
||||
if err := dec(in); err != nil {
|
||||
@@ -271,6 +304,10 @@ var ResticUI_ServiceDesc = grpc.ServiceDesc{
|
||||
MethodName: "AddRepo",
|
||||
Handler: _ResticUI_AddRepo_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "ListSnapshots",
|
||||
Handler: _ResticUI_ListSnapshots_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "PathAutocomplete",
|
||||
Handler: _ResticUI_PathAutocomplete_Handler,
|
||||
|
||||
1
go.mod
1
go.mod
@@ -5,6 +5,7 @@ go 1.21.3
|
||||
require (
|
||||
github.com/gitploy-io/cronexpr v0.2.2
|
||||
github.com/google/renameio v1.0.1
|
||||
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.1
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.1
|
||||
github.com/hashicorp/go-multierror v1.1.1
|
||||
go.uber.org/zap v1.26.0
|
||||
|
||||
2
go.sum
2
go.sum
@@ -28,6 +28,8 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||
github.com/google/renameio v1.0.1 h1:Lh/jXZmvZxb0BBeSY5VKEfidcbcbenKjZFzM/q0fSeU=
|
||||
github.com/google/renameio v1.0.1/go.mod h1:t/HQoYBZSsWSNK35C6CO/TpPLDVWvxOHboWUAweKUpk=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.1 h1:HcUWd006luQPljE73d5sk+/VgYPGUReEVz2y1/qylwY=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.1/go.mod h1:w9Y7gY31krpLmrVU5ZPG9H7l9fZuRu5/3R3S3FMtVQ4=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.2 h1:dygLcbEBA+t/P7ck6a8AkXv6juQ4cK0RHBoh32jxhHM=
|
||||
|
||||
@@ -9,18 +9,68 @@ import (
|
||||
"path/filepath"
|
||||
|
||||
v1 "github.com/garethgeorge/resticui/gen/go/v1"
|
||||
"github.com/garethgeorge/resticui/internal/orchestrator"
|
||||
"github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging"
|
||||
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
|
||||
"go.uber.org/zap"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
)
|
||||
|
||||
func serveGRPC(ctx context.Context, socket string) error {
|
||||
func loggingFunc(l *zap.Logger) logging.Logger {
|
||||
return logging.LoggerFunc(func(ctx context.Context, lvl logging.Level, msg string, fields ...any) {
|
||||
f := make([]zap.Field, 0, len(fields)/2)
|
||||
|
||||
for i := 0; i < len(fields); i += 2 {
|
||||
key := fields[i]
|
||||
value := fields[i+1]
|
||||
|
||||
switch v := value.(type) {
|
||||
case string:
|
||||
f = append(f, zap.String(key.(string), v))
|
||||
case int:
|
||||
f = append(f, zap.Int(key.(string), v))
|
||||
case bool:
|
||||
f = append(f, zap.Bool(key.(string), v))
|
||||
default:
|
||||
f = append(f, zap.Any(key.(string), v))
|
||||
}
|
||||
}
|
||||
|
||||
logger := l.WithOptions(zap.AddCallerSkip(1)).With(f...)
|
||||
|
||||
switch lvl {
|
||||
case logging.LevelDebug:
|
||||
logger.Debug(msg)
|
||||
case logging.LevelInfo:
|
||||
logger.Info(msg)
|
||||
case logging.LevelWarn:
|
||||
logger.Warn(msg)
|
||||
case logging.LevelError:
|
||||
logger.Error(msg)
|
||||
default:
|
||||
panic(fmt.Sprintf("unknown level %v", lvl))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
func serveGRPC(ctx context.Context, orchestrator *orchestrator.Orchestrator, socket string) error {
|
||||
lis, err := net.Listen("unix", socket)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to listen: %w", err)
|
||||
}
|
||||
grpcServer := grpc.NewServer()
|
||||
v1.RegisterResticUIServer(grpcServer, NewServer())
|
||||
|
||||
logger := zap.L()
|
||||
grpcServer := grpc.NewServer(
|
||||
grpc.ChainUnaryInterceptor(
|
||||
logging.UnaryServerInterceptor(loggingFunc(logger)),
|
||||
),
|
||||
grpc.ChainStreamInterceptor(
|
||||
logging.StreamServerInterceptor(loggingFunc(logger)),
|
||||
),
|
||||
)
|
||||
v1.RegisterResticUIServer(grpcServer, NewServer(orchestrator))
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
grpcServer.GracefulStop()
|
||||
@@ -32,7 +82,7 @@ func serveGRPC(ctx context.Context, socket string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func serveHTTPHandlers(ctx context.Context, mux *runtime.ServeMux) error {
|
||||
func serveHTTPHandlers(ctx context.Context, orchestrator *orchestrator.Orchestrator, mux *runtime.ServeMux) error {
|
||||
tmpDir, err := os.MkdirTemp("", "resticui")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create temp dir for unix domain socket: %w", err)
|
||||
@@ -49,7 +99,7 @@ func serveHTTPHandlers(ctx context.Context, mux *runtime.ServeMux) error {
|
||||
return fmt.Errorf("failed to register gateway: %w", err)
|
||||
}
|
||||
|
||||
if err := serveGRPC(ctx, socket); err != nil {
|
||||
if err := serveGRPC(ctx, orchestrator, socket); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -57,8 +107,8 @@ func serveHTTPHandlers(ctx context.Context, mux *runtime.ServeMux) error {
|
||||
}
|
||||
|
||||
// Handler returns an http.Handler serving the API, cancel the context to cleanly shut down the server.
|
||||
func ServeAPI(ctx context.Context, mux *http.ServeMux) error {
|
||||
func ServeAPI(ctx context.Context, orchestrator *orchestrator.Orchestrator, mux *http.ServeMux) error {
|
||||
apiMux := runtime.NewServeMux()
|
||||
mux.Handle("/api/", http.StripPrefix("/api", apiMux))
|
||||
return serveHTTPHandlers(ctx, apiMux)
|
||||
return serveHTTPHandlers(ctx, orchestrator, apiMux)
|
||||
}
|
||||
@@ -7,18 +7,20 @@ import (
|
||||
"os"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/garethgeorge/resticui/gen/go/types"
|
||||
v1 "github.com/garethgeorge/resticui/gen/go/v1"
|
||||
"github.com/garethgeorge/resticui/internal/config"
|
||||
"github.com/garethgeorge/resticui/internal/orchestrator"
|
||||
"github.com/garethgeorge/resticui/pkg/restic"
|
||||
"go.uber.org/zap"
|
||||
"google.golang.org/protobuf/proto"
|
||||
"google.golang.org/protobuf/types/known/emptypb"
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
*v1.UnimplementedResticUIServer
|
||||
orchestrator *orchestrator.Orchestrator
|
||||
|
||||
reqId atomic.Uint64
|
||||
eventChannelsMu sync.Mutex
|
||||
@@ -27,23 +29,25 @@ type Server struct {
|
||||
|
||||
var _ v1.ResticUIServer = &Server{}
|
||||
|
||||
func NewServer() *Server {
|
||||
func NewServer(orchestrator *orchestrator.Orchestrator) *Server {
|
||||
s := &Server{
|
||||
eventChannels: make(map[uint64]chan *v1.Event),
|
||||
orchestrator: orchestrator,
|
||||
}
|
||||
|
||||
go func() {
|
||||
for {
|
||||
time.Sleep(3 * time.Second)
|
||||
s.PublishEvent(&v1.Event{
|
||||
Event: &v1.Event_Log{
|
||||
Log: &v1.LogEvent{
|
||||
Message: fmt.Sprintf("event push test, it is %v", time.Now().Format(time.RFC3339)),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
}()
|
||||
// go func() {
|
||||
// // TODO: disable this when proper event sources are implemented.
|
||||
// for {
|
||||
// time.Sleep(3 * time.Second)
|
||||
// s.PublishEvent(&v1.Event{
|
||||
// Event: &v1.Event_Log{
|
||||
// Log: &v1.LogEvent{
|
||||
// Message: fmt.Sprintf("event push test, it is %v", time.Now().Format(time.RFC3339)),
|
||||
// },
|
||||
// },
|
||||
// })
|
||||
// }
|
||||
// }()
|
||||
|
||||
return s
|
||||
}
|
||||
@@ -55,8 +59,18 @@ func (s *Server) GetConfig(ctx context.Context, empty *emptypb.Empty) (*v1.Confi
|
||||
|
||||
// SetConfig implements POST /v1/config
|
||||
func (s *Server) SetConfig(ctx context.Context, c *v1.Config) (*v1.Config, error) {
|
||||
err := config.Default.Update(c)
|
||||
existing, err := config.Default.Get()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to check current config: %w", err)
|
||||
}
|
||||
|
||||
// Compare and increment modno
|
||||
if existing.Modno != c.Modno {
|
||||
return nil, errors.New("config modno mismatch, reload and try again")
|
||||
}
|
||||
c.Modno += 1
|
||||
|
||||
if err := config.Default.Update(c); err != nil {
|
||||
return nil, fmt.Errorf("failed to update config: %w", err)
|
||||
}
|
||||
return config.Default.Get()
|
||||
@@ -69,14 +83,20 @@ func (s *Server) AddRepo(ctx context.Context, repo *v1.Repo) (*v1.Config, error)
|
||||
return nil, fmt.Errorf("failed to get config: %w", err)
|
||||
}
|
||||
|
||||
c = proto.Clone(c).(*v1.Config)
|
||||
c.Repos = append(c.Repos, repo)
|
||||
|
||||
if err := config.ValidateConfig(c); err != nil {
|
||||
return nil, fmt.Errorf("validation error: %w", err)
|
||||
}
|
||||
|
||||
r := restic.NewRepo(repo)
|
||||
// use background context such that the init op can try to complete even if the connection is closed.
|
||||
if err := r.Init(context.Background()); err != nil {
|
||||
return nil, fmt.Errorf("failed to init repo: %w", err)
|
||||
}
|
||||
|
||||
c.Repos = append(c.Repos, repo)
|
||||
|
||||
zap.S().Debug("Updating config")
|
||||
if err := config.Default.Update(c); err != nil {
|
||||
return nil, fmt.Errorf("failed to update config: %w", err)
|
||||
}
|
||||
@@ -84,6 +104,40 @@ func (s *Server) AddRepo(ctx context.Context, repo *v1.Repo) (*v1.Config, error)
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// ListSnapshots implements GET /v1/snapshots/{repo.id}/{plan.id?}
|
||||
func (s *Server) ListSnapshots(ctx context.Context, query *v1.ListSnapshotsRequest) (*v1.ResticSnapshotList, error) {
|
||||
repo, err := s.orchestrator.GetRepo(query.RepoId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get repo: %w", err)
|
||||
}
|
||||
|
||||
var snapshots []*restic.Snapshot
|
||||
if query.PlanId != "" {
|
||||
var plan *v1.Plan
|
||||
plan, err = s.orchestrator.GetPlan(query.PlanId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get plan %q: %w", query.PlanId, err)
|
||||
}
|
||||
|
||||
snapshots, err = repo.SnapshotsForPlan(ctx, plan)
|
||||
} else {
|
||||
snapshots, err = repo.Snapshots(ctx)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list snapshots: %w", err)
|
||||
}
|
||||
|
||||
// Transform the snapshots and return them.
|
||||
var rs []*v1.ResticSnapshot
|
||||
for _, snapshot := range snapshots {
|
||||
rs = append(rs, snapshot.ToProto())
|
||||
}
|
||||
|
||||
return &v1.ResticSnapshotList{
|
||||
Snapshots: rs,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GetEvents implements GET /v1/events
|
||||
func (s *Server) GetEvents(_ *emptypb.Empty, stream v1.ResticUI_GetEventsServer) error {
|
||||
|
||||
@@ -1,18 +1,23 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"sync"
|
||||
|
||||
v1 "github.com/garethgeorge/resticui/gen/go/v1"
|
||||
)
|
||||
|
||||
var ErrConfigNotFound = fmt.Errorf("config not found")
|
||||
var configDirFlag = flag.String("config_dir", "", "The directory to store the config file")
|
||||
|
||||
var Default ConfigStore = &YamlFileStore{
|
||||
var Default ConfigStore = &CachingValidatingStore{
|
||||
ConfigStore: &YamlFileStore{
|
||||
Path: path.Join(configDir(*configDirFlag), "config.yaml"),
|
||||
},
|
||||
}
|
||||
|
||||
type ConfigStore interface {
|
||||
@@ -43,3 +48,50 @@ func configDir(override string) string {
|
||||
|
||||
return fmt.Sprintf("%v/.config/resticui", home)
|
||||
}
|
||||
|
||||
type CachingValidatingStore struct {
|
||||
ConfigStore
|
||||
mu sync.Mutex
|
||||
config *v1.Config
|
||||
}
|
||||
|
||||
func (c *CachingValidatingStore) Get() (*v1.Config, error) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
|
||||
if c.config != nil {
|
||||
return c.config, nil
|
||||
}
|
||||
|
||||
config, err := c.ConfigStore.Get()
|
||||
if err != nil {
|
||||
if errors.Is(err, ErrConfigNotFound) {
|
||||
c.config = NewDefaultConfig()
|
||||
return c.config, nil
|
||||
}
|
||||
return c.config, err
|
||||
}
|
||||
|
||||
if err := ValidateConfig(config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c.config = config
|
||||
return config, nil
|
||||
}
|
||||
|
||||
func (c *CachingValidatingStore) Update(config *v1.Config) error {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
|
||||
if err := ValidateConfig(config); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := c.ConfigStore.Update(config); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.config = config
|
||||
return nil
|
||||
}
|
||||
114
internal/config/config_test.go
Normal file
114
internal/config/config_test.go
Normal file
@@ -0,0 +1,114 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
v1 "github.com/garethgeorge/resticui/gen/go/v1"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
|
||||
func TestConfig(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
|
||||
testRepo := &v1.Repo{
|
||||
Id: "test-repo",
|
||||
Uri: "/tmp/test",
|
||||
Password: "test",
|
||||
}
|
||||
|
||||
testPlan := &v1.Plan{
|
||||
Id: "test-plan",
|
||||
Repo: "test-repo",
|
||||
Paths: []string{"/tmp/foo"},
|
||||
Cron: "* * * * *",
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
config *v1.Config
|
||||
wantErr bool
|
||||
wantErrContains string
|
||||
store ConfigStore
|
||||
}{
|
||||
{
|
||||
name: "default config",
|
||||
config: NewDefaultConfig(),
|
||||
store: &CachingValidatingStore{ConfigStore: &YamlFileStore{Path: dir + "/default-config.yaml"}},
|
||||
},
|
||||
{
|
||||
name: "simple valid config",
|
||||
config: &v1.Config{
|
||||
Repos: []*v1.Repo{testRepo},
|
||||
Plans: []*v1.Plan{testPlan},
|
||||
},
|
||||
store: &CachingValidatingStore{ConfigStore: &YamlFileStore{Path: dir + "/valid-config.yaml"}},
|
||||
},
|
||||
{
|
||||
name: "plan references non-existent repo",
|
||||
config: &v1.Config{
|
||||
Plans: []*v1.Plan{testPlan},
|
||||
},
|
||||
store: &CachingValidatingStore{ConfigStore: &YamlFileStore{Path: dir + "/invalid-config.yaml"}},
|
||||
wantErr: true,
|
||||
wantErrContains: "repo \"test-repo\" not found",
|
||||
},
|
||||
{
|
||||
name: "repo with duplicate id",
|
||||
config: &v1.Config{
|
||||
Repos: []*v1.Repo{
|
||||
testRepo,
|
||||
testRepo,
|
||||
},
|
||||
},
|
||||
store: &CachingValidatingStore{ConfigStore: &YamlFileStore{Path: dir + "/invalid-config2.yaml"}},
|
||||
wantErr: true,
|
||||
wantErrContains: "repo test-repo: duplicate id",
|
||||
},
|
||||
{
|
||||
name: "plan with bad cron",
|
||||
config: &v1.Config{
|
||||
Repos: []*v1.Repo{
|
||||
testRepo,
|
||||
},
|
||||
Plans: []*v1.Plan{
|
||||
{
|
||||
Id: "test-plan",
|
||||
Repo: "test-repo",
|
||||
Paths: []string{"/tmp/foo"},
|
||||
Cron: "bad cron",
|
||||
},
|
||||
},
|
||||
},
|
||||
store: &CachingValidatingStore{ConfigStore: &YamlFileStore{Path: dir + "/invalid-config3.yaml"}},
|
||||
wantErr: true,
|
||||
wantErrContains: "invalid cron \"bad cron\"",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
err := tc.store.Update(tc.config)
|
||||
if (err != nil) != tc.wantErr {
|
||||
t.Errorf("Config.Update() error = %v, wantErr %v", err, tc.wantErr)
|
||||
}
|
||||
|
||||
if tc.wantErrContains != "" && (err == nil || !strings.Contains(err.Error(), tc.wantErrContains)) {
|
||||
t.Errorf("Config.Update() error = %v, wantErrContains %v", err, tc.wantErrContains)
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
config, err := tc.store.Get()
|
||||
if err != nil {
|
||||
t.Errorf("Config.Get() error = %v, wantErr nil", err)
|
||||
}
|
||||
|
||||
if !proto.Equal(config, tc.config) {
|
||||
t.Errorf("Config.Get() = %v, want %v", config, tc.config)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"github.com/hashicorp/go-multierror"
|
||||
)
|
||||
|
||||
func validateConfig(c *v1.Config) error {
|
||||
func ValidateConfig(c *v1.Config) error {
|
||||
var err error
|
||||
repos := make(map[string]*v1.Repo)
|
||||
if c.Repos != nil {
|
||||
@@ -19,15 +19,17 @@ func validateConfig(c *v1.Config) error {
|
||||
if e := validateRepo(repo); e != nil {
|
||||
err = multierror.Append(e, fmt.Errorf("repo %s: %w", repo.GetId(), err))
|
||||
}
|
||||
if _, ok := repos[repo.GetId()]; ok {
|
||||
err = multierror.Append(err, fmt.Errorf("repo %s: duplicate id", repo.GetId()))
|
||||
}
|
||||
repos[repo.GetId()] = repo
|
||||
}
|
||||
}
|
||||
|
||||
if c.Plans != nil {
|
||||
for _, plan := range c.Plans {
|
||||
err := validatePlan(plan, repos);
|
||||
if err != nil {
|
||||
err = multierror.Append(err, fmt.Errorf("plan %s: %w", plan.GetId(), err))
|
||||
if e := validatePlan(plan, repos); e != nil {
|
||||
err = multierror.Append(err, fmt.Errorf("plan %s: %w", plan.GetId(), e))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -73,7 +75,7 @@ func validatePlan(plan *v1.Plan, repos map[string]*v1.Repo) error {
|
||||
}
|
||||
|
||||
|
||||
if _, e := cronexpr.Parse(plan.GetCron()); err != nil {
|
||||
if _, e := cronexpr.Parse(plan.GetCron()); e != nil {
|
||||
err = multierror.Append(err, fmt.Errorf("invalid cron %q: %w", plan.GetCron(), e))
|
||||
}
|
||||
|
||||
|
||||
@@ -17,31 +17,22 @@ import (
|
||||
type YamlFileStore struct {
|
||||
Path string
|
||||
mu sync.Mutex
|
||||
config *v1.Config
|
||||
}
|
||||
|
||||
var _ ConfigStore = &YamlFileStore{}
|
||||
|
||||
func (f *YamlFileStore) Get() (*v1.Config, error) {
|
||||
f.mu.Lock()
|
||||
|
||||
if f.config != nil {
|
||||
f.mu.Unlock()
|
||||
return f.config, nil
|
||||
}
|
||||
defer f.mu.Unlock()
|
||||
|
||||
data, err := os.ReadFile(f.Path)
|
||||
if err != nil {
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
f.config = NewDefaultConfig()
|
||||
f.mu.Unlock()
|
||||
f.Update(f.config)
|
||||
return f.config, nil
|
||||
return nil, ErrConfigNotFound
|
||||
}
|
||||
return nil, fmt.Errorf("failed to read config file: %w", err)
|
||||
}
|
||||
|
||||
defer f.mu.Unlock()
|
||||
|
||||
data, err = yamlToJson(data)
|
||||
if err != nil {
|
||||
@@ -54,19 +45,18 @@ func (f *YamlFileStore) Get() (*v1.Config, error) {
|
||||
return nil, fmt.Errorf("failed to unmarshal config: %w", err)
|
||||
}
|
||||
|
||||
if err := validateConfig(&config); err != nil {
|
||||
if err := ValidateConfig(&config); err != nil {
|
||||
return nil, fmt.Errorf("invalid config: %w", err)
|
||||
}
|
||||
|
||||
f.config = &config
|
||||
return f.config, nil
|
||||
return &config, nil
|
||||
}
|
||||
|
||||
func (f *YamlFileStore) Update(config *v1.Config) error {
|
||||
f.mu.Lock()
|
||||
defer f.mu.Unlock()
|
||||
|
||||
if err := validateConfig(config); err != nil {
|
||||
if err := ValidateConfig(config); err != nil {
|
||||
return fmt.Errorf("invalid config: %w", err)
|
||||
}
|
||||
|
||||
@@ -90,7 +80,6 @@ func (f *YamlFileStore) Update(config *v1.Config) error {
|
||||
return fmt.Errorf("failed to write config file: %w", err)
|
||||
}
|
||||
|
||||
f.config = config
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
121
internal/orchestrator/orchestrator.go
Normal file
121
internal/orchestrator/orchestrator.go
Normal file
@@ -0,0 +1,121 @@
|
||||
package orchestrator
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
v1 "github.com/garethgeorge/resticui/gen/go/v1"
|
||||
"github.com/garethgeorge/resticui/internal/config"
|
||||
"github.com/garethgeorge/resticui/pkg/restic"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
var ErrRepoNotFound = errors.New("repo not found")
|
||||
var ErrRepoInitializationFailed = errors.New("repo initialization failed")
|
||||
var ErrPlanNotFound = errors.New("plan not found")
|
||||
|
||||
|
||||
|
||||
// Orchestrator is responsible for managing repos and backups.
|
||||
type Orchestrator struct {
|
||||
configProvider config.ConfigStore
|
||||
repoPool *resticRepoPool
|
||||
}
|
||||
|
||||
func NewOrchestrator(configProvider config.ConfigStore) *Orchestrator {
|
||||
return &Orchestrator{
|
||||
configProvider: configProvider,
|
||||
repoPool: newResticRepoPool(configProvider),
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Orchestrator) GetRepo(repoId string) (repo *RepoOrchestrator, err error) {
|
||||
r, err := o.repoPool.GetRepo(repoId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get repo %q: %w", repoId, err)
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func (o *Orchestrator) GetPlan(planId string) (*v1.Plan, error) {
|
||||
cfg, err := o.configProvider.Get()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get config: %w", err)
|
||||
}
|
||||
|
||||
if cfg.Plans == nil {
|
||||
return nil, ErrPlanNotFound
|
||||
}
|
||||
|
||||
for _, p := range cfg.Plans {
|
||||
if p.Id == planId {
|
||||
return p, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, ErrPlanNotFound
|
||||
}
|
||||
|
||||
// resticRepoPool caches restic repos.
|
||||
type resticRepoPool struct {
|
||||
mu sync.Mutex
|
||||
repos map[string]*RepoOrchestrator
|
||||
configProvider config.ConfigStore
|
||||
}
|
||||
|
||||
|
||||
func newResticRepoPool(configProvider config.ConfigStore) *resticRepoPool {
|
||||
return &resticRepoPool{
|
||||
repos: make(map[string]*RepoOrchestrator),
|
||||
configProvider: configProvider,
|
||||
}
|
||||
}
|
||||
|
||||
func (rp *resticRepoPool) GetRepo(repoId string) (repo *RepoOrchestrator, err error) {
|
||||
cfg, err := rp.configProvider.Get()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get config: %w", err)
|
||||
}
|
||||
|
||||
rp.mu.Lock()
|
||||
defer rp.mu.Unlock()
|
||||
|
||||
if cfg.Repos == nil {
|
||||
return nil, ErrRepoNotFound
|
||||
}
|
||||
|
||||
var repoProto *v1.Repo
|
||||
for _, r := range cfg.Repos {
|
||||
if r.GetId() == repoId {
|
||||
repoProto = r
|
||||
}
|
||||
}
|
||||
|
||||
if repoProto == nil {
|
||||
return nil, ErrRepoNotFound
|
||||
}
|
||||
|
||||
// Check if we already have a repo for this id, if we do return it.
|
||||
repo, ok := rp.repos[repoId]
|
||||
if ok && proto.Equal(repo.repoConfig, repoProto) {
|
||||
return repo, nil
|
||||
}
|
||||
delete(rp.repos, repoId);
|
||||
|
||||
var opts []restic.GenericOption
|
||||
if len(repoProto.GetEnv()) > 0 {
|
||||
opts = append(opts, restic.WithEnv(repoProto.GetEnv()...))
|
||||
}
|
||||
if len(repoProto.GetFlags()) > 0 {
|
||||
opts = append(opts, restic.WithFlags(repoProto.GetFlags()...))
|
||||
}
|
||||
|
||||
// Otherwise create a new repo.
|
||||
repo = &RepoOrchestrator{
|
||||
repoConfig: repoProto,
|
||||
repo: restic.NewRepo(repoProto, opts...),
|
||||
}
|
||||
rp.repos[repoId] = repo
|
||||
return repo, nil
|
||||
}
|
||||
108
internal/orchestrator/repo.go
Normal file
108
internal/orchestrator/repo.go
Normal file
@@ -0,0 +1,108 @@
|
||||
package orchestrator
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"slices"
|
||||
"sort"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
v1 "github.com/garethgeorge/resticui/gen/go/v1"
|
||||
"github.com/garethgeorge/resticui/pkg/restic"
|
||||
)
|
||||
|
||||
// RepoOrchestrator is responsible for managing a single repo.
|
||||
type RepoOrchestrator struct {
|
||||
mu sync.Mutex
|
||||
|
||||
repoConfig *v1.Repo
|
||||
repo *restic.Repo
|
||||
|
||||
snapshotsAge time.Time
|
||||
snapshots []*restic.Snapshot
|
||||
}
|
||||
|
||||
func (r *RepoOrchestrator) updateSnapshotsIfNeeded(ctx context.Context) error {
|
||||
if time.Since(r.snapshotsAge) > 10 * time.Minute {
|
||||
r.snapshots = nil
|
||||
}
|
||||
|
||||
if r.snapshots != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
snapshots, err := r.repo.Snapshots(ctx, restic.WithPropagatedEnvVars(restic.EnvToPropagate...))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update snapshots: %w", err)
|
||||
}
|
||||
|
||||
sort.SliceStable(snapshots, func(i, j int) bool {
|
||||
return snapshots[i].Time > snapshots[j].Time
|
||||
})
|
||||
|
||||
r.snapshots = snapshots
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *RepoOrchestrator) Snapshots(ctx context.Context) ([]*restic.Snapshot, error) {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
|
||||
if err := r.updateSnapshotsIfNeeded(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return r.snapshots, nil
|
||||
}
|
||||
|
||||
func (r *RepoOrchestrator) SnapshotsForPlan(ctx context.Context, plan *v1.Plan) ([]*restic.Snapshot, error) {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
|
||||
if err := r.updateSnapshotsIfNeeded(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return filterSnapshotsForPlan(r.snapshots, plan), nil
|
||||
}
|
||||
|
||||
func (r *RepoOrchestrator) Backup(ctx context.Context, plan *v1.Plan, progressCallback func(event *restic.BackupProgressEntry)) error {
|
||||
snapshots, err := r.SnapshotsForPlan(ctx, plan)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var opts []restic.BackupOption
|
||||
opts = append(opts, restic.WithBackupPaths(plan.Paths...))
|
||||
opts = append(opts, restic.WithBackupExcludes(plan.Excludes...))
|
||||
opts = append(opts, restic.WithBackupTags(tagForPlan(plan)))
|
||||
|
||||
if len(snapshots) > 0 {
|
||||
// TODO: design a test strategy to verify that the backup parent is used correctly.
|
||||
opts = append(opts, restic.WithBackupParent(snapshots[len(snapshots) - 1].Id))
|
||||
}
|
||||
|
||||
panic("not yet implemented")
|
||||
}
|
||||
|
||||
func filterSnapshotsForPlan(snapshots []*restic.Snapshot, plan *v1.Plan) []*restic.Snapshot {
|
||||
wantTag := tagForPlan(plan)
|
||||
var filtered []*restic.Snapshot
|
||||
for _, snapshot := range snapshots {
|
||||
if snapshot.Tags == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if slices.Contains(snapshot.Tags, wantTag) {
|
||||
filtered = append(filtered, snapshot)
|
||||
}
|
||||
}
|
||||
|
||||
return filtered
|
||||
}
|
||||
|
||||
func tagForPlan(plan *v1.Plan) string {
|
||||
return fmt.Sprintf("plan:%s", plan.Id)
|
||||
}
|
||||
@@ -7,6 +7,9 @@ import (
|
||||
"io"
|
||||
"os/exec"
|
||||
"slices"
|
||||
"time"
|
||||
|
||||
v1 "github.com/garethgeorge/resticui/gen/go/v1"
|
||||
)
|
||||
|
||||
type LsEntry struct {
|
||||
@@ -33,6 +36,23 @@ type Snapshot struct {
|
||||
Parent string `json:"parent"`
|
||||
}
|
||||
|
||||
func (s *Snapshot) ToProto() *v1.ResticSnapshot {
|
||||
t, err := time.Parse(time.RFC3339Nano, s.Time)
|
||||
if err != nil {
|
||||
t = time.Unix(0, 0)
|
||||
}
|
||||
return &v1.ResticSnapshot{
|
||||
Id: s.Id,
|
||||
UnixTimeMs: t.UnixMilli(),
|
||||
Tree: s.Tree,
|
||||
Paths: s.Paths,
|
||||
Hostname: s.Hostname,
|
||||
Username: s.Username,
|
||||
Tags: s.Tags,
|
||||
Parent: s.Parent,
|
||||
}
|
||||
}
|
||||
|
||||
type BackupProgressEntry struct {
|
||||
// Common fields
|
||||
MessageType string `json:"message_type"` // "summary" or "status"
|
||||
|
||||
@@ -27,6 +27,7 @@ func TestReadBackupProgressEntries(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func TestReadLs(t *testing.T) {
|
||||
testInput := `{"time":"2023-11-10T19:14:17.053824063-08:00","tree":"3e2918b261948e69602ee9504b8f475bcc7cdc4dcec0b3f34ecdb014287d07b2","paths":["/resticui"],"hostname":"pop-os","username":"dontpanic","uid":1000,"gid":1000,"id":"db155169d788e6e432e320aedbdff5a54cc439653093bb56944a67682528aa52","short_id":"db155169","struct_type":"snapshot"}
|
||||
{"name":".git","type":"dir","path":"/.git","uid":1000,"gid":1000,"mode":2147484157,"mtime":"2023-11-10T18:32:38.156599473-08:00","atime":"2023-11-10T18:32:38.156599473-08:00","ctime":"2023-11-10T18:32:38.156599473-08:00","struct_type":"node"}
|
||||
@@ -46,3 +47,40 @@ func TestReadLs(t *testing.T) {
|
||||
t.Errorf("wanted 3 entries, got: %d", len(entries))
|
||||
}
|
||||
}
|
||||
|
||||
func TestSnapshotToProto(t *testing.T) {
|
||||
snapshot := &Snapshot{
|
||||
Id: "db155169d788e6e432e320aedbdff5a54cc439653093bb56944a67682528aa52",
|
||||
Time: "2023-11-10T19:14:17.053824063-08:00",
|
||||
Tree: "3e2918b261948e69602ee9504b8f475bcc7cdc4dcec0b3f34ecdb014287d07b2",
|
||||
Paths: []string{"/resticui"},
|
||||
Hostname: "pop-os",
|
||||
Username: "dontpanic",
|
||||
Tags: []string{},
|
||||
Parent: "",
|
||||
}
|
||||
|
||||
proto := snapshot.ToProto()
|
||||
|
||||
if proto.Id != snapshot.Id {
|
||||
t.Errorf("wanted id %q, got: %q", snapshot.Id, proto.Id)
|
||||
}
|
||||
if proto.Tree != snapshot.Tree {
|
||||
t.Errorf("wanted tree %q, got: %q", snapshot.Tree, proto.Tree)
|
||||
}
|
||||
if proto.Hostname != snapshot.Hostname {
|
||||
t.Errorf("wanted hostname %q, got: %q", snapshot.Hostname, proto.Hostname)
|
||||
}
|
||||
if proto.Username != snapshot.Username {
|
||||
t.Errorf("wanted username %q, got: %q", snapshot.Username, proto.Username)
|
||||
}
|
||||
if len(proto.Tags) != len(snapshot.Tags) {
|
||||
t.Errorf("wanted %d tags, got: %d", len(snapshot.Tags), len(proto.Tags))
|
||||
}
|
||||
if proto.Parent != snapshot.Parent {
|
||||
t.Errorf("wanted parent %q, got: %q", snapshot.Parent, proto.Parent)
|
||||
}
|
||||
if proto.UnixTimeMs != 1699672457053 {
|
||||
t.Errorf("wanted unix time %d, got: %d", 1699672457053, proto.UnixTimeMs)
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
v1 "github.com/garethgeorge/resticui/gen/go/v1"
|
||||
@@ -25,6 +26,7 @@ type Repo struct {
|
||||
extraEnv []string
|
||||
}
|
||||
|
||||
// NewRepo instantiates a new repository. TODO: should not accept a v1.Repo
|
||||
func NewRepo(repo *v1.Repo, opts ...GenericOption) *Repo {
|
||||
opt := &GenericOpts{}
|
||||
for _, o := range opts {
|
||||
@@ -63,8 +65,10 @@ func (r *Repo) init(ctx context.Context) error {
|
||||
cmd.Env = append(cmd.Env, r.buildEnv()...)
|
||||
|
||||
if output, err := cmd.CombinedOutput(); err != nil {
|
||||
if !strings.Contains(string(output), "config file already exists") {
|
||||
return NewCmdError(cmd, output, err)
|
||||
}
|
||||
}
|
||||
|
||||
r.initialized = true
|
||||
return nil
|
||||
@@ -242,6 +246,12 @@ func WithBackupTags(tags ...string) BackupOption {
|
||||
}
|
||||
}
|
||||
|
||||
func WithBackupParent(parent string) BackupOption {
|
||||
return func(opts *BackupOpts) {
|
||||
opts.extraArgs = append(opts.extraArgs, "--parent", parent)
|
||||
}
|
||||
}
|
||||
|
||||
type GenericOpts struct {
|
||||
extraArgs []string
|
||||
extraEnv []string
|
||||
|
||||
@@ -140,6 +140,13 @@ func TestSnapshot(t *testing.T) {
|
||||
if len(snapshots) != tc.count {
|
||||
t.Errorf("wanted %d snapshots, got: %d", tc.count, len(snapshots))
|
||||
}
|
||||
|
||||
// Ensure that snapshot timestamps are set, this is critical for correct ordering in the orchestrator.
|
||||
for _, snapshot := range snapshots {
|
||||
if p := snapshot.ToProto(); p.UnixTimeMs == 0 {
|
||||
t.Errorf("wanted snapshot time to be non-zero, got: %v", p.UnixTimeMs)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,14 +5,15 @@ package v1;
|
||||
option go_package = "github.com/garethgeorge/resticui/go/proto/v1";
|
||||
|
||||
message Config {
|
||||
int32 version = 1;
|
||||
repeated Repo repos = 3 [json_name="repos"];
|
||||
repeated Plan plans = 4 [json_name="plans"];
|
||||
}
|
||||
// modification number, used for read-modify-write consistency in the UI. Incremented on every write.
|
||||
int32 modno = 1 [json_name="modno"];
|
||||
|
||||
message User {
|
||||
string name = 1;
|
||||
string password = 2; // plaintext password
|
||||
// override the hostname tagged on backups. If provided it will be used in addition to tags to group backups.
|
||||
string host_override = 2 [json_name="host_override"];
|
||||
|
||||
repeated Repo repos = 3 [json_name="repos"];
|
||||
|
||||
repeated Plan plans = 4 [json_name="plans"];
|
||||
}
|
||||
|
||||
message Repo {
|
||||
|
||||
@@ -6,22 +6,22 @@ option go_package = "github.com/garethgeorge/resticui/go/proto/v1";
|
||||
|
||||
message Event {
|
||||
// timestamp is the number of milliseconds since the Unix epoch.
|
||||
int64 timestamp = 1 [json_name="timestamp"];
|
||||
int64 timestamp = 1;
|
||||
|
||||
oneof event {
|
||||
LogEvent log = 3 [json_name="log"];
|
||||
BackupStatusEvent backup_status_change = 4 [json_name="backup_status"];
|
||||
LogEvent log = 3;
|
||||
BackupStatusEvent backup_status_change = 4;
|
||||
}
|
||||
}
|
||||
|
||||
message LogEvent {
|
||||
string message = 1 [json_name="message"];
|
||||
string message = 1;
|
||||
}
|
||||
|
||||
message BackupStatusEvent {
|
||||
string plan = 1 [json_name="plan"];
|
||||
Status status = 2 [json_name="status"];
|
||||
uint32 percent = 3 [json_name="percent"];
|
||||
string plan = 1;
|
||||
Status status = 2;
|
||||
uint32 percent = 3;
|
||||
}
|
||||
|
||||
enum Status {
|
||||
|
||||
@@ -5,43 +5,47 @@ package v1;
|
||||
option go_package = "github.com/garethgeorge/resticui/go/proto/v1";
|
||||
|
||||
message ResticSnapshot {
|
||||
string id = 1 [json_name = "id"];
|
||||
int64 unix_time_ms = 2 [json_name = "time"];
|
||||
string hostname = 3 [json_name = "hostname"];
|
||||
string username = 4 [json_name = "username"];
|
||||
string tree = 5 [json_name = "tree"]; // tree hash
|
||||
string parent = 6 [json_name = "parent"]; // parent snapshot's id
|
||||
repeated string paths = 7 [json_name = "paths"];
|
||||
repeated string tags = 8 [json_name = "tags"];
|
||||
string id = 1;
|
||||
int64 unix_time_ms = 2;
|
||||
string hostname = 3;
|
||||
string username = 4;
|
||||
string tree = 5; // tree hash
|
||||
string parent = 6; // parent snapshot's id
|
||||
repeated string paths = 7;
|
||||
repeated string tags = 8;
|
||||
}
|
||||
|
||||
message ResticSnapshotList {
|
||||
repeated ResticSnapshot snapshots = 1;
|
||||
}
|
||||
|
||||
message BackupProgressEntry {
|
||||
oneof entry {
|
||||
BackupProgressStatusEntry status = 1 [json_name = "status"];
|
||||
BackupProgressSummary summary = 2 [json_name = "summary"];
|
||||
BackupProgressStatusEntry status = 1;
|
||||
BackupProgressSummary summary = 2;
|
||||
}
|
||||
}
|
||||
|
||||
message BackupProgressStatusEntry {
|
||||
double percent_done = 1 [json_name = "percent"]; // 0.0 - 1.0
|
||||
int64 total_files = 2 [json_name = "total_files"];
|
||||
int64 total_bytes = 3 [json_name = "total_bytes"];
|
||||
int64 files_done = 4 [json_name = "files_done"];
|
||||
int64 bytes_done = 5 [json_name = "bytes_done"];
|
||||
double percent_done = 1; // 0.0 - 1.0
|
||||
int64 total_files = 2;
|
||||
int64 total_bytes = 3;
|
||||
int64 files_done = 4;
|
||||
int64 bytes_done = 5;
|
||||
}
|
||||
|
||||
message BackupProgressSummary {
|
||||
int64 files_new = 1 [json_name = "files_new"];
|
||||
int64 files_changed = 2 [json_name = "files_changed"];
|
||||
int64 files_unmodified = 3 [json_name = "files_unmodified"];
|
||||
int64 dirs_new = 4 [json_name = "dirs_new"];
|
||||
int64 dirs_changed = 5 [json_name = "dirs_changed"];
|
||||
int64 dirs_unmodified = 6 [json_name = "dirs_unmodified"];
|
||||
int64 data_blobs = 7 [json_name = "data_blobs"];
|
||||
int64 tree_blobs = 8 [json_name = "tree_blobs"];
|
||||
int64 data_added = 9 [json_name = "data_added"];
|
||||
int64 total_files_processed = 10 [json_name = "total_files_processed"];
|
||||
int64 total_bytes_processed = 11 [json_name = "total_bytes_processed"];
|
||||
int64 total_duration = 12 [json_name = "total_duration"];
|
||||
string snapshot_id = 13 [json_name = "snapshot_id"];
|
||||
int64 files_new = 1;
|
||||
int64 files_changed = 2;
|
||||
int64 files_unmodified = 3;
|
||||
int64 dirs_new = 4;
|
||||
int64 dirs_changed = 5;
|
||||
int64 dirs_unmodified = 6;
|
||||
int64 data_blobs = 7;
|
||||
int64 tree_blobs = 8;
|
||||
int64 data_added = 9;
|
||||
int64 total_files_processed = 10;
|
||||
int64 total_bytes_processed = 11;
|
||||
int64 total_duration = 12;
|
||||
string snapshot_id = 13;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ option go_package = "github.com/garethgeorge/resticui/go/proto/v1";
|
||||
|
||||
import "v1/config.proto";
|
||||
import "v1/events.proto";
|
||||
import "v1/restic.proto";
|
||||
import "types/value.proto";
|
||||
import "google/protobuf/empty.proto";
|
||||
import "google/api/annotations.proto";
|
||||
@@ -37,6 +38,13 @@ service ResticUI {
|
||||
};
|
||||
}
|
||||
|
||||
rpc ListSnapshots(ListSnapshotsRequest) returns (ResticSnapshotList) {
|
||||
option (google.api.http) = {
|
||||
post: "/v1/snapshots"
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
|
||||
rpc PathAutocomplete (types.StringValue) returns (types.StringList) {
|
||||
option (google.api.http) = {
|
||||
post: "/v1/autocomplete/path"
|
||||
@@ -44,3 +52,8 @@ service ResticUI {
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
message ListSnapshotsRequest {
|
||||
string repo_id = 1;
|
||||
string plan_id = 2;
|
||||
}
|
||||
|
||||
@@ -4,16 +4,12 @@
|
||||
* This file is a generated Typescript file for GRPC Gateway, DO NOT MODIFY
|
||||
*/
|
||||
export type Config = {
|
||||
version?: number
|
||||
modno?: number
|
||||
hostOverride?: string
|
||||
repos?: Repo[]
|
||||
plans?: Plan[]
|
||||
}
|
||||
|
||||
export type User = {
|
||||
name?: string
|
||||
password?: string
|
||||
}
|
||||
|
||||
export type Repo = {
|
||||
id?: string
|
||||
uri?: string
|
||||
|
||||
@@ -23,6 +23,10 @@ export type ResticSnapshot = {
|
||||
tags?: string[]
|
||||
}
|
||||
|
||||
export type ResticSnapshotList = {
|
||||
snapshots?: ResticSnapshot[]
|
||||
}
|
||||
|
||||
|
||||
type BaseBackupProgressEntry = {
|
||||
}
|
||||
|
||||
@@ -9,6 +9,12 @@ import * as GoogleProtobufEmpty from "../google/protobuf/empty.pb"
|
||||
import * as TypesValue from "../types/value.pb"
|
||||
import * as V1Config from "./config.pb"
|
||||
import * as V1Events from "./events.pb"
|
||||
import * as V1Restic from "./restic.pb"
|
||||
export type ListSnapshotsRequest = {
|
||||
repoId?: string
|
||||
planId?: string
|
||||
}
|
||||
|
||||
export class ResticUI {
|
||||
static GetConfig(req: GoogleProtobufEmpty.Empty, initReq?: fm.InitReq): Promise<V1Config.Config> {
|
||||
return fm.fetchReq<GoogleProtobufEmpty.Empty, V1Config.Config>(`/v1/config?${fm.renderURLSearchParams(req, [])}`, {...initReq, method: "GET"})
|
||||
@@ -22,6 +28,9 @@ export class ResticUI {
|
||||
static GetEvents(req: GoogleProtobufEmpty.Empty, entityNotifier?: fm.NotifyStreamEntityArrival<V1Events.Event>, initReq?: fm.InitReq): Promise<void> {
|
||||
return fm.fetchStreamingRequest<GoogleProtobufEmpty.Empty, V1Events.Event>(`/v1/events?${fm.renderURLSearchParams(req, [])}`, entityNotifier, {...initReq, method: "GET"})
|
||||
}
|
||||
static ListSnapshots(req: ListSnapshotsRequest, initReq?: fm.InitReq): Promise<V1Restic.ResticSnapshotList> {
|
||||
return fm.fetchReq<ListSnapshotsRequest, V1Restic.ResticSnapshotList>(`/v1/snapshots`, {...initReq, method: "POST", body: JSON.stringify(req, fm.replacer)})
|
||||
}
|
||||
static PathAutocomplete(req: TypesValue.StringValue, initReq?: fm.InitReq): Promise<TypesValue.StringList> {
|
||||
return fm.fetchReq<TypesValue.StringValue, TypesValue.StringList>(`/v1/autocomplete/path`, {...initReq, method: "POST", body: JSON.stringify(req, fm.replacer)})
|
||||
}
|
||||
|
||||
@@ -5,7 +5,9 @@ import { StringList } from "../../gen/ts/types/value.pb";
|
||||
|
||||
let timeout: NodeJS.Timeout | undefined = undefined;
|
||||
|
||||
export const URIAutocomplete = (props: React.PropsWithChildren) => {
|
||||
export const URIAutocomplete = (
|
||||
props: React.PropsWithChildren<{ disabled: boolean }>
|
||||
) => {
|
||||
const [value, setValue] = useState("");
|
||||
const [options, setOptions] = useState<{ value: string }[]>([]);
|
||||
const [showOptions, setShowOptions] = useState<{ value: string }[]>([]);
|
||||
|
||||
@@ -17,7 +17,7 @@ export const addRepo = async (repo: Repo): Promise<Config> => {
|
||||
});
|
||||
};
|
||||
|
||||
export const setConfig = async (config: Config): Promise<Config> => {
|
||||
export const updateConfig = async (config: Config): Promise<Config> => {
|
||||
return await ResticUI.SetConfig(config, {
|
||||
pathPrefix: "/api/",
|
||||
});
|
||||
|
||||
@@ -14,20 +14,26 @@ import { URIAutocomplete } from "../components/URIAutocomplete";
|
||||
import { MinusCircleOutlined, PlusOutlined } from "@ant-design/icons";
|
||||
import { useAlertApi } from "../components/Alerts";
|
||||
import { ResticUI } from "../../gen/ts/v1/service.pb";
|
||||
import {
|
||||
addRepo,
|
||||
configState,
|
||||
fetchConfig,
|
||||
updateConfig,
|
||||
} from "../state/config";
|
||||
import { useRecoilState, useSetRecoilState } from "recoil";
|
||||
|
||||
export const AddRepoModel = ({
|
||||
template,
|
||||
}: {
|
||||
template: Partial<Repo> | null;
|
||||
}) => {
|
||||
const setConfig = useSetRecoilState(configState);
|
||||
const [confirmLoading, setConfirmLoading] = useState(false);
|
||||
const showModal = useShowModal();
|
||||
const alertsApi = useAlertApi()!;
|
||||
const [form] = Form.useForm<Repo>();
|
||||
|
||||
template = template || {};
|
||||
|
||||
const handleOk = () => {
|
||||
const handleOk = async () => {
|
||||
const errors = form
|
||||
.getFieldsError()
|
||||
.map((e) => e.errors)
|
||||
@@ -40,22 +46,43 @@ export const AddRepoModel = ({
|
||||
|
||||
const repo = form.getFieldsValue() as Repo;
|
||||
|
||||
if (template === null) {
|
||||
if (template !== null) {
|
||||
// We are in the edit repo flow, update the repo in the config
|
||||
try {
|
||||
let config = await fetchConfig();
|
||||
const idx = config.repos!.findIndex((r) => r.id === template!.id);
|
||||
if (idx === -1) {
|
||||
alertsApi.error("Can't update repo, not found");
|
||||
return;
|
||||
}
|
||||
config.repos![idx] = { ...repo };
|
||||
setConfig(await updateConfig(config));
|
||||
showModal(null);
|
||||
alertsApi.success("Updated repo " + repo.uri);
|
||||
|
||||
// Update the snapshots for the repo
|
||||
await ResticUI.ListSnapshots(
|
||||
{
|
||||
repoId: repo.id,
|
||||
},
|
||||
{ pathPrefix: "/api" }
|
||||
);
|
||||
} catch (e: any) {
|
||||
alertsApi.error("Error updating repo: " + e.message, 15);
|
||||
} finally {
|
||||
setConfirmLoading(false);
|
||||
}
|
||||
} else {
|
||||
// We are in the create repo flow, create the new repo via the service
|
||||
ResticUI.AddRepo(repo, {
|
||||
pathPrefix: "/api",
|
||||
})
|
||||
.then((res) => {
|
||||
try {
|
||||
setConfig(await addRepo(repo));
|
||||
showModal(null);
|
||||
alertsApi.success("Added repo " + repo.uri);
|
||||
})
|
||||
.catch((e) => {
|
||||
} catch (e: any) {
|
||||
alertsApi.error("Error adding repo: " + e.message, 15);
|
||||
})
|
||||
.finally(() => {
|
||||
} finally {
|
||||
setConfirmLoading(false);
|
||||
});
|
||||
} else {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -67,7 +94,7 @@ export const AddRepoModel = ({
|
||||
<>
|
||||
<Modal
|
||||
open={true}
|
||||
title={template ? "Add Restic Repository" : "Edit Restic Repository"}
|
||||
title={template ? "Edit Restic Repository" : "Add Restic Repository"}
|
||||
onOk={handleOk}
|
||||
confirmLoading={confirmLoading}
|
||||
onCancel={handleCancel}
|
||||
@@ -78,7 +105,7 @@ export const AddRepoModel = ({
|
||||
hasFeedback
|
||||
name="id"
|
||||
label="Repo Name"
|
||||
initialValue={template.id}
|
||||
initialValue={template && template.id}
|
||||
validateTrigger={["onChange", "onBlur"]}
|
||||
rules={[
|
||||
{
|
||||
@@ -91,7 +118,7 @@ export const AddRepoModel = ({
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Input />
|
||||
<Input disabled={!!template} />
|
||||
</Form.Item>
|
||||
|
||||
{/* Repo.uri */}
|
||||
@@ -118,8 +145,8 @@ export const AddRepoModel = ({
|
||||
<Form.Item<Repo>
|
||||
hasFeedback
|
||||
name="uri"
|
||||
label="Repo URI"
|
||||
initialValue={template.id}
|
||||
label="Repository URI (e.g. ./local-path or s3://bucket-name/path)"
|
||||
initialValue={template && template.uri}
|
||||
validateTrigger={["onChange", "onBlur"]}
|
||||
rules={[
|
||||
{
|
||||
@@ -128,7 +155,7 @@ export const AddRepoModel = ({
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Input />
|
||||
<URIAutocomplete disabled={!!template} />
|
||||
</Form.Item>
|
||||
</Tooltip>
|
||||
|
||||
@@ -137,7 +164,7 @@ export const AddRepoModel = ({
|
||||
hasFeedback
|
||||
name="password"
|
||||
label="Password"
|
||||
initialValue={template.password}
|
||||
initialValue={template && template.password}
|
||||
validateTrigger={["onChange", "onBlur"]}
|
||||
rules={[
|
||||
{
|
||||
@@ -150,7 +177,7 @@ export const AddRepoModel = ({
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Input />
|
||||
<Input disabled={!!template} />
|
||||
</Form.Item>
|
||||
|
||||
{/* Repo.env */}
|
||||
@@ -164,7 +191,7 @@ export const AddRepoModel = ({
|
||||
},
|
||||
},
|
||||
]}
|
||||
initialValue={[]}
|
||||
initialValue={(template && template.env) || undefined}
|
||||
>
|
||||
{(fields, { add, remove }, { errors }) => (
|
||||
<>
|
||||
|
||||
@@ -11,7 +11,7 @@ import { configState, fetchConfig } from "../state/config";
|
||||
import { useRecoilState } from "recoil";
|
||||
import { Config } from "../../gen/ts/v1/config.pb";
|
||||
import { AlertContextProvider, useAlertApi } from "../components/Alerts";
|
||||
import { useShowModal, useShowSpinner } from "../components/ModalManager";
|
||||
import { useShowModal } from "../components/ModalManager";
|
||||
import { AddPlanModal } from "./AddPlanModel";
|
||||
import { AddRepoModel } from "./AddRepoModel";
|
||||
|
||||
@@ -41,6 +41,7 @@ export const App: React.FC = () => {
|
||||
});
|
||||
}, []);
|
||||
|
||||
console.log("rerender config ", config);
|
||||
const items = getSidenavItems(config);
|
||||
|
||||
return (
|
||||
|
||||
@@ -2,8 +2,7 @@ package static
|
||||
|
||||
import (
|
||||
"embed"
|
||||
_ "embed"
|
||||
)
|
||||
|
||||
//go:embed *
|
||||
//go:embed dist/*.js dist/*.css dist/*.html
|
||||
var FS embed.FS
|
||||
Reference in New Issue
Block a user