Skip to content

Commit 142416e

Browse files
committed
Just a lot of changes
1 parent fbfc632 commit 142416e

36 files changed

+801
-272
lines changed

.goreleaser.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ builds:
77
env:
88
- CGO_ENABLED=0
99
targets:
10-
- windows_amd64
11-
- windows_arm64
10+
# - windows_amd64
11+
# - windows_arm64
1212
- darwin_amd64
1313
- darwin_arm64
1414
- linux_amd64
@@ -22,8 +22,8 @@ builds:
2222
env:
2323
- CGO_ENABLED=0
2424
targets:
25-
- windows_amd64
26-
- windows_arm64
25+
# - windows_amd64
26+
# - windows_arm64
2727
- darwin_amd64
2828
- darwin_arm64
2929
- linux_amd64

app/backend/agent.go

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package appbackend
2+
3+
import (
4+
"fmt"
5+
"github.com/graphql-go/graphql"
6+
)
7+
8+
var packageType = graphql.NewObject(graphql.ObjectConfig{
9+
Name: "Package",
10+
Fields: graphql.Fields{
11+
"goos": &graphql.Field{Type: graphql.NewNonNull(graphql.String)},
12+
"goarch": &graphql.Field{Type: graphql.NewNonNull(graphql.String)},
13+
"version": &graphql.Field{Type: graphql.NewNonNull(graphql.String)},
14+
"goarm": &graphql.Field{Type: graphql.String},
15+
},
16+
})
17+
18+
var listPackages = &graphql.Field{
19+
Type: graphql.NewList(packageType),
20+
Args: graphql.FieldConfigArgument{},
21+
Resolve: wrapper(func(rctx resolveContext[any]) (any, error) {
22+
return rctx.packages.GetLatestPackages(rctx)
23+
}),
24+
}
25+
26+
var buildDeployAgentCommand = &graphql.Field{
27+
Type: graphql.NewNonNull(graphql.String),
28+
Args: graphql.FieldConfigArgument{
29+
"projectId": &graphql.ArgumentConfig{Type: graphql.NewNonNull(graphql.String)},
30+
"goos": &graphql.ArgumentConfig{Type: graphql.NewNonNull(graphql.String)},
31+
"goarch": &graphql.ArgumentConfig{Type: graphql.NewNonNull(graphql.String)},
32+
"generatePsk": &graphql.ArgumentConfig{Type: graphql.NewNonNull(graphql.Boolean)},
33+
},
34+
Resolve: wrapper(func(rctx resolveContext[any]) (string, error) {
35+
goos := rctx.getStringArg("goos")
36+
projectId := rctx.getStringArg("projectId")
37+
err := rctx.canAccessProject(projectId)
38+
if err != nil {
39+
return "", err
40+
}
41+
42+
// Optionally generate a pre-shared key for the agent to use
43+
var psk string
44+
if rctx.getBoolArg("generatePsk") {
45+
psk, err = rctx.db.GeneratePreSharedKey(rctx, projectId)
46+
if err != nil {
47+
return "", fmt.Errorf("generating psk: %w", err)
48+
}
49+
}
50+
51+
switch goos {
52+
case "linux":
53+
// We can use the same command for all linux architectures
54+
// and the installation script will handle the nuances and
55+
// platform detection processes that need to happen.
56+
return buildLinuxInstallCommand(psk), nil
57+
default:
58+
return "", fmt.Errorf("unsupported goos: %s", goos)
59+
}
60+
}),
61+
}
62+
63+
func buildLinuxInstallCommand(psk string) string {
64+
if len(psk) == 0 {
65+
return fmt.Sprintf("curl -fsSL https://raw.githubusercontent.com/clarkmcc/cloudcore/main/scripts/linux/install.sh | sh")
66+
} else {
67+
return fmt.Sprintf("curl -fsSL https://raw.githubusercontent.com/clarkmcc/cloudcore/main/scripts/linux/install.sh | sh -s -- --psk %s", psk)
68+
}
69+
}

