Skip to content

Commit

Permalink
feat: refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
fitbeard committed Jul 18, 2023
1 parent 0d03e8e commit b1d6d8c
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 82 deletions.
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@
!/rally
!/go.mod
!/go.sum
!/delete-tasks.sh
!/rally_exporter.go
9 changes: 7 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
FROM golang:1.13-stretch AS builder
FROM golang:1.20-bullseye AS builder

WORKDIR /go/src/app
COPY . .
RUN go build

FROM xrally/xrally-openstack:1.7.0
# FROM xrally/xrally-openstack:2.2.0
FROM xrally/xrally-openstack:latest

COPY delete-tasks.sh /delete-tasks.sh
RUN chmod +x /delete-tasks.sh
COPY --from=builder /go/src/app/rally-exporter /rally-exporter
ENTRYPOINT ["/rally-exporter"]
7 changes: 7 additions & 0 deletions delete-tasks.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env bash

COUNT=$(($1 + 1))

TASKID=$(rally task list | tail -$COUNT | head -1 | awk '{print $2}')

rally task delete --uuid $TASKID
20 changes: 0 additions & 20 deletions rally/deployment.go

This file was deleted.

85 changes: 37 additions & 48 deletions rally/runner.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
package rally

import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"os/exec"
"strconv"
"time"

"github.com/gophercloud/utils/openstack/clientconfig"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/sqlite"
"github.com/prometheus/client_golang/prometheus"
Expand All @@ -25,18 +22,21 @@ type PeriodicRunner struct {
prometheus.Collector

CloudName string
TaskFile string
ExecTime int
TaskCount int

TaskDuration *prometheus.Desc
TaskSLADesc *prometheus.Desc
TaskTime *prometheus.Desc
}

