Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
9 changes: 9 additions & 0 deletions .github/workflows/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# For more information about the Codesphere teams see: https://github.com/orgs/codesphere-cloud/teams
#
# add users to groups at: https://github.com/orgs/codesphere-cloud/teams/dev/teams
# new groups should have dev as parent (or else one of the subgroups)
#
# IMPORTANT: only add groups as owners (below); never individual users.

# Global owners.
* @codesphere-cloud/Architects
28 changes: 28 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# This workflow will build a golang project
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go

name: Build & Test

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

jobs:

build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v4
with:
go-version-file: 'go.mod'

- name: Build
run: make build

- name: Test
run: make test
24 changes: 24 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Lint
on:
push:
branches:
- main
pull_request:

permissions:
contents: read
pull-requests: read

jobs:
golangci:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: 'go.mod'
- name: golangci-lint
uses: golangci/golangci-lint-action@v7
with:
version: v2.0
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ OPENAPI_DIR = ./pkg/api/openapi_client
format:
go fmt ./...

check:
go vet ./...
lint:
golangci-lint run

test:
go test ./...
Expand Down
39 changes: 24 additions & 15 deletions cmd/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,10 @@ func (logCmd *LogCmd) RunE(_ *cobra.Command, args []string) (err error) {
if *logCmd.scope.workspaceId == 0 {
*logCmd.scope.workspaceId, err = strconv.Atoi(os.Getenv("CS_WORKSPACE_ID"))
if err != nil {
return fmt.Errorf("Failed to read env var: %e", err)
return fmt.Errorf("failer to read env var: %e", err)
}
if *logCmd.scope.workspaceId == 0 {
return errors.New("Workspace ID required, but not provided.")
return errors.New("workspace ID required, but not provided")
}
}

Expand All @@ -119,9 +119,9 @@ func (logCmd *LogCmd) RunE(_ *cobra.Command, args []string) (err error) {
return printLogsOfServer(&logCmd.scope)
}

logCmd.printAllLogs()
err = logCmd.printAllLogs()
if err != nil {
return fmt.Errorf("Failed to print logs: %e", err)
return fmt.Errorf("failed to print logs: %e", err)
}

return nil
Expand All @@ -132,20 +132,23 @@ func (l *LogCmd) printAllLogs() error {

replicas, err := cs.GetPipelineStatus(*l.scope.workspaceId, "run")
if err != nil {
return fmt.Errorf("Failed to get pipeline status: %e", err)
return fmt.Errorf("failed to get pipeline status: %e", err)
}

var wg sync.WaitGroup
for _, replica := range replicas {
for s, _ := range replica.Steps {
for s := range replica.Steps {
wg.Add(1)
go func() {
defer wg.Done()
scope := l.scope
*scope.step = s
*scope.replica = replica.Replica
prefix := fmt.Sprintf("|%-10s|%s", replica.Server, replica.Replica[len(replica.Replica)-11:])
printLogsOfReplica(prefix, &scope)
err = printLogsOfReplica(prefix, &scope)
if err != nil {
fmt.Printf("Error printling logs: %e\n", err)
}
}()
}
}
Expand Down Expand Up @@ -183,21 +186,24 @@ func printLogsOfEndpoint(prefix string, endpoint string) error {

req, err := http.NewRequestWithContext(ctx, "GET", endpoint, nil)
if err != nil {
return fmt.Errorf("Failed to construct request: %s", err)
return fmt.Errorf("failed to construct request: %s", err)
}

// Set the Accept header to indicate SSE
req.Header.Set("Accept", "text/event-stream")
cs.SetAuthoriziationHeader(req)
err = cs.SetAuthoriziationHeader(req)
if err != nil {
return fmt.Errorf("failed to set header: %e", err)
}

resp, err := http.DefaultClient.Do(req)
if err != nil {
return fmt.Errorf("Failed to request logs: %s", err)
return fmt.Errorf("failed to request logs: %e", err)
}
defer resp.Body.Close()
defer func() { _ = resp.Body.Close() }()

if resp.StatusCode != http.StatusOK {
return fmt.Errorf("Log server responded with non-ok code: %d", resp.StatusCode)
return fmt.Errorf("log server responded with non-ok code: %d", resp.StatusCode)
}

reader := bufio.NewReader(resp.Body)
Expand All @@ -210,7 +216,7 @@ func printLogsOfEndpoint(prefix string, endpoint string) error {
if err == io.EOF {
return nil
}
return fmt.Errorf("Failed to parse log: %s", err)
return fmt.Errorf("failed to parse log: %s", err)
}

line = strings.TrimSpace(line)
Expand Down Expand Up @@ -247,9 +253,12 @@ func printLogsOfEndpoint(prefix string, endpoint string) error {
err := json.Unmarshal([]byte(sse.data), &log)
if err != nil {
var errRes ErrResponse
json.Unmarshal([]byte(sse.data), &errRes)
err = json.Unmarshal([]byte(sse.data), &errRes)
if err != nil {
return fmt.Errorf("error reading error json: %e", err)
}
return fmt.Errorf(
"Server responded with error: %d %s: %s",
"server responded with error: %d %s: %s",
errRes.Status, errRes.Title, errRes.Detail,
)
}
Expand Down
20 changes: 14 additions & 6 deletions pkg/cs/cs.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,28 +33,36 @@ func GetPipelineStatus(ws int, stage string) (res []ReplicaStatus, err error) {

status, err := Get(fmt.Sprintf("workspaces/%d/pipeline/%s", ws, stage))
if err != nil {
err = fmt.Errorf("Failed to get pipeline status: %e", err)
err = fmt.Errorf("failed to get pipeline status: %e", err)
return
}

json.Unmarshal(status, &res)
err = json.Unmarshal(status, &res)
if err != nil {
err = fmt.Errorf("Failed to unmarshal pipeline status: %e", err)
err = fmt.Errorf("failed to unmarshal pipeline status: %e", err)
return
}
return
}

func Get(path string) (body []byte, err error) {
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s/%s", GetApiUrl(), strings.TrimPrefix(path, "/")), http.NoBody)
SetAuthoriziationHeader(req)
if err != nil {
err = fmt.Errorf("failed to create request: %e", err)
return
}
err = SetAuthoriziationHeader(req)
if err != nil {
err = fmt.Errorf("failed to set header: %e", err)
return
}

res, err := http.DefaultClient.Do(req)
if err != nil {
err = fmt.Errorf("GET failed: %e", err)
return
}
defer res.Body.Close()
defer func() { _ = res.Body.Close() }()
body, err = io.ReadAll(res.Body)
return
}
Expand All @@ -63,7 +71,7 @@ func SetAuthoriziationHeader(req *http.Request) error {

apiToken := os.Getenv("CS_TOKEN")
if apiToken == "" {
return errors.New("CS_TOKEN env var required, but not set.")
return errors.New("CS_TOKEN env var required, but not set")
}
req.Header.Set("Authorization", "Bearer "+apiToken)
return nil
Expand Down