app/backend/backend.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"github.com/clarkmcc/cloudcore/app/backend/middleware"
77
"github.com/clarkmcc/cloudcore/cmd/cloudcore-server/config"
88
"github.com/clarkmcc/cloudcore/cmd/cloudcore-server/database"
9+
"github.com/clarkmcc/cloudcore/pkg/packages"
910
"github.com/gin-gonic/gin"
1011
"github.com/graphql-go/graphql"
1112
"go.uber.org/fx"
@@ -19,9 +20,10 @@ type Server struct {
1920
schema graphql.Schema
2021
logger *zap.Logger
2122
database database.Database
23+
packages packages.Provider
2224
}
2325

24-
func New(lc fx.Lifecycle, config *config.Config, database database.Database, logger *zap.Logger) (*Server, error) {
26+
func New(lc fx.Lifecycle, config *config.Config, database database.Database, logger *zap.Logger, packages packages.Provider) (*Server, error) {
2527
logger = logger.Named("app-backend")
2628
s, err := graphql.NewSchema(schemaConfig)
2729
if err != nil {
@@ -31,6 +33,7 @@ func New(lc fx.Lifecycle, config *config.Config, database database.Database, log
3133
schema: s,
3234
logger: logger,
3335
database: database,
36+
packages: packages,
3437
}
3538

3639
r := gin.Default()

app/backend/context.go

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,40 +5,40 @@ import (
55
"fmt"
66
"github.com/clarkmcc/cloudcore/app/backend/middleware"
77
"github.com/clarkmcc/cloudcore/cmd/cloudcore-server/database"
8+
"github.com/clarkmcc/cloudcore/pkg/packages"
89
"github.com/graphql-go/graphql"
910
"github.com/spf13/cast"
1011
"go.uber.org/zap"
1112
)
1213

13-
const contextKeyLogger = "logger"
14-
const contextKeyDatabase = "database"
14+
type contextKeyLogger struct{}
15+
type contextKeyDatabase struct{}
16+
type contextKeyPackages struct{}
1517

1618
func (s *Server) graphqlContext(ctx context.Context) context.Context {
17-
ctx = context.WithValue(ctx, contextKeyLogger, s.logger)
18-
ctx = context.WithValue(ctx, contextKeyDatabase, s.database)
19+
ctx = context.WithValue(ctx, contextKeyLogger{}, s.logger)
20+
ctx = context.WithValue(ctx, contextKeyDatabase{}, s.database)
21+
ctx = context.WithValue(ctx, contextKeyPackages{}, s.packages)
1922
return ctx
2023
}
2124

22-
func logger(ctx context.Context) *zap.Logger {
23-
return ctx.Value(contextKeyLogger).(*zap.Logger)
24-
}
25-
26-
func db(ctx context.Context) database.Database {
27-
return ctx.Value(contextKeyDatabase).(database.Database)
28-
}
29-
3025
type resolveContext[S any] struct {
3126
context.Context
32-
db database.Database
33-
params graphql.ResolveParams
34-
logger *zap.Logger
35-
source S
27+
db database.Database
28+
params graphql.ResolveParams
29+
logger *zap.Logger
30+
packages packages.Provider
31+
source S
3632
}
3733

3834
func (r *resolveContext[S]) getStringArg(name string) string {
3935
return cast.ToString(r.params.Args[name])
4036
}
4137

38+
func (r *resolveContext[S]) getBoolArg(name string) bool {
39+
return cast.ToBool(r.params.Args[name])
40+
}
41+
4242
func (r *resolveContext[S]) canAccessProject(projectId string) error {
4343
sub := middleware.SubjectFromContext(r)
4444
if sub == "" {
@@ -65,11 +65,12 @@ func wrapper[S any, T any](fn resolverFunc[T, S]) func(params graphql.ResolvePar
6565
return nil, fmt.Errorf("invalid source type: %T, expected %T", params.Source, s)
6666
}
6767
return fn(resolveContext[S]{
68-
Context: ctx,
69-
db: db(ctx),
70-
logger: logger(ctx),
71-
source: source,
72-
params: params,
68+
Context: ctx,
69+
db: ctx.Value(contextKeyDatabase{}).(database.Database),
70+
packages: ctx.Value(contextKeyPackages{}).(packages.Provider),
71+
logger: ctx.Value(contextKeyLogger{}).(*zap.Logger),
72+
source: source,
73+
params: params,
7374
})
7475
}
7576
}

app/backend/schema.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,15 @@ var schemaConfig = graphql.SchemaConfig{
1414
"hosts": hostList,
1515
"host": hostDetails,
1616
"projectMetrics": projectMetrics,
17+
"packages": listPackages,
1718
},
1819
}),
1920
Mutation: graphql.NewObject(graphql.ObjectConfig{
2021
Name: "Mutation",
2122
Fields: graphql.Fields{
22-
"ensureUser": ensureUser,
23-
"projectCreate": projectCreate,
23+
"ensureUser": ensureUser,
24+
"projectCreate": projectCreate,
25+
"buildDeployAgentCommand": buildDeployAgentCommand,
2426
},
2527
}),
2628
}