// NewPeriodicRunner creates a rally runner which executes every 5 minutes
func NewPeriodicRunner(cloudName string, taskFile string) *PeriodicRunner {
// NewPeriodicRunner creates a rally runner which executes every
// `execTime` minutes after last run.
func NewPeriodicRunner(cloudName string, execTime int, taskCount int) *PeriodicRunner {
return &PeriodicRunner{
CloudName: cloudName,
TaskFile: taskFile,
ExecTime: execTime,
TaskCount: taskCount,
TaskDuration: prometheus.NewDesc(
"rally_task_duration",
"Rally task duration",
Expand All @@ -55,13 +55,29 @@ func NewPeriodicRunner(cloudName string, taskFile string) *PeriodicRunner {
}
}

// Run starts the PeriodicRunner which runs Rally every 5 minutes.
// Run starts the PeriodicRunner which runs Rally every
// `execTime` minutes after last run.
func (runner *PeriodicRunner) Run() {
runner.createDeployment()

for {
log.Info("Starting Rally run...")
cmd := exec.Command("rally", "task", "start", runner.TaskFile)
currentTime := time.Now()

count := strconv.Itoa(runner.TaskCount)

log.Info("Deleting last Rally task")
// This is horrible. Should be rewritten in native golang.
precmd := exec.Command("/delete-tasks.sh", count)
preoutput, err := precmd.CombinedOutput()
if err != nil {
log.Error("Failed to delete last Rally task:")
} else {
log.Info("Deleted last Rally task:")
}
fmt.Println(string(preoutput))

log.Info("Starting Rally run at ", currentTime.String())
cmd := exec.Command("rally", "task", "start", "/conf/tasks.yml", "--task-args-file", "/conf/arguments.yml")
output, err := cmd.CombinedOutput()
if err != nil {
log.Error("Failed test, output below:")
Expand All @@ -70,50 +86,23 @@ func (runner *PeriodicRunner) Run() {
}
fmt.Println(string(output))

time.Sleep(5 * time.Minute)
minutes := runner.ExecTime
time.Sleep(time.Duration(minutes) * time.Minute)
}
}

func (runner *PeriodicRunner) createDeployment() {
opts := &clientconfig.ClientOpts{Cloud: runner.CloudName}
cloud, err := clientconfig.GetCloudFromYAML(opts)
if err != nil {
log.Fatal(err)
}

deployment := &Deployment{
OpenStackDeployment: OpenStackDeployment{
AuthURL: cloud.AuthInfo.AuthURL,
RegionName: cloud.RegionName,
EndpointType: cloud.EndpointType,
Users: []OpenStackUser{
OpenStackUser{
Username: cloud.AuthInfo.Username,
Password: cloud.AuthInfo.Password,
UserDomainName: cloud.AuthInfo.UserDomainName,
ProjectName: cloud.AuthInfo.ProjectName,
ProjectDomainName: cloud.AuthInfo.ProjectDomainName,
},
},
},
}

b, err := json.Marshal(deployment)
if err != nil {
log.Fatal(err)
}

file, err := ioutil.TempFile("/tmp", "deployment")
precmd := exec.Command("rally", "deployment", "destroy", runner.CloudName)
preoutput, err := precmd.CombinedOutput()
if err != nil {
log.Fatal(err)
}
defer os.Remove(file.Name())
_, err = file.Write(b)
if err != nil {
log.Fatal(err)
log.Warn("There is no Rally deployment named '", runner.CloudName, "' to destroy.")
} else {
log.Info("Successfully destroyed Rally deployment named '", runner.CloudName, "'.")
}
fmt.Println(string(preoutput))

cmd := exec.Command("rally", "deployment", "create", "--filename", file.Name(), "--name", runner.CloudName)
cmd := exec.Command("rally", "deployment", "create", "--filename", "/conf/deployment.yml", "--name", runner.CloudName)
output, err := cmd.CombinedOutput()
if err != nil {
fmt.Println(string(output))
Expand All @@ -137,7 +126,7 @@ func getLatestTask(db *gorm.DB) (*models.Task, error) {

// Collect grabs all the data from the Rally database
func (runner *PeriodicRunner) Collect(ch chan<- prometheus.Metric) {
db, err := gorm.Open("sqlite3", "/home/rally/data/rally.db")
db, err := gorm.Open("sqlite3", "/home/rally/.rally/rally.db")
if err != nil {
log.Fatal(err)
}
Expand Down
35 changes: 23 additions & 12 deletions rally_exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,31 +22,42 @@ func main() {
"web.telemetry-path",
"Path under which to expose metrics.",
).Default("/metrics").String()
cloud = kingpin.Arg(
"cloud",
"Name of the cloud from clouds.yaml",
).Required().String()
task = kingpin.Arg(
"file",
"Name of the task file",
deployment = kingpin.Flag(
"deployment-name",
"Name of the Rally deployment",
).Required().String()
exectime = kingpin.Flag(
"execution-time",
"Wait X minutes before next run. Default: 5",
).Default("5").Int()
taskcount = kingpin.Flag(
"task-history",
"Number of tasks to keep in history. Default: 10",
).Default("10").Int()
)

kingpin.Version(version.Print("rally-exporter"))
kingpin.HelpFlag.Short('h')
kingpin.Parse()

runner := rally.NewPeriodicRunner(*cloud, *task)
prometheus.MustRegister(runner)
// Get rid of any additional metrics
// we have to expose our metrics with a custom registry
registry := prometheus.NewRegistry()

runner := rally.NewPeriodicRunner(*deployment, *exectime, *taskcount)

registry.MustRegister(runner)

go runner.Run()

http.Handle("/metrics", promhttp.Handler())
handler := promhttp.HandlerFor(registry, promhttp.HandlerOpts{})
http.Handle("/metrics", handler)

http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
_, err := w.Write([]byte(`<html>
<head><title>Rally Exporter</title></head>
<head><title>OpenStack Rally Exporter</title></head>
<body>
<h1>Rally Exporter</h1>
<h1>OpenStack Rally Exporter</h1>
<p><a href="` + *metricsPath + `">Metrics</a></p>
</body>
</html>`))
Expand Down

0 comments on commit b1d6d8c

Please sign in to comment.