-
-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add docker, nomad and k8s manifests for exporter #35
Changes from all commits
3628f8d
cd6fefb
62387cb
f35a7a0
c56af9f
6e1a0e3
9f11f98
ec08eb8
d09affb
d225a16
3837a23
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
name: docker-integration-test | ||
on: [push] | ||
jobs: | ||
docker-integration-test: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- | ||
name: Checkout code | ||
uses: actions/checkout@v3 | ||
- | ||
name: Go build | ||
run: CGO_ENABLED=0 GOOS=linux go build -o grid-intensity . | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Binary is named grid-intensity in the dockerfile not grid-intensity-go for consistency with the CLI |
||
- | ||
name: Set up QEMU | ||
uses: docker/setup-qemu-action@v2 | ||
- | ||
name: Set up Docker Buildx | ||
uses: docker/setup-buildx-action@v2 | ||
- | ||
name: Docker build | ||
uses: docker/build-push-action@v3 | ||
with: | ||
context: . | ||
load: true | ||
tags: thegreenwebfoundation/grid-intensity:integration-test | ||
- | ||
name: Docker run | ||
run: docker run -d -e GRID_INTENSITY_REGION=GBR -p 8000:8000 thegreenwebfoundation/grid-intensity:integration-test exporter | ||
- | ||
name: Run integration test | ||
run: go test -v -tags=dockerrequired ./integration/test/exporter |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
name: kubernetes-integration-test | ||
on: [push] | ||
jobs: | ||
kubernetes-integration-test: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- | ||
name: Checkout code | ||
uses: actions/checkout@v3 | ||
- | ||
name: Go build | ||
run: CGO_ENABLED=0 GOOS=linux go build -o grid-intensity . | ||
- | ||
name: Set up QEMU | ||
uses: docker/setup-qemu-action@v2 | ||
- | ||
name: Set up Docker Buildx | ||
uses: docker/setup-buildx-action@v2 | ||
- | ||
name: Docker build | ||
uses: docker/build-push-action@v3 | ||
with: | ||
context: . | ||
load: true | ||
tags: thegreenwebfoundation/grid-intensity:integration-test | ||
- | ||
name: Create kubernetes Kind Cluster | ||
uses: helm/[email protected] | ||
- | ||
name: Load image into Kind cluster | ||
run: kind load docker-image --name chart-testing thegreenwebfoundation/grid-intensity:integration-test | ||
- | ||
name: Set up Helm | ||
uses: azure/setup-helm@v3 | ||
- | ||
name: Helm install | ||
run: helm install grid-intensity-exporter helm/grid-intensity-exporter --set image.tag=integration-test | ||
- | ||
name: Set up Kubectl | ||
uses: azure/setup-kubectl@v3 | ||
- | ||
name: Wait for ready pod | ||
run: kubectl wait --for=condition=ready -l app.kubernetes.io/name=grid-intensity-exporter pod | ||
- | ||
name: Create port forward to metrics port | ||
run: kubectl port-forward deployment/grid-intensity-exporter 8000:8000 & | ||
- | ||
name: Run integration test | ||
run: go test -v -tags=dockerrequired ./integration/test/exporter |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
name: nomad-integration-test | ||
on: [push] | ||
jobs: | ||
nomad-integration-test: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- | ||
name: Checkout code | ||
uses: actions/checkout@v3 | ||
- | ||
name: Go build | ||
run: CGO_ENABLED=0 GOOS=linux go build -o grid-intensity . | ||
- | ||
name: Set up QEMU | ||
uses: docker/setup-qemu-action@v2 | ||
- | ||
name: Set up Docker Buildx | ||
uses: docker/setup-buildx-action@v2 | ||
- | ||
name: Docker build | ||
uses: docker/build-push-action@v3 | ||
with: | ||
context: . | ||
load: true | ||
tags: thegreenwebfoundation/grid-intensity:integration-test | ||
- | ||
name: Add HashiCorp GPG key | ||
run: curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add - | ||
- | ||
name: Add HashiCorp Linux repository | ||
run: sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | ||
- | ||
name: Install nomad | ||
run: sudo apt-get update && sudo apt-get install nomad | ||
- | ||
name: Start running nomad in agent mode, then background it | ||
run: nomad agent --dev & | ||
- | ||
name: Submit the grid-intensity-exporter.nomad job to nomad | ||
run: nomad run ./nomad/grid-intensity-exporter.nomad | ||
- | ||
name: Run integration test | ||
run: go test -v -tags=dockerrequired ./integration/test/exporter |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
FROM alpine:3.16 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I updated to the latest alpine. We could automate with dependabot here to update the docker base image, go packages and the github actions. |
||
|
||
RUN apk add --no-cache ca-certificates | ||
|
||
ADD ./grid-intensity /grid-intensity | ||
|
||
EXPOSE 8000/tcp | ||
|
||
ENTRYPOINT ["/grid-intensity"] |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
package cmd | ||
|
||
import ( | ||
"errors" | ||
"os" | ||
"path/filepath" | ||
|
||
"github.com/spf13/viper" | ||
) | ||
|
||
const ( | ||
electricityMapAPITokenEnvVar = "ELECTRICITY_MAP_API_TOKEN" | ||
wattTimeUserEnvVar = "WATT_TIME_USER" | ||
wattTimePasswordEnvVar = "WATT_TIME_PASSWORD" | ||
) | ||
|
||
func getConfigFile() (string, error) { | ||
homeDir, err := os.UserHomeDir() | ||
if err != nil { | ||
return "", nil | ||
} | ||
|
||
return filepath.Join(homeDir, configDir, configFileName), nil | ||
} | ||
|
||
func configFileExists(configFile string) (bool, error) { | ||
_, err := os.Stat(configFile) | ||
if err == nil { | ||
return true, nil | ||
} | ||
if errors.Is(err, os.ErrNotExist) { | ||
return false, nil | ||
} | ||
|
||
return false, err | ||
} | ||
|
||
func readConfig() (string, string, error) { | ||
configFile, err := getConfigFile() | ||
if err != nil { | ||
return "", "", err | ||
} | ||
|
||
viper.SetConfigFile(configFile) | ||
|
||
err = viper.ReadInConfig() | ||
if errors.Is(err, os.ErrNotExist) { | ||
// Config file may not be available e.g. when running as a container. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The config file support and docker where not playing nicely so I refactored this part. We now try to use the config file but it can't be written we still use the CLI arguments or env vars. As this will work better when run in nomad or k8s. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oh thanks Ross. this is what the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes totally, under the hood viper is just a key value store. The viper.GetString is to fetch a key. In front of the k/v store you can use flags, env vars, or config files. These changes mean we handle when there isn't a config file and we can't write to the filesystem. |
||
} else if err != nil { | ||
return "", "", err | ||
} | ||
|
||
providerName := viper.GetString(provider) | ||
regionCode := viper.GetString(region) | ||
|
||
return providerName, regionCode, nil | ||
} | ||
|
||
func writeConfig() error { | ||
configFile, err := getConfigFile() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
fileExists, err := configFileExists(configFile) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if !fileExists { | ||
// Create config dir if it doesn't exist. | ||
err = os.MkdirAll(filepath.Dir(configFile), os.ModePerm) | ||
if err != nil && !os.IsExist(err) { | ||
return nil | ||
} | ||
|
||
// Create config file if it doesn't exist. | ||
_, err = os.Create(configFile) | ||
if err != nil { | ||
// If we can't create file don't try to write config. | ||
return nil | ||
} | ||
} | ||
|
||
err = viper.WriteConfig() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
return nil | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -61,6 +61,11 @@ func init() { | |
|
||
viper.BindPFlag(provider, rootCmd.PersistentFlags().Lookup(provider)) | ||
viper.BindPFlag(region, rootCmd.PersistentFlags().Lookup(region)) | ||
|
||
// Also support environment variables. | ||
viper.SetEnvPrefix("grid_intensity") | ||
viper.BindEnv(provider) | ||
viper.BindEnv(region) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This adds support for the |
||
} | ||
|
||
func getEmberGridIntensityForCountry(countryCode string) error { | ||
|
@@ -143,7 +148,7 @@ func getCountryCode() (string, error) { | |
func runRoot() error { | ||
ctx := context.Background() | ||
|
||
providerName, regionCode, err := getConfig() | ||
providerName, regionCode, err := readConfig() | ||
if err != nil { | ||
return err | ||
} | ||
|
@@ -172,7 +177,7 @@ func runRoot() error { | |
return fmt.Errorf("provider %q not recognized", providerName) | ||
} | ||
|
||
err = viper.WriteConfig() | ||
err = writeConfig() | ||
if err != nil { | ||
return err | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
apiVersion: "v1" | ||
description: "A prometheus exporter for understanding the carbon intensity of compute." | ||
home: "https://github.com/thegreenwebfoundation/grid-intensity-go" | ||
name: "grid-intensity-exporter" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here comes the YAML 😂 I've kept the helm chart named grid-intensity-exporter as I don't think there is a good use case for running the CLI in k8s. |
||
version: "0.1.0" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
apiVersion: v1 | ||
kind: ConfigMap | ||
metadata: | ||
name: {{ .Release.Name }} | ||
labels: | ||
app.kubernetes.io/name: {{ .Release.Name }} | ||
data: | ||
gridIntensityProvider: {{ .Values.gridIntensity.provider | quote }} | ||
gridIntensityRegion: {{ .Values.gridIntensity.region | quote }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The github actions are mainly lift and shift but I updated the versions to the latest.