Drone CI and linting (#14)

This commit is contained in:
Stanislav Nikitin 2019-10-16 18:32:21 +00:00 committed by Gitea
parent ef597063cf
commit 5acc64de59
12 changed files with 51 additions and 11 deletions

View File

@ -5,29 +5,31 @@ name: build
steps: steps:
- name: notify-start - name: notify-start
image: appleboy/drone-discord image: pztrn/discordrone
settings: settings:
webhook_id: webhook_id:
from_secret: discord_webhook_id from_secret: discord_webhook_id
webhook_token: webhook_token:
from_secret: discord_webhook_secret from_secret: discord_webhook_secret
message: 'Starting building **{{repo.name}}#{{build.number}}@{{build.commit}}** @ {{datetime build.started "02-Jan-2006 15:04:05 MST" "Asia/Yekaterinburg"}} (See {{build.link}} for logs).' message: 'Starting building **{{repo.name}}#{{build.number}}@{{commit.sha}}** @ {{datetime build.started "02-Jan-2006 15:04:05 MST" "Asia/Yekaterinburg"}} (See {{build.link}} for logs).'
- name: lint - name: lint
image: golangci/golangci-lint:latest image: golangci/golangci-lint:latest
environment: environment:
GOFLAGS: -mod=vendor
CGO_ENABLED: 0 CGO_ENABLED: 0
commands: commands:
- golangci-lint run - golangci-lint run
depends_on:
- notify-start
- name: test - name: test
image: golang:1.13.1-alpine image: golang:1.13.1-alpine
environment: environment:
GOFLAGS: -mod=vendor
CGO_ENABLED: 0 CGO_ENABLED: 0
commands: commands:
- go test ./... - go test ./...
depends_on:
- notify-start
- name: docker - name: docker
image: plugins/docker image: plugins/docker
@ -41,13 +43,16 @@ steps:
from_secret: dockerhub_password from_secret: dockerhub_password
repo: pztrn/giredore repo: pztrn/giredore
auto_tag: true auto_tag: true
depends_on:
- lint
- test
- name: notify-end - name: notify-end
when: when:
status: status:
- success - success
- failure - failure
image: appleboy/drone-discord image: pztrn/discordrone
settings: settings:
webhook_id: webhook_id:
from_secret: discord_webhook_id from_secret: discord_webhook_id
@ -55,7 +60,9 @@ steps:
from_secret: discord_webhook_secret from_secret: discord_webhook_secret
message: " message: "
{{#success build.status}} {{#success build.status}}
**{{repo.name}}#{{build.number}}@{{build.commit}}** built and pushed to hub.docker.com. **{{repo.name}}#{{build.number}}@{{commit.sha}}** built in {{since build.startedint}} and pushed to hub.docker.com.
{{ else }} {{ else }}
**{{repo.name}}#{{build.number}}@{{build.commit}}** failed. See {{build.link}}. **{{repo.name}}#{{build.number}}@{{commit.sha}}** failed. See {{build.link}}.
{{/success}}" {{/success}}"
depends_on:
- docker

View File

@ -3,7 +3,8 @@ FROM golang:1.13.1-alpine AS build
WORKDIR /go/src/sources.dev.pztrn.name/pztrn/giredore WORKDIR /go/src/sources.dev.pztrn.name/pztrn/giredore
COPY . . COPY . .
RUN cd /go/src/sources.dev.pztrn.name/pztrn/giredore/cmd/giredored && go build && cd ../giredorectl && go build ENV CGO_ENABLED=0
RUN cd /go/src/sources.dev.pztrn.name/pztrn/giredore/cmd/giredored && go build -tags netgo -ldflags '-w -extldflags "-static"' && cd ../giredorectl && go build -tags netgo -ldflags '-w -extldflags "-static"'
FROM alpine:latest FROM alpine:latest
LABEL maintainer "Stanislav N. <pztrn@pztrn.name>" LABEL maintainer "Stanislav N. <pztrn@pztrn.name>"

View File

@ -29,7 +29,9 @@ func main() {
// CTRL+C handler. // CTRL+C handler.
signalHandler := make(chan os.Signal, 1) signalHandler := make(chan os.Signal, 1)
shutdownDone := make(chan bool, 1) shutdownDone := make(chan bool, 1)
signal.Notify(signalHandler, os.Interrupt, syscall.SIGTERM) signal.Notify(signalHandler, os.Interrupt, syscall.SIGTERM)
go func() { go func() {
<-signalHandler <-signalHandler
httpserver.Shutdown() httpserver.Shutdown()

View File

@ -11,6 +11,7 @@ import (
func GetConfiguration(options map[string]string) { func GetConfiguration(options map[string]string) {
url := "http://" + options["server"] + "/_api/configuration" url := "http://" + options["server"] + "/_api/configuration"
log.Info().Msg("Getting configuration from giredore server...") log.Info().Msg("Getting configuration from giredore server...")
data, err := requester.Get(url) data, err := requester.Get(url)
@ -23,6 +24,7 @@ func GetConfiguration(options map[string]string) {
func SetAllowedIPs(args []string, options map[string]string) { func SetAllowedIPs(args []string, options map[string]string) {
url := "http://" + options["server"] + "/_api/configuration/allowedips" url := "http://" + options["server"] + "/_api/configuration/allowedips"
log.Info().Str("allowed IPs", args[0]).Msg("Setting allowed IPs for API interaction...") log.Info().Str("allowed IPs", args[0]).Msg("Setting allowed IPs for API interaction...")
req := &structs.AllowedIPsSetRequest{ req := &structs.AllowedIPsSetRequest{

View File

@ -17,6 +17,7 @@ func DeletePackage(args []string, options map[string]string) {
log.Info().Str("original path", req.OriginalPath).Msg("Sending package deletion request to giredored...") log.Info().Str("original path", req.OriginalPath).Msg("Sending package deletion request to giredored...")
url := "http://" + options["server"] + "/_api/packages" url := "http://" + options["server"] + "/_api/packages"
data, err := requester.Delete(url, req) data, err := requester.Delete(url, req)
if err != nil { if err != nil {
log.Fatal().Err(err).Msg("Failed to send package deletion request to giredored") log.Fatal().Err(err).Msg("Failed to send package deletion request to giredored")
@ -36,6 +37,7 @@ func GetPackages(args []string, options map[string]string) {
} }
url := "http://" + options["server"] + "/_api/packages" url := "http://" + options["server"] + "/_api/packages"
log.Info().Msg("Getting packages data from giredore server...") log.Info().Msg("Getting packages data from giredore server...")
data, err := requester.Post(url, req) data, err := requester.Post(url, req)
@ -57,6 +59,7 @@ func SetPackage(args []string, options map[string]string) {
log.Info().Str("description", pkg.Description).Str("original path", pkg.OriginalPath).Str("real path", pkg.RealPath).Str("VCS", pkg.VCS).Msg("Sending set/update request to giredored...") log.Info().Str("description", pkg.Description).Str("original path", pkg.OriginalPath).Str("real path", pkg.RealPath).Str("VCS", pkg.VCS).Msg("Sending set/update request to giredored...")
url := "http://" + options["server"] + "/_api/packages" url := "http://" + options["server"] + "/_api/packages"
data, err := requester.Put(url, pkg) data, err := requester.Put(url, pkg)
if err != nil { if err != nil {
log.Fatal().Err(err).Msg("Failed to send package update/set request to giredored") log.Fatal().Err(err).Msg("Failed to send package update/set request to giredored")

View File

@ -18,7 +18,9 @@ func throwGoImports(ec echo.Context) error {
// to list available packages. // to list available packages.
// For now only package itself is supported, all other features in ToDo. // For now only package itself is supported, all other features in ToDo.
packageNameRaw := ec.Request().URL.Path packageNameRaw := ec.Request().URL.Path
pkgs, errs := configuration.Cfg.GetPackagesInfo([]string{packageNameRaw}) pkgs, errs := configuration.Cfg.GetPackagesInfo([]string{packageNameRaw})
if errs != nil { if errs != nil {
log.Error().Str("package", packageNameRaw).Msgf("Failed to get package information: %+v", errs) log.Error().Str("package", packageNameRaw).Msgf("Failed to get package information: %+v", errs)
return ec.JSON(http.StatusBadRequest, &structs.Reply{Status: structs.StatusFailure, Errors: errs}) return ec.JSON(http.StatusBadRequest, &structs.Reply{Status: structs.StatusFailure, Errors: errs})

View File

@ -24,7 +24,9 @@ func packagesGET(ec echo.Context) error {
log.Info().Msgf("Received package(s) info get request: %+v", req) log.Info().Msgf("Received package(s) info get request: %+v", req)
var pkgs map[string]*structs.Package var pkgs map[string]*structs.Package
var errors []structs.Error var errors []structs.Error
if req.All { if req.All {
pkgs = configuration.Cfg.GetAllPackagesInfo() pkgs = configuration.Cfg.GetAllPackagesInfo()
} else { } else {

View File

@ -62,6 +62,7 @@ func (fc *fileConfig) DeletePackage(req *structs.PackageDeleteRequest) []structs
func (fc *fileConfig) GetAllowedIPs() []string { func (fc *fileConfig) GetAllowedIPs() []string {
var allowedIPs []string var allowedIPs []string
fc.HTTP.allowedipsmutex.RLock() fc.HTTP.allowedipsmutex.RLock()
allowedIPs = append(allowedIPs, fc.HTTP.AllowedIPs...) allowedIPs = append(allowedIPs, fc.HTTP.AllowedIPs...)
fc.HTTP.allowedipsmutex.RUnlock() fc.HTTP.allowedipsmutex.RUnlock()
@ -83,6 +84,7 @@ func (fc *fileConfig) GetAllPackagesInfo() map[string]*structs.Package {
func (fc *fileConfig) GetPackagesInfo(packages []string) (map[string]*structs.Package, []structs.Error) { func (fc *fileConfig) GetPackagesInfo(packages []string) (map[string]*structs.Package, []structs.Error) {
pkgs := make(map[string]*structs.Package) pkgs := make(map[string]*structs.Package)
var errors []structs.Error var errors []structs.Error
fc.packagesMutex.Lock() fc.packagesMutex.Lock()
@ -135,6 +137,7 @@ func (fc *fileConfig) Initialize() {
// Ensure that localhost (127.0.0.1) are defined in AllowedIPs. // Ensure that localhost (127.0.0.1) are defined in AllowedIPs.
var localhostIsAllowed bool var localhostIsAllowed bool
for _, ip := range fc.HTTP.AllowedIPs { for _, ip := range fc.HTTP.AllowedIPs {
if strings.Contains(ip, "127.0.0.1") { if strings.Contains(ip, "127.0.0.1") {
localhostIsAllowed = true localhostIsAllowed = true
@ -144,6 +147,7 @@ func (fc *fileConfig) Initialize() {
if !localhostIsAllowed { if !localhostIsAllowed {
cfgLoadLog.Warn().Msg("Localhost (127.0.0.1) wasn't allowed to access configuration API, adding it to list of allowed IP addresses") cfgLoadLog.Warn().Msg("Localhost (127.0.0.1) wasn't allowed to access configuration API, adding it to list of allowed IP addresses")
fc.HTTP.AllowedIPs = append(fc.HTTP.AllowedIPs, "127.0.0.1") fc.HTTP.AllowedIPs = append(fc.HTTP.AllowedIPs, "127.0.0.1")
} else { } else {
cfgLoadLog.Debug().Msg("Localhost (127.0.0.1) is allowed to access configuration API") cfgLoadLog.Debug().Msg("Localhost (127.0.0.1) is allowed to access configuration API")
@ -161,6 +165,7 @@ func (fc *fileConfig) normalizePath(configPath string) (string, error) {
if err != nil { if err != nil {
return "", err return "", err
} }
configPath = strings.Replace(configPath, "~", homeDir, 1) configPath = strings.Replace(configPath, "~", homeDir, 1)
} }

View File

@ -44,10 +44,12 @@ func Initialize() {
// Shutdown stops HTTP server. Returns true on success and false on failure. // Shutdown stops HTTP server. Returns true on success and false on failure.
func Shutdown() { func Shutdown() {
log.Info().Msg("Shutting down HTTP server...") log.Info().Msg("Shutting down HTTP server...")
err := Srv.Shutdown(context.Background()) err := Srv.Shutdown(context.Background())
if err != nil { if err != nil {
log.Fatal().Err(err).Msg("Failed to stop HTTP server") log.Fatal().Err(err).Msg("Failed to stop HTTP server")
} }
log.Info().Msg("HTTP server shutted down") log.Info().Msg("HTTP server shutted down")
} }
@ -59,19 +61,23 @@ func Start() {
go func() { go func() {
err := Srv.Start(configuration.Cfg.HTTP.Listen) err := Srv.Start(configuration.Cfg.HTTP.Listen)
if !strings.Contains(err.Error(), "Server closed") { if !strings.Contains(err.Error(), "Server closed") {
log.Fatal().Err(err).Msg("HTTP server critial error occurred") log.Fatal().Err(err).Msg("HTTP server critical error occurred")
} }
}() }()
// Check that HTTP server was started. // Check that HTTP server was started.
httpc := &http.Client{Timeout: time.Second * 1} httpc := &http.Client{Timeout: time.Second * 1}
checks := 0 checks := 0
for { for {
checks++ checks++
if checks >= configuration.Cfg.HTTP.WaitForSeconds { if checks >= configuration.Cfg.HTTP.WaitForSeconds {
log.Fatal().Int("seconds passed", checks).Msg("HTTP server isn't up") log.Fatal().Int("seconds passed", checks).Msg("HTTP server isn't up")
} }
time.Sleep(time.Second * 1) time.Sleep(time.Second * 1)
resp, err := httpc.Get("http://" + configuration.Cfg.HTTP.Listen + "/_internal/waitForOnline") resp, err := httpc.Get("http://" + configuration.Cfg.HTTP.Listen + "/_internal/waitForOnline")
if err != nil { if err != nil {
log.Debug().Err(err).Msg("HTTP error occurred, HTTP server isn't ready, waiting...") log.Debug().Err(err).Msg("HTTP error occurred, HTTP server isn't ready, waiting...")
@ -80,10 +86,12 @@ func Start() {
response, err := ioutil.ReadAll(resp.Body) response, err := ioutil.ReadAll(resp.Body)
resp.Body.Close() resp.Body.Close()
if err != nil { if err != nil {
log.Debug().Err(err).Msg("Failed to read response body, HTTP server isn't ready, waiting...") log.Debug().Err(err).Msg("Failed to read response body, HTTP server isn't ready, waiting...")
continue continue
} }
log.Debug().Str("status", resp.Status).Int("body length", len(response)).Msg("HTTP response received") log.Debug().Str("status", resp.Status).Int("body length", len(response)).Msg("HTTP response received")
if resp.StatusCode == http.StatusOK { if resp.StatusCode == http.StatusOK {
@ -91,7 +99,9 @@ func Start() {
log.Debug().Msg("Response is empty, HTTP server isn't ready, waiting...") log.Debug().Msg("Response is empty, HTTP server isn't ready, waiting...")
continue continue
} }
log.Debug().Int("status code", resp.StatusCode).Msgf("Response: %+v", string(response)) log.Debug().Int("status code", resp.StatusCode).Msgf("Response: %+v", string(response))
if len(response) == 17 { if len(response) == 17 {
break break
} }
@ -104,5 +114,6 @@ func waitForHTTPServerToBeUpHandler(ec echo.Context) error {
response := map[string]string{ response := map[string]string{
"error": "None", "error": "None",
} }
return ec.JSON(200, response) return ec.JSON(200, response)
} }

View File

@ -24,6 +24,7 @@ func (sjb *StrictJSONBinder) Bind(i interface{}, c echo.Context) error {
// Decode it. // Decode it.
decoder := json.NewDecoder(req.Body) decoder := json.NewDecoder(req.Body)
decoder.DisallowUnknownFields() decoder.DisallowUnknownFields()
if err := decoder.Decode(i); err != nil { if err := decoder.Decode(i); err != nil {
if ute, ok := err.(*json.UnmarshalTypeError); ok { if ute, ok := err.(*json.UnmarshalTypeError); ok {
return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Unmarshal type error: expected=%v, got=%v, field=%v, offset=%v", ute.Type, ute.Value, ute.Field, ute.Offset)) return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Unmarshal type error: expected=%v, got=%v, field=%v, offset=%v", ute.Type, ute.Value, ute.Field, ute.Offset))

View File

@ -23,6 +23,7 @@ func Initialize() {
loggerLevel, loggerLevelFound := os.LookupEnv("LOGGER_LEVEL") loggerLevel, loggerLevelFound := os.LookupEnv("LOGGER_LEVEL")
if loggerLevelFound { if loggerLevelFound {
fmt.Println("Setting logger level to:", loggerLevel) fmt.Println("Setting logger level to:", loggerLevel)
switch strings.ToUpper(loggerLevel) { switch strings.ToUpper(loggerLevel) {
case "DEBUG": case "DEBUG":
zerolog.SetGlobalLevel(zerolog.DebugLevel) zerolog.SetGlobalLevel(zerolog.DebugLevel)
@ -36,7 +37,7 @@ func Initialize() {
zerolog.SetGlobalLevel(zerolog.FatalLevel) zerolog.SetGlobalLevel(zerolog.FatalLevel)
default: default:
fmt.Println("Invalid logger level passed:", loggerLevel) fmt.Println("Invalid logger level passed:", loggerLevel)
fmt.Println("Fofcing INFO") fmt.Println("Forcing INFO")
zerolog.SetGlobalLevel(zerolog.InfoLevel) zerolog.SetGlobalLevel(zerolog.InfoLevel)
} }
} else { } else {
@ -47,6 +48,7 @@ func Initialize() {
output := zerolog.ConsoleWriter{Out: os.Stdout, NoColor: false, TimeFormat: time.RFC3339} output := zerolog.ConsoleWriter{Out: os.Stdout, NoColor: false, TimeFormat: time.RFC3339}
output.FormatLevel = func(i interface{}) string { output.FormatLevel = func(i interface{}) string {
var v string var v string
if ii, ok := i.(string); ok { if ii, ok := i.(string); ok {
ii = strings.ToUpper(ii) ii = strings.ToUpper(ii)
switch ii { switch ii {
@ -66,6 +68,7 @@ func Initialize() {
v = ii v = ii
} }
} }
return fmt.Sprintf("| %s |", v) return fmt.Sprintf("| %s |", v)
} }

View File

@ -52,6 +52,7 @@ func execRequest(method string, url string, data interface{}) ([]byte, error) {
if err2 != nil { if err2 != nil {
return nil, err2 return nil, err2
} }
response.Body.Close() response.Body.Close()
log.Debug().Int("response body length (bytes)", len(bodyBytes)).Msg("Got response") log.Debug().Int("response body length (bytes)", len(bodyBytes)).Msg("Got response")