]> git.puffer.fish Git - matthieu/nova.git/commitdiff
Add missing files
authorMatthieu <matthieu@developershouse.xyz>
Sun, 26 Sep 2021 17:27:21 +0000 (21:27 +0400)
committerMatthieu <matthieu@developershouse.xyz>
Sun, 26 Sep 2021 17:27:21 +0000 (21:27 +0400)
.circleci/config.yml
.gitignore
Makefile [new file with mode: 0644]
bazel/lib/BUILD [new file with mode: 0644]
bazel/lib/expand_template.bzl [new file with mode: 0644]
common/management/BUILD.bazel [new file with mode: 0644]
common/management/nova.management.v1alpha.proto [new file with mode: 0644]
common/version.go.in [new file with mode: 0644]
novactl/cmd/cluster.go [new file with mode: 0644]
novactl/lib/conn.go [new file with mode: 0644]

index df9ffe066beb9b0098de75dd8b3b10502c685733..5539cceda3575ca9f4d6a42ccca7ab0f12da5d81 100644 (file)
@@ -18,16 +18,28 @@ commands:
 
 jobs:
   build:
-    docker:
-      - image: cimg/base:stable
+    machine:
+      image: 'ubuntu-2004:202010-01'
     steps:
       - checkout
       - setup-bazel
+      - restore_cache:
+          keys:
+            - bazel-cache-{{ .Branch }}
       - run:
           name: "Build"
           command: "bazel build //:packages"
+      - save_cache:
+          paths:
+            - ~/.cache/bazel
+          key: bazel-cache-{{ .Branch }}
+      - run:
+          name: "Move artifacts"
+          command: |
+            mkdir ~/project/artifacts
+            mv ~/project/bazel-bin/packages* ~/project/artifacts
       - store_artifacts:
-          path: ~/project/bazel-bin/packages*
+          path: ~/project/artifacts
 
 workflows:
   build-workflow:
index 2cd395b8ca08fb17a6c7cb4dcb4a9d27aadacbd8..161aa0dbc7364088533f06dfcf6aebf23bf0c4fc 100644 (file)
@@ -2,4 +2,6 @@ bazel-*
 .vscode\r
 ratelimiter/target\r
 target/\r
