mirror of
https://github.com/garethgeorge/backrest.git
synced 2025-12-14 17:45:36 +00:00
Add webui
This commit is contained in:
2
.github/workflows/build-and-test.yml
vendored
2
.github/workflows/build-and-test.yml
vendored
@@ -23,7 +23,7 @@ jobs:
|
|||||||
go-version: '1.20'
|
go-version: '1.20'
|
||||||
|
|
||||||
- name: Restic
|
- name: Restic
|
||||||
run: apt install restic
|
run: sudo apt install -y restic
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: go build -v ./...
|
run: go build -v ./...
|
||||||
|
|||||||
@@ -91,6 +91,61 @@ func (x *Config) GetPlans() []*Plan {
|
|||||||
return nil
|
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 {
|
type Repo struct {
|
||||||
state protoimpl.MessageState
|
state protoimpl.MessageState
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
@@ -105,7 +160,7 @@ type Repo struct {
|
|||||||
func (x *Repo) Reset() {
|
func (x *Repo) Reset() {
|
||||||
*x = Repo{}
|
*x = Repo{}
|
||||||
if protoimpl.UnsafeEnabled {
|
if protoimpl.UnsafeEnabled {
|
||||||
mi := &file_v1_config_proto_msgTypes[1]
|
mi := &file_v1_config_proto_msgTypes[2]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@@ -118,7 +173,7 @@ func (x *Repo) String() string {
|
|||||||
func (*Repo) ProtoMessage() {}
|
func (*Repo) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *Repo) ProtoReflect() protoreflect.Message {
|
func (x *Repo) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_v1_config_proto_msgTypes[1]
|
mi := &file_v1_config_proto_msgTypes[2]
|
||||||
if protoimpl.UnsafeEnabled && x != nil {
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@@ -131,7 +186,7 @@ func (x *Repo) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use Repo.ProtoReflect.Descriptor instead.
|
// Deprecated: Use Repo.ProtoReflect.Descriptor instead.
|
||||||
func (*Repo) Descriptor() ([]byte, []int) {
|
func (*Repo) Descriptor() ([]byte, []int) {
|
||||||
return file_v1_config_proto_rawDescGZIP(), []int{1}
|
return file_v1_config_proto_rawDescGZIP(), []int{2}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *Repo) GetId() string {
|
func (x *Repo) GetId() string {
|
||||||
@@ -167,16 +222,15 @@ type Plan struct {
|
|||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||||
Repo string `protobuf:"bytes,2,opt,name=repo,proto3" json:"repo,omitempty"`
|
Repo string `protobuf:"bytes,2,opt,name=repo,proto3" json:"repo,omitempty"`
|
||||||
RepoPath string `protobuf:"bytes,3,opt,name=repo_path,proto3" json:"repo_path,omitempty"` // subpath of the repo to backup to
|
Paths []string `protobuf:"bytes,4,rep,name=paths,proto3" json:"paths,omitempty"`
|
||||||
Paths []string `protobuf:"bytes,4,rep,name=paths,proto3" json:"paths,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *Plan) Reset() {
|
func (x *Plan) Reset() {
|
||||||
*x = Plan{}
|
*x = Plan{}
|
||||||
if protoimpl.UnsafeEnabled {
|
if protoimpl.UnsafeEnabled {
|
||||||
mi := &file_v1_config_proto_msgTypes[2]
|
mi := &file_v1_config_proto_msgTypes[3]
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
ms.StoreMessageInfo(mi)
|
ms.StoreMessageInfo(mi)
|
||||||
}
|
}
|
||||||
@@ -189,7 +243,7 @@ func (x *Plan) String() string {
|
|||||||
func (*Plan) ProtoMessage() {}
|
func (*Plan) ProtoMessage() {}
|
||||||
|
|
||||||
func (x *Plan) ProtoReflect() protoreflect.Message {
|
func (x *Plan) ProtoReflect() protoreflect.Message {
|
||||||
mi := &file_v1_config_proto_msgTypes[2]
|
mi := &file_v1_config_proto_msgTypes[3]
|
||||||
if protoimpl.UnsafeEnabled && x != nil {
|
if protoimpl.UnsafeEnabled && x != nil {
|
||||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
if ms.LoadMessageInfo() == nil {
|
if ms.LoadMessageInfo() == nil {
|
||||||
@@ -202,7 +256,7 @@ func (x *Plan) ProtoReflect() protoreflect.Message {
|
|||||||
|
|
||||||
// Deprecated: Use Plan.ProtoReflect.Descriptor instead.
|
// Deprecated: Use Plan.ProtoReflect.Descriptor instead.
|
||||||
func (*Plan) Descriptor() ([]byte, []int) {
|
func (*Plan) Descriptor() ([]byte, []int) {
|
||||||
return file_v1_config_proto_rawDescGZIP(), []int{2}
|
return file_v1_config_proto_rawDescGZIP(), []int{3}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *Plan) GetId() string {
|
func (x *Plan) GetId() string {
|
||||||
@@ -219,13 +273,6 @@ func (x *Plan) GetRepo() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *Plan) GetRepoPath() string {
|
|
||||||
if x != nil {
|
|
||||||
return x.RepoPath
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
func (x *Plan) GetPaths() []string {
|
func (x *Plan) GetPaths() []string {
|
||||||
if x != nil {
|
if x != nil {
|
||||||
return x.Paths
|
return x.Paths
|
||||||
@@ -245,22 +292,23 @@ var file_v1_config_proto_rawDesc = []byte{
|
|||||||
0x28, 0x0b, 0x32, 0x08, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x52, 0x05, 0x72, 0x65,
|
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,
|
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,
|
0x28, 0x0b, 0x32, 0x08, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x6c, 0x61, 0x6e, 0x52, 0x05, 0x70, 0x6c,
|
||||||
0x61, 0x6e, 0x73, 0x22, 0x56, 0x0a, 0x04, 0x52, 0x65, 0x70, 0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x69,
|
0x61, 0x6e, 0x73, 0x22, 0x36, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e,
|
||||||
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75,
|
0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12,
|
||||||
0x72, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x69, 0x12, 0x1a, 0x0a,
|
0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||||
0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
|
0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x56, 0x0a, 0x04, 0x52,
|
||||||
0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, 0x76,
|
0x65, 0x70, 0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||||
0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x65, 0x6e, 0x76, 0x22, 0x5e, 0x0a, 0x04, 0x50,
|
0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
|
||||||
0x6c, 0x61, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
|
0x52, 0x03, 0x75, 0x72, 0x69, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72,
|
||||||
0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28,
|
0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72,
|
||||||
0x09, 0x52, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x70, 0x6f, 0x5f,
|
0x64, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, 0x76, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x03,
|
||||||
0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x70, 0x6f,
|
0x65, 0x6e, 0x76, 0x22, 0x40, 0x0a, 0x04, 0x50, 0x6c, 0x61, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69,
|
||||||
0x5f, 0x70, 0x61, 0x74, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x68, 0x73, 0x18, 0x04,
|
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x72,
|
||||||
0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x70, 0x61, 0x74, 0x68, 0x73, 0x42, 0x2e, 0x5a, 0x2c, 0x67,
|
0x65, 0x70, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x12,
|
||||||
0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x61, 0x72, 0x65, 0x74, 0x68,
|
0x14, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x68, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05,
|
||||||
0x67, 0x65, 0x6f, 0x72, 0x67, 0x65, 0x2f, 0x72, 0x65, 0x73, 0x74, 0x69, 0x63, 0x75, 0x69, 0x2f,
|
0x70, 0x61, 0x74, 0x68, 0x73, 0x42, 0x2e, 0x5a, 0x2c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
|
||||||
0x67, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f,
|
0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x61, 0x72, 0x65, 0x74, 0x68, 0x67, 0x65, 0x6f, 0x72, 0x67, 0x65,
|
||||||
0x74, 0x6f, 0x33,
|
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 (
|
var (
|
||||||
@@ -275,15 +323,16 @@ func file_v1_config_proto_rawDescGZIP() []byte {
|
|||||||
return file_v1_config_proto_rawDescData
|
return file_v1_config_proto_rawDescData
|
||||||
}
|
}
|
||||||
|
|
||||||
var file_v1_config_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
|
var file_v1_config_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
|
||||||
var file_v1_config_proto_goTypes = []interface{}{
|
var file_v1_config_proto_goTypes = []interface{}{
|
||||||
(*Config)(nil), // 0: v1.Config
|
(*Config)(nil), // 0: v1.Config
|
||||||
(*Repo)(nil), // 1: v1.Repo
|
(*User)(nil), // 1: v1.User
|
||||||
(*Plan)(nil), // 2: v1.Plan
|
(*Repo)(nil), // 2: v1.Repo
|
||||||
|
(*Plan)(nil), // 3: v1.Plan
|
||||||
}
|
}
|
||||||
var file_v1_config_proto_depIdxs = []int32{
|
var file_v1_config_proto_depIdxs = []int32{
|
||||||
1, // 0: v1.Config.repos:type_name -> v1.Repo
|
2, // 0: v1.Config.repos:type_name -> v1.Repo
|
||||||
2, // 1: v1.Config.plans:type_name -> v1.Plan
|
3, // 1: v1.Config.plans:type_name -> v1.Plan
|
||||||
2, // [2:2] is the sub-list for method output_type
|
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 method input_type
|
||||||
2, // [2:2] is the sub-list for extension type_name
|
2, // [2:2] is the sub-list for extension type_name
|
||||||
@@ -310,7 +359,7 @@ func file_v1_config_proto_init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
file_v1_config_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
file_v1_config_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||||
switch v := v.(*Repo); i {
|
switch v := v.(*User); i {
|
||||||
case 0:
|
case 0:
|
||||||
return &v.state
|
return &v.state
|
||||||
case 1:
|
case 1:
|
||||||
@@ -322,6 +371,18 @@ func file_v1_config_proto_init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
file_v1_config_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
file_v1_config_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||||
|
switch v := v.(*Repo); i {
|
||||||
|
case 0:
|
||||||
|
return &v.state
|
||||||
|
case 1:
|
||||||
|
return &v.sizeCache
|
||||||
|
case 2:
|
||||||
|
return &v.unknownFields
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file_v1_config_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||||
switch v := v.(*Plan); i {
|
switch v := v.(*Plan); i {
|
||||||
case 0:
|
case 0:
|
||||||
return &v.state
|
return &v.state
|
||||||
@@ -340,7 +401,7 @@ func file_v1_config_proto_init() {
|
|||||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||||
RawDescriptor: file_v1_config_proto_rawDesc,
|
RawDescriptor: file_v1_config_proto_rawDesc,
|
||||||
NumEnums: 0,
|
NumEnums: 0,
|
||||||
NumMessages: 3,
|
NumMessages: 4,
|
||||||
NumExtensions: 0,
|
NumExtensions: 0,
|
||||||
NumServices: 0,
|
NumServices: 0,
|
||||||
},
|
},
|
||||||
|
|||||||
612
gen/go/v1/restic.pb.go
Normal file
612
gen/go/v1/restic.pb.go
Normal file
@@ -0,0 +1,612 @@
|
|||||||
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// protoc-gen-go v1.31.0
|
||||||
|
// protoc (unknown)
|
||||||
|
// source: v1/restic.proto
|
||||||
|
|
||||||
|
package v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||||
|
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||||
|
reflect "reflect"
|
||||||
|
sync "sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Verify that this generated code is sufficiently up-to-date.
|
||||||
|
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||||
|
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||||
|
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||||
|
)
|
||||||
|
|
||||||
|
type ResticSnapshot struct {
|
||||||
|
state protoimpl.MessageState
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
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"`
|
||||||
|
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
|
||||||
|
Parent string `protobuf:"bytes,6,opt,name=parent,proto3" json:"parent,omitempty"` // parent snapshot's id
|
||||||
|
Paths []string `protobuf:"bytes,7,rep,name=paths,proto3" json:"paths,omitempty"`
|
||||||
|
Tags []string `protobuf:"bytes,8,rep,name=tags,proto3" json:"tags,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *ResticSnapshot) Reset() {
|
||||||
|
*x = ResticSnapshot{}
|
||||||
|
if protoimpl.UnsafeEnabled {
|
||||||
|
mi := &file_v1_restic_proto_msgTypes[0]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *ResticSnapshot) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*ResticSnapshot) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *ResticSnapshot) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_v1_restic_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 ResticSnapshot.ProtoReflect.Descriptor instead.
|
||||||
|
func (*ResticSnapshot) Descriptor() ([]byte, []int) {
|
||||||
|
return file_v1_restic_proto_rawDescGZIP(), []int{0}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *ResticSnapshot) GetId() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Id
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *ResticSnapshot) GetUnixTimeMs() int64 {
|
||||||
|
if x != nil {
|
||||||
|
return x.UnixTimeMs
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *ResticSnapshot) GetHostname() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Hostname
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *ResticSnapshot) GetUsername() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Username
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *ResticSnapshot) GetTree() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Tree
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *ResticSnapshot) GetParent() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Parent
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *ResticSnapshot) GetPaths() []string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Paths
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *ResticSnapshot) GetTags() []string {
|
||||||
|
if x != nil {
|
||||||
|
return x.Tags
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type BackupProgressEntry struct {
|
||||||
|
state protoimpl.MessageState
|
||||||
|
sizeCache protoimpl.SizeCache
|
||||||
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
|
// Types that are assignable to Entry:
|
||||||
|
//
|
||||||
|
// *BackupProgressEntry_Status
|
||||||
|
// *BackupProgressEntry_Summary
|
||||||
|
Entry isBackupProgressEntry_Entry `protobuf_oneof:"entry"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *BackupProgressEntry) Reset() {
|
||||||
|
*x = BackupProgressEntry{}
|
||||||
|
if protoimpl.UnsafeEnabled {
|
||||||
|
mi := &file_v1_restic_proto_msgTypes[1]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *BackupProgressEntry) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*BackupProgressEntry) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *BackupProgressEntry) 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 BackupProgressEntry.ProtoReflect.Descriptor instead.
|
||||||
|
func (*BackupProgressEntry) Descriptor() ([]byte, []int) {
|
||||||
|
return file_v1_restic_proto_rawDescGZIP(), []int{1}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *BackupProgressEntry) GetEntry() isBackupProgressEntry_Entry {
|
||||||
|
if m != nil {
|
||||||
|
return m.Entry
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *BackupProgressEntry) GetStatus() *BackupProgressStatusEntry {
|
||||||
|
if x, ok := x.GetEntry().(*BackupProgressEntry_Status); ok {
|
||||||
|
return x.Status
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *BackupProgressEntry) GetSummary() *BackupProgressSummary {
|
||||||
|
if x, ok := x.GetEntry().(*BackupProgressEntry_Summary); ok {
|
||||||
|
return x.Summary
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type isBackupProgressEntry_Entry interface {
|
||||||
|
isBackupProgressEntry_Entry()
|
||||||
|
}
|
||||||
|
|
||||||
|
type BackupProgressEntry_Status struct {
|
||||||
|
Status *BackupProgressStatusEntry `protobuf:"bytes,1,opt,name=status,proto3,oneof"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type BackupProgressEntry_Summary struct {
|
||||||
|
Summary *BackupProgressSummary `protobuf:"bytes,2,opt,name=summary,proto3,oneof"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*BackupProgressEntry_Status) isBackupProgressEntry_Entry() {}
|
||||||
|
|
||||||
|
func (*BackupProgressEntry_Summary) isBackupProgressEntry_Entry() {}
|
||||||
|
|
||||||
|
type BackupProgressStatusEntry struct {
|
||||||
|
state protoimpl.MessageState
|
||||||
|
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"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *BackupProgressStatusEntry) Reset() {
|
||||||
|
*x = BackupProgressStatusEntry{}
|
||||||
|
if protoimpl.UnsafeEnabled {
|
||||||
|
mi := &file_v1_restic_proto_msgTypes[2]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *BackupProgressStatusEntry) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*BackupProgressStatusEntry) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *BackupProgressStatusEntry) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_v1_restic_proto_msgTypes[2]
|
||||||
|
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 BackupProgressStatusEntry.ProtoReflect.Descriptor instead.
|
||||||
|
func (*BackupProgressStatusEntry) Descriptor() ([]byte, []int) {
|
||||||
|
return file_v1_restic_proto_rawDescGZIP(), []int{2}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *BackupProgressStatusEntry) GetPercentDone() float64 {
|
||||||
|
if x != nil {
|
||||||
|
return x.PercentDone
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *BackupProgressStatusEntry) GetTotalFiles() int64 {
|
||||||
|
if x != nil {
|
||||||
|
return x.TotalFiles
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *BackupProgressStatusEntry) GetTotalBytes() int64 {
|
||||||
|
if x != nil {
|
||||||
|
return x.TotalBytes
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *BackupProgressStatusEntry) GetFilesDone() int64 {
|
||||||
|
if x != nil {
|
||||||
|
return x.FilesDone
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *BackupProgressStatusEntry) GetBytesDone() int64 {
|
||||||
|
if x != nil {
|
||||||
|
return x.BytesDone
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
type BackupProgressSummary struct {
|
||||||
|
state protoimpl.MessageState
|
||||||
|
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"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *BackupProgressSummary) Reset() {
|
||||||
|
*x = BackupProgressSummary{}
|
||||||
|
if protoimpl.UnsafeEnabled {
|
||||||
|
mi := &file_v1_restic_proto_msgTypes[3]
|
||||||
|
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||||
|
ms.StoreMessageInfo(mi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *BackupProgressSummary) String() string {
|
||||||
|
return protoimpl.X.MessageStringOf(x)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*BackupProgressSummary) ProtoMessage() {}
|
||||||
|
|
||||||
|
func (x *BackupProgressSummary) ProtoReflect() protoreflect.Message {
|
||||||
|
mi := &file_v1_restic_proto_msgTypes[3]
|
||||||
|
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 BackupProgressSummary.ProtoReflect.Descriptor instead.
|
||||||
|
func (*BackupProgressSummary) Descriptor() ([]byte, []int) {
|
||||||
|
return file_v1_restic_proto_rawDescGZIP(), []int{3}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *BackupProgressSummary) GetFilesNew() int64 {
|
||||||
|
if x != nil {
|
||||||
|
return x.FilesNew
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *BackupProgressSummary) GetFilesChanged() int64 {
|
||||||
|
if x != nil {
|
||||||
|
return x.FilesChanged
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *BackupProgressSummary) GetFilesUnmodified() int64 {
|
||||||
|
if x != nil {
|
||||||
|
return x.FilesUnmodified
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *BackupProgressSummary) GetDirsNew() int64 {
|
||||||
|
if x != nil {
|
||||||
|
return x.DirsNew
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *BackupProgressSummary) GetDirsChanged() int64 {
|
||||||
|
if x != nil {
|
||||||
|
return x.DirsChanged
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *BackupProgressSummary) GetDirsUnmodified() int64 {
|
||||||
|
if x != nil {
|
||||||
|
return x.DirsUnmodified
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *BackupProgressSummary) GetDataBlobs() int64 {
|
||||||
|
if x != nil {
|
||||||
|
return x.DataBlobs
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *BackupProgressSummary) GetTreeBlobs() int64 {
|
||||||
|
if x != nil {
|
||||||
|
return x.TreeBlobs
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *BackupProgressSummary) GetDataAdded() int64 {
|
||||||
|
if x != nil {
|
||||||
|
return x.DataAdded
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *BackupProgressSummary) GetTotalFilesProcessed() int64 {
|
||||||
|
if x != nil {
|
||||||
|
return x.TotalFilesProcessed
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *BackupProgressSummary) GetTotalBytesProcessed() int64 {
|
||||||
|
if x != nil {
|
||||||
|
return x.TotalBytesProcessed
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *BackupProgressSummary) GetTotalDuration() int64 {
|
||||||
|
if x != nil {
|
||||||
|
return x.TotalDuration
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *BackupProgressSummary) GetSnapshotId() string {
|
||||||
|
if x != nil {
|
||||||
|
return x.SnapshotId
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
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,
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
file_v1_restic_proto_rawDescOnce sync.Once
|
||||||
|
file_v1_restic_proto_rawDescData = file_v1_restic_proto_rawDesc
|
||||||
|
)
|
||||||
|
|
||||||
|
func file_v1_restic_proto_rawDescGZIP() []byte {
|
||||||
|
file_v1_restic_proto_rawDescOnce.Do(func() {
|
||||||
|
file_v1_restic_proto_rawDescData = protoimpl.X.CompressGZIP(file_v1_restic_proto_rawDescData)
|
||||||
|
})
|
||||||
|
return file_v1_restic_proto_rawDescData
|
||||||
|
}
|
||||||
|
|
||||||
|
var file_v1_restic_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
|
||||||
|
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
|
||||||
|
}
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() { file_v1_restic_proto_init() }
|
||||||
|
func file_v1_restic_proto_init() {
|
||||||
|
if File_v1_restic_proto != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !protoimpl.UnsafeEnabled {
|
||||||
|
file_v1_restic_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||||
|
switch v := v.(*ResticSnapshot); i {
|
||||||
|
case 0:
|
||||||
|
return &v.state
|
||||||
|
case 1:
|
||||||
|
return &v.sizeCache
|
||||||
|
case 2:
|
||||||
|
return &v.unknownFields
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file_v1_restic_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||||
|
switch v := v.(*BackupProgressEntry); i {
|
||||||
|
case 0:
|
||||||
|
return &v.state
|
||||||
|
case 1:
|
||||||
|
return &v.sizeCache
|
||||||
|
case 2:
|
||||||
|
return &v.unknownFields
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file_v1_restic_proto_msgTypes[2].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[3].Exporter = func(v interface{}, i int) interface{} {
|
||||||
|
switch v := v.(*BackupProgressSummary); i {
|
||||||
|
case 0:
|
||||||
|
return &v.state
|
||||||
|
case 1:
|
||||||
|
return &v.sizeCache
|
||||||
|
case 2:
|
||||||
|
return &v.unknownFields
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file_v1_restic_proto_msgTypes[1].OneofWrappers = []interface{}{
|
||||||
|
(*BackupProgressEntry_Status)(nil),
|
||||||
|
(*BackupProgressEntry_Summary)(nil),
|
||||||
|
}
|
||||||
|
type x struct{}
|
||||||
|
out := protoimpl.TypeBuilder{
|
||||||
|
File: protoimpl.DescBuilder{
|
||||||
|
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||||
|
RawDescriptor: file_v1_restic_proto_rawDesc,
|
||||||
|
NumEnums: 0,
|
||||||
|
NumMessages: 4,
|
||||||
|
NumExtensions: 0,
|
||||||
|
NumServices: 0,
|
||||||
|
},
|
||||||
|
GoTypes: file_v1_restic_proto_goTypes,
|
||||||
|
DependencyIndexes: file_v1_restic_proto_depIdxs,
|
||||||
|
MessageInfos: file_v1_restic_proto_msgTypes,
|
||||||
|
}.Build()
|
||||||
|
File_v1_restic_proto = out.File
|
||||||
|
file_v1_restic_proto_rawDesc = nil
|
||||||
|
file_v1_restic_proto_goTypes = nil
|
||||||
|
file_v1_restic_proto_depIdxs = nil
|
||||||
|
}
|
||||||
@@ -20,7 +20,7 @@ func serveGRPC(ctx context.Context, socket string) error {
|
|||||||
return fmt.Errorf("failed to listen: %w", err)
|
return fmt.Errorf("failed to listen: %w", err)
|
||||||
}
|
}
|
||||||
grpcServer := grpc.NewServer()
|
grpcServer := grpc.NewServer()
|
||||||
v1.RegisterResticUIServer(grpcServer, &server{})
|
v1.RegisterResticUIServer(grpcServer, NewServer())
|
||||||
go func() {
|
go func() {
|
||||||
<-ctx.Done()
|
<-ctx.Done()
|
||||||
grpcServer.GracefulStop()
|
grpcServer.GracefulStop()
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ package api
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
v1 "github.com/garethgeorge/resticui/gen/go/v1"
|
v1 "github.com/garethgeorge/resticui/gen/go/v1"
|
||||||
@@ -11,17 +13,44 @@ import (
|
|||||||
"google.golang.org/protobuf/types/known/emptypb"
|
"google.golang.org/protobuf/types/known/emptypb"
|
||||||
)
|
)
|
||||||
|
|
||||||
type server struct {
|
type Server struct {
|
||||||
*v1.UnimplementedResticUIServer
|
*v1.UnimplementedResticUIServer
|
||||||
|
|
||||||
|
reqId atomic.Uint64
|
||||||
|
eventChannelsMu sync.Mutex
|
||||||
|
eventChannels map[uint64]chan *v1.Event
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ v1.ResticUIServer = &server{}
|
var _ v1.ResticUIServer = &Server{}
|
||||||
|
|
||||||
func (s *server) GetConfig(ctx context.Context, empty *emptypb.Empty) (*v1.Config, error) {
|
func NewServer() *Server {
|
||||||
|
s := &Server{
|
||||||
|
eventChannels: make(map[uint64]chan *v1.Event),
|
||||||
|
}
|
||||||
|
|
||||||
|
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)),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetConfig implements GET /v1/config
|
||||||
|
func (s *Server) GetConfig(ctx context.Context, empty *emptypb.Empty) (*v1.Config, error) {
|
||||||
return config.Default.Get()
|
return config.Default.Get()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *server) SetConfig(ctx context.Context, c *v1.Config) (*v1.Config, error) {
|
// SetConfig implements PUT /v1/config
|
||||||
|
func (s *Server) SetConfig(ctx context.Context, c *v1.Config) (*v1.Config, error) {
|
||||||
err := config.Default.Update(c)
|
err := config.Default.Update(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to update config: %w", err)
|
return nil, fmt.Errorf("failed to update config: %w", err)
|
||||||
@@ -29,27 +58,33 @@ func (s *server) SetConfig(ctx context.Context, c *v1.Config) (*v1.Config, error
|
|||||||
return config.Default.Get()
|
return config.Default.Get()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *server) GetEvents(_ *emptypb.Empty, stream v1.ResticUI_GetEventsServer) error {
|
// GetEvents implements GET /v1/events
|
||||||
|
func (s *Server) GetEvents(_ *emptypb.Empty, stream v1.ResticUI_GetEventsServer) error {
|
||||||
|
reqId := s.reqId.Add(1)
|
||||||
|
|
||||||
|
// Register a channel to receive events for this invocation
|
||||||
|
s.eventChannelsMu.Lock()
|
||||||
|
eventChan := make(chan *v1.Event, 3)
|
||||||
|
s.eventChannels[reqId] = eventChan
|
||||||
|
s.eventChannelsMu.Unlock()
|
||||||
|
defer delete(s.eventChannels, reqId)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
zap.S().Info("Sending event")
|
|
||||||
stream.Send(&v1.Event{
|
|
||||||
Timestamp: 0,
|
|
||||||
Event: &v1.Event_BackupStatusChange{
|
|
||||||
BackupStatusChange: &v1.BackupStatusEvent{
|
|
||||||
Status: v1.Status_IN_PROGRESS,
|
|
||||||
Percent: 0,
|
|
||||||
Plan: "myplan",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
timer := time.NewTimer(time.Second * 1)
|
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-stream.Context().Done():
|
case <-stream.Context().Done():
|
||||||
zap.S().Info("Get events hangup")
|
|
||||||
return nil
|
return nil
|
||||||
case <-timer.C:
|
case event := <-eventChan:
|
||||||
|
stream.Send(event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PublishEvent publishes an event to all GetEvents streams. It is effectively a multicast.
|
||||||
|
func (s *Server) PublishEvent(event *v1.Event) {
|
||||||
|
zap.S().Debug("Publishing event", zap.Any("event", event))
|
||||||
|
s.eventChannelsMu.Lock()
|
||||||
|
defer s.eventChannelsMu.Unlock()
|
||||||
|
for _, ch := range s.eventChannels {
|
||||||
|
ch <- event
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -23,14 +23,14 @@ type LsEntry struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Snapshot struct {
|
type Snapshot struct {
|
||||||
|
Id string `json:"id"`
|
||||||
Time string `json:"time"`
|
Time string `json:"time"`
|
||||||
Tree string `json:"tree"`
|
Tree string `json:"tree"`
|
||||||
Paths []string `json:"paths"`
|
Paths []string `json:"paths"`
|
||||||
Hostname string `json:"hostname"`
|
Hostname string `json:"hostname"`
|
||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
Id string `json:"id"`
|
|
||||||
ShortId string `json:"short_id"`
|
|
||||||
Tags []string `json:"tags"`
|
Tags []string `json:"tags"`
|
||||||
|
Parent string `json:"parent"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type BackupProgressEntry struct {
|
type BackupProgressEntry struct {
|
||||||
@@ -58,9 +58,6 @@ type BackupProgressEntry struct {
|
|||||||
FilesDone int `json:"files_done"`
|
FilesDone int `json:"files_done"`
|
||||||
TotalBytes int `json:"total_bytes"`
|
TotalBytes int `json:"total_bytes"`
|
||||||
BytesDone int `json:"bytes_done"`
|
BytesDone int `json:"bytes_done"`
|
||||||
|
|
||||||
// Error fields
|
|
||||||
Error string `json:"error"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// readBackupProgressEntrys returns the summary event or an error if the command failed.
|
// readBackupProgressEntrys returns the summary event or an error if the command failed.
|
||||||
|
|||||||
@@ -14,6 +14,6 @@ plugins:
|
|||||||
- paths=source_relative
|
- paths=source_relative
|
||||||
- generate_unbound_methods=true
|
- generate_unbound_methods=true
|
||||||
- plugin: grpc-gateway-ts
|
- plugin: grpc-gateway-ts
|
||||||
out: ../gen/ts
|
out: ../webui/gen/ts
|
||||||
opt:
|
opt:
|
||||||
- paths=source_relative
|
- paths=source_relative
|
||||||
@@ -27,4 +27,4 @@ message Plan {
|
|||||||
string id = 1 [json_name="id"];
|
string id = 1 [json_name="id"];
|
||||||
string repo = 2 [json_name="repo"];
|
string repo = 2 [json_name="repo"];
|
||||||
repeated string paths = 4 [json_name="paths"];
|
repeated string paths = 4 [json_name="paths"];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ message Event {
|
|||||||
LogEvent log = 3 [json_name="log"];
|
LogEvent log = 3 [json_name="log"];
|
||||||
BackupStatusEvent backup_status_change = 4 [json_name="backup_status"];
|
BackupStatusEvent backup_status_change = 4 [json_name="backup_status"];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message LogEvent {
|
message LogEvent {
|
||||||
|
|||||||
47
proto/v1/restic.proto
Normal file
47
proto/v1/restic.proto
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
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"];
|
||||||
|
}
|
||||||
|
|
||||||
|
message BackupProgressEntry {
|
||||||
|
oneof entry {
|
||||||
|
BackupProgressStatusEntry status = 1 [json_name = "status"];
|
||||||
|
BackupProgressSummary summary = 2 [json_name = "summary"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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"];
|
||||||
|
}
|
||||||
|
|
||||||
|
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"];
|
||||||
|
}
|
||||||
@@ -15,6 +15,7 @@ service ResticUI {
|
|||||||
get: "/v1/config"
|
get: "/v1/config"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
rpc SetConfig (Config) returns (Config) {
|
rpc SetConfig (Config) returns (Config) {
|
||||||
option (google.api.http) = {
|
option (google.api.http) = {
|
||||||
post: "/v1/config"
|
post: "/v1/config"
|
||||||
|
|||||||
3
webui/.gitignore
vendored
Normal file
3
webui/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
.parcel-cache
|
||||||
|
node_modules
|
||||||
|
dist
|
||||||
@@ -10,6 +10,11 @@ export type Config = {
|
|||||||
plans?: Plan[]
|
plans?: Plan[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type User = {
|
||||||
|
name?: string
|
||||||
|
password?: string
|
||||||
|
}
|
||||||
|
|
||||||
export type Repo = {
|
export type Repo = {
|
||||||
id?: string
|
id?: string
|
||||||
uri?: string
|
uri?: string
|
||||||
@@ -20,6 +25,5 @@ export type Repo = {
|
|||||||
export type Plan = {
|
export type Plan = {
|
||||||
id?: string
|
id?: string
|
||||||
repo?: string
|
repo?: string
|
||||||
repoPath?: string
|
|
||||||
paths?: string[]
|
paths?: string[]
|
||||||
}
|
}
|
||||||
55
webui/gen/ts/v1/restic.pb.ts
Normal file
55
webui/gen/ts/v1/restic.pb.ts
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
// @ts-nocheck
|
||||||
|
/*
|
||||||
|
* This file is a generated Typescript file for GRPC Gateway, DO NOT MODIFY
|
||||||
|
*/
|
||||||
|
|
||||||
|
type Absent<T, K extends keyof T> = { [k in Exclude<keyof T, K>]?: undefined };
|
||||||
|
type OneOf<T> =
|
||||||
|
| { [k in keyof T]?: undefined }
|
||||||
|
| (
|
||||||
|
keyof T extends infer K ?
|
||||||
|
(K extends string & keyof T ? { [k in K]: T[K] } & Absent<T, K>
|
||||||
|
: never)
|
||||||
|
: never);
|
||||||
|
export type ResticSnapshot = {
|
||||||
|
id?: string
|
||||||
|
unixTimeMs?: string
|
||||||
|
hostname?: string
|
||||||
|
username?: string
|
||||||
|
tree?: string
|
||||||
|
parent?: string
|
||||||
|
paths?: string[]
|
||||||
|
tags?: string[]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type BaseBackupProgressEntry = {
|
||||||
|
}
|
||||||
|
|
||||||
|
export type BackupProgressEntry = BaseBackupProgressEntry
|
||||||
|
& OneOf<{ status: BackupProgressStatusEntry; summary: BackupProgressSummary }>
|
||||||
|
|
||||||
|
export type BackupProgressStatusEntry = {
|
||||||
|
percentDone?: number
|
||||||
|
totalFiles?: string
|
||||||
|
totalBytes?: string
|
||||||
|
filesDone?: string
|
||||||
|
bytesDone?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type BackupProgressSummary = {
|
||||||
|
filesNew?: string
|
||||||
|
filesChanged?: string
|
||||||
|
filesUnmodified?: string
|
||||||
|
dirsNew?: string
|
||||||
|
dirsChanged?: string
|
||||||
|
dirsUnmodified?: string
|
||||||
|
dataBlobs?: string
|
||||||
|
treeBlobs?: string
|
||||||
|
dataAdded?: string
|
||||||
|
totalFilesProcessed?: string
|
||||||
|
totalBytesProcessed?: string
|
||||||
|
totalDuration?: string
|
||||||
|
snapshotId?: string
|
||||||
|
}
|
||||||
3589
webui/package-lock.json
generated
Normal file
3589
webui/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,11 +1,28 @@
|
|||||||
{
|
{
|
||||||
"name": "webui",
|
"name": "resticui",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "index.js",
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
"start": "parcel serve src/index.html",
|
||||||
|
"build": "parcel build src/index.html",
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
},
|
},
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC"
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/lodash": "^4.14.191",
|
||||||
|
"@types/node": "^18.11.18",
|
||||||
|
"@types/react": "^18.0.26",
|
||||||
|
"@types/react-dom": "^18.0.10",
|
||||||
|
"axios": "^1.2.2",
|
||||||
|
"lodash": "^4.17.21",
|
||||||
|
"parcel": "^2.8.2",
|
||||||
|
"react": "^18.2.0",
|
||||||
|
"react-dom": "^18.2.0",
|
||||||
|
"typescript": "^4.9.4"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"buffer": "^5.7.1",
|
||||||
|
"process": "^0.11.10"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
5
webui/src/index.css
Normal file
5
webui/src/index.css
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
body {
|
||||||
|
font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue",
|
||||||
|
Helvetica, Arial, "Lucida Grande", sans-serif;
|
||||||
|
font-weight: 300;
|
||||||
|
}
|
||||||
12
webui/src/index.html
Normal file
12
webui/src/index.html
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Guidebook FS Search</title>
|
||||||
|
<link rel="stylesheet" href="./index.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<!-- The script tag below is just a place holder.
|
||||||
|
Parcel will perform magic to insert TSC output here: -->
|
||||||
|
<script src="index.tsx" type="module"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
6
webui/src/index.tsx
Normal file
6
webui/src/index.tsx
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
import { createRoot } from "react-dom/client";
|
||||||
|
import { App } from "./views/App";
|
||||||
|
|
||||||
|
const el = document.querySelector("#app");
|
||||||
|
el && createRoot(el).render(<App />);
|
||||||
24
webui/src/views/App.tsx
Normal file
24
webui/src/views/App.tsx
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import test from "node:test";
|
||||||
|
import * as React from "react";
|
||||||
|
import _ from "lodash";
|
||||||
|
|
||||||
|
export const App = () => {
|
||||||
|
const [searchTerm, setSearchTerm] = React.useState("");
|
||||||
|
const [results, setResults] = React.useState<any>();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h1>Guidebook FS Search</h1>
|
||||||
|
<div>
|
||||||
|
Search:
|
||||||
|
<input
|
||||||
|
value={searchTerm}
|
||||||
|
onChange={(e) => setSearchTerm(e.target.value)}
|
||||||
|
></input>
|
||||||
|
</div>
|
||||||
|
<pre>
|
||||||
|
<code>{"RESULTS: " + JSON.stringify(results, null, 2)}</code>
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
11
webui/tsconfig.json
Normal file
11
webui/tsconfig.json
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"jsx": "react",
|
||||||
|
"target": "es2016",
|
||||||
|
"module": "commonjs",
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"strict": true,
|
||||||
|
"skipLibCheck": true
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user