Skip to content

Commit

Permalink
add CI pipeline
Browse files Browse the repository at this point in the history
Signed-off-by: Dmitry Shmulevich <[email protected]>
  • Loading branch information
dmitsh committed Sep 27, 2024
1 parent e52b050 commit a6088d5
Show file tree
Hide file tree
Showing 17 changed files with 215 additions and 44 deletions.
76 changes: 76 additions & 0 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
name: Docker

# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.

on: workflow_dispatch

env:
REGISTRY: ghcr.io
# github.repository as <account>/<repo>
IMAGE_NAME: ${{ github.repository }}

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4

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

- name: Install Protoc
run: |
PROTOC_ZIP=protoc-28.2-linux-x86_64.zip
curl -OL https://github.com/protocolbuffers/protobuf/releases/download/v28.2/$PROTOC_ZIP
sudo unzip -o $PROTOC_ZIP -d /usr/local bin/protoc
sudo unzip -o $PROTOC_ZIP -d /usr/local 'include/*'
rm -f $PROTOC_ZIP
- name: Verify Protoc Version
run: protoc --version

- name: Build
run: |
make init-proto
make build
# Login against a Docker registry except on PR
# https://github.com/docker/login-action
- name: Log into registry ${{ env.REGISTRY }}
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

# Extract metadata (tags, labels) for Docker
# https://github.com/docker/metadata-action
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@96383f45573cb7f253c731d3b3ab81c87ef81934 # v5.0.0
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha,priority=100,prefix=,suffix=,format=short
# Build and push Docker image with Buildx (don't push on PR)
# https://github.com/docker/build-push-action
- name: Build and push Docker image
id: build-and-push
uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v5.0.0
with:
context: .
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
81 changes: 81 additions & 0 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# 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: Go

on:
pull_request:
types:
- opened
- synchronize
- reopened
branches:
- main
push:
branches:
- main

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

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

- name: Lint
uses: golangci/golangci-lint-action@v5
with:
version: 'v1.58.0'
args: -v --timeout 5m
skip-cache: true

- name: vet
run:
make vet

- name: fmt
run:
test -z "$(go fmt ./...)"

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

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

- name: Test
run: go test -v ./...

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

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

- name: Install Protoc
run: |
PROTOC_ZIP=protoc-28.2-linux-x86_64.zip
curl -OL https://github.com/protocolbuffers/protobuf/releases/download/v28.2/$PROTOC_ZIP
sudo unzip -o $PROTOC_ZIP -d /usr/local bin/protoc
sudo unzip -o $PROTOC_ZIP -d /usr/local 'include/*'
rm -f $PROTOC_ZIP
- name: Verify Protoc Version
run: protoc --version

- name: Build
run: |
make init-proto
make build
6 changes: 3 additions & 3 deletions cmd/node-observer/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import (
"k8s.io/client-go/rest"
"k8s.io/klog/v2"

"github.com/NVIDIA/topograph/pkg/state_observer"
"github.com/NVIDIA/topograph/pkg/node_observer"
)

var GitTag string
Expand All @@ -55,7 +55,7 @@ func main() {
}