-**/local*
\ No newline at end of file
+**/local*\r
+.ijwb\r
+.idea
\ No newline at end of file
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..ee23d38
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,2 @@
+gazelle:
+       bazel run //:gazelle -- update-repos -from_file=go.mod -to_macro=//bazel:deps.bzl%go_dependencies
\ No newline at end of file
diff --git a/bazel/lib/BUILD b/bazel/lib/BUILD
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/bazel/lib/expand_template.bzl b/bazel/lib/expand_template.bzl
new file mode 100644 (file)
index 0000000..742565a
--- /dev/null
@@ -0,0 +1,45 @@
+"""Rule for simple expansion of template files. This performs a simple
+search over the template file for the keys in substitutions,
+and replaces them with the corresponding values.
+
+Typical usage:
+  load("//tools/build_rules:expand_template.bzl", "expand_template")
+  expand_template(
+      name = "ExpandMyTemplate",
+      template = "my.template",
+      out = "my.txt",
+      substitutions = {
+        "$VAR1": "foo",
+        "$VAR2": "bar",
+      }
+  )
+
+Args:
+  name: The name of the rule.
+  template: The template file to expand
+  out: The destination of the expanded file
+  substitutions: A dictionary mapping strings to their substitutions
+  is_executable: A boolean indicating whether the output file should be executable
+"""
+
+def expand_template_impl(ctx):
+    ctx.actions.expand_template(
+        template = ctx.file.template,
+        output = ctx.outputs.out,
+        substitutions = {
+            k: ctx.expand_location(v, ctx.attr.data)
+            for k, v in ctx.attr.substitutions.items()
+        },
+        is_executable = ctx.attr.is_executable,
+    )
+
+expand_template = rule(
+    implementation = expand_template_impl,
+    attrs = {
+        "template": attr.label(mandatory = True, allow_single_file = True),
+        "substitutions": attr.string_dict(mandatory = True),
+        "out": attr.output(mandatory = True),
+        "is_executable": attr.bool(default = False, mandatory = False),
+        "data": attr.label_list(allow_files = True),
+    },
+)
\ No newline at end of file
diff --git a/common/management/BUILD.bazel b/common/management/BUILD.bazel
new file mode 100644 (file)
index 0000000..2e8f53f
--- /dev/null
@@ -0,0 +1,24 @@
+load("@rules_proto//proto:defs.bzl", "proto_library")
+load("@io_bazel_rules_go//go:def.bzl", "go_library")
+load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
+
+proto_library(
+    name = "nova_ratelimit_v1_proto",
+    srcs = ["nova.management.v1alpha.proto"],
+    visibility = ["//visibility:public"],
+)
+
+go_proto_library(
+    name = "nova_ratelimit_v1_go_proto",
+    compilers = ["@io_bazel_rules_go//proto:go_grpc"],
+    importpath = "github.com/discordnova/nova/common/management",
+    proto = ":nova_ratelimit_v1_proto",
+    visibility = ["//visibility:public"],
+)
+
+go_library(
+    name = "management",
+    embed = [":nova_ratelimit_v1_go_proto"],
+    importpath = "github.com/discordnova/nova/common/management",
+    visibility = ["//visibility:public"],
+)
diff --git a/common/management/nova.management.v1alpha.proto b/common/management/nova.management.v1alpha.proto
new file mode 100644 (file)
index 0000000..f07aa9b
--- /dev/null
@@ -0,0 +1,58 @@
+syntax = "proto3";
+package nova.ratelimit.v1;
+
+message Empty {}
+
+// Represents the status of a shard
+enum ShardStatus {
+    DISCONNECTED = 0;
+    RUNNING = 1;
+    RECONNECTING = 2;
+}
+
+// represents the state of a nova shard
+message ShardStatusResponse {
+    // Status of the shard in the cluster
+     ShardStatus status = 1;
+    // Index of the discord shard
+     int64 identifier = 2;
+    // If the cluster have a node assigned
+    string cluster = 3;
+    // the websocket latency of the shard
+    int64 latency = 4;
+}
+
+message ShardStatusRequest {
+    // the id of the shard
+     int64 identifier = 1;
+}
+
+// represents the status of a cluster
+// (an instance of the gateway which holds multiple shards)
+message ClusterStatusResponse {
+    // the unique id of the cluster
+     string id = 1;
+    // the node the cluster is running on
+     string node = 2;
+    // the average latency of the cluster
+    int64 average_latency = 3;
+    // list of all the shards on the cluster
+    repeated ShardStatusResponse shards = 4;
+}
+
+message ClusterStatusRequest {
+     string id = 1;    
+}
+
+// Represents the status of all the nova clusters & shards
+message GlobalClusterStatusResponse {
+    int64 size = 1;
+    repeated ClusterStatusResponse shards = 2;
+}
+
+// used by the cli to interact with the nova manager
+service ManagementService {
+    rpc GetGlobalClusterStatus (Empty) returns (GlobalClusterStatusResponse);
+    rpc GetClusterStatus (ClusterStatusRequest) returns (ClusterStatusResponse);
+    rpc GetShardStatus (ShardStatusRequest) returns (ShardStatusResponse);
+}
\ No newline at end of file
diff --git a/common/version.go.in b/common/version.go.in
new file mode 100644 (file)
index 0000000..aacaad5
--- /dev/null
@@ -0,0 +1,5 @@
+package common
+
+const (
+       VERSION = "$VERSION"
+)
diff --git a/novactl/cmd/cluster.go b/novactl/cmd/cluster.go
new file mode 100644 (file)
index 0000000..3d56c21
--- /dev/null
@@ -0,0 +1,96 @@
+package cmd
+
+import (
+       "context"
+       "errors"
+       "github.com/discordnova/nova/common/management"
+       "github.com/discordnova/nova/novactl/lib"
+       "github.com/olekukonko/tablewriter"
+       "github.com/rs/zerolog/log"
+       "github.com/spf13/cobra"
+       "os"
+       "strconv"
+       "time"
+)
+
+var ClusterCommand = createClusterCommand()
+
+var (
+       ServerUrl *string = nil
+       Ctx               = context.Background()
+)
+
+func createClusterCommand() *cobra.Command {
+       command := &cobra.Command{
+               Use:              "cluster",
+               Short:            "Commands to interact with the nova cluster",
+               Aliases:          []string{"c"},
+               TraverseChildren: true,
+       }
+       // shard sub command
+       shard := cobra.Command{
+               Use:   "shard [shard]",
+               Short: "Returns information about a specific shard",
+               Run:   shardCommand,
+               Args: func(cmd *cobra.Command, args []string) error {
+                       if len(args) != 1 {
+                               return errors.New("one shard id must be specified")
+                       } else {
+                               if _, err := strconv.Atoi(args[0]); err != nil {
+                                       return errors.New("the shard id must be a string")
+                               }
+                       }
+                       return nil
+               },
+               TraverseChildren: true,
+       }
+       // info sub command
+       info := cobra.Command{
+               Use:              "info",
+               Short:            "Gets the status of the cluster",
+               Aliases:          []string{"i"},
+               Run:              infoCommand,
+               TraverseChildren: true,
+       }
+
+       ServerUrl = command.Flags().StringP("server", "s", "localhost:8053", "")
+
+       command.AddCommand(&shard)
+       command.AddCommand(&info)
+
+       return command
+}
+
+func shardCommand(command *cobra.Command, args []string) {
+       id, err := strconv.ParseInt(args[0], 10, 64)
+       if err != nil {
+               log.Err(err).Msg("Failed to parse the shard id")
+               os.Exit(1)
+       }
+
+       log.Info().Msgf("Starting connection with server %s", *ServerUrl)
+       conn, err := lib.NewConn(*ServerUrl)
+
+       if err != nil {
+               log.Err(err).Msg("Failed to connect to the manager")
+               return
+       }
+       ctx, _ := context.WithTimeout(Ctx, time.Second*10)
+
+       manager := *conn
+       data, err := manager.GetShardStatus(ctx, &management.ShardStatusRequest{
+               Identifier: id,
+       })
+
+       if err != nil {
+               log.Err(err).Msg("Failed to get the status of the shard")
+               return
+       }
+
+       table := tablewriter.NewWriter(os.Stdout)
+       table.SetHeader([]string{"Status", "Id", "Cluster", "Latency"})
+       table.Append([]string{string(data.Status), string(data.Identifier), data.Cluster, string(data.Latency)})
+       table.Render()
+}
+
+func infoCommand(command *cobra.Command, args []string) {}
diff --git a/novactl/lib/conn.go b/novactl/lib/conn.go
new file mode 100644 (file)
index 0000000..362c9ed
--- /dev/null
@@ -0,0 +1,19 @@
+package lib
+
+import (
+       "google.golang.org/grpc"
+
+       "github.com/discordnova/nova/common/management"
+)
+
+// NewConn creates a connection to the manager
+func NewConn(host string) (*management.ManagementServiceClient, error) {
+       lis, err := grpc.Dial(host, grpc.WithInsecure())
+       if err != nil {
+               return nil, err
+       }
+
+       conn := management.NewManagementServiceClient(lis)
+
+       return &conn, nil
+}