app/frontend/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
"react-dom": "^18.2.0",
4242
"react-hook-form": "^7.48.2",
4343
"react-router-dom": "^6.19.0",
44-
"react-usage-bar": "^1.1.22",
44+
"react-usage-bar": "^1.2.0",
4545
"sort-by": "^1.2.0",
4646
"tailwind-merge": "^2.0.0",
4747
"tailwindcss-animate": "^1.0.7",

app/frontend/schema.graphql

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ type Host {
4747
}
4848

4949
type Mutation {
50+
buildDeployAgentCommand(generatePsk: Boolean!, goarch: String!, goos: String!, projectId: String!): String!
5051
ensureUser: [Project]
5152
projectCreate(description: String, name: String!): ProjectCreate
5253
}
@@ -56,6 +57,13 @@ type OsNameCount {
5657
osName: String!
5758
}
5859

60+
type Package {
61+
goarch: String!
62+
goarm: String
63+
goos: String!
64+
version: String!
65+
}
66+
5967
type Project {
6068
created_at: DateTime
6169
id: String
@@ -80,6 +88,7 @@ type ProjectMetrics {
8088
type Query {
8189
host(hostId: String!, projectId: String!): Host
8290
hosts(projectId: String!): [Host]
91+
packages: [Package]
8392
projectMetrics(projectId: String!): ProjectMetrics
8493
}
8594

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { useState } from "react";
2+
import { ClipboardCopy } from "lucide-react";
3+
4+
export function CommandCopy(props: { command: string }) {
5+
const [copied, setCopied] = useState(false);
6+
7+
const handleCopy = async () => {
8+
await navigator.clipboard.writeText(props.command);
9+
setCopied(true);
10+
setTimeout(() => setCopied(false), 2000);
11+
};
12+
13+
return (
14+
<div className="relative p-4 bg-neutral-100 dark:bg-neutral-900 dark:text-white font-mono text-sm rounded-md overflow-auto">
15+
<div className="overflow-x-auto whitespace-nowrap scroll-auto">
16+
{props.command}
17+
</div>
18+
<button
19+
onClick={handleCopy}
20+
className="absolute top-2 right-2 flex items-center gap-2 p-1 text-xs bg-neutral-200 hover:bg-neutral-300 dark:bg-neutral-700 dark:hover:bg-neutral-600 rounded"
21+
>
22+
<ClipboardCopy className="h-4 w-4" />
23+
{copied ? "Copied" : "Copy"}
24+
</button>
25+
</div>
26+
);
27+
}

0 commit comments

Comments
 (0)