Skip to content

Commit

Permalink
chore: remove codersdk dependency (#194)
Browse files Browse the repository at this point in the history
Part of #178

In order to update our branch of Kaniko, we need to first update to go1.22.
This is not currently possible while depending on codersdk.

- Manually vendored relevant parts of codersdk and agentsdk into internal/notcodersdk
- Replaced existing usage of codersdk / agentsdk with internal/notcodersdk
- Added test for coder log sending functionality
  • Loading branch information
johnstcn authored May 17, 2024
1 parent e6844c2 commit 85290fa
Show file tree
Hide file tree
Showing 13 changed files with 786 additions and 725 deletions.
36 changes: 20 additions & 16 deletions cmd/envbuilder/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@ import (
"time"

"cdr.dev/slog"
"github.com/coder/coder/v2/codersdk"
"github.com/coder/coder/v2/codersdk/agentsdk"
"github.com/coder/envbuilder"
"github.com/coder/envbuilder/internal/notcodersdk"
"github.com/coder/serpent"

// *Never* remove this. Certificates are not bundled as part
Expand All @@ -25,12 +24,21 @@ import (
)

func main() {
cmd := envbuilderCmd()
err := cmd.Invoke().WithOS().Run()
if err != nil {
fmt.Fprintf(os.Stderr, "error: %v", err)
os.Exit(1)
}
}

func envbuilderCmd() serpent.Command {
var options envbuilder.Options
cmd := serpent.Command{
Use: "envbuilder",
Options: options.CLI(),
Handler: func(inv *serpent.Invocation) error {
var sendLogs func(ctx context.Context, log ...agentsdk.Log) error
var sendLogs func(ctx context.Context, log ...notcodersdk.Log) error
if options.CoderAgentToken != "" {
if options.CoderAgentURL == "" {
return errors.New("CODER_AGENT_URL must be set if CODER_AGENT_TOKEN is set")
Expand All @@ -39,34 +47,34 @@ func main() {
if err != nil {
return fmt.Errorf("unable to parse CODER_AGENT_URL as URL: %w", err)
}
client := agentsdk.New(u)
client := notcodersdk.New(u)
client.SetSessionToken(options.CoderAgentToken)
client.SDK.HTTPClient = &http.Client{
client.HTTPClient = &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: options.Insecure,
},
},
}
var flushAndClose func(ctx context.Context) error
sendLogs, flushAndClose = agentsdk.LogsSender(agentsdk.ExternalLogSourceID, client.PatchLogs, slog.Logger{})
sendLogs, flushAndClose = notcodersdk.LogsSender(notcodersdk.ExternalLogSourceID, client.PatchLogs, slog.Logger{})
defer flushAndClose(inv.Context())

// This adds the envbuilder subsystem.
// If telemetry is enabled in a Coder deployment,
// this will be reported and help us understand
// envbuilder usage.
if !slices.Contains(options.CoderAgentSubsystem, string(codersdk.AgentSubsystemEnvbuilder)) {
options.CoderAgentSubsystem = append(options.CoderAgentSubsystem, string(codersdk.AgentSubsystemEnvbuilder))
if !slices.Contains(options.CoderAgentSubsystem, string(notcodersdk.AgentSubsystemEnvbuilder)) {
options.CoderAgentSubsystem = append(options.CoderAgentSubsystem, string(notcodersdk.AgentSubsystemEnvbuilder))
os.Setenv("CODER_AGENT_SUBSYSTEM", strings.Join(options.CoderAgentSubsystem, ","))
}
}

options.Logger = func(level codersdk.LogLevel, format string, args ...interface{}) {
options.Logger = func(level notcodersdk.LogLevel, format string, args ...interface{}) {
output := fmt.Sprintf(format, args...)
fmt.Fprintln(inv.Stderr, output)
if sendLogs != nil {
sendLogs(inv.Context(), agentsdk.Log{
sendLogs(inv.Context(), notcodersdk.Log{
CreatedAt: time.Now(),
Output: output,
Level: level,
Expand All @@ -76,14 +84,10 @@ func main() {

err := envbuilder.Run(inv.Context(), options)
if err != nil {
options.Logger(codersdk.LogLevelError, "error: %s", err)
options.Logger(notcodersdk.LogLevelError, "error: %s", err)
}
return err
},
}
err := cmd.Invoke().WithOS().Run()
if err != nil {
fmt.Fprintf(os.Stderr, "error: %v", err)
os.Exit(1)
}
return cmd
}
84 changes: 84 additions & 0 deletions cmd/envbuilder/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package main

import (
"context"
"encoding/json"
"net/http"
"net/http/httptest"
"path/filepath"
"testing"
"time"

"cdr.dev/slog/sloggers/slogtest"
"github.com/coder/envbuilder/internal/notcodersdk"
"github.com/coder/serpent"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func Test_sendLogs(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
// Random token for testing log fowarding
agentToken := uuid.NewString()

// Server to read logs posted by envbuilder. Matched to backlog limit.
logCh := make(chan notcodersdk.Log, 100)
logs := make([]notcodersdk.Log, 0)
go func() {
for {
select {
case <-ctx.Done():
return
case log, ok := <-logCh:
if !ok {
return
}
logs = append(logs, log)
}
}
}()
logSrv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if !assert.Equal(t, http.MethodPatch, r.Method) {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
assert.Equal(t, agentToken, r.Header.Get(notcodersdk.SessionTokenHeader))
var res notcodersdk.PatchLogs
if !assert.NoError(t, json.NewDecoder(r.Body).Decode(&res)) {
w.WriteHeader(http.StatusInternalServerError)
return
}
if !assert.Equal(t, notcodersdk.ExternalLogSourceID, res.LogSourceID) {
w.WriteHeader(http.StatusInternalServerError)
return
}
for _, log := range res.Logs {
logCh <- log
}
w.WriteHeader(http.StatusOK)
}))

// Make an empty working directory
tmpDir := t.TempDir()
t.Setenv("ENVBUILDER_DEVCONTAINER_DIR", tmpDir)
t.Setenv("ENVBUILDER_DOCKERFILE_DIR", filepath.Join(tmpDir, "Dockerfile"))
t.Setenv("ENVBUILDER_WORKSPACE_FOLDER", tmpDir)
t.Setenv("CODER_AGENT_TOKEN", agentToken)
t.Setenv("CODER_AGENT_URL", logSrv.URL)

testLogger := slogtest.Make(t, &slogtest.Options{IgnoreErrors: true})
cmd := envbuilderCmd()
inv := &serpent.Invocation{
Command: &cmd,
Args: []string{},
Logger: testLogger,
Environ: serpent.Environ{},
}

err := inv.WithOS().Run()
require.ErrorContains(t, err, "no such file or directory")
require.NotEmpty(t, logs)
require.Contains(t, logs[len(logs)-1].Output, "no such file or directory")
}
Loading

0 comments on commit 85290fa

Please sign in to comment.