ci: linter (#14)
* ci: add linter * chore: update dependencies * remove package.json * feat: use enums * ci: rename workflow
This commit is contained in:
parent
b52e18aca1
commit
7e3d56c3e0
9 changed files with 71 additions and 72 deletions
5
.github/workflows/docker.yml
vendored
5
.github/workflows/docker.yml
vendored
|
@ -1,4 +1,4 @@
|
||||||
name: Publish Release
|
name: docker
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
@ -16,7 +16,7 @@ on:
|
||||||
branches: ["main"]
|
branches: ["main"]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build_docker_release:
|
build_and_push:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
|
@ -33,7 +33,6 @@ jobs:
|
||||||
ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}
|
ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}
|
||||||
tags: |
|
tags: |
|
||||||
type=raw,value=latest,enable=${{ github.event_name == 'release' }}
|
type=raw,value=latest,enable=${{ github.event_name == 'release' }}
|
||||||
type=sha
|
|
||||||
type=ref,event=branch
|
type=ref,event=branch
|
||||||
type=ref,event=pr
|
type=ref,event=pr
|
||||||
type=raw,value=${{ inputs.tags }},enable=${{ github.event_name == 'workflow_dispatch' }}
|
type=raw,value=${{ inputs.tags }},enable=${{ github.event_name == 'workflow_dispatch' }}
|
||||||
|
|
7
.github/workflows/test.yml
vendored
7
.github/workflows/test.yml
vendored
|
@ -13,7 +13,14 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Run unit tests
|
- name: Run unit tests
|
||||||
run: go test -v ./src/tests
|
run: go test -v ./src/tests
|
||||||
|
|
||||||
- name: Run formatter
|
- name: Run formatter
|
||||||
run: test -z $(gofmt -l ./src)
|
run: test -z $(gofmt -l ./src)
|
||||||
|
|
||||||
|
- name: golangci-lint
|
||||||
|
uses: golangci/golangci-lint-action@v3
|
||||||
|
with:
|
||||||
|
version: v1.55.2
|
||||||
|
|
|
@ -10,7 +10,6 @@ RUN go build -o /go/bin/immich-exporter ./src
|
||||||
FROM alpine:3.18
|
FROM alpine:3.18
|
||||||
|
|
||||||
COPY --from=builder /go/bin/immich-exporter /go/bin/immich-exporter
|
COPY --from=builder /go/bin/immich-exporter /go/bin/immich-exporter
|
||||||
COPY package.json /go/bin/
|
|
||||||
|
|
||||||
WORKDIR /go/bin
|
WORKDIR /go/bin
|
||||||
|
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -16,5 +16,5 @@ require (
|
||||||
github.com/prometheus/common v0.45.0 // indirect
|
github.com/prometheus/common v0.45.0 // indirect
|
||||||
github.com/prometheus/procfs v0.12.0 // indirect
|
github.com/prometheus/procfs v0.12.0 // indirect
|
||||||
golang.org/x/sys v0.15.0 // indirect
|
golang.org/x/sys v0.15.0 // indirect
|
||||||
google.golang.org/protobuf v1.31.0 // indirect
|
google.golang.org/protobuf v1.32.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
8
go.sum
8
go.sum
|
@ -5,8 +5,6 @@ github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
|
||||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||||
|
@ -31,10 +29,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
||||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
|
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
|
||||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=
|
||||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||||
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
|
||||||
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
|
14
makefile
Normal file
14
makefile
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
build:
|
||||||
|
go build -o ./qbittorrent-exporter.out ./src
|
||||||
|
dev :
|
||||||
|
go run ./src
|
||||||
|
dev-env :
|
||||||
|
go run ./src -e
|
||||||
|
format :
|
||||||
|
go fmt ./src
|
||||||
|
lint:
|
||||||
|
docker run --rm -v ./:/app -w /app golangci/golangci-lint:latest golangci-lint run -v
|
||||||
|
test:
|
||||||
|
go test -v ./src/tests
|
||||||
|
update:
|
||||||
|
go get -u ./src && go mod tidy
|
24
package.json
24
package.json
|
@ -1,24 +0,0 @@
|
||||||
{
|
|
||||||
"name": "immich-exporter",
|
|
||||||
"version": "1.2.0",
|
|
||||||
"description": "exporter for immich",
|
|
||||||
"main": "src/main.go",
|
|
||||||
"scripts": {
|
|
||||||
"build" : "go build -o ./immich-exporter.out ./src && ./immich-exporter.out",
|
|
||||||
"build:env" : "go build -o ./immich-exporter.out ./src && ./immich-exporter.out -e",
|
|
||||||
"dev" : "go run ./src",
|
|
||||||
"dev:env" : "go run ./src -e",
|
|
||||||
"test": "go test -v ./src/tests",
|
|
||||||
"update": "go get -u ./src && go mod tidy"
|
|
||||||
},
|
|
||||||
"keywords": [
|
|
||||||
"exporter",
|
|
||||||
"immich",
|
|
||||||
"grafana",
|
|
||||||
"dashboard",
|
|
||||||
"metrics",
|
|
||||||
"prometheus"
|
|
||||||
],
|
|
||||||
"author": "martabal",
|
|
||||||
"license": "MIT"
|
|
||||||
}
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"immich-exp/src/models"
|
"immich-exp/src/models"
|
||||||
"io/ioutil"
|
"io"
|
||||||
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"sync"
|
"sync"
|
||||||
|
@ -22,6 +22,28 @@ var (
|
||||||
mutex sync.Mutex
|
mutex sync.Mutex
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Data struct {
|
||||||
|
URL string
|
||||||
|
HTTPMethod string
|
||||||
|
}
|
||||||
|
|
||||||
|
var httpGetUsers = Data{
|
||||||
|
URL: "/api/user?isAll=true",
|
||||||
|
HTTPMethod: http.MethodGet,
|
||||||
|
}
|
||||||
|
var httpServerVersion = Data{
|
||||||
|
URL: "/api/server-info/version",
|
||||||
|
HTTPMethod: http.MethodGet,
|
||||||
|
}
|
||||||
|
var httpStatistics = Data{
|
||||||
|
URL: "/api/server-info/statistics",
|
||||||
|
HTTPMethod: http.MethodGet,
|
||||||
|
}
|
||||||
|
var httpGetJobs = Data{
|
||||||
|
URL: "/api/jobs",
|
||||||
|
HTTPMethod: http.MethodGet,
|
||||||
|
}
|
||||||
|
|
||||||
var unmarshalError = "Can not unmarshal JSON"
|
var unmarshalError = "Can not unmarshal JSON"
|
||||||
|
|
||||||
func Allrequests(r *prometheus.Registry) {
|
func Allrequests(r *prometheus.Registry) {
|
||||||
|
@ -63,10 +85,10 @@ func Analyze(r *prometheus.Registry) {
|
||||||
|
|
||||||
func GetAllUsers(c chan func() (*models.StructAllUsers, error)) {
|
func GetAllUsers(c chan func() (*models.StructAllUsers, error)) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
resp, err := Apirequest("/api/user?isAll=true", "GET")
|
resp, err := Apirequest(httpGetUsers.URL, httpGetUsers.HTTPMethod)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|
||||||
body, err := ioutil.ReadAll(resp.Body)
|
body, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln(err)
|
log.Fatalln(err)
|
||||||
} else {
|
} else {
|
||||||
|
@ -85,10 +107,10 @@ func GetAllUsers(c chan func() (*models.StructAllUsers, error)) {
|
||||||
|
|
||||||
func ServerVersion(r *prometheus.Registry) {
|
func ServerVersion(r *prometheus.Registry) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
resp, err := Apirequest("/api/server-info/version", "GET")
|
resp, err := Apirequest(httpServerVersion.URL, httpServerVersion.HTTPMethod)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|
||||||
body, err := ioutil.ReadAll(resp.Body)
|
body, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln(err)
|
log.Fatalln(err)
|
||||||
} else {
|
} else {
|
||||||
|
@ -105,10 +127,10 @@ func ServerVersion(r *prometheus.Registry) {
|
||||||
|
|
||||||
func ServerInfo(c chan func() (*models.StructServerInfo, error)) {
|
func ServerInfo(c chan func() (*models.StructServerInfo, error)) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
resp, err := Apirequest("/api/server-info/statistics", "GET")
|
resp, err := Apirequest(httpStatistics.URL, httpStatistics.HTTPMethod)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|
||||||
body, err := ioutil.ReadAll(resp.Body)
|
body, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln(err)
|
log.Fatalln(err)
|
||||||
} else {
|
} else {
|
||||||
|
@ -126,10 +148,10 @@ func ServerInfo(c chan func() (*models.StructServerInfo, error)) {
|
||||||
|
|
||||||
func GetAllJobsStatus(c chan func() (*models.StructAllJobsStatus, error)) {
|
func GetAllJobsStatus(c chan func() (*models.StructAllJobsStatus, error)) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
resp, err := Apirequest("/api/jobs", "GET")
|
resp, err := Apirequest(httpGetJobs.URL, httpGetJobs.HTTPMethod)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|
||||||
body, err := ioutil.ReadAll(resp.Body)
|
body, err := io.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln(err)
|
log.Fatalln(err)
|
||||||
} else {
|
} else {
|
||||||
|
@ -158,7 +180,7 @@ func Apirequest(uri string, method string) (*http.Response, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err := fmt.Errorf("Can't connect to server")
|
err := fmt.Errorf("Can't connect to server")
|
||||||
mutex.Lock()
|
mutex.Lock()
|
||||||
if models.GetPromptError() == false {
|
if !models.GetPromptError() {
|
||||||
log.Error(err.Error())
|
log.Error(err.Error())
|
||||||
models.SetPromptError(true)
|
models.SetPromptError(true)
|
||||||
}
|
}
|
||||||
|
@ -175,17 +197,15 @@ func Apirequest(uri string, method string) (*http.Response, error) {
|
||||||
mutex.Unlock()
|
mutex.Unlock()
|
||||||
return resp, nil
|
return resp, nil
|
||||||
case http.StatusNotFound:
|
case http.StatusNotFound:
|
||||||
err := fmt.Errorf("%d", resp.StatusCode)
|
|
||||||
|
|
||||||
log.Fatal("Error code ", resp.StatusCode, " for ", models.Getbaseurl()+uri)
|
log.Fatal("Error code ", resp.StatusCode, " for ", models.Getbaseurl()+uri)
|
||||||
|
|
||||||
return resp, err
|
return resp, fmt.Errorf("%d", resp.StatusCode)
|
||||||
case http.StatusUnauthorized, http.StatusForbidden:
|
case http.StatusUnauthorized, http.StatusForbidden:
|
||||||
err := fmt.Errorf("%d", resp.StatusCode)
|
|
||||||
|
|
||||||
log.Fatal("Api key unauthorized")
|
log.Fatal("Api key unauthorized")
|
||||||
|
|
||||||
return resp, err
|
return resp, fmt.Errorf("%d", resp.StatusCode)
|
||||||
default:
|
default:
|
||||||
err := fmt.Errorf("%d", resp.StatusCode)
|
err := fmt.Errorf("%d", resp.StatusCode)
|
||||||
mutex.Lock()
|
mutex.Lock()
|
||||||
|
|
32
src/init.go
32
src/init.go
|
@ -1,7 +1,6 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
immich "immich-exp/src/immich"
|
immich "immich-exp/src/immich"
|
||||||
|
@ -20,16 +19,24 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const DEFAULTPORT = 8090
|
const DEFAULTPORT = 8090
|
||||||
|
const AUTHOR = "martabal"
|
||||||
|
const VERSION = "1.2.0"
|
||||||
|
const PROJECT_NAME = "immich-exporter"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
loadenv()
|
loadenv()
|
||||||
projectinfo()
|
fmt.Printf("%s (version %s)\n", PROJECT_NAME, VERSION)
|
||||||
|
fmt.Println("Author: ", AUTHOR)
|
||||||
|
fmt.Println("Using log level: ", log.GetLevel())
|
||||||
log.Info("Immich URL: ", models.Getbaseurl())
|
log.Info("Immich URL: ", models.Getbaseurl())
|
||||||
log.Info("Started")
|
log.Info("Started")
|
||||||
http.HandleFunc("/metrics", metrics)
|
http.HandleFunc("/metrics", metrics)
|
||||||
addr := ":" + strconv.Itoa(models.GetPort())
|
addr := ":" + strconv.Itoa(models.GetPort())
|
||||||
log.Info("Listening on port ", models.GetPort())
|
log.Info("Listening on port ", models.GetPort())
|
||||||
http.ListenAndServe(addr, nil)
|
err := http.ListenAndServe(addr, nil)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func metrics(w http.ResponseWriter, r *http.Request) {
|
func metrics(w http.ResponseWriter, r *http.Request) {
|
||||||
|
@ -40,25 +47,6 @@ func metrics(w http.ResponseWriter, r *http.Request) {
|
||||||
h.ServeHTTP(w, r)
|
h.ServeHTTP(w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
func projectinfo() {
|
|
||||||
fileContent, err := os.ReadFile("./package.json")
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var res map[string]interface{}
|
|
||||||
err = json.Unmarshal(fileContent, &res)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Print(res["name"], " (version ", res["version"], ")\n")
|
|
||||||
fmt.Print("Author: ", res["author"], "\n")
|
|
||||||
fmt.Print("Using log level: ", log.GetLevel(), "\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
func loadenv() {
|
func loadenv() {
|
||||||
var envfile bool
|
var envfile bool
|
||||||
flag.BoolVar(&envfile, "e", false, "Use .env file")
|
flag.BoolVar(&envfile, "e", false, "Use .env file")
|
||||||
|
|
Loading…
Reference in a new issue