Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,7 @@ oapi-gen:
.PHONY: start-observability
start-observability:
@docker compose up valkyrie-otel-collector jaeger prometheus -d

.PHONY: odinc
odinc:
@go build -o odinc pkg/odin/client/main.go
6 changes: 3 additions & 3 deletions build/package/nix/odin.nix
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
buildGoModule rec {
pname = "odin";
version = "0.0.1";
vendorHash = "sha256-g+YA2d4tuAtGazjtNiIyyaWbJfnZXMeHk7e8EDr+uUw=";
vendorHash = "sha256-dofEXl3JiXq0Xqk6bGqW5gSpPfBo2Y5SH7g47Rt9ZDo=";

src = ../../..;

Expand All @@ -33,8 +33,8 @@ buildGoModule rec {

meta = with lib; {
description = "Odin Server";
license = licenses.asl20;
maintainers = with maintainers; [ ];
license = licenses.mit;
maintainers = with maintainers; [ deepak ];
mainProgram = "odin";
};
}
26 changes: 26 additions & 0 deletions build/package/nix/odin_client.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{ lib
, pkgs
, stdenv
, buildGoModule
}:

buildGoModule rec {
pname = "odinc";
version = "0.0.1";
vendorHash = "sha256-dofEXl3JiXq0Xqk6bGqW5gSpPfBo2Y5SH7g47Rt9ZDo=";

src = ../../..;

doCheck = false;

subPackages = [ "pkg/odin/odinc" ];

ldflags = [ "-s" "-w" "-X info.version=${version}" ];

meta = with lib; {
description = "Odin Client";
license = licenses.mit;
maintainers = with maintainers; [ deepak ];
mainProgram = "odinc";
};
}
1 change: 1 addition & 0 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
packages = {
odin = pkgs.callPackage ./build/package/nix/odin.nix { inherit pkgs; };
nardump = pkgs.callPackage ./build/package/nix/nardump.nix { inherit pkgs; };
odinc = pkgs.callPackage ./build/package/nix/odin_client.nix { inherit pkgs; };
};
defaultPackage = packages.odin;

Expand Down
6 changes: 4 additions & 2 deletions internal/odin/config/environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ type EnvConfig struct {
POSTGRES_DB string `mapstructure:"POSTGRES_DB"` // represents the name of the PostgreSQL database.
POSTGRES_SSL_MODE string `mapstructure:"POSTGRES_SSL_MODE"` // represents the SSL mode for connecting to PostgreSQL.

ODIN_SERVER_HOST string `mapstructure:"ODIN_SERVER_HOST"` // represents the host on which the Odin server will listen.
ODIN_SERVER_PORT string `mapstructure:"ODIN_SERVER_PORT"` // represents the port on which the Odin server will listen.
ODIN_SERVER_HOST string `mapstructure:"ODIN_SERVER_HOST"` // represents the host on which the Odin server will listen.
ODIN_SERVER_PORT string `mapstructure:"ODIN_SERVER_PORT"` // represents the port on which the Odin server will listen.
ODIN_SERVER_BASE_URL string

ODIN_WORKER_PROVIDER string `mapstructure:"ODIN_WORKER_PROVIDER"` // represents the worker provider.
ODIN_WORKER_CONCURRENCY int32 `mapstructure:"ODIN_WORKER_CONCURRENCY"` // represents the concurrency level for the worker.
Expand Down Expand Up @@ -103,5 +104,6 @@ func GetEnvConfig() (*EnvConfig, error) {
EnvConfig.ODIN_INFO_DIR = fmt.Sprintf("%s/%s", EnvConfig.USER_HOME_DIR, ".odin")
EnvConfig.ODIN_WORKER_DIR = fmt.Sprintf("%s/%s", EnvConfig.ODIN_INFO_DIR, "worker")
EnvConfig.ODIN_WORKER_INFO_FILE = fmt.Sprintf("%s/%s", EnvConfig.ODIN_WORKER_DIR, "worker-info.json")
EnvConfig.ODIN_SERVER_BASE_URL = fmt.Sprintf("http://%s:%s", EnvConfig.ODIN_SERVER_HOST, EnvConfig.ODIN_SERVER_PORT)
return &EnvConfig, nil
}
6 changes: 3 additions & 3 deletions internal/odin/server/execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ func (s *OdinServer) Execute(ctx context.Context, req *api.ExecutionRequest) (ap
switch err.(type) {
case *execution.ExecutionServiceError:
return &api.ExecuteInternalServerError{
Message: fmt.Sprintf("Execution Service: %v", err),
Message: fmt.Sprintf("Execution Service -> %v", err),
}, nil
case *execution.TemplateError:
return &api.ExecuteBadRequest{
Message: fmt.Sprintf("Failed to execute: %v", err),
Message: fmt.Sprintf("Failed to execute -> %v", err),
}, nil
default:
return &api.ExecuteInternalServerError{
Message: fmt.Sprintf("Failed to execute: %v", err),
Message: fmt.Sprintf("Failed to execute -> %v", err),
}, nil
}
}
Expand Down
6 changes: 6 additions & 0 deletions internal/odin/services/execution/execute.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,12 @@ func (s *ExecutionService) convertExecSpecToFlake(execSpec *api.ExecutionRequest
}

func (s *ExecutionService) AddJob(ctx context.Context, req *api.ExecutionRequest) (int64, error) {
if req.Environment.Value.Type == "" {
return 0, &ExecutionServiceError{
Type: "environment",
Message: "Specify flake or language",
}
}
execReq, err := s.prepareExecutionRequest(req)
if err != nil {
return 0, err
Expand Down
82 changes: 82 additions & 0 deletions pkg/odin/odinc/cmd/execute.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package cmd

import (
"fmt"
"os"

"github.com/spf13/cobra"

"github.com/deepakdinesh1123/valkyrie/pkg/odin/api"
)

var executeCmd = &cobra.Command{
Use: "execute",
Short: "Execute a job",
Long: `Execute a job`,
RunE: executeExec,
}

func executeExec(cmd *cobra.Command, args []string) error {
baseURL := cmd.Flag("base-url").Value.String()

client, err := api.NewClient(baseURL)
if err != nil {
return err
}

var req api.ExecutionRequest

language := cmd.Flag("language").Value.String()
file := cmd.Flag("file_path").Value.String()
// arguments := cmd.Flag("args").Value.String()
code := cmd.Flag("code").Value.String()
flake := cmd.Flag("flake").Value.String()
// dir := cmd.Flag("dir").Value.String()

if language != "" {
req.Language = language
req.Environment.Set = true
req.Environment.Value.Type = "ExecutionEnvironmentSpec"

if code != "" && file != "" {
return fmt.Errorf("language must be specified with either code or file")
} else if code != "" {
req.Code = code
} else if file != "" {
file_content, err := os.ReadFile(file)
if err != nil {
return err
}
req.Code = string(file_content)
}
} else if flake != "" {
req.Environment.Set = true
req.Environment.Value.Type = "Flake"
req.Environment.Value.Flake = api.Flake(flake)
} else {
return fmt.Errorf("environment must be specified with either language or flake not both")
}
res, err := client.Execute(cmd.Context(), &req)
if err != nil {
return err
}

switch res := res.(type) {
case *api.ExecuteOK:
fmt.Println("Execution ID: ", res.ExecutionId)
case *api.ExecuteBadRequest:
fmt.Println(res.Message)
case *api.ExecuteInternalServerError:
fmt.Println(res.Message)
}
return nil
}

func init() {
executeCmd.Flags().String("language", "", "Language to execute in")
executeCmd.Flags().String("file_path", "", "File to execute")
executeCmd.Flags().String("args", "", "Arguments to pass to the script")
executeCmd.Flags().String("code", "", "Code to execute")
executeCmd.Flags().String("flake", "", "Flake for the environment")
executeCmd.Flags().String("dir", ".", "Path to the directory that contains the flake and script")
}
188 changes: 188 additions & 0 deletions pkg/odin/odinc/cmd/executions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
package cmd

import (
"fmt"
"strconv"

"github.com/deepakdinesh1123/valkyrie/pkg/odin/api"
"github.com/spf13/cobra"
)

var (
page int32
pageSz int32
)

var executionsCmd = &cobra.Command{
Use: "executions",
Short: "Manage executions",
Long: `Manage executions`,
RunE: executionsExec,
}

func executionsExec(cmd *cobra.Command, args []string) error {
_ = cmd.Usage()
return nil
}

func init() {
executionsCmd.AddCommand(executionsListCmd)
executionsCmd.AddCommand(executionsResultsCmd)
executionsCmd.AddCommand(execitionResultByIdCmd)
executionsCmd.AddCommand(executionConfig)
executionsCmd.AddCommand(deleteExecutionCmd)

executionsCmd.PersistentFlags().Int32VarP(&page, "page", "p", 0, "Page number")
executionsCmd.PersistentFlags().Int32VarP(&pageSz, "page-size", "s", 10, "Page size")
}

var executionsListCmd = &cobra.Command{
Use: "list",
Short: "List executions",
Long: `List executions`,
RunE: executionsListExec,
}

func executionsListExec(cmd *cobra.Command, args []string) error {
baseURL := cmd.Flag("base-url").Value.String()
client, err := api.NewClient(baseURL)
if err != nil {
return err
}
res, err := client.GetAllExecutions(cmd.Context(), api.GetAllExecutionsParams{
Page: api.NewOptInt32(page),
PageSize: api.NewOptInt32(pageSz),
})
if err != nil {
return err
}
switch res := res.(type) {
case *api.GetAllExecutionsOK:
fmt.Println(res.Executions)
case *api.GetAllExecutionsBadRequest:
fmt.Println(res.Message)
}
return nil
}

var executionsResultsCmd = &cobra.Command{
Use: "results",
Short: "List execution results",
Long: `List execution results`,
RunE: executionsResultsExec,
}

func executionsResultsExec(cmd *cobra.Command, args []string) error {
baseURL := cmd.Flag("base-url").Value.String()
client, err := api.NewClient(baseURL)
if err != nil {
return err
}
res, err := client.GetAllExecutionResults(cmd.Context(), api.GetAllExecutionResultsParams{
Page: api.NewOptInt32(page),
PageSize: api.NewOptInt32(pageSz),
})
if err != nil {
return err
}
switch res := res.(type) {
case *api.GetAllExecutionResultsOK:
fmt.Println(res.Executions)
case *api.GetAllExecutionResultsBadRequest:
fmt.Println(res.Message)
}
return nil
}

var execitionResultByIdCmd = &cobra.Command{
Use: "get",
Short: "Get execution result by id",
Long: `Get execution result by id`,
RunE: execitionResultByIdExec,
}

func execitionResultByIdExec(cmd *cobra.Command, args []string) error {
baseURL := cmd.Flag("base-url").Value.String()
if len(args) == 0 {
return fmt.Errorf("id is required")
}
jobId, err := strconv.ParseInt(args[0], 10, 32)
if err != nil {
return err
}
client, err := api.NewClient(baseURL)
if err != nil {
return err
}
res, err := client.GetExecutionResultsById(cmd.Context(), api.GetExecutionResultsByIdParams{
JobId: jobId,
Page: api.NewOptInt32(page),
PageSize: api.NewOptInt32(pageSz),
})
if err != nil {
return err
}
switch res := res.(type) {
case *api.GetExecutionResultsByIdOK:
fmt.Println(res.Executions)
case *api.GetExecutionResultsByIdBadRequest:
fmt.Println(res.Message)
}
return nil
}

var executionConfig = &cobra.Command{
Use: "config",
Short: "Get execution config",
Long: `Get execution config`,
RunE: executionConfigExec,
}

func executionConfigExec(cmd *cobra.Command, args []string) error {
baseURL := cmd.Flag("base-url").Value.String()
client, err := api.NewClient(baseURL)
if err != nil {
return err
}
res, err := client.GetExecutionConfig(cmd.Context())
if err != nil {
return err
}
fmt.Println(res)
return nil
}

var deleteExecutionCmd = &cobra.Command{
Use: "delete",
Short: "Delete execution",
Long: `Delete execution`,
RunE: deleteExecutionExec,
}

func deleteExecutionExec(cmd *cobra.Command, args []string) error {
baseURL := cmd.Flag("base-url").Value.String()
if len(args) == 0 {
return fmt.Errorf("id is required")
}
jobId, err := strconv.ParseInt(args[0], 10, 32)
if err != nil {
return err
}
client, err := api.NewClient(baseURL)
if err != nil {
return err
}
res, err := client.DeleteJob(cmd.Context(), api.DeleteJobParams{
JobId: jobId,
})
if err != nil {
return err
}
switch res := res.(type) {
case *api.DeleteJobOK:
fmt.Println(res)
case *api.DeleteJobBadRequest:
fmt.Println(res.Message)
}
return nil
}
Loading