A => .envrc +1 -0
A => .gitignore +3 -0
@@ 1,3 @@
+/.direnv/
+
+/.pre-commit-config.yaml
A => flake.lock +125 -0
@@ 1,125 @@
+{
+ "nodes": {
+ "flake-compat": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1696426674,
+ "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
+ "owner": "edolstra",
+ "repo": "flake-compat",
+ "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
+ "type": "github"
+ },
+ "original": {
+ "owner": "edolstra",
+ "repo": "flake-compat",
+ "type": "github"
+ }
+ },
+ "flake-parts": {
+ "inputs": {
+ "nixpkgs-lib": [
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1730504689,
+ "narHash": "sha256-hgmguH29K2fvs9szpq2r3pz2/8cJd2LPS+b4tfNFCwE=",
+ "owner": "hercules-ci",
+ "repo": "flake-parts",
+ "rev": "506278e768c2a08bec68eb62932193e341f55c90",
+ "type": "github"
+ },
+ "original": {
+ "owner": "hercules-ci",
+ "repo": "flake-parts",
+ "type": "github"
+ }
+ },
+ "gitignore": {
+ "inputs": {
+ "nixpkgs": [
+ "pre-commit-hooks",
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1709087332,
+ "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
+ "owner": "hercules-ci",
+ "repo": "gitignore.nix",
+ "rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
+ "type": "github"
+ },
+ "original": {
+ "owner": "hercules-ci",
+ "repo": "gitignore.nix",
+ "type": "github"
+ }
+ },
+ "nixpkgs": {
+ "locked": {
+ "lastModified": 1731763621,
+ "narHash": "sha256-ddcX4lQL0X05AYkrkV2LMFgGdRvgap7Ho8kgon3iWZk=",
+ "owner": "nixos",
+ "repo": "nixpkgs",
+ "rev": "c69a9bffbecde46b4b939465422ddc59493d3e4d",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nixos",
+ "ref": "nixpkgs-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs-stable": {
+ "locked": {
+ "lastModified": 1730741070,
+ "narHash": "sha256-edm8WG19kWozJ/GqyYx2VjW99EdhjKwbY3ZwdlPAAlo=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "d063c1dd113c91ab27959ba540c0d9753409edf3",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixos-24.05",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "pre-commit-hooks": {
+ "inputs": {
+ "flake-compat": "flake-compat",
+ "gitignore": "gitignore",
+ "nixpkgs": [
+ "nixpkgs"
+ ],
+ "nixpkgs-stable": "nixpkgs-stable"
+ },
+ "locked": {
+ "lastModified": 1731363552,
+ "narHash": "sha256-vFta1uHnD29VUY4HJOO/D6p6rxyObnf+InnSMT4jlMU=",
+ "owner": "cachix",
+ "repo": "git-hooks.nix",
+ "rev": "cd1af27aa85026ac759d5d3fccf650abe7e1bbf0",
+ "type": "github"
+ },
+ "original": {
+ "owner": "cachix",
+ "repo": "git-hooks.nix",
+ "type": "github"
+ }
+ },
+ "root": {
+ "inputs": {
+ "flake-parts": "flake-parts",
+ "nixpkgs": "nixpkgs",
+ "pre-commit-hooks": "pre-commit-hooks"
+ }
+ }
+ },
+ "root": "root",
+ "version": 7
+}
A => flake.nix +64 -0
@@ 1,64 @@
+{
+ inputs = {
+ nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
+ flake-parts = {
+ url = "github:hercules-ci/flake-parts";
+ inputs.nixpkgs-lib.follows = "nixpkgs";
+ };
+
+ pre-commit-hooks = {
+ url = "github:cachix/git-hooks.nix";
+ inputs.nixpkgs.follows = "nixpkgs";
+ };
+ };
+
+ outputs = inputs @ {
+ self,
+ nixpkgs,
+ flake-parts,
+ pre-commit-hooks,
+ ...
+ }:
+ flake-parts.lib.mkFlake {inherit inputs;} {
+ systems = ["x86_64-linux"];
+ perSystem = {
+ config,
+ lib,
+ pkgs,
+ system,
+ ...
+ }: let
+ libs = [];
+ in {
+ checks.pre-commit-check = pre-commit-hooks.lib.${system}.run {
+ src = ./.;
+ hooks = {
+ # Nix formatting
+ alejandra.enable = true;
+
+ # Spell checking
+ typos.enable = true;
+ };
+ };
+
+ devShells.default = pkgs.mkShell {
+ buildInputs = with pkgs;
+ [
+ just
+
+ protobuf
+ protoc-gen-go
+ protoc-gen-go-grpc
+ ]
+ ++ libs
+ ++ [
+ self.checks.${system}.pre-commit-check.enabledPackages
+ ];
+ LD_LIBRARY_PATH = lib.makeLibraryPath libs;
+ shellHook = ''
+ ${self.checks.${system}.pre-commit-check.shellHook}
+ '';
+ };
+ };
+ };
+}
A => go/shared/target.pb.go +344 -0
@@ 1,344 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.35.1
+// protoc v5.28.3
+// source: shared/target.proto
+
+package target
+
+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 TargetState int32
+
+const (
+ TargetState_DOWN TargetState = 0
+ TargetState_UP TargetState = 1
+ TargetState_UNKNOWN TargetState = 2
+)
+
+// Enum value maps for TargetState.
+var (
+ TargetState_name = map[int32]string{
+ 0: "DOWN",
+ 1: "UP",
+ 2: "UNKNOWN",
+ }
+ TargetState_value = map[string]int32{
+ "DOWN": 0,
+ "UP": 1,
+ "UNKNOWN": 2,
+ }
+)
+
+func (x TargetState) Enum() *TargetState {
+ p := new(TargetState)
+ *p = x
+ return p
+}
+
+func (x TargetState) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (TargetState) Descriptor() protoreflect.EnumDescriptor {
+ return file_shared_target_proto_enumTypes[0].Descriptor()
+}
+
+func (TargetState) Type() protoreflect.EnumType {
+ return &file_shared_target_proto_enumTypes[0]
+}
+
+func (x TargetState) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use TargetState.Descriptor instead.
+func (TargetState) EnumDescriptor() ([]byte, []int) {
+ return file_shared_target_proto_rawDescGZIP(), []int{0}
+}
+
+type Target struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
+ Addr string `protobuf:"bytes,2,opt,name=addr,proto3" json:"addr,omitempty"`
+ Interval uint32 `protobuf:"varint,3,opt,name=interval,proto3" json:"interval,omitempty"`
+ // Types that are assignable to Method:
+ //
+ // *Target_Ping
+ // *Target_Get
+ Method isTarget_Method `protobuf_oneof:"method"`
+}
+
+func (x *Target) Reset() {
+ *x = Target{}
+ mi := &file_shared_target_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *Target) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Target) ProtoMessage() {}
+
+func (x *Target) ProtoReflect() protoreflect.Message {
+ mi := &file_shared_target_proto_msgTypes[0]
+ 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 Target.ProtoReflect.Descriptor instead.
+func (*Target) Descriptor() ([]byte, []int) {
+ return file_shared_target_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *Target) GetId() uint32 {
+ if x != nil {
+ return x.Id
+ }
+ return 0
+}
+
+func (x *Target) GetAddr() string {
+ if x != nil {
+ return x.Addr
+ }
+ return ""
+}
+
+func (x *Target) GetInterval() uint32 {
+ if x != nil {
+ return x.Interval
+ }
+ return 0
+}
+
+func (m *Target) GetMethod() isTarget_Method {
+ if m != nil {
+ return m.Method
+ }
+ return nil
+}
+
+func (x *Target) GetPing() *Target_MethodPing {
+ if x, ok := x.GetMethod().(*Target_Ping); ok {
+ return x.Ping
+ }
+ return nil
+}
+
+func (x *Target) GetGet() *Target_MethodGET {
+ if x, ok := x.GetMethod().(*Target_Get); ok {
+ return x.Get
+ }
+ return nil
+}
+
+type isTarget_Method interface {
+ isTarget_Method()
+}
+
+type Target_Ping struct {
+ Ping *Target_MethodPing `protobuf:"bytes,4,opt,name=ping,proto3,oneof"`
+}
+
+type Target_Get struct {
+ Get *Target_MethodGET `protobuf:"bytes,5,opt,name=get,proto3,oneof"`
+}
+
+func (*Target_Ping) isTarget_Method() {}
+
+func (*Target_Get) isTarget_Method() {}
+
+type Target_MethodPing struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+}
+
+func (x *Target_MethodPing) Reset() {
+ *x = Target_MethodPing{}
+ mi := &file_shared_target_proto_msgTypes[1]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *Target_MethodPing) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Target_MethodPing) ProtoMessage() {}
+
+func (x *Target_MethodPing) ProtoReflect() protoreflect.Message {
+ mi := &file_shared_target_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 Target_MethodPing.ProtoReflect.Descriptor instead.
+func (*Target_MethodPing) Descriptor() ([]byte, []int) {
+ return file_shared_target_proto_rawDescGZIP(), []int{0, 0}
+}
+
+type Target_MethodGET struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ OkCodes []uint32 `protobuf:"varint,1,rep,packed,name=ok_codes,json=okCodes,proto3" json:"ok_codes,omitempty"`
+}
+
+func (x *Target_MethodGET) Reset() {
+ *x = Target_MethodGET{}
+ mi := &file_shared_target_proto_msgTypes[2]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *Target_MethodGET) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Target_MethodGET) ProtoMessage() {}
+
+func (x *Target_MethodGET) ProtoReflect() protoreflect.Message {
+ mi := &file_shared_target_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 Target_MethodGET.ProtoReflect.Descriptor instead.
+func (*Target_MethodGET) Descriptor() ([]byte, []int) {
+ return file_shared_target_proto_rawDescGZIP(), []int{0, 1}
+}
+
+func (x *Target_MethodGET) GetOkCodes() []uint32 {
+ if x != nil {
+ return x.OkCodes
+ }
+ return nil
+}
+
+var File_shared_target_proto protoreflect.FileDescriptor
+
+var file_shared_target_proto_rawDesc = []byte{
+ 0x0a, 0x13, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x2e,
+ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0e, 0x65, 0x6d, 0x65, 0x72, 0x77, 0x65, 0x6e, 0x2e, 0x73,
+ 0x68, 0x61, 0x72, 0x65, 0x64, 0x22, 0xf7, 0x01, 0x0a, 0x06, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74,
+ 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x69, 0x64,
+ 0x12, 0x12, 0x0a, 0x04, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
+ 0x61, 0x64, 0x64, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c,
+ 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c,
+ 0x12, 0x37, 0x0a, 0x04, 0x70, 0x69, 0x6e, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21,
+ 0x2e, 0x65, 0x6d, 0x65, 0x72, 0x77, 0x65, 0x6e, 0x2e, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2e,
+ 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x50, 0x69, 0x6e,
+ 0x67, 0x48, 0x00, 0x52, 0x04, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x34, 0x0a, 0x03, 0x67, 0x65, 0x74,
+ 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x65, 0x6d, 0x65, 0x72, 0x77, 0x65, 0x6e,
+ 0x2e, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x2e, 0x4d,
+ 0x65, 0x74, 0x68, 0x6f, 0x64, 0x47, 0x45, 0x54, 0x48, 0x00, 0x52, 0x03, 0x67, 0x65, 0x74, 0x1a,
+ 0x0c, 0x0a, 0x0a, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x50, 0x69, 0x6e, 0x67, 0x1a, 0x26, 0x0a,
+ 0x09, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x47, 0x45, 0x54, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x6b,
+ 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0d, 0x52, 0x07, 0x6f, 0x6b,
+ 0x43, 0x6f, 0x64, 0x65, 0x73, 0x42, 0x08, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x2a,
+ 0x2c, 0x0a, 0x0b, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x08,
+ 0x0a, 0x04, 0x44, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x06, 0x0a, 0x02, 0x55, 0x50, 0x10, 0x01,
+ 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x02, 0x42, 0x30, 0x5a,
+ 0x2e, 0x67, 0x69, 0x74, 0x2e, 0x73, 0x72, 0x63, 0x2e, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2f, 0x7e,
+ 0x6c, 0x69, 0x6c, 0x6a, 0x61, 0x6d, 0x6f, 0x2f, 0x65, 0x6d, 0x65, 0x72, 0x77, 0x65, 0x6e, 0x2d,
+ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x62,
+ 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+ file_shared_target_proto_rawDescOnce sync.Once
+ file_shared_target_proto_rawDescData = file_shared_target_proto_rawDesc
+)
+
+func file_shared_target_proto_rawDescGZIP() []byte {
+ file_shared_target_proto_rawDescOnce.Do(func() {
+ file_shared_target_proto_rawDescData = protoimpl.X.CompressGZIP(file_shared_target_proto_rawDescData)
+ })
+ return file_shared_target_proto_rawDescData
+}
+
+var file_shared_target_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
+var file_shared_target_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
+var file_shared_target_proto_goTypes = []any{
+ (TargetState)(0), // 0: emerwen.shared.TargetState
+ (*Target)(nil), // 1: emerwen.shared.Target
+ (*Target_MethodPing)(nil), // 2: emerwen.shared.Target.MethodPing
+ (*Target_MethodGET)(nil), // 3: emerwen.shared.Target.MethodGET
+}
+var file_shared_target_proto_depIdxs = []int32{
+ 2, // 0: emerwen.shared.Target.ping:type_name -> emerwen.shared.Target.MethodPing
+ 3, // 1: emerwen.shared.Target.get:type_name -> emerwen.shared.Target.MethodGET
+ 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_shared_target_proto_init() }
+func file_shared_target_proto_init() {
+ if File_shared_target_proto != nil {
+ return
+ }
+ file_shared_target_proto_msgTypes[0].OneofWrappers = []any{
+ (*Target_Ping)(nil),
+ (*Target_Get)(nil),
+ }
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor: file_shared_target_proto_rawDesc,
+ NumEnums: 1,
+ NumMessages: 3,
+ NumExtensions: 0,
+ NumServices: 0,
+ },
+ GoTypes: file_shared_target_proto_goTypes,
+ DependencyIndexes: file_shared_target_proto_depIdxs,
+ EnumInfos: file_shared_target_proto_enumTypes,
+ MessageInfos: file_shared_target_proto_msgTypes,
+ }.Build()
+ File_shared_target_proto = out.File
+ file_shared_target_proto_rawDesc = nil
+ file_shared_target_proto_goTypes = nil
+ file_shared_target_proto_depIdxs = nil
+}
A => go/shared/worker.pb.go +153 -0
@@ 1,153 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.35.1
+// protoc v5.28.3
+// source: shared/worker.proto
+
+package worker
+
+import (
+ target "git.src.quest/~liljamo/emerwen-proto/go/target"
+ 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 Worker struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
+ AuthToken string `protobuf:"bytes,2,opt,name=auth_token,json=authToken,proto3" json:"auth_token,omitempty"`
+ Targets []*target.Target `protobuf:"bytes,3,rep,name=targets,proto3" json:"targets,omitempty"`
+}
+
+func (x *Worker) Reset() {
+ *x = Worker{}
+ mi := &file_shared_worker_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *Worker) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Worker) ProtoMessage() {}
+
+func (x *Worker) ProtoReflect() protoreflect.Message {
+ mi := &file_shared_worker_proto_msgTypes[0]
+ 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 Worker.ProtoReflect.Descriptor instead.
+func (*Worker) Descriptor() ([]byte, []int) {
+ return file_shared_worker_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *Worker) GetId() uint32 {
+ if x != nil {
+ return x.Id
+ }
+ return 0
+}
+
+func (x *Worker) GetAuthToken() string {
+ if x != nil {
+ return x.AuthToken
+ }
+ return ""
+}
+
+func (x *Worker) GetTargets() []*target.Target {
+ if x != nil {
+ return x.Targets
+ }
+ return nil
+}
+
+var File_shared_worker_proto protoreflect.FileDescriptor
+
+var file_shared_worker_proto_rawDesc = []byte{
+ 0x0a, 0x13, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x2e,
+ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0e, 0x65, 0x6d, 0x65, 0x72, 0x77, 0x65, 0x6e, 0x2e, 0x73,
+ 0x68, 0x61, 0x72, 0x65, 0x64, 0x1a, 0x13, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2f, 0x74, 0x61,
+ 0x72, 0x67, 0x65, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x69, 0x0a, 0x06, 0x57, 0x6f,
+ 0x72, 0x6b, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d,
+ 0x52, 0x02, 0x69, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x74, 0x6f, 0x6b,
+ 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, 0x54, 0x6f,
+ 0x6b, 0x65, 0x6e, 0x12, 0x30, 0x0a, 0x07, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x18, 0x03,
+ 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x65, 0x6d, 0x65, 0x72, 0x77, 0x65, 0x6e, 0x2e, 0x73,
+ 0x68, 0x61, 0x72, 0x65, 0x64, 0x2e, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x07, 0x74, 0x61,
+ 0x72, 0x67, 0x65, 0x74, 0x73, 0x42, 0x30, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x2e, 0x73, 0x72, 0x63,
+ 0x2e, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2f, 0x7e, 0x6c, 0x69, 0x6c, 0x6a, 0x61, 0x6d, 0x6f, 0x2f,
+ 0x65, 0x6d, 0x65, 0x72, 0x77, 0x65, 0x6e, 0x2d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f,
+ 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+ file_shared_worker_proto_rawDescOnce sync.Once
+ file_shared_worker_proto_rawDescData = file_shared_worker_proto_rawDesc
+)
+
+func file_shared_worker_proto_rawDescGZIP() []byte {
+ file_shared_worker_proto_rawDescOnce.Do(func() {
+ file_shared_worker_proto_rawDescData = protoimpl.X.CompressGZIP(file_shared_worker_proto_rawDescData)
+ })
+ return file_shared_worker_proto_rawDescData
+}
+
+var file_shared_worker_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
+var file_shared_worker_proto_goTypes = []any{
+ (*Worker)(nil), // 0: emerwen.shared.Worker
+ (*target.Target)(nil), // 1: emerwen.shared.Target
+}
+var file_shared_worker_proto_depIdxs = []int32{
+ 1, // 0: emerwen.shared.Worker.targets:type_name -> emerwen.shared.Target
+ 1, // [1:1] is the sub-list for method output_type
+ 1, // [1:1] is the sub-list for method input_type
+ 1, // [1:1] is the sub-list for extension type_name
+ 1, // [1:1] is the sub-list for extension extendee
+ 0, // [0:1] is the sub-list for field type_name
+}
+
+func init() { file_shared_worker_proto_init() }
+func file_shared_worker_proto_init() {
+ if File_shared_worker_proto != nil {
+ return
+ }
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor: file_shared_worker_proto_rawDesc,
+ NumEnums: 0,
+ NumMessages: 1,
+ NumExtensions: 0,
+ NumServices: 0,
+ },
+ GoTypes: file_shared_worker_proto_goTypes,
+ DependencyIndexes: file_shared_worker_proto_depIdxs,
+ MessageInfos: file_shared_worker_proto_msgTypes,
+ }.Build()
+ File_shared_worker_proto = out.File
+ file_shared_worker_proto_rawDesc = nil
+ file_shared_worker_proto_goTypes = nil
+ file_shared_worker_proto_depIdxs = nil
+}
A => go/webtomaster.pb.go +146 -0
@@ 1,146 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.35.1
+// protoc v5.28.3
+// source: webtomaster.proto
+
+package _go
+
+import (
+ worker "git.src.quest/~liljamo/emerwen-proto/go/worker"
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+ emptypb "google.golang.org/protobuf/types/known/emptypb"
+ 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 WorkersResponse struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Workers []*worker.Worker `protobuf:"bytes,1,rep,name=workers,proto3" json:"workers,omitempty"`
+}
+
+func (x *WorkersResponse) Reset() {
+ *x = WorkersResponse{}
+ mi := &file_webtomaster_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+}
+
+func (x *WorkersResponse) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*WorkersResponse) ProtoMessage() {}
+
+func (x *WorkersResponse) ProtoReflect() protoreflect.Message {
+ mi := &file_webtomaster_proto_msgTypes[0]
+ 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 WorkersResponse.ProtoReflect.Descriptor instead.
+func (*WorkersResponse) Descriptor() ([]byte, []int) {
+ return file_webtomaster_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *WorkersResponse) GetWorkers() []*worker.Worker {
+ if x != nil {
+ return x.Workers
+ }
+ return nil
+}
+
+var File_webtomaster_proto protoreflect.FileDescriptor
+
+var file_webtomaster_proto_rawDesc = []byte{
+ 0x0a, 0x11, 0x77, 0x65, 0x62, 0x74, 0x6f, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x70, 0x72,
+ 0x6f, 0x74, 0x6f, 0x12, 0x13, 0x65, 0x6d, 0x65, 0x72, 0x77, 0x65, 0x6e, 0x2e, 0x77, 0x65, 0x62,
+ 0x74, 0x6f, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
+ 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e,
+ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x13, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2f, 0x77, 0x6f,
+ 0x72, 0x6b, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x43, 0x0a, 0x0f, 0x57, 0x6f,
+ 0x72, 0x6b, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a,
+ 0x07, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16,
+ 0x2e, 0x65, 0x6d, 0x65, 0x72, 0x77, 0x65, 0x6e, 0x2e, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x2e,
+ 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x52, 0x07, 0x77, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x73, 0x32,
+ 0x59, 0x0a, 0x0b, 0x57, 0x65, 0x62, 0x54, 0x6f, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x12, 0x4a,
+ 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x57, 0x6f, 0x72, 0x6b, 0x65, 0x72, 0x73, 0x12, 0x16, 0x2e, 0x67,
+ 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45,
+ 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x24, 0x2e, 0x65, 0x6d, 0x65, 0x72, 0x77, 0x65, 0x6e, 0x2e, 0x77,
+ 0x65, 0x62, 0x74, 0x6f, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x65,
+ 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x29, 0x5a, 0x27, 0x67, 0x69,
+ 0x74, 0x2e, 0x73, 0x72, 0x63, 0x2e, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2f, 0x7e, 0x6c, 0x69, 0x6c,
+ 0x6a, 0x61, 0x6d, 0x6f, 0x2f, 0x65, 0x6d, 0x65, 0x72, 0x77, 0x65, 0x6e, 0x2d, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+ file_webtomaster_proto_rawDescOnce sync.Once
+ file_webtomaster_proto_rawDescData = file_webtomaster_proto_rawDesc
+)
+
+func file_webtomaster_proto_rawDescGZIP() []byte {
+ file_webtomaster_proto_rawDescOnce.Do(func() {
+ file_webtomaster_proto_rawDescData = protoimpl.X.CompressGZIP(file_webtomaster_proto_rawDescData)
+ })
+ return file_webtomaster_proto_rawDescData
+}
+
+var file_webtomaster_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
+var file_webtomaster_proto_goTypes = []any{
+ (*WorkersResponse)(nil), // 0: emerwen.webtomaster.WorkersResponse
+ (*worker.Worker)(nil), // 1: emerwen.shared.Worker
+ (*emptypb.Empty)(nil), // 2: google.protobuf.Empty
+}
+var file_webtomaster_proto_depIdxs = []int32{
+ 1, // 0: emerwen.webtomaster.WorkersResponse.workers:type_name -> emerwen.shared.Worker
+ 2, // 1: emerwen.webtomaster.WebToMaster.GetWorkers:input_type -> google.protobuf.Empty
+ 0, // 2: emerwen.webtomaster.WebToMaster.GetWorkers:output_type -> emerwen.webtomaster.WorkersResponse
+ 2, // [2:3] is the sub-list for method output_type
+ 1, // [1:2] is the sub-list for method input_type
+ 1, // [1:1] is the sub-list for extension type_name
+ 1, // [1:1] is the sub-list for extension extendee
+ 0, // [0:1] is the sub-list for field type_name
+}
+
+func init() { file_webtomaster_proto_init() }
+func file_webtomaster_proto_init() {
+ if File_webtomaster_proto != nil {
+ return
+ }
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor: file_webtomaster_proto_rawDesc,
+ NumEnums: 0,
+ NumMessages: 1,
+ NumExtensions: 0,
+ NumServices: 1,
+ },
+ GoTypes: file_webtomaster_proto_goTypes,
+ DependencyIndexes: file_webtomaster_proto_depIdxs,
+ MessageInfos: file_webtomaster_proto_msgTypes,
+ }.Build()
+ File_webtomaster_proto = out.File
+ file_webtomaster_proto_rawDesc = nil
+ file_webtomaster_proto_goTypes = nil
+ file_webtomaster_proto_depIdxs = nil
+}
A => go/webtomaster_grpc.pb.go +110 -0
@@ 1,110 @@
+// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
+// versions:
+// - protoc-gen-go-grpc v1.3.0
+// - protoc v5.28.3
+// source: webtomaster.proto
+
+package _go
+
+import (
+ context "context"
+ grpc "google.golang.org/grpc"
+ codes "google.golang.org/grpc/codes"
+ status "google.golang.org/grpc/status"
+ emptypb "google.golang.org/protobuf/types/known/emptypb"
+)
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+// Requires gRPC-Go v1.32.0 or later.
+const _ = grpc.SupportPackageIsVersion7
+
+const (
+ WebToMaster_GetWorkers_FullMethodName = "/emerwen.webtomaster.WebToMaster/GetWorkers"
+)
+
+// WebToMasterClient is the client API for WebToMaster service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
+type WebToMasterClient interface {
+ GetWorkers(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*WorkersResponse, error)
+}
+
+type webToMasterClient struct {
+ cc grpc.ClientConnInterface
+}
+
+func NewWebToMasterClient(cc grpc.ClientConnInterface) WebToMasterClient {
+ return &webToMasterClient{cc}
+}
+
+func (c *webToMasterClient) GetWorkers(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*WorkersResponse, error) {
+ out := new(WorkersResponse)
+ err := c.cc.Invoke(ctx, WebToMaster_GetWorkers_FullMethodName, in, out, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+// WebToMasterServer is the server API for WebToMaster service.
+// All implementations must embed UnimplementedWebToMasterServer
+// for forward compatibility
+type WebToMasterServer interface {
+ GetWorkers(context.Context, *emptypb.Empty) (*WorkersResponse, error)
+ mustEmbedUnimplementedWebToMasterServer()
+}
+
+// UnimplementedWebToMasterServer must be embedded to have forward compatible implementations.
+type UnimplementedWebToMasterServer struct {
+}
+
+func (UnimplementedWebToMasterServer) GetWorkers(context.Context, *emptypb.Empty) (*WorkersResponse, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method GetWorkers not implemented")
+}
+func (UnimplementedWebToMasterServer) mustEmbedUnimplementedWebToMasterServer() {}
+
+// UnsafeWebToMasterServer may be embedded to opt out of forward compatibility for this service.
+// Use of this interface is not recommended, as added methods to WebToMasterServer will
+// result in compilation errors.
+type UnsafeWebToMasterServer interface {
+ mustEmbedUnimplementedWebToMasterServer()
+}
+
+func RegisterWebToMasterServer(s grpc.ServiceRegistrar, srv WebToMasterServer) {
+ s.RegisterService(&WebToMaster_ServiceDesc, srv)
+}
+
+func _WebToMaster_GetWorkers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(emptypb.Empty)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(WebToMasterServer).GetWorkers(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: WebToMaster_GetWorkers_FullMethodName,
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(WebToMasterServer).GetWorkers(ctx, req.(*emptypb.Empty))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
+// WebToMaster_ServiceDesc is the grpc.ServiceDesc for WebToMaster service.
+// It's only intended for direct use with grpc.RegisterService,
+// and not to be introspected or modified (even as a copy)
+var WebToMaster_ServiceDesc = grpc.ServiceDesc{
+ ServiceName: "emerwen.webtomaster.WebToMaster",
+ HandlerType: (*WebToMasterServer)(nil),
+ Methods: []grpc.MethodDesc{
+ {
+ MethodName: "GetWorkers",
+ Handler: _WebToMaster_GetWorkers_Handler,
+ },
+ },
+ Streams: []grpc.StreamDesc{},
+ Metadata: "webtomaster.proto",
+}
A => justfile +8 -0
@@ 1,8 @@
+_default:
+ just --list
+
+compile-protos-go:
+ protoc --go_out=go --go_opt=paths=source_relative \
+ --go-grpc_out=go --go-grpc_opt=paths=source_relative \
+ --proto_path=proto \
+ proto/webtomaster.proto proto/shared/target.proto proto/shared/worker.proto
A => proto/shared/target.proto +25 -0
@@ 1,25 @@
+syntax = "proto3";
+package emerwen.shared;
+
+option go_package = "git.src.quest/~liljamo/emerwen-proto/go/target";
+
+message Target {
+ uint32 id = 1;
+ string addr = 2;
+ uint32 interval = 3;
+ oneof method {
+ MethodPing ping = 4;
+ MethodGET get = 5;
+ }
+
+ message MethodPing {}
+ message MethodGET {
+ repeated uint32 ok_codes = 1;
+ }
+}
+
+enum TargetState {
+ DOWN = 0;
+ UP = 1;
+ UNKNOWN = 2;
+}
A => proto/shared/worker.proto +12 -0
@@ 1,12 @@
+syntax = "proto3";
+package emerwen.shared;
+
+option go_package = "git.src.quest/~liljamo/emerwen-proto/go/worker";
+
+import "shared/target.proto";
+
+message Worker {
+ uint32 id = 1;
+ string auth_token = 2;
+ repeated shared.Target targets = 3;
+}
A => proto/webtomaster.proto +15 -0
@@ 1,15 @@
+syntax = "proto3";
+package emerwen.webtomaster;
+
+option go_package = "git.src.quest/~liljamo/emerwen-proto/go";
+
+import "google/protobuf/empty.proto";
+import "shared/worker.proto";
+
+service WebToMaster {
+ rpc GetWorkers (google.protobuf.Empty) returns (WorkersResponse);
+}
+
+message WorkersResponse {
+ repeated shared.Worker workers = 1;
+}
A => proto/workertomaster.proto +19 -0
@@ 1,19 @@
+syntax = "proto3";
+package emerwen.workertomaster;
+
+import "google/protobuf/empty.proto";
+import "shared/target.proto";
+
+service WorkerToMaster {
+ rpc GetTargets (google.protobuf.Empty) returns (TargetsResponse);
+ rpc SetTargetState (SetTargetStateRequest) returns (google.protobuf.Empty);
+}
+
+message TargetsResponse {
+ repeated shared.Target targets = 1;
+}
+
+message SetTargetStateRequest {
+ uint32 id = 1;
+ shared.TargetState state = 2;
+}