func mainInternal(c string) error {
cfg, err := state_observer.NewConfigFromFile(c)
cfg, err := node_observer.NewConfigFromFile(c)
if err != nil {
return err
}
Expand All @@ -73,7 +73,7 @@ func mainInternal(c string) error {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

controller, err := state_observer.NewController(ctx, kubeClient, cfg)
controller, err := node_observer.NewController(ctx, kubeClient, cfg)
if err != nil {
return err
}
Expand Down
4 changes: 3 additions & 1 deletion cmd/topograph/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ func mainInternal(c string) error {
return err
}

cfg.UpdateEnv()
if err = cfg.UpdateEnv(); err != nil {
return err
}

ctx, cancel := context.WithCancel(context.Background())
defer cancel()
Expand Down
2 changes: 1 addition & 1 deletion pkg/aws/imds.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func getMetadata(path string) ([]byte, error) {
if err != nil {
return nil, err
}
defer resp.Body.Close()
defer func() { _ = resp.Body.Close() }()

if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("HTTP status: %s", resp.Status)
Expand Down
13 changes: 9 additions & 4 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,15 +99,20 @@ func (cfg *Config) validate() error {
return cfg.readCredentials()
}

func (cfg *Config) UpdateEnv() {
func (cfg *Config) UpdateEnv() (err error) {
for env, val := range cfg.Env {
if env == "PATH" { // special case for PATH env var
os.Setenv("PATH", fmt.Sprintf("%s:%s", os.Getenv("PATH"), val))
err = os.Setenv("PATH", fmt.Sprintf("%s:%s", os.Getenv("PATH"), val))
} else {
os.Setenv(env, val)
err = os.Setenv(env, val)
}
if err != nil {
return fmt.Errorf("failed to set %q environment variable: %v", env, err)
}
klog.Infof("Updated env %s=%s", env, os.Getenv(env))
}

return
}

func (cfg *Config) readCredentials() error {
Expand All @@ -122,7 +127,7 @@ func (cfg *Config) readCredentials() error {
if err != nil {
return err
}
defer file.Close()
defer func() { _ = file.Close() }()

data, err := io.ReadAll(file)
if err != nil {
Expand Down
42 changes: 22 additions & 20 deletions pkg/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,23 +42,23 @@ env:
func TestConfig(t *testing.T) {
file, err := os.CreateTemp("", "test-cfg-*.yml")
require.NoError(t, err)
defer os.Remove(file.Name())
defer file.Close()
defer func() { _ = os.Remove(file.Name()) }()
defer func() { _ = file.Close() }()

cert, err := os.CreateTemp("", "test-cert-*.yml")
require.NoError(t, err)
defer os.Remove(cert.Name())
defer cert.Close()
defer func() { _ = os.Remove(cert.Name()) }()
defer func() { _ = cert.Close() }()

key, err := os.CreateTemp("", "test-key-*.yml")
require.NoError(t, err)
defer os.Remove(key.Name())
defer key.Close()
defer func() { _ = os.Remove(key.Name()) }()
defer func() { _ = key.Close() }()

caCert, err := os.CreateTemp("", "test-ca-cert-*.yml")
require.NoError(t, err)
defer os.Remove(caCert.Name())
defer caCert.Close()
defer func() { _ = os.Remove(caCert.Name()) }()
defer func() { _ = caCert.Close() }()

_, err = file.WriteString(fmt.Sprintf(configTemplate, cert.Name(), key.Name(), caCert.Name()))
require.NoError(t, err)
Expand All @@ -84,32 +84,34 @@ func TestConfig(t *testing.T) {
}
require.Equal(t, expected, cfg)

var oldPath, newPath = os.Getenv("PATH"), ""
if len(oldPath) == 0 {
newPath = oldPath
var path string
if path = os.Getenv("PATH"); len(path) == 0 {
path = "/a/b/c"
} else {
newPath = oldPath + ":" + "/a/b/c"
path = path + ":" + "/a/b/c"
}

cfg.UpdateEnv()
err = cfg.UpdateEnv()
require.NoError(t, err)

require.Equal(t, "/etc/slurm/config.yaml", os.Getenv("SLURM_CONF"))
require.Equal(t, newPath, os.Getenv("PATH"))
require.Equal(t, path, os.Getenv("PATH"))
}
func TestValidate(t *testing.T) {
cert, err := os.CreateTemp("", "test-cert-*.yml")
require.NoError(t, err)
defer os.Remove(cert.Name())
defer cert.Close()
defer func() { _ = os.Remove(cert.Name()) }()
defer func() { _ = cert.Close() }()

key, err := os.CreateTemp("", "test-key-*.yml")
require.NoError(t, err)
defer os.Remove(key.Name())
defer key.Close()
defer func() { _ = os.Remove(key.Name()) }()
defer func() { _ = key.Close() }()

caCert, err := os.CreateTemp("", "test-ca-cert-*.yml")
require.NoError(t, err)
defer os.Remove(caCert.Name())
defer caCert.Close()
defer func() { _ = os.Remove(caCert.Name()) }()
defer func() { _ = caCert.Close() }()

testCases := []struct {
name string
Expand Down
2 changes: 1 addition & 1 deletion pkg/gcp/instance_topology.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func GenerateInstanceTopology(ctx context.Context, _ interface{}, instanceToNode
if err != nil {
return nil, fmt.Errorf("unable to get zones client: %s", err.Error())
}
projectID, err := metadata.ProjectID()
projectID, err := metadata.ProjectIDWithContext(ctx)
if err != nil {
return nil, fmt.Errorf("unable to get project ID: %s", err.Error())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

package state_observer
package node_observer

import (
"fmt"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

package state_observer
package node_observer

import (
"context"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

package state_observer
package node_observer

import (
"context"
Expand Down Expand Up @@ -56,7 +56,7 @@ func (n *NodeInformer) Start() error {

informer := n.factory.Core().V1().Nodes().Informer()

informer.AddEventHandler(cache.ResourceEventHandlerFuncs{
_, err := informer.AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) {
node := obj.(*v1.Node)
klog.V(4).Infof("Node informer added node %s", node.Name)
Expand All @@ -72,6 +72,9 @@ func (n *NodeInformer) Start() error {
n.SendRequest()
},
})
if err != nil {
return err
}

informer.Run(n.ctx.Done())

Expand Down
2 changes: 1 addition & 1 deletion pkg/server/grpc_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func forwardRequest(ctx context.Context, tr *TopologyRequest, url string, cis []
if err != nil {
return nil, fmt.Errorf("failed to connect to %s: %v", url, err)
}
defer conn.Close()
defer func() { _ = conn.Close() }()

client := pb.NewTopologyServiceClient(conn)

Expand Down
Loading

0 comments on commit a6088d5

Please sign in to comment.