Monitor update
Deploy / deploy (push) Successful in 8s

This commit is contained in:
2026-08-31 22:42:40 +05:00
parent 47ea18d020
commit 28702bd029
13 changed files with 434 additions and 217 deletions
+1
View File
@@ -69,6 +69,7 @@ docs/ markdown-доки, НЕ в репо — живут толь
- Логи сервера: monitors, RunScript и ServiceAction/ServiceInfo пишут в stdout; ошибки проб сервисов (`probe <key>: ...`) логируются один раз на изменение (появление/восстановление), не на каждый 3s тик; `ListContent` (поллинг-шум) исключён из HTTP-лога echo. - Логи сервера: monitors, RunScript и ServiceAction/ServiceInfo пишут в stdout; ошибки проб сервисов (`probe <key>: ...`) логируются один раз на изменение (появление/восстановление), не на каждый 3s тик; `ListContent` (поллинг-шум) исключён из HTTP-лога echo.
- SW: `web/public/sw.js`, версия кэша `homelab-shell-vN` — **бампить при изменении** офлайн-логики, иначе iOS не обновит. - SW: `web/public/sw.js`, версия кэша `homelab-shell-vN` — **бампить при изменении** офлайн-логики, иначе iOS не обновит.
- Тесты: `make test` (smoke RPC) + `tsc --noEmit` внутри `make web`. Не плодить фреймворки. - Тесты: `make test` (smoke RPC) + `tsc --noEmit` внутри `make web`. Не плодить фреймворки.
- После правок Go-кода — прогонять `gofmt -w server/` (агент делает это сам после любых правок).
## Подводные камни ## Подводные камни
-3
View File
@@ -7,15 +7,12 @@ monitor:
- name: cpu - name: cpu
script: scripts/cpu.sh script: scripts/cpu.sh
refresh: 5 refresh: 5
data: percentage
- name: disk - name: disk
script: scripts/disk.sh script: scripts/disk.sh
refresh: 60 refresh: 60
data: percentage
- name: mem - name: mem
script: scripts/mem.sh script: scripts/mem.sh
refresh: 5 refresh: 5
data: percentage
exec: exec:
- name: greet - name: greet
script: scripts/greet.sh script: scripts/greet.sh
+230 -123
View File
@@ -120,8 +120,6 @@ func (ServiceOp) EnumDescriptor() ([]byte, []int) {
type Item struct { type Item struct {
state protoimpl.MessageState `protogen:"open.v1"` state protoimpl.MessageState `protogen:"open.v1"`
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
Data string `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` // monitor: text | percentage
Value string `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"` // monitor: last output
Args int32 `protobuf:"varint,4,opt,name=args,proto3" json:"args,omitempty"` // exec: arg count Args int32 `protobuf:"varint,4,opt,name=args,proto3" json:"args,omitempty"` // exec: arg count
ArgTypes []string `protobuf:"bytes,5,rep,name=arg_types,json=argTypes,proto3" json:"arg_types,omitempty"` // exec: text | number per arg ArgTypes []string `protobuf:"bytes,5,rep,name=arg_types,json=argTypes,proto3" json:"arg_types,omitempty"` // exec: text | number per arg
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
@@ -165,20 +163,6 @@ func (x *Item) GetName() string {
return "" return ""
} }
func (x *Item) GetData() string {
if x != nil {
return x.Data
}
return ""
}
func (x *Item) GetValue() string {
if x != nil {
return x.Value
}
return ""
}
func (x *Item) GetArgs() int32 { func (x *Item) GetArgs() int32 {
if x != nil { if x != nil {
return x.Args return x.Args
@@ -193,6 +177,119 @@ func (x *Item) GetArgTypes() []string {
return nil return nil
} }
type Stat struct {
state protoimpl.MessageState `protogen:"open.v1"`
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Stat) Reset() {
*x = Stat{}
mi := &file_homelab_v1_homelab_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Stat) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Stat) ProtoMessage() {}
func (x *Stat) ProtoReflect() protoreflect.Message {
mi := &file_homelab_v1_homelab_proto_msgTypes[1]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Stat.ProtoReflect.Descriptor instead.
func (*Stat) Descriptor() ([]byte, []int) {
return file_homelab_v1_homelab_proto_rawDescGZIP(), []int{1}
}
func (x *Stat) GetName() string {
if x != nil {
return x.Name
}
return ""
}
func (x *Stat) GetValue() string {
if x != nil {
return x.Value
}
return ""
}
// Карточка монитора: процент (-1 = скрипт не дал процент) + строки для подписей.
type Monitor struct {
state protoimpl.MessageState `protogen:"open.v1"`
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
Percentage int32 `protobuf:"varint,2,opt,name=percentage,proto3" json:"percentage,omitempty"`
Stats []*Stat `protobuf:"bytes,3,rep,name=stats,proto3" json:"stats,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
func (x *Monitor) Reset() {
*x = Monitor{}
mi := &file_homelab_v1_homelab_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
func (x *Monitor) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Monitor) ProtoMessage() {}
func (x *Monitor) ProtoReflect() protoreflect.Message {
mi := &file_homelab_v1_homelab_proto_msgTypes[2]
if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Monitor.ProtoReflect.Descriptor instead.
func (*Monitor) Descriptor() ([]byte, []int) {
return file_homelab_v1_homelab_proto_rawDescGZIP(), []int{2}
}
func (x *Monitor) GetName() string {
if x != nil {
return x.Name
}
return ""
}
func (x *Monitor) GetPercentage() int32 {
if x != nil {
return x.Percentage
}
return 0
}
func (x *Monitor) GetStats() []*Stat {
if x != nil {
return x.Stats
}
return nil
}
type Link struct { type Link struct {
state protoimpl.MessageState `protogen:"open.v1"` state protoimpl.MessageState `protogen:"open.v1"`
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
@@ -203,7 +300,7 @@ type Link struct {
func (x *Link) Reset() { func (x *Link) Reset() {
*x = Link{} *x = Link{}
mi := &file_homelab_v1_homelab_proto_msgTypes[1] mi := &file_homelab_v1_homelab_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -215,7 +312,7 @@ func (x *Link) String() string {
func (*Link) ProtoMessage() {} func (*Link) ProtoMessage() {}
func (x *Link) ProtoReflect() protoreflect.Message { func (x *Link) ProtoReflect() protoreflect.Message {
mi := &file_homelab_v1_homelab_proto_msgTypes[1] mi := &file_homelab_v1_homelab_proto_msgTypes[3]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -228,7 +325,7 @@ func (x *Link) ProtoReflect() protoreflect.Message {
// Deprecated: Use Link.ProtoReflect.Descriptor instead. // Deprecated: Use Link.ProtoReflect.Descriptor instead.
func (*Link) Descriptor() ([]byte, []int) { func (*Link) Descriptor() ([]byte, []int) {
return file_homelab_v1_homelab_proto_rawDescGZIP(), []int{1} return file_homelab_v1_homelab_proto_rawDescGZIP(), []int{3}
} }
func (x *Link) GetName() string { func (x *Link) GetName() string {
@@ -253,7 +350,7 @@ type ListContentRequest struct {
func (x *ListContentRequest) Reset() { func (x *ListContentRequest) Reset() {
*x = ListContentRequest{} *x = ListContentRequest{}
mi := &file_homelab_v1_homelab_proto_msgTypes[2] mi := &file_homelab_v1_homelab_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -265,7 +362,7 @@ func (x *ListContentRequest) String() string {
func (*ListContentRequest) ProtoMessage() {} func (*ListContentRequest) ProtoMessage() {}
func (x *ListContentRequest) ProtoReflect() protoreflect.Message { func (x *ListContentRequest) ProtoReflect() protoreflect.Message {
mi := &file_homelab_v1_homelab_proto_msgTypes[2] mi := &file_homelab_v1_homelab_proto_msgTypes[4]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -278,13 +375,13 @@ func (x *ListContentRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use ListContentRequest.ProtoReflect.Descriptor instead. // Deprecated: Use ListContentRequest.ProtoReflect.Descriptor instead.
func (*ListContentRequest) Descriptor() ([]byte, []int) { func (*ListContentRequest) Descriptor() ([]byte, []int) {
return file_homelab_v1_homelab_proto_rawDescGZIP(), []int{2} return file_homelab_v1_homelab_proto_rawDescGZIP(), []int{4}
} }
type ListContentResponse struct { type ListContentResponse struct {
state protoimpl.MessageState `protogen:"open.v1"` state protoimpl.MessageState `protogen:"open.v1"`
Links []*Link `protobuf:"bytes,1,rep,name=links,proto3" json:"links,omitempty"` Links []*Link `protobuf:"bytes,1,rep,name=links,proto3" json:"links,omitempty"`
Monitors []*Item `protobuf:"bytes,2,rep,name=monitors,proto3" json:"monitors,omitempty"` Monitors []*Monitor `protobuf:"bytes,2,rep,name=monitors,proto3" json:"monitors,omitempty"`
Exec []*Item `protobuf:"bytes,3,rep,name=exec,proto3" json:"exec,omitempty"` Exec []*Item `protobuf:"bytes,3,rep,name=exec,proto3" json:"exec,omitempty"`
Services []*Service `protobuf:"bytes,4,rep,name=services,proto3" json:"services,omitempty"` Services []*Service `protobuf:"bytes,4,rep,name=services,proto3" json:"services,omitempty"`
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
@@ -293,7 +390,7 @@ type ListContentResponse struct {
func (x *ListContentResponse) Reset() { func (x *ListContentResponse) Reset() {
*x = ListContentResponse{} *x = ListContentResponse{}
mi := &file_homelab_v1_homelab_proto_msgTypes[3] mi := &file_homelab_v1_homelab_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -305,7 +402,7 @@ func (x *ListContentResponse) String() string {
func (*ListContentResponse) ProtoMessage() {} func (*ListContentResponse) ProtoMessage() {}
func (x *ListContentResponse) ProtoReflect() protoreflect.Message { func (x *ListContentResponse) ProtoReflect() protoreflect.Message {
mi := &file_homelab_v1_homelab_proto_msgTypes[3] mi := &file_homelab_v1_homelab_proto_msgTypes[5]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -318,7 +415,7 @@ func (x *ListContentResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use ListContentResponse.ProtoReflect.Descriptor instead. // Deprecated: Use ListContentResponse.ProtoReflect.Descriptor instead.
func (*ListContentResponse) Descriptor() ([]byte, []int) { func (*ListContentResponse) Descriptor() ([]byte, []int) {
return file_homelab_v1_homelab_proto_rawDescGZIP(), []int{3} return file_homelab_v1_homelab_proto_rawDescGZIP(), []int{5}
} }
func (x *ListContentResponse) GetLinks() []*Link { func (x *ListContentResponse) GetLinks() []*Link {
@@ -328,7 +425,7 @@ func (x *ListContentResponse) GetLinks() []*Link {
return nil return nil
} }
func (x *ListContentResponse) GetMonitors() []*Item { func (x *ListContentResponse) GetMonitors() []*Monitor {
if x != nil { if x != nil {
return x.Monitors return x.Monitors
} }
@@ -359,7 +456,7 @@ type DocMeta struct {
func (x *DocMeta) Reset() { func (x *DocMeta) Reset() {
*x = DocMeta{} *x = DocMeta{}
mi := &file_homelab_v1_homelab_proto_msgTypes[4] mi := &file_homelab_v1_homelab_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -371,7 +468,7 @@ func (x *DocMeta) String() string {
func (*DocMeta) ProtoMessage() {} func (*DocMeta) ProtoMessage() {}
func (x *DocMeta) ProtoReflect() protoreflect.Message { func (x *DocMeta) ProtoReflect() protoreflect.Message {
mi := &file_homelab_v1_homelab_proto_msgTypes[4] mi := &file_homelab_v1_homelab_proto_msgTypes[6]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -384,7 +481,7 @@ func (x *DocMeta) ProtoReflect() protoreflect.Message {
// Deprecated: Use DocMeta.ProtoReflect.Descriptor instead. // Deprecated: Use DocMeta.ProtoReflect.Descriptor instead.
func (*DocMeta) Descriptor() ([]byte, []int) { func (*DocMeta) Descriptor() ([]byte, []int) {
return file_homelab_v1_homelab_proto_rawDescGZIP(), []int{4} return file_homelab_v1_homelab_proto_rawDescGZIP(), []int{6}
} }
func (x *DocMeta) GetName() string { func (x *DocMeta) GetName() string {
@@ -409,7 +506,7 @@ type ListDocsRequest struct {
func (x *ListDocsRequest) Reset() { func (x *ListDocsRequest) Reset() {
*x = ListDocsRequest{} *x = ListDocsRequest{}
mi := &file_homelab_v1_homelab_proto_msgTypes[5] mi := &file_homelab_v1_homelab_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -421,7 +518,7 @@ func (x *ListDocsRequest) String() string {
func (*ListDocsRequest) ProtoMessage() {} func (*ListDocsRequest) ProtoMessage() {}
func (x *ListDocsRequest) ProtoReflect() protoreflect.Message { func (x *ListDocsRequest) ProtoReflect() protoreflect.Message {
mi := &file_homelab_v1_homelab_proto_msgTypes[5] mi := &file_homelab_v1_homelab_proto_msgTypes[7]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -434,7 +531,7 @@ func (x *ListDocsRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use ListDocsRequest.ProtoReflect.Descriptor instead. // Deprecated: Use ListDocsRequest.ProtoReflect.Descriptor instead.
func (*ListDocsRequest) Descriptor() ([]byte, []int) { func (*ListDocsRequest) Descriptor() ([]byte, []int) {
return file_homelab_v1_homelab_proto_rawDescGZIP(), []int{5} return file_homelab_v1_homelab_proto_rawDescGZIP(), []int{7}
} }
type ListDocsResponse struct { type ListDocsResponse struct {
@@ -446,7 +543,7 @@ type ListDocsResponse struct {
func (x *ListDocsResponse) Reset() { func (x *ListDocsResponse) Reset() {
*x = ListDocsResponse{} *x = ListDocsResponse{}
mi := &file_homelab_v1_homelab_proto_msgTypes[6] mi := &file_homelab_v1_homelab_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -458,7 +555,7 @@ func (x *ListDocsResponse) String() string {
func (*ListDocsResponse) ProtoMessage() {} func (*ListDocsResponse) ProtoMessage() {}
func (x *ListDocsResponse) ProtoReflect() protoreflect.Message { func (x *ListDocsResponse) ProtoReflect() protoreflect.Message {
mi := &file_homelab_v1_homelab_proto_msgTypes[6] mi := &file_homelab_v1_homelab_proto_msgTypes[8]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -471,7 +568,7 @@ func (x *ListDocsResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use ListDocsResponse.ProtoReflect.Descriptor instead. // Deprecated: Use ListDocsResponse.ProtoReflect.Descriptor instead.
func (*ListDocsResponse) Descriptor() ([]byte, []int) { func (*ListDocsResponse) Descriptor() ([]byte, []int) {
return file_homelab_v1_homelab_proto_rawDescGZIP(), []int{6} return file_homelab_v1_homelab_proto_rawDescGZIP(), []int{8}
} }
func (x *ListDocsResponse) GetDocs() []*DocMeta { func (x *ListDocsResponse) GetDocs() []*DocMeta {
@@ -490,7 +587,7 @@ type GetDocRequest struct {
func (x *GetDocRequest) Reset() { func (x *GetDocRequest) Reset() {
*x = GetDocRequest{} *x = GetDocRequest{}
mi := &file_homelab_v1_homelab_proto_msgTypes[7] mi := &file_homelab_v1_homelab_proto_msgTypes[9]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -502,7 +599,7 @@ func (x *GetDocRequest) String() string {
func (*GetDocRequest) ProtoMessage() {} func (*GetDocRequest) ProtoMessage() {}
func (x *GetDocRequest) ProtoReflect() protoreflect.Message { func (x *GetDocRequest) ProtoReflect() protoreflect.Message {
mi := &file_homelab_v1_homelab_proto_msgTypes[7] mi := &file_homelab_v1_homelab_proto_msgTypes[9]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -515,7 +612,7 @@ func (x *GetDocRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use GetDocRequest.ProtoReflect.Descriptor instead. // Deprecated: Use GetDocRequest.ProtoReflect.Descriptor instead.
func (*GetDocRequest) Descriptor() ([]byte, []int) { func (*GetDocRequest) Descriptor() ([]byte, []int) {
return file_homelab_v1_homelab_proto_rawDescGZIP(), []int{7} return file_homelab_v1_homelab_proto_rawDescGZIP(), []int{9}
} }
func (x *GetDocRequest) GetName() string { func (x *GetDocRequest) GetName() string {
@@ -534,7 +631,7 @@ type GetDocResponse struct {
func (x *GetDocResponse) Reset() { func (x *GetDocResponse) Reset() {
*x = GetDocResponse{} *x = GetDocResponse{}
mi := &file_homelab_v1_homelab_proto_msgTypes[8] mi := &file_homelab_v1_homelab_proto_msgTypes[10]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -546,7 +643,7 @@ func (x *GetDocResponse) String() string {
func (*GetDocResponse) ProtoMessage() {} func (*GetDocResponse) ProtoMessage() {}
func (x *GetDocResponse) ProtoReflect() protoreflect.Message { func (x *GetDocResponse) ProtoReflect() protoreflect.Message {
mi := &file_homelab_v1_homelab_proto_msgTypes[8] mi := &file_homelab_v1_homelab_proto_msgTypes[10]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -559,7 +656,7 @@ func (x *GetDocResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use GetDocResponse.ProtoReflect.Descriptor instead. // Deprecated: Use GetDocResponse.ProtoReflect.Descriptor instead.
func (*GetDocResponse) Descriptor() ([]byte, []int) { func (*GetDocResponse) Descriptor() ([]byte, []int) {
return file_homelab_v1_homelab_proto_rawDescGZIP(), []int{8} return file_homelab_v1_homelab_proto_rawDescGZIP(), []int{10}
} }
func (x *GetDocResponse) GetContent() string { func (x *GetDocResponse) GetContent() string {
@@ -579,7 +676,7 @@ type SaveDocRequest struct {
func (x *SaveDocRequest) Reset() { func (x *SaveDocRequest) Reset() {
*x = SaveDocRequest{} *x = SaveDocRequest{}
mi := &file_homelab_v1_homelab_proto_msgTypes[9] mi := &file_homelab_v1_homelab_proto_msgTypes[11]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -591,7 +688,7 @@ func (x *SaveDocRequest) String() string {
func (*SaveDocRequest) ProtoMessage() {} func (*SaveDocRequest) ProtoMessage() {}
func (x *SaveDocRequest) ProtoReflect() protoreflect.Message { func (x *SaveDocRequest) ProtoReflect() protoreflect.Message {
mi := &file_homelab_v1_homelab_proto_msgTypes[9] mi := &file_homelab_v1_homelab_proto_msgTypes[11]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -604,7 +701,7 @@ func (x *SaveDocRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use SaveDocRequest.ProtoReflect.Descriptor instead. // Deprecated: Use SaveDocRequest.ProtoReflect.Descriptor instead.
func (*SaveDocRequest) Descriptor() ([]byte, []int) { func (*SaveDocRequest) Descriptor() ([]byte, []int) {
return file_homelab_v1_homelab_proto_rawDescGZIP(), []int{9} return file_homelab_v1_homelab_proto_rawDescGZIP(), []int{11}
} }
func (x *SaveDocRequest) GetName() string { func (x *SaveDocRequest) GetName() string {
@@ -630,7 +727,7 @@ type SaveDocResponse struct {
func (x *SaveDocResponse) Reset() { func (x *SaveDocResponse) Reset() {
*x = SaveDocResponse{} *x = SaveDocResponse{}
mi := &file_homelab_v1_homelab_proto_msgTypes[10] mi := &file_homelab_v1_homelab_proto_msgTypes[12]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -642,7 +739,7 @@ func (x *SaveDocResponse) String() string {
func (*SaveDocResponse) ProtoMessage() {} func (*SaveDocResponse) ProtoMessage() {}
func (x *SaveDocResponse) ProtoReflect() protoreflect.Message { func (x *SaveDocResponse) ProtoReflect() protoreflect.Message {
mi := &file_homelab_v1_homelab_proto_msgTypes[10] mi := &file_homelab_v1_homelab_proto_msgTypes[12]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -655,7 +752,7 @@ func (x *SaveDocResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use SaveDocResponse.ProtoReflect.Descriptor instead. // Deprecated: Use SaveDocResponse.ProtoReflect.Descriptor instead.
func (*SaveDocResponse) Descriptor() ([]byte, []int) { func (*SaveDocResponse) Descriptor() ([]byte, []int) {
return file_homelab_v1_homelab_proto_rawDescGZIP(), []int{10} return file_homelab_v1_homelab_proto_rawDescGZIP(), []int{12}
} }
func (x *SaveDocResponse) GetHash() string { func (x *SaveDocResponse) GetHash() string {
@@ -681,7 +778,7 @@ type Service struct {
func (x *Service) Reset() { func (x *Service) Reset() {
*x = Service{} *x = Service{}
mi := &file_homelab_v1_homelab_proto_msgTypes[11] mi := &file_homelab_v1_homelab_proto_msgTypes[13]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -693,7 +790,7 @@ func (x *Service) String() string {
func (*Service) ProtoMessage() {} func (*Service) ProtoMessage() {}
func (x *Service) ProtoReflect() protoreflect.Message { func (x *Service) ProtoReflect() protoreflect.Message {
mi := &file_homelab_v1_homelab_proto_msgTypes[11] mi := &file_homelab_v1_homelab_proto_msgTypes[13]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -706,7 +803,7 @@ func (x *Service) ProtoReflect() protoreflect.Message {
// Deprecated: Use Service.ProtoReflect.Descriptor instead. // Deprecated: Use Service.ProtoReflect.Descriptor instead.
func (*Service) Descriptor() ([]byte, []int) { func (*Service) Descriptor() ([]byte, []int) {
return file_homelab_v1_homelab_proto_rawDescGZIP(), []int{11} return file_homelab_v1_homelab_proto_rawDescGZIP(), []int{13}
} }
func (x *Service) GetKind() ServiceKind { func (x *Service) GetKind() ServiceKind {
@@ -776,7 +873,7 @@ type ServiceActionRequest struct {
func (x *ServiceActionRequest) Reset() { func (x *ServiceActionRequest) Reset() {
*x = ServiceActionRequest{} *x = ServiceActionRequest{}
mi := &file_homelab_v1_homelab_proto_msgTypes[12] mi := &file_homelab_v1_homelab_proto_msgTypes[14]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -788,7 +885,7 @@ func (x *ServiceActionRequest) String() string {
func (*ServiceActionRequest) ProtoMessage() {} func (*ServiceActionRequest) ProtoMessage() {}
func (x *ServiceActionRequest) ProtoReflect() protoreflect.Message { func (x *ServiceActionRequest) ProtoReflect() protoreflect.Message {
mi := &file_homelab_v1_homelab_proto_msgTypes[12] mi := &file_homelab_v1_homelab_proto_msgTypes[14]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -801,7 +898,7 @@ func (x *ServiceActionRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use ServiceActionRequest.ProtoReflect.Descriptor instead. // Deprecated: Use ServiceActionRequest.ProtoReflect.Descriptor instead.
func (*ServiceActionRequest) Descriptor() ([]byte, []int) { func (*ServiceActionRequest) Descriptor() ([]byte, []int) {
return file_homelab_v1_homelab_proto_rawDescGZIP(), []int{12} return file_homelab_v1_homelab_proto_rawDescGZIP(), []int{14}
} }
func (x *ServiceActionRequest) GetName() string { func (x *ServiceActionRequest) GetName() string {
@@ -834,7 +931,7 @@ type ServiceActionResponse struct {
func (x *ServiceActionResponse) Reset() { func (x *ServiceActionResponse) Reset() {
*x = ServiceActionResponse{} *x = ServiceActionResponse{}
mi := &file_homelab_v1_homelab_proto_msgTypes[13] mi := &file_homelab_v1_homelab_proto_msgTypes[15]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -846,7 +943,7 @@ func (x *ServiceActionResponse) String() string {
func (*ServiceActionResponse) ProtoMessage() {} func (*ServiceActionResponse) ProtoMessage() {}
func (x *ServiceActionResponse) ProtoReflect() protoreflect.Message { func (x *ServiceActionResponse) ProtoReflect() protoreflect.Message {
mi := &file_homelab_v1_homelab_proto_msgTypes[13] mi := &file_homelab_v1_homelab_proto_msgTypes[15]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -859,7 +956,7 @@ func (x *ServiceActionResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use ServiceActionResponse.ProtoReflect.Descriptor instead. // Deprecated: Use ServiceActionResponse.ProtoReflect.Descriptor instead.
func (*ServiceActionResponse) Descriptor() ([]byte, []int) { func (*ServiceActionResponse) Descriptor() ([]byte, []int) {
return file_homelab_v1_homelab_proto_rawDescGZIP(), []int{13} return file_homelab_v1_homelab_proto_rawDescGZIP(), []int{15}
} }
func (x *ServiceActionResponse) GetOutput() string { func (x *ServiceActionResponse) GetOutput() string {
@@ -879,7 +976,7 @@ type ServiceInfoRequest struct {
func (x *ServiceInfoRequest) Reset() { func (x *ServiceInfoRequest) Reset() {
*x = ServiceInfoRequest{} *x = ServiceInfoRequest{}
mi := &file_homelab_v1_homelab_proto_msgTypes[14] mi := &file_homelab_v1_homelab_proto_msgTypes[16]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -891,7 +988,7 @@ func (x *ServiceInfoRequest) String() string {
func (*ServiceInfoRequest) ProtoMessage() {} func (*ServiceInfoRequest) ProtoMessage() {}
func (x *ServiceInfoRequest) ProtoReflect() protoreflect.Message { func (x *ServiceInfoRequest) ProtoReflect() protoreflect.Message {
mi := &file_homelab_v1_homelab_proto_msgTypes[14] mi := &file_homelab_v1_homelab_proto_msgTypes[16]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -904,7 +1001,7 @@ func (x *ServiceInfoRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use ServiceInfoRequest.ProtoReflect.Descriptor instead. // Deprecated: Use ServiceInfoRequest.ProtoReflect.Descriptor instead.
func (*ServiceInfoRequest) Descriptor() ([]byte, []int) { func (*ServiceInfoRequest) Descriptor() ([]byte, []int) {
return file_homelab_v1_homelab_proto_rawDescGZIP(), []int{14} return file_homelab_v1_homelab_proto_rawDescGZIP(), []int{16}
} }
func (x *ServiceInfoRequest) GetName() string { func (x *ServiceInfoRequest) GetName() string {
@@ -930,7 +1027,7 @@ type ServiceInfoResponse struct {
func (x *ServiceInfoResponse) Reset() { func (x *ServiceInfoResponse) Reset() {
*x = ServiceInfoResponse{} *x = ServiceInfoResponse{}
mi := &file_homelab_v1_homelab_proto_msgTypes[15] mi := &file_homelab_v1_homelab_proto_msgTypes[17]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -942,7 +1039,7 @@ func (x *ServiceInfoResponse) String() string {
func (*ServiceInfoResponse) ProtoMessage() {} func (*ServiceInfoResponse) ProtoMessage() {}
func (x *ServiceInfoResponse) ProtoReflect() protoreflect.Message { func (x *ServiceInfoResponse) ProtoReflect() protoreflect.Message {
mi := &file_homelab_v1_homelab_proto_msgTypes[15] mi := &file_homelab_v1_homelab_proto_msgTypes[17]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -955,7 +1052,7 @@ func (x *ServiceInfoResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use ServiceInfoResponse.ProtoReflect.Descriptor instead. // Deprecated: Use ServiceInfoResponse.ProtoReflect.Descriptor instead.
func (*ServiceInfoResponse) Descriptor() ([]byte, []int) { func (*ServiceInfoResponse) Descriptor() ([]byte, []int) {
return file_homelab_v1_homelab_proto_rawDescGZIP(), []int{15} return file_homelab_v1_homelab_proto_rawDescGZIP(), []int{17}
} }
func (x *ServiceInfoResponse) GetOutput() string { func (x *ServiceInfoResponse) GetOutput() string {
@@ -975,7 +1072,7 @@ type RunScriptRequest struct {
func (x *RunScriptRequest) Reset() { func (x *RunScriptRequest) Reset() {
*x = RunScriptRequest{} *x = RunScriptRequest{}
mi := &file_homelab_v1_homelab_proto_msgTypes[16] mi := &file_homelab_v1_homelab_proto_msgTypes[18]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -987,7 +1084,7 @@ func (x *RunScriptRequest) String() string {
func (*RunScriptRequest) ProtoMessage() {} func (*RunScriptRequest) ProtoMessage() {}
func (x *RunScriptRequest) ProtoReflect() protoreflect.Message { func (x *RunScriptRequest) ProtoReflect() protoreflect.Message {
mi := &file_homelab_v1_homelab_proto_msgTypes[16] mi := &file_homelab_v1_homelab_proto_msgTypes[18]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -1000,7 +1097,7 @@ func (x *RunScriptRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use RunScriptRequest.ProtoReflect.Descriptor instead. // Deprecated: Use RunScriptRequest.ProtoReflect.Descriptor instead.
func (*RunScriptRequest) Descriptor() ([]byte, []int) { func (*RunScriptRequest) Descriptor() ([]byte, []int) {
return file_homelab_v1_homelab_proto_rawDescGZIP(), []int{16} return file_homelab_v1_homelab_proto_rawDescGZIP(), []int{18}
} }
func (x *RunScriptRequest) GetName() string { func (x *RunScriptRequest) GetName() string {
@@ -1026,7 +1123,7 @@ type RunScriptResponse struct {
func (x *RunScriptResponse) Reset() { func (x *RunScriptResponse) Reset() {
*x = RunScriptResponse{} *x = RunScriptResponse{}
mi := &file_homelab_v1_homelab_proto_msgTypes[17] mi := &file_homelab_v1_homelab_proto_msgTypes[19]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@@ -1038,7 +1135,7 @@ func (x *RunScriptResponse) String() string {
func (*RunScriptResponse) ProtoMessage() {} func (*RunScriptResponse) ProtoMessage() {}
func (x *RunScriptResponse) ProtoReflect() protoreflect.Message { func (x *RunScriptResponse) ProtoReflect() protoreflect.Message {
mi := &file_homelab_v1_homelab_proto_msgTypes[17] mi := &file_homelab_v1_homelab_proto_msgTypes[19]
if x != nil { if x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@@ -1051,7 +1148,7 @@ func (x *RunScriptResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use RunScriptResponse.ProtoReflect.Descriptor instead. // Deprecated: Use RunScriptResponse.ProtoReflect.Descriptor instead.
func (*RunScriptResponse) Descriptor() ([]byte, []int) { func (*RunScriptResponse) Descriptor() ([]byte, []int) {
return file_homelab_v1_homelab_proto_rawDescGZIP(), []int{17} return file_homelab_v1_homelab_proto_rawDescGZIP(), []int{19}
} }
func (x *RunScriptResponse) GetOutput() string { func (x *RunScriptResponse) GetOutput() string {
@@ -1066,20 +1163,27 @@ var File_homelab_v1_homelab_proto protoreflect.FileDescriptor
const file_homelab_v1_homelab_proto_rawDesc = "" + const file_homelab_v1_homelab_proto_rawDesc = "" +
"\n" + "\n" +
"\x18homelab/v1/homelab.proto\x12\n" + "\x18homelab/v1/homelab.proto\x12\n" +
"homelab.v1\"u\n" + "homelab.v1\"K\n" +
"\x04Item\x12\x12\n" + "\x04Item\x12\x12\n" +
"\x04name\x18\x01 \x01(\tR\x04name\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\x12\x12\n" +
"\x04data\x18\x02 \x01(\tR\x04data\x12\x14\n" +
"\x05value\x18\x03 \x01(\tR\x05value\x12\x12\n" +
"\x04args\x18\x04 \x01(\x05R\x04args\x12\x1b\n" + "\x04args\x18\x04 \x01(\x05R\x04args\x12\x1b\n" +
"\targ_types\x18\x05 \x03(\tR\bargTypes\",\n" + "\targ_types\x18\x05 \x03(\tR\bargTypes\"0\n" +
"\x04Stat\x12\x12\n" +
"\x04name\x18\x01 \x01(\tR\x04name\x12\x14\n" +
"\x05value\x18\x02 \x01(\tR\x05value\"e\n" +
"\aMonitor\x12\x12\n" +
"\x04name\x18\x01 \x01(\tR\x04name\x12\x1e\n" +
"\n" +
"percentage\x18\x02 \x01(\x05R\n" +
"percentage\x12&\n" +
"\x05stats\x18\x03 \x03(\v2\x10.homelab.v1.StatR\x05stats\",\n" +
"\x04Link\x12\x12\n" + "\x04Link\x12\x12\n" +
"\x04name\x18\x01 \x01(\tR\x04name\x12\x10\n" + "\x04name\x18\x01 \x01(\tR\x04name\x12\x10\n" +
"\x03url\x18\x02 \x01(\tR\x03url\"\x14\n" + "\x03url\x18\x02 \x01(\tR\x03url\"\x14\n" +
"\x12ListContentRequest\"\xc2\x01\n" + "\x12ListContentRequest\"\xc5\x01\n" +
"\x13ListContentResponse\x12&\n" + "\x13ListContentResponse\x12&\n" +
"\x05links\x18\x01 \x03(\v2\x10.homelab.v1.LinkR\x05links\x12,\n" + "\x05links\x18\x01 \x03(\v2\x10.homelab.v1.LinkR\x05links\x12/\n" +
"\bmonitors\x18\x02 \x03(\v2\x10.homelab.v1.ItemR\bmonitors\x12$\n" + "\bmonitors\x18\x02 \x03(\v2\x13.homelab.v1.MonitorR\bmonitors\x12$\n" +
"\x04exec\x18\x03 \x03(\v2\x10.homelab.v1.ItemR\x04exec\x12/\n" + "\x04exec\x18\x03 \x03(\v2\x10.homelab.v1.ItemR\x04exec\x12/\n" +
"\bservices\x18\x04 \x03(\v2\x13.homelab.v1.ServiceR\bservices\"1\n" + "\bservices\x18\x04 \x03(\v2\x13.homelab.v1.ServiceR\bservices\"1\n" +
"\aDocMeta\x12\x12\n" + "\aDocMeta\x12\x12\n" +
@@ -1155,58 +1259,61 @@ func file_homelab_v1_homelab_proto_rawDescGZIP() []byte {
} }
var file_homelab_v1_homelab_proto_enumTypes = make([]protoimpl.EnumInfo, 2) var file_homelab_v1_homelab_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
var file_homelab_v1_homelab_proto_msgTypes = make([]protoimpl.MessageInfo, 18) var file_homelab_v1_homelab_proto_msgTypes = make([]protoimpl.MessageInfo, 20)
var file_homelab_v1_homelab_proto_goTypes = []any{ var file_homelab_v1_homelab_proto_goTypes = []any{
(ServiceKind)(0), // 0: homelab.v1.ServiceKind (ServiceKind)(0), // 0: homelab.v1.ServiceKind
(ServiceOp)(0), // 1: homelab.v1.ServiceOp (ServiceOp)(0), // 1: homelab.v1.ServiceOp
(*Item)(nil), // 2: homelab.v1.Item (*Item)(nil), // 2: homelab.v1.Item
(*Link)(nil), // 3: homelab.v1.Link (*Stat)(nil), // 3: homelab.v1.Stat
(*ListContentRequest)(nil), // 4: homelab.v1.ListContentRequest (*Monitor)(nil), // 4: homelab.v1.Monitor
(*ListContentResponse)(nil), // 5: homelab.v1.ListContentResponse (*Link)(nil), // 5: homelab.v1.Link
(*DocMeta)(nil), // 6: homelab.v1.DocMeta (*ListContentRequest)(nil), // 6: homelab.v1.ListContentRequest
(*ListDocsRequest)(nil), // 7: homelab.v1.ListDocsRequest (*ListContentResponse)(nil), // 7: homelab.v1.ListContentResponse
(*ListDocsResponse)(nil), // 8: homelab.v1.ListDocsResponse (*DocMeta)(nil), // 8: homelab.v1.DocMeta
(*GetDocRequest)(nil), // 9: homelab.v1.GetDocRequest (*ListDocsRequest)(nil), // 9: homelab.v1.ListDocsRequest
(*GetDocResponse)(nil), // 10: homelab.v1.GetDocResponse (*ListDocsResponse)(nil), // 10: homelab.v1.ListDocsResponse
(*SaveDocRequest)(nil), // 11: homelab.v1.SaveDocRequest (*GetDocRequest)(nil), // 11: homelab.v1.GetDocRequest
(*SaveDocResponse)(nil), // 12: homelab.v1.SaveDocResponse (*GetDocResponse)(nil), // 12: homelab.v1.GetDocResponse
(*Service)(nil), // 13: homelab.v1.Service (*SaveDocRequest)(nil), // 13: homelab.v1.SaveDocRequest
(*ServiceActionRequest)(nil), // 14: homelab.v1.ServiceActionRequest (*SaveDocResponse)(nil), // 14: homelab.v1.SaveDocResponse
(*ServiceActionResponse)(nil), // 15: homelab.v1.ServiceActionResponse (*Service)(nil), // 15: homelab.v1.Service
(*ServiceInfoRequest)(nil), // 16: homelab.v1.ServiceInfoRequest (*ServiceActionRequest)(nil), // 16: homelab.v1.ServiceActionRequest
(*ServiceInfoResponse)(nil), // 17: homelab.v1.ServiceInfoResponse (*ServiceActionResponse)(nil), // 17: homelab.v1.ServiceActionResponse
(*RunScriptRequest)(nil), // 18: homelab.v1.RunScriptRequest (*ServiceInfoRequest)(nil), // 18: homelab.v1.ServiceInfoRequest
(*RunScriptResponse)(nil), // 19: homelab.v1.RunScriptResponse (*ServiceInfoResponse)(nil), // 19: homelab.v1.ServiceInfoResponse
(*RunScriptRequest)(nil), // 20: homelab.v1.RunScriptRequest
(*RunScriptResponse)(nil), // 21: homelab.v1.RunScriptResponse
} }
var file_homelab_v1_homelab_proto_depIdxs = []int32{ var file_homelab_v1_homelab_proto_depIdxs = []int32{
3, // 0: homelab.v1.ListContentResponse.links:type_name -> homelab.v1.Link 3, // 0: homelab.v1.Monitor.stats:type_name -> homelab.v1.Stat
2, // 1: homelab.v1.ListContentResponse.monitors:type_name -> homelab.v1.Item 5, // 1: homelab.v1.ListContentResponse.links:type_name -> homelab.v1.Link
2, // 2: homelab.v1.ListContentResponse.exec:type_name -> homelab.v1.Item 4, // 2: homelab.v1.ListContentResponse.monitors:type_name -> homelab.v1.Monitor
13, // 3: homelab.v1.ListContentResponse.services:type_name -> homelab.v1.Service 2, // 3: homelab.v1.ListContentResponse.exec:type_name -> homelab.v1.Item
6, // 4: homelab.v1.ListDocsResponse.docs:type_name -> homelab.v1.DocMeta 15, // 4: homelab.v1.ListContentResponse.services:type_name -> homelab.v1.Service
0, // 5: homelab.v1.Service.kind:type_name -> homelab.v1.ServiceKind 8, // 5: homelab.v1.ListDocsResponse.docs:type_name -> homelab.v1.DocMeta
0, // 6: homelab.v1.ServiceActionRequest.kind:type_name -> homelab.v1.ServiceKind 0, // 6: homelab.v1.Service.kind:type_name -> homelab.v1.ServiceKind
1, // 7: homelab.v1.ServiceActionRequest.op:type_name -> homelab.v1.ServiceOp 0, // 7: homelab.v1.ServiceActionRequest.kind:type_name -> homelab.v1.ServiceKind
0, // 8: homelab.v1.ServiceInfoRequest.kind:type_name -> homelab.v1.ServiceKind 1, // 8: homelab.v1.ServiceActionRequest.op:type_name -> homelab.v1.ServiceOp
4, // 9: homelab.v1.HomelabService.ListContent:input_type -> homelab.v1.ListContentRequest 0, // 9: homelab.v1.ServiceInfoRequest.kind:type_name -> homelab.v1.ServiceKind
7, // 10: homelab.v1.HomelabService.ListDocs:input_type -> homelab.v1.ListDocsRequest 6, // 10: homelab.v1.HomelabService.ListContent:input_type -> homelab.v1.ListContentRequest
9, // 11: homelab.v1.HomelabService.GetDoc:input_type -> homelab.v1.GetDocRequest 9, // 11: homelab.v1.HomelabService.ListDocs:input_type -> homelab.v1.ListDocsRequest
11, // 12: homelab.v1.HomelabService.SaveDoc:input_type -> homelab.v1.SaveDocRequest 11, // 12: homelab.v1.HomelabService.GetDoc:input_type -> homelab.v1.GetDocRequest
14, // 13: homelab.v1.HomelabService.ServiceAction:input_type -> homelab.v1.ServiceActionRequest 13, // 13: homelab.v1.HomelabService.SaveDoc:input_type -> homelab.v1.SaveDocRequest
16, // 14: homelab.v1.HomelabService.ServiceInfo:input_type -> homelab.v1.ServiceInfoRequest 16, // 14: homelab.v1.HomelabService.ServiceAction:input_type -> homelab.v1.ServiceActionRequest
18, // 15: homelab.v1.HomelabService.RunScript:input_type -> homelab.v1.RunScriptRequest 18, // 15: homelab.v1.HomelabService.ServiceInfo:input_type -> homelab.v1.ServiceInfoRequest
5, // 16: homelab.v1.HomelabService.ListContent:output_type -> homelab.v1.ListContentResponse 20, // 16: homelab.v1.HomelabService.RunScript:input_type -> homelab.v1.RunScriptRequest
8, // 17: homelab.v1.HomelabService.ListDocs:output_type -> homelab.v1.ListDocsResponse 7, // 17: homelab.v1.HomelabService.ListContent:output_type -> homelab.v1.ListContentResponse
10, // 18: homelab.v1.HomelabService.GetDoc:output_type -> homelab.v1.GetDocResponse 10, // 18: homelab.v1.HomelabService.ListDocs:output_type -> homelab.v1.ListDocsResponse
12, // 19: homelab.v1.HomelabService.SaveDoc:output_type -> homelab.v1.SaveDocResponse 12, // 19: homelab.v1.HomelabService.GetDoc:output_type -> homelab.v1.GetDocResponse
15, // 20: homelab.v1.HomelabService.ServiceAction:output_type -> homelab.v1.ServiceActionResponse 14, // 20: homelab.v1.HomelabService.SaveDoc:output_type -> homelab.v1.SaveDocResponse
17, // 21: homelab.v1.HomelabService.ServiceInfo:output_type -> homelab.v1.ServiceInfoResponse 17, // 21: homelab.v1.HomelabService.ServiceAction:output_type -> homelab.v1.ServiceActionResponse
19, // 22: homelab.v1.HomelabService.RunScript:output_type -> homelab.v1.RunScriptResponse 19, // 22: homelab.v1.HomelabService.ServiceInfo:output_type -> homelab.v1.ServiceInfoResponse
16, // [16:23] is the sub-list for method output_type 21, // 23: homelab.v1.HomelabService.RunScript:output_type -> homelab.v1.RunScriptResponse
9, // [9:16] is the sub-list for method input_type 17, // [17:24] is the sub-list for method output_type
9, // [9:9] is the sub-list for extension type_name 10, // [10:17] is the sub-list for method input_type
9, // [9:9] is the sub-list for extension extendee 10, // [10:10] is the sub-list for extension type_name
0, // [0:9] is the sub-list for field type_name 10, // [10:10] is the sub-list for extension extendee
0, // [0:10] is the sub-list for field type_name
} }
func init() { file_homelab_v1_homelab_proto_init() } func init() { file_homelab_v1_homelab_proto_init() }
@@ -1220,7 +1327,7 @@ func file_homelab_v1_homelab_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: unsafe.Slice(unsafe.StringData(file_homelab_v1_homelab_proto_rawDesc), len(file_homelab_v1_homelab_proto_rawDesc)), RawDescriptor: unsafe.Slice(unsafe.StringData(file_homelab_v1_homelab_proto_rawDesc), len(file_homelab_v1_homelab_proto_rawDesc)),
NumEnums: 2, NumEnums: 2,
NumMessages: 18, NumMessages: 20,
NumExtensions: 0, NumExtensions: 0,
NumServices: 1, NumServices: 1,
}, },
+13 -3
View File
@@ -6,12 +6,22 @@ option go_package = "pwa-homelab-mon/gen/homelab/v1;homelabv1";
message Item { message Item {
string name = 1; string name = 1;
string data = 2; // monitor: text | percentage
string value = 3; // monitor: last output
int32 args = 4; // exec: arg count int32 args = 4; // exec: arg count
repeated string arg_types = 5; // exec: text | number per arg repeated string arg_types = 5; // exec: text | number per arg
} }
message Stat {
string name = 1;
string value = 2;
}
// Карточка монитора: процент (-1 = скрипт не дал процент) + строки для подписей.
message Monitor {
string name = 1;
int32 percentage = 2;
repeated Stat stats = 3;
}
message Link { message Link {
string name = 1; string name = 1;
string url = 2; string url = 2;
@@ -20,7 +30,7 @@ message Link {
message ListContentRequest {} message ListContentRequest {}
message ListContentResponse { message ListContentResponse {
repeated Link links = 1; repeated Link links = 1;
repeated Item monitors = 2; repeated Monitor monitors = 2;
repeated Item exec = 3; repeated Item exec = 3;
repeated Service services = 4; repeated Service services = 4;
} }
+3 -2
View File
@@ -1,7 +1,8 @@
#!/bin/sh #!/bin/sh
# Суммарная загрузка CPU в процентах 0-100 (mac + linux). # CPU: процент загрузки + число ядер. Linux + mac.
# Контракт мониторов: 1-я строка — процент, дальше — key=value.
case "$(uname)" in case "$(uname)" in
Darwin) cores=$(sysctl -n hw.ncpu) ;; Darwin) cores=$(sysctl -n hw.ncpu) ;;
*) cores=$(nproc) ;; *) cores=$(nproc) ;;
esac esac
ps -A -o %cpu | awk -v c="$cores" '{s+=$1} END {printf "%d", s/c}' ps -A -o %cpu | awk -v c="$cores" '{s+=$1} END {printf "%d\nядер=%d\n", s/c, c}'
+11 -4
View File
@@ -1,6 +1,13 @@
#!/bin/sh #!/bin/sh
# Заполненность корневого раздела в процентах (linux + mac). # Диск /: процент + занято/свободно/всего. Linux + mac.
# Контракт мониторов: 1-я строка — процент, дальше — key=value.
case "$(uname)" in case "$(uname)" in
Darwin) df -k / | awk 'NR==2 {print $5}' | tr -d '%' ;; Darwin) df -k / ;;
*) df -Pk / | awk 'NR==2 {print $5}' | tr -d '%' ;; *) df -Pk / ;;
esac esac | awk 'NR==2 {
pct = $5; sub(/%/, "", pct)
printf "%d\n", pct
printf "занято=%.1f ГБ\n", $3/1048576
printf "свободно=%.1f ГБ\n", $4/1048576
printf "всего=%.1f ГБ\n", $2/1048576
}'
+14 -2
View File
@@ -1,3 +1,15 @@
#!/bin/sh #!/bin/sh
# Заполненность RAM в процентах: ps %mem — уже доля от общей памяти, суммируем как есть (mac + linux). # RAM: процент занятого + строка занято/всего. Linux + mac.
ps -A -o %mem | awk '{s+=$1} END {printf "%d", s}' # Контракт мониторов: 1-я строка — процент, дальше — key=value.
# ponytail: used = сумма RSS процессов (без кэшей ОС) — на mac «доступно» дёшево не получить;
# если нужен точный linux used — /proc/meminfo MemAvailable.
case "$(uname)" in
Darwin) total_kb=$(( $(sysctl -n hw.memsize) / 1024 )) ;;
*) total_kb=$(awk '/MemTotal/ {print $2}' /proc/meminfo) ;;
esac
ps -A -o rss=,%mem= | awk -v t="$total_kb" '
{rss+=$1; mem+=$2}
END {
printf "%d\n", mem
printf "занято=%.1f / %.1f ГБ\n", rss/1048576, t/1048576
}'
+13 -12
View File
@@ -7,9 +7,9 @@ import (
) )
type Config struct { type Config struct {
Links []Link `yaml:"links"` Links []Link `yaml:"links"`
Monitor []Item `yaml:"monitor"` Monitor []Monitor `yaml:"monitor"`
Exec []Item `yaml:"exec"` Exec []Item `yaml:"exec"`
} }
func loadConfig(path string) (*Config, error) { func loadConfig(path string) (*Config, error) {
@@ -31,21 +31,22 @@ func loadConfig(path string) (*Config, error) {
} }
seen[l.Name] = true seen[l.Name] = true
} }
for _, list := range [][]Item{cfg.Monitor, cfg.Exec} { for _, m := range cfg.Monitor {
for _, it := range list { if seen[m.Name] {
if seen[it.Name] { return nil, fmt.Errorf("duplicate name %q", m.Name)
return nil, fmt.Errorf("duplicate name %q", it.Name)
}
seen[it.Name] = true
} }
seen[m.Name] = true
}
for _, it := range cfg.Exec {
if seen[it.Name] {
return nil, fmt.Errorf("duplicate name %q", it.Name)
}
seen[it.Name] = true
} }
for _, it := range cfg.Monitor { for _, it := range cfg.Monitor {
if it.Refresh <= 0 { if it.Refresh <= 0 {
return nil, fmt.Errorf("monitor %q: refresh must be > 0", it.Name) return nil, fmt.Errorf("monitor %q: refresh must be > 0", it.Name)
} }
if it.Data != "text" && it.Data != "percentage" {
return nil, fmt.Errorf("monitor %q: data must be text|percentage", it.Name)
}
} }
for _, it := range cfg.Exec { for _, it := range cfg.Exec {
if len(it.ArgTypes) != it.Args { if len(it.ArgTypes) != it.Args {
+40 -11
View File
@@ -8,6 +8,7 @@ import (
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"strconv"
"strings" "strings"
"sync" "sync"
"time" "time"
@@ -24,11 +25,16 @@ type Item struct {
Name string `yaml:"name"` Name string `yaml:"name"`
Script string `yaml:"script"` Script string `yaml:"script"`
Refresh int `yaml:"refresh"` // monitor: seconds Refresh int `yaml:"refresh"` // monitor: seconds
Data string `yaml:"data"` // monitor: text | percentage
Args int `yaml:"args"` // exec: arg count Args int `yaml:"args"` // exec: arg count
ArgTypes []string `yaml:"arg_types"` // exec: text | number per arg ArgTypes []string `yaml:"arg_types"` // exec: text | number per arg
} }
type Monitor struct {
Name string `yaml:"name"`
Script string `yaml:"script"`
Refresh int `yaml:"refresh"` // seconds
}
type Link struct { type Link struct {
Name string `yaml:"name"` Name string `yaml:"name"`
URL string `yaml:"url"` URL string `yaml:"url"`
@@ -39,7 +45,7 @@ type Link struct {
type server struct { type server struct {
cfg *Config cfg *Config
exec map[string]*Item // by item name, read-only after start exec map[string]*Item // by item name, read-only after start
monVals sync.Map // monitor item name -> string (last output) monVals sync.Map // monitor item name -> *monData (last parsed output)
docsDir string docsDir string
srvDir string // dir with *.service units (~/srv on the box) srvDir string // dir with *.service units (~/srv on the box)
probeErr sync.Map // probe key -> last logged error; poll errors log once per change, not every 3s tick probeErr sync.Map // probe key -> last logged error; poll errors log once per change, not every 3s tick
@@ -48,10 +54,34 @@ type server struct {
const execTimeout = 10 * time.Second const execTimeout = 10 * time.Second
func runScript(s *Item, args ...string) (string, error) { // monData — распарсенный вывод скрипта-монитора: первая строка — процент,
// остальные — строки key=value для подписей в карточке.
type monData struct {
percentage int32 // -1 = скрипт не дал процент
stats []*homelabv1.Stat
}
func parseMonitor(out string) *monData {
d := &monData{percentage: -1}
lines := strings.Split(strings.TrimSpace(out), "\n")
if lines[0] == "" {
return d
}
if n, err := strconv.Atoi(strings.TrimSpace(lines[0])); err == nil {
d.percentage = int32(n)
}
for _, l := range lines[1:] {
if k, v, ok := strings.Cut(strings.TrimSpace(l), "="); ok {
d.stats = append(d.stats, &homelabv1.Stat{Name: strings.TrimSpace(k), Value: strings.TrimSpace(v)})
}
}
return d
}
func runScript(script string, args ...string) (string, error) {
ctx, cancel := context.WithTimeout(context.Background(), execTimeout) ctx, cancel := context.WithTimeout(context.Background(), execTimeout)
defer cancel() defer cancel()
out, err := exec.CommandContext(ctx, s.Script, args...).CombinedOutput() out, err := exec.CommandContext(ctx, script, args...).CombinedOutput()
if err != nil { if err != nil {
return "", fmt.Errorf("%v: %s", err, out) return "", fmt.Errorf("%v: %s", err, out)
} }
@@ -62,17 +92,16 @@ func (s *server) startMonitors() {
for i := range s.cfg.Monitor { for i := range s.cfg.Monitor {
sc := &s.cfg.Monitor[i] sc := &s.cfg.Monitor[i]
log.Printf("monitor started: %s (%s) every %ds", sc.Name, sc.Script, sc.Refresh) log.Printf("monitor started: %s (%s) every %ds", sc.Name, sc.Script, sc.Refresh)
go func(sc *Item) { go func(sc *Monitor) {
for { for {
v, err := runScript(sc) out, err := runScript(sc.Script)
if err != nil { if err != nil {
log.Printf("monitor %s: %v", sc.Name, err) log.Printf("monitor %s: %v", sc.Name, err)
v = "error: " + err.Error() out = "-\nerror=" + err.Error()
} else {
v = strings.TrimSpace(v)
log.Printf("monitor %s -> %s", sc.Name, v)
} }
s.monVals.Store(sc.Name, v) d := parseMonitor(out)
log.Printf("monitor %s -> %d%% (%d stats)", sc.Name, d.percentage, len(d.stats))
s.monVals.Store(sc.Name, d)
time.Sleep(time.Duration(sc.Refresh) * time.Second) time.Sleep(time.Duration(sc.Refresh) * time.Second)
} }
}(sc) }(sc)
+7 -4
View File
@@ -18,9 +18,12 @@ func (s *server) ListContent(ctx context.Context, _ *connect.Request[homelabv1.L
} }
for i := range s.cfg.Monitor { for i := range s.cfg.Monitor {
it := &s.cfg.Monitor[i] it := &s.cfg.Monitor[i]
val, _ := s.monVals.Load(it.Name) m := &homelabv1.Monitor{Name: it.Name}
v, _ := val.(string) if d, ok := s.monVals.Load(it.Name); ok {
resp.Monitors = append(resp.Monitors, &homelabv1.Item{Name: it.Name, Data: it.Data, Value: v}) md := d.(*monData)
m.Percentage, m.Stats = md.percentage, md.stats
}
resp.Monitors = append(resp.Monitors, m)
} }
for i := range s.cfg.Exec { for i := range s.cfg.Exec {
it := &s.cfg.Exec[i] it := &s.cfg.Exec[i]
@@ -38,7 +41,7 @@ func (s *server) RunScript(_ context.Context, req *connect.Request[homelabv1.Run
if len(req.Msg.GetArgs()) != it.Args { if len(req.Msg.GetArgs()) != it.Args {
return nil, connect.NewError(connect.CodeInvalidArgument, fmt.Errorf("%q takes %d args, got %d", it.Name, it.Args, len(req.Msg.GetArgs()))) return nil, connect.NewError(connect.CodeInvalidArgument, fmt.Errorf("%q takes %d args, got %d", it.Name, it.Args, len(req.Msg.GetArgs())))
} }
out, err := runScript(it, req.Msg.GetArgs()...) out, err := runScript(it.Script, req.Msg.GetArgs()...)
if err != nil { if err != nil {
log.Printf("script %s args=%v: ERROR %v", it.Name, req.Msg.GetArgs(), err) log.Printf("script %s args=%v: ERROR %v", it.Name, req.Msg.GetArgs(), err)
return nil, connect.NewError(connect.CodeInternal, err) return nil, connect.NewError(connect.CodeInternal, err)
+2 -2
View File
@@ -2,7 +2,7 @@ import { useCallback, useEffect, useState } from "preact/hooks";
import { createClient } from "@connectrpc/connect"; import { createClient } from "@connectrpc/connect";
import { createConnectTransport } from "@connectrpc/connect-web"; import { createConnectTransport } from "@connectrpc/connect-web";
import { BookOpen, Gauge, Link as LinkIcon, Play, Server } from "lucide-preact"; import { BookOpen, Gauge, Link as LinkIcon, Play, Server } from "lucide-preact";
import type { Item, Link, Service } from "./gen/homelab/v1/homelab_pb"; import type { Item, Link, Service, Monitor } from "./gen/homelab/v1/homelab_pb";
import { HomelabService } from "./gen/homelab/v1/homelab_pb"; import { HomelabService } from "./gen/homelab/v1/homelab_pb";
import { MonitorCard } from "./components/MonitorCard"; import { MonitorCard } from "./components/MonitorCard";
import { ScriptCard } from "./components/ScriptCard"; import { ScriptCard } from "./components/ScriptCard";
@@ -203,7 +203,7 @@ function MainScreen({
type Content = { type Content = {
links: Link[]; links: Link[];
monitors: Item[]; monitors: Monitor[];
exec: Item[]; exec: Item[];
services: Service[]; services: Service[];
}; };
+29 -17
View File
@@ -1,24 +1,36 @@
import type { Item } from "../gen/homelab/v1/homelab_pb"; import type { Item, Monitor } from "../gen/homelab/v1/homelab_pb";
/** Карточка монитора: percentage → radial-progress, иначе текст. */ /** Карточка монитора: percentage → radial-progress, иначе текст. */
export function MonitorCard({ s }: { s: Item }) { export function MonitorCard({ s }: { s: Monitor }) {
const pct = Number.parseInt(s.value, 10); const pct = s.percentage;
const isPct = s.data === "percentage" && !Number.isNaN(pct); const isPct = !Number.isNaN(pct);
return ( return (
<div class="card bg-base-200 shadow"> <div class="card bg-base-200 shadow">
<div class="card-body p-4"> <div class="card-body p-4 flex flex-row justify-between align-center">
<h2 class="card-title text-sm font-medium text-base-content/60">{s.name}</h2> <div>
{isPct ? ( <h2 class="card-title text-sm font-medium text-base-content/60">
<div {s.name}
class="radial-progress text-primary" </h2>
style={{ "--value": pct } as preact.JSX.CSSProperties} {isPct ? (
role="progressbar" <div
> class="radial-progress text-primary"
{pct}% style={{ "--value": pct } as preact.JSX.CSSProperties}
</div> role="progressbar"
) : ( >
<p class="font-mono text-lg break-all">{s.value || "…"}</p> {pct}%
)} </div>
) : (
<p class="font-mono text-lg break-all">{s.percentage || "…"}</p>
)}
</div>
<div class="flex flex-col gap-2">
{s.stats.map((it) => (
<div class="flex items-center gap-2 justify-end">
<span class="text-xs text-base-content/40">{it.name}</span>
<span class="font-mono text-lg break-all">{it.value}</span>
</div>
))}
</div>
</div> </div>
</div> </div>
); );
+71 -34
View File
@@ -10,7 +10,7 @@ import type { Message } from "@bufbuild/protobuf";
* Describes the file homelab/v1/homelab.proto. * Describes the file homelab/v1/homelab.proto.
*/ */
export const file_homelab_v1_homelab: GenFile = /*@__PURE__*/ export const file_homelab_v1_homelab: GenFile = /*@__PURE__*/
fileDesc("Chhob21lbGFiL3YxL2hvbWVsYWIucHJvdG8SCmhvbWVsYWIudjEiUgoESXRlbRIMCgRuYW1lGAEgASgJEgwKBGRhdGEYAiABKAkSDQoFdmFsdWUYAyABKAkSDAoEYXJncxgEIAEoBRIRCglhcmdfdHlwZXMYBSADKAkiIQoETGluaxIMCgRuYW1lGAEgASgJEgsKA3VybBgCIAEoCSIUChJMaXN0Q29udGVudFJlcXVlc3QioQEKE0xpc3RDb250ZW50UmVzcG9uc2USHwoFbGlua3MYASADKAsyEC5ob21lbGFiLnYxLkxpbmsSIgoIbW9uaXRvcnMYAiADKAsyEC5ob21lbGFiLnYxLkl0ZW0SHgoEZXhlYxgDIAMoCzIQLmhvbWVsYWIudjEuSXRlbRIlCghzZXJ2aWNlcxgEIAMoCzITLmhvbWVsYWIudjEuU2VydmljZSIlCgdEb2NNZXRhEgwKBG5hbWUYASABKAkSDAoEaGFzaBgCIAEoCSIRCg9MaXN0RG9jc1JlcXVlc3QiNQoQTGlzdERvY3NSZXNwb25zZRIhCgRkb2NzGAEgAygLMhMuaG9tZWxhYi52MS5Eb2NNZXRhIh0KDUdldERvY1JlcXVlc3QSDAoEbmFtZRgBIAEoCSIhCg5HZXREb2NSZXNwb25zZRIPCgdjb250ZW50GAEgASgJIi8KDlNhdmVEb2NSZXF1ZXN0EgwKBG5hbWUYASABKAkSDwoHY29udGVudBgCIAEoCSIfCg9TYXZlRG9jUmVzcG9uc2USDAoEaGFzaBgBIAEoCSKvAQoHU2VydmljZRIlCgRraW5kGAEgASgOMhcuaG9tZWxhYi52MS5TZXJ2aWNlS2luZBIMCgRuYW1lGAIgASgJEg0KBXN0YXRlGAMgASgJEhAKCHN1YnN0YXRlGAQgASgJEhIKCmxvYWRfc3RhdGUYBSABKAkSFwoPdW5pdF9maWxlX3N0YXRlGAYgASgJEhIKCmNvbnRhaW5lcnMYByADKAkSDQoFZXJyb3IYCCABKAkibgoUU2VydmljZUFjdGlvblJlcXVlc3QSDAoEbmFtZRgBIAEoCRIlCgRraW5kGAIgASgOMhcuaG9tZWxhYi52MS5TZXJ2aWNlS2luZBIhCgJvcBgDIAEoDjIVLmhvbWVsYWIudjEuU2VydmljZU9wIicKFVNlcnZpY2VBY3Rpb25SZXNwb25zZRIOCgZvdXRwdXQYASABKAkiSQoSU2VydmljZUluZm9SZXF1ZXN0EgwKBG5hbWUYASABKAkSJQoEa2luZBgCIAEoDjIXLmhvbWVsYWIudjEuU2VydmljZUtpbmQiJQoTU2VydmljZUluZm9SZXNwb25zZRIOCgZvdXRwdXQYASABKAkiLgoQUnVuU2NyaXB0UmVxdWVzdBIMCgRuYW1lGAEgASgJEgwKBGFyZ3MYAiADKAkiIwoRUnVuU2NyaXB0UmVzcG9uc2USDgoGb3V0cHV0GAEgASgJKiYKC1NlcnZpY2VLaW5kEgsKB1NZU1RFTUQQABIKCgZET0NLRVIQASotCglTZXJ2aWNlT3ASCQoFU1RBUlQQABIICgRTVE9QEAESCwoHUkVTVEFSVBACMpwECg5Ib21lbGFiU2VydmljZRJOCgtMaXN0Q29udGVudBIeLmhvbWVsYWIudjEuTGlzdENvbnRlbnRSZXF1ZXN0Gh8uaG9tZWxhYi52MS5MaXN0Q29udGVudFJlc3BvbnNlEkUKCExpc3REb2NzEhsuaG9tZWxhYi52MS5MaXN0RG9jc1JlcXVlc3QaHC5ob21lbGFiLnYxLkxpc3REb2NzUmVzcG9uc2USPwoGR2V0RG9jEhkuaG9tZWxhYi52MS5HZXREb2NSZXF1ZXN0GhouaG9tZWxhYi52MS5HZXREb2NSZXNwb25zZRJCCgdTYXZlRG9jEhouaG9tZWxhYi52MS5TYXZlRG9jUmVxdWVzdBobLmhvbWVsYWIudjEuU2F2ZURvY1Jlc3BvbnNlElQKDVNlcnZpY2VBY3Rpb24SIC5ob21lbGFiLnYxLlNlcnZpY2VBY3Rpb25SZXF1ZXN0GiEuaG9tZWxhYi52MS5TZXJ2aWNlQWN0aW9uUmVzcG9uc2USTgoLU2VydmljZUluZm8SHi5ob21lbGFiLnYxLlNlcnZpY2VJbmZvUmVxdWVzdBofLmhvbWVsYWIudjEuU2VydmljZUluZm9SZXNwb25zZRJICglSdW5TY3JpcHQSHC5ob21lbGFiLnYxLlJ1blNjcmlwdFJlcXVlc3QaHS5ob21lbGFiLnYxLlJ1blNjcmlwdFJlc3BvbnNlQipaKHB3YS1ob21lbGFiLW1vbi9nZW4vaG9tZWxhYi92MTtob21lbGFidjFiBnByb3RvMw"); fileDesc("Chhob21lbGFiL3YxL2hvbWVsYWIucHJvdG8SCmhvbWVsYWIudjEiNQoESXRlbRIMCgRuYW1lGAEgASgJEgwKBGFyZ3MYBCABKAUSEQoJYXJnX3R5cGVzGAUgAygJIiMKBFN0YXQSDAoEbmFtZRgBIAEoCRINCgV2YWx1ZRgCIAEoCSJMCgdNb25pdG9yEgwKBG5hbWUYASABKAkSEgoKcGVyY2VudGFnZRgCIAEoBRIfCgVzdGF0cxgDIAMoCzIQLmhvbWVsYWIudjEuU3RhdCIhCgRMaW5rEgwKBG5hbWUYASABKAkSCwoDdXJsGAIgASgJIhQKEkxpc3RDb250ZW50UmVxdWVzdCKkAQoTTGlzdENvbnRlbnRSZXNwb25zZRIfCgVsaW5rcxgBIAMoCzIQLmhvbWVsYWIudjEuTGluaxIlCghtb25pdG9ycxgCIAMoCzITLmhvbWVsYWIudjEuTW9uaXRvchIeCgRleGVjGAMgAygLMhAuaG9tZWxhYi52MS5JdGVtEiUKCHNlcnZpY2VzGAQgAygLMhMuaG9tZWxhYi52MS5TZXJ2aWNlIiUKB0RvY01ldGESDAoEbmFtZRgBIAEoCRIMCgRoYXNoGAIgASgJIhEKD0xpc3REb2NzUmVxdWVzdCI1ChBMaXN0RG9jc1Jlc3BvbnNlEiEKBGRvY3MYASADKAsyEy5ob21lbGFiLnYxLkRvY01ldGEiHQoNR2V0RG9jUmVxdWVzdBIMCgRuYW1lGAEgASgJIiEKDkdldERvY1Jlc3BvbnNlEg8KB2NvbnRlbnQYASABKAkiLwoOU2F2ZURvY1JlcXVlc3QSDAoEbmFtZRgBIAEoCRIPCgdjb250ZW50GAIgASgJIh8KD1NhdmVEb2NSZXNwb25zZRIMCgRoYXNoGAEgASgJIq8BCgdTZXJ2aWNlEiUKBGtpbmQYASABKA4yFy5ob21lbGFiLnYxLlNlcnZpY2VLaW5kEgwKBG5hbWUYAiABKAkSDQoFc3RhdGUYAyABKAkSEAoIc3Vic3RhdGUYBCABKAkSEgoKbG9hZF9zdGF0ZRgFIAEoCRIXCg91bml0X2ZpbGVfc3RhdGUYBiABKAkSEgoKY29udGFpbmVycxgHIAMoCRINCgVlcnJvchgIIAEoCSJuChRTZXJ2aWNlQWN0aW9uUmVxdWVzdBIMCgRuYW1lGAEgASgJEiUKBGtpbmQYAiABKA4yFy5ob21lbGFiLnYxLlNlcnZpY2VLaW5kEiEKAm9wGAMgASgOMhUuaG9tZWxhYi52MS5TZXJ2aWNlT3AiJwoVU2VydmljZUFjdGlvblJlc3BvbnNlEg4KBm91dHB1dBgBIAEoCSJJChJTZXJ2aWNlSW5mb1JlcXVlc3QSDAoEbmFtZRgBIAEoCRIlCgRraW5kGAIgASgOMhcuaG9tZWxhYi52MS5TZXJ2aWNlS2luZCIlChNTZXJ2aWNlSW5mb1Jlc3BvbnNlEg4KBm91dHB1dBgBIAEoCSIuChBSdW5TY3JpcHRSZXF1ZXN0EgwKBG5hbWUYASABKAkSDAoEYXJncxgCIAMoCSIjChFSdW5TY3JpcHRSZXNwb25zZRIOCgZvdXRwdXQYASABKAkqJgoLU2VydmljZUtpbmQSCwoHU1lTVEVNRBAAEgoKBkRPQ0tFUhABKi0KCVNlcnZpY2VPcBIJCgVTVEFSVBAAEggKBFNUT1AQARILCgdSRVNUQVJUEAIynAQKDkhvbWVsYWJTZXJ2aWNlEk4KC0xpc3RDb250ZW50Eh4uaG9tZWxhYi52MS5MaXN0Q29udGVudFJlcXVlc3QaHy5ob21lbGFiLnYxLkxpc3RDb250ZW50UmVzcG9uc2USRQoITGlzdERvY3MSGy5ob21lbGFiLnYxLkxpc3REb2NzUmVxdWVzdBocLmhvbWVsYWIudjEuTGlzdERvY3NSZXNwb25zZRI/CgZHZXREb2MSGS5ob21lbGFiLnYxLkdldERvY1JlcXVlc3QaGi5ob21lbGFiLnYxLkdldERvY1Jlc3BvbnNlEkIKB1NhdmVEb2MSGi5ob21lbGFiLnYxLlNhdmVEb2NSZXF1ZXN0GhsuaG9tZWxhYi52MS5TYXZlRG9jUmVzcG9uc2USVAoNU2VydmljZUFjdGlvbhIgLmhvbWVsYWIudjEuU2VydmljZUFjdGlvblJlcXVlc3QaIS5ob21lbGFiLnYxLlNlcnZpY2VBY3Rpb25SZXNwb25zZRJOCgtTZXJ2aWNlSW5mbxIeLmhvbWVsYWIudjEuU2VydmljZUluZm9SZXF1ZXN0Gh8uaG9tZWxhYi52MS5TZXJ2aWNlSW5mb1Jlc3BvbnNlEkgKCVJ1blNjcmlwdBIcLmhvbWVsYWIudjEuUnVuU2NyaXB0UmVxdWVzdBodLmhvbWVsYWIudjEuUnVuU2NyaXB0UmVzcG9uc2VCKloocHdhLWhvbWVsYWItbW9uL2dlbi9ob21lbGFiL3YxO2hvbWVsYWJ2MWIGcHJvdG8z");
/** /**
* @generated from message homelab.v1.Item * @generated from message homelab.v1.Item
@@ -21,20 +21,6 @@ export type Item = Message<"homelab.v1.Item"> & {
*/ */
name: string; name: string;
/**
* monitor: text | percentage
*
* @generated from field: string data = 2;
*/
data: string;
/**
* monitor: last output
*
* @generated from field: string value = 3;
*/
value: string;
/** /**
* exec: arg count * exec: arg count
* *
@@ -57,6 +43,57 @@ export type Item = Message<"homelab.v1.Item"> & {
export const ItemSchema: GenMessage<Item> = /*@__PURE__*/ export const ItemSchema: GenMessage<Item> = /*@__PURE__*/
messageDesc(file_homelab_v1_homelab, 0); messageDesc(file_homelab_v1_homelab, 0);
/**
* @generated from message homelab.v1.Stat
*/
export type Stat = Message<"homelab.v1.Stat"> & {
/**
* @generated from field: string name = 1;
*/
name: string;
/**
* @generated from field: string value = 2;
*/
value: string;
};
/**
* Describes the message homelab.v1.Stat.
* Use `create(StatSchema)` to create a new message.
*/
export const StatSchema: GenMessage<Stat> = /*@__PURE__*/
messageDesc(file_homelab_v1_homelab, 1);
/**
* Карточка монитора: процент (-1 = скрипт не дал процент) + строки для подписей.
*
* @generated from message homelab.v1.Monitor
*/
export type Monitor = Message<"homelab.v1.Monitor"> & {
/**
* @generated from field: string name = 1;
*/
name: string;
/**
* @generated from field: int32 percentage = 2;
*/
percentage: number;
/**
* @generated from field: repeated homelab.v1.Stat stats = 3;
*/
stats: Stat[];
};
/**
* Describes the message homelab.v1.Monitor.
* Use `create(MonitorSchema)` to create a new message.
*/
export const MonitorSchema: GenMessage<Monitor> = /*@__PURE__*/
messageDesc(file_homelab_v1_homelab, 2);
/** /**
* @generated from message homelab.v1.Link * @generated from message homelab.v1.Link
*/ */
@@ -77,7 +114,7 @@ export type Link = Message<"homelab.v1.Link"> & {
* Use `create(LinkSchema)` to create a new message. * Use `create(LinkSchema)` to create a new message.
*/ */
export const LinkSchema: GenMessage<Link> = /*@__PURE__*/ export const LinkSchema: GenMessage<Link> = /*@__PURE__*/
messageDesc(file_homelab_v1_homelab, 1); messageDesc(file_homelab_v1_homelab, 3);
/** /**
* @generated from message homelab.v1.ListContentRequest * @generated from message homelab.v1.ListContentRequest
@@ -90,7 +127,7 @@ export type ListContentRequest = Message<"homelab.v1.ListContentRequest"> & {
* Use `create(ListContentRequestSchema)` to create a new message. * Use `create(ListContentRequestSchema)` to create a new message.
*/ */
export const ListContentRequestSchema: GenMessage<ListContentRequest> = /*@__PURE__*/ export const ListContentRequestSchema: GenMessage<ListContentRequest> = /*@__PURE__*/
messageDesc(file_homelab_v1_homelab, 2); messageDesc(file_homelab_v1_homelab, 4);
/** /**
* @generated from message homelab.v1.ListContentResponse * @generated from message homelab.v1.ListContentResponse
@@ -102,9 +139,9 @@ export type ListContentResponse = Message<"homelab.v1.ListContentResponse"> & {
links: Link[]; links: Link[];
/** /**
* @generated from field: repeated homelab.v1.Item monitors = 2; * @generated from field: repeated homelab.v1.Monitor monitors = 2;
*/ */
monitors: Item[]; monitors: Monitor[];
/** /**
* @generated from field: repeated homelab.v1.Item exec = 3; * @generated from field: repeated homelab.v1.Item exec = 3;
@@ -122,7 +159,7 @@ export type ListContentResponse = Message<"homelab.v1.ListContentResponse"> & {
* Use `create(ListContentResponseSchema)` to create a new message. * Use `create(ListContentResponseSchema)` to create a new message.
*/ */
export const ListContentResponseSchema: GenMessage<ListContentResponse> = /*@__PURE__*/ export const ListContentResponseSchema: GenMessage<ListContentResponse> = /*@__PURE__*/
messageDesc(file_homelab_v1_homelab, 3); messageDesc(file_homelab_v1_homelab, 5);
/** /**
* @generated from message homelab.v1.DocMeta * @generated from message homelab.v1.DocMeta
@@ -146,7 +183,7 @@ export type DocMeta = Message<"homelab.v1.DocMeta"> & {
* Use `create(DocMetaSchema)` to create a new message. * Use `create(DocMetaSchema)` to create a new message.
*/ */
export const DocMetaSchema: GenMessage<DocMeta> = /*@__PURE__*/ export const DocMetaSchema: GenMessage<DocMeta> = /*@__PURE__*/
messageDesc(file_homelab_v1_homelab, 4); messageDesc(file_homelab_v1_homelab, 6);
/** /**
* @generated from message homelab.v1.ListDocsRequest * @generated from message homelab.v1.ListDocsRequest
@@ -159,7 +196,7 @@ export type ListDocsRequest = Message<"homelab.v1.ListDocsRequest"> & {
* Use `create(ListDocsRequestSchema)` to create a new message. * Use `create(ListDocsRequestSchema)` to create a new message.
*/ */
export const ListDocsRequestSchema: GenMessage<ListDocsRequest> = /*@__PURE__*/ export const ListDocsRequestSchema: GenMessage<ListDocsRequest> = /*@__PURE__*/
messageDesc(file_homelab_v1_homelab, 5); messageDesc(file_homelab_v1_homelab, 7);
/** /**
* @generated from message homelab.v1.ListDocsResponse * @generated from message homelab.v1.ListDocsResponse
@@ -176,7 +213,7 @@ export type ListDocsResponse = Message<"homelab.v1.ListDocsResponse"> & {
* Use `create(ListDocsResponseSchema)` to create a new message. * Use `create(ListDocsResponseSchema)` to create a new message.
*/ */
export const ListDocsResponseSchema: GenMessage<ListDocsResponse> = /*@__PURE__*/ export const ListDocsResponseSchema: GenMessage<ListDocsResponse> = /*@__PURE__*/
messageDesc(file_homelab_v1_homelab, 6); messageDesc(file_homelab_v1_homelab, 8);
/** /**
* @generated from message homelab.v1.GetDocRequest * @generated from message homelab.v1.GetDocRequest
@@ -193,7 +230,7 @@ export type GetDocRequest = Message<"homelab.v1.GetDocRequest"> & {
* Use `create(GetDocRequestSchema)` to create a new message. * Use `create(GetDocRequestSchema)` to create a new message.
*/ */
export const GetDocRequestSchema: GenMessage<GetDocRequest> = /*@__PURE__*/ export const GetDocRequestSchema: GenMessage<GetDocRequest> = /*@__PURE__*/
messageDesc(file_homelab_v1_homelab, 7); messageDesc(file_homelab_v1_homelab, 9);
/** /**
* @generated from message homelab.v1.GetDocResponse * @generated from message homelab.v1.GetDocResponse
@@ -210,7 +247,7 @@ export type GetDocResponse = Message<"homelab.v1.GetDocResponse"> & {
* Use `create(GetDocResponseSchema)` to create a new message. * Use `create(GetDocResponseSchema)` to create a new message.
*/ */
export const GetDocResponseSchema: GenMessage<GetDocResponse> = /*@__PURE__*/ export const GetDocResponseSchema: GenMessage<GetDocResponse> = /*@__PURE__*/
messageDesc(file_homelab_v1_homelab, 8); messageDesc(file_homelab_v1_homelab, 10);
/** /**
* @generated from message homelab.v1.SaveDocRequest * @generated from message homelab.v1.SaveDocRequest
@@ -232,7 +269,7 @@ export type SaveDocRequest = Message<"homelab.v1.SaveDocRequest"> & {
* Use `create(SaveDocRequestSchema)` to create a new message. * Use `create(SaveDocRequestSchema)` to create a new message.
*/ */
export const SaveDocRequestSchema: GenMessage<SaveDocRequest> = /*@__PURE__*/ export const SaveDocRequestSchema: GenMessage<SaveDocRequest> = /*@__PURE__*/
messageDesc(file_homelab_v1_homelab, 9); messageDesc(file_homelab_v1_homelab, 11);
/** /**
* @generated from message homelab.v1.SaveDocResponse * @generated from message homelab.v1.SaveDocResponse
@@ -249,7 +286,7 @@ export type SaveDocResponse = Message<"homelab.v1.SaveDocResponse"> & {
* Use `create(SaveDocResponseSchema)` to create a new message. * Use `create(SaveDocResponseSchema)` to create a new message.
*/ */
export const SaveDocResponseSchema: GenMessage<SaveDocResponse> = /*@__PURE__*/ export const SaveDocResponseSchema: GenMessage<SaveDocResponse> = /*@__PURE__*/
messageDesc(file_homelab_v1_homelab, 10); messageDesc(file_homelab_v1_homelab, 12);
/** /**
* @generated from message homelab.v1.Service * @generated from message homelab.v1.Service
@@ -315,7 +352,7 @@ export type Service = Message<"homelab.v1.Service"> & {
* Use `create(ServiceSchema)` to create a new message. * Use `create(ServiceSchema)` to create a new message.
*/ */
export const ServiceSchema: GenMessage<Service> = /*@__PURE__*/ export const ServiceSchema: GenMessage<Service> = /*@__PURE__*/
messageDesc(file_homelab_v1_homelab, 11); messageDesc(file_homelab_v1_homelab, 13);
/** /**
* @generated from message homelab.v1.ServiceActionRequest * @generated from message homelab.v1.ServiceActionRequest
@@ -342,7 +379,7 @@ export type ServiceActionRequest = Message<"homelab.v1.ServiceActionRequest"> &
* Use `create(ServiceActionRequestSchema)` to create a new message. * Use `create(ServiceActionRequestSchema)` to create a new message.
*/ */
export const ServiceActionRequestSchema: GenMessage<ServiceActionRequest> = /*@__PURE__*/ export const ServiceActionRequestSchema: GenMessage<ServiceActionRequest> = /*@__PURE__*/
messageDesc(file_homelab_v1_homelab, 12); messageDesc(file_homelab_v1_homelab, 14);
/** /**
* @generated from message homelab.v1.ServiceActionResponse * @generated from message homelab.v1.ServiceActionResponse
@@ -359,7 +396,7 @@ export type ServiceActionResponse = Message<"homelab.v1.ServiceActionResponse">
* Use `create(ServiceActionResponseSchema)` to create a new message. * Use `create(ServiceActionResponseSchema)` to create a new message.
*/ */
export const ServiceActionResponseSchema: GenMessage<ServiceActionResponse> = /*@__PURE__*/ export const ServiceActionResponseSchema: GenMessage<ServiceActionResponse> = /*@__PURE__*/
messageDesc(file_homelab_v1_homelab, 13); messageDesc(file_homelab_v1_homelab, 15);
/** /**
* @generated from message homelab.v1.ServiceInfoRequest * @generated from message homelab.v1.ServiceInfoRequest
@@ -381,7 +418,7 @@ export type ServiceInfoRequest = Message<"homelab.v1.ServiceInfoRequest"> & {
* Use `create(ServiceInfoRequestSchema)` to create a new message. * Use `create(ServiceInfoRequestSchema)` to create a new message.
*/ */
export const ServiceInfoRequestSchema: GenMessage<ServiceInfoRequest> = /*@__PURE__*/ export const ServiceInfoRequestSchema: GenMessage<ServiceInfoRequest> = /*@__PURE__*/
messageDesc(file_homelab_v1_homelab, 14); messageDesc(file_homelab_v1_homelab, 16);
/** /**
* @generated from message homelab.v1.ServiceInfoResponse * @generated from message homelab.v1.ServiceInfoResponse
@@ -398,7 +435,7 @@ export type ServiceInfoResponse = Message<"homelab.v1.ServiceInfoResponse"> & {
* Use `create(ServiceInfoResponseSchema)` to create a new message. * Use `create(ServiceInfoResponseSchema)` to create a new message.
*/ */
export const ServiceInfoResponseSchema: GenMessage<ServiceInfoResponse> = /*@__PURE__*/ export const ServiceInfoResponseSchema: GenMessage<ServiceInfoResponse> = /*@__PURE__*/
messageDesc(file_homelab_v1_homelab, 15); messageDesc(file_homelab_v1_homelab, 17);
/** /**
* @generated from message homelab.v1.RunScriptRequest * @generated from message homelab.v1.RunScriptRequest
@@ -420,7 +457,7 @@ export type RunScriptRequest = Message<"homelab.v1.RunScriptRequest"> & {
* Use `create(RunScriptRequestSchema)` to create a new message. * Use `create(RunScriptRequestSchema)` to create a new message.
*/ */
export const RunScriptRequestSchema: GenMessage<RunScriptRequest> = /*@__PURE__*/ export const RunScriptRequestSchema: GenMessage<RunScriptRequest> = /*@__PURE__*/
messageDesc(file_homelab_v1_homelab, 16); messageDesc(file_homelab_v1_homelab, 18);
/** /**
* @generated from message homelab.v1.RunScriptResponse * @generated from message homelab.v1.RunScriptResponse
@@ -437,7 +474,7 @@ export type RunScriptResponse = Message<"homelab.v1.RunScriptResponse"> & {
* Use `create(RunScriptResponseSchema)` to create a new message. * Use `create(RunScriptResponseSchema)` to create a new message.
*/ */
export const RunScriptResponseSchema: GenMessage<RunScriptResponse> = /*@__PURE__*/ export const RunScriptResponseSchema: GenMessage<RunScriptResponse> = /*@__PURE__*/
messageDesc(file_homelab_v1_homelab, 17); messageDesc(file_homelab_v1_homelab, 19);
/** /**
* One card in the Services view: a systemd user unit or a docker compose project. * One card in the Services view: a systemd user unit or a docker compose project.