Skip to content

Commit d362cd1

Browse files
authored
Add a new API for listing logs and artifacts from a log area (#66)
* Add a new API for listing logs and artifacts from a log area
1 parent ce37ae7 commit d362cd1

23 files changed

+1258
-51
lines changed

.github/workflows/build-push.yml

+34-2
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,39 @@ jobs:
6666
echo "::set-output name=version::$VERSION"
6767
outputs:
6868
sseVersion: ${{ steps.image.outputs.version }}
69+
build_logarea:
70+
if: ${{ github.event_name == 'workflow_dispatch' || github.event.pull_request.merged == true }}
71+
runs-on: ubuntu-latest
72+
steps:
73+
- uses: actions/checkout@v3
74+
- name: Build app image
75+
run: docker build . -f deploy/etos-logarea/Dockerfile --tag image
76+
77+
- name: Log into registry
78+
run: echo "${{ secrets.REGISTRYPASSWORD }}" | docker login registry.nordix.org -u ${{ secrets.REGISTRYUSERNAME }} --password-stdin
79+
80+
- name: Push app image
81+
id: image
82+
run: |
83+
IMAGE_ID=registry.nordix.org/eiffel/etos-logarea
84+
# Strip git ref prefix from version
85+
VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,')
86+
# Strip "v" prefix from tag name
87+
[[ "${{ github.ref }}" == "refs/tags/"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//')
88+
# Use Docker `latest` tag convention
89+
[ "$VERSION" == "main" ] && VERSION=$(echo ${{ github.sha }} | cut -c1-8)
90+
echo IMAGE_ID=$IMAGE_ID
91+
echo VERSION=$VERSION
92+
docker tag image $IMAGE_ID:$VERSION
93+
docker push $IMAGE_ID:$VERSION
94+
echo $IMAGE_ID:$VERSION
95+
echo "::set-output name=version::$VERSION"
96+
outputs:
97+
logAreaVersion: ${{ steps.image.outputs.version }}
6998
update_manifests:
7099
if: ${{ github.event_name == 'workflow_dispatch' || github.event.pull_request.merged == true }}
71100
runs-on: ubuntu-latest
72-
needs: [build_api, build_sse]
101+
needs: [build_api, build_sse, build_logarea]
73102
steps:
74103
- uses: actions/checkout@v3
75104
- name: Update manifests
@@ -83,7 +112,10 @@ jobs:
83112
"manifests/base/deployment.yaml": {
84113
"spec.template.spec.containers[0].image": "registry.nordix.org/eiffel/etos-api:${{ needs.build_api.outputs.apiVersion }}"
85114
}
115+
"manifests/base/logarea/deployment.yaml": {
116+
"spec.template.spec.containers[0].image": "registry.nordix.org/eiffel/etos-logarea:${{ needs.build_logarea.outputs.logAreaVersion }}"
117+
},
86118
}
87119
branch: main
88120
commitChange: true
89-
message: Updating SSE image to ${{ needs.build_sse.outputs.sseVersion }} and API image to ${{ needs.build_api.outputs.apiVersion }}
121+
message: Updating SSE image to ${{ needs.build_sse.outputs.sseVersion }}, LogArea image to ${{ needs.build_logarea.outputs.logAreaVersion }} and API image to ${{ needs.build_api.outputs.apiVersion }}

.github/workflows/main.yml

+23-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,20 @@ jobs:
2828
- name: Run Tox
2929
run: tox
3030
working-directory: ./python
31-
31+
run-gotest:
32+
runs-on: ubuntu-latest
33+
strategy:
34+
matrix:
35+
# Since we have 1.21 in the go.mod file, but toolchain is go1.22.1
36+
go-version: [ '1.21', '1.22.1' ]
37+
steps:
38+
- uses: actions/checkout@v4
39+
- name: Setup Go ${{ matrix.go-version }}
40+
uses: actions/setup-go@v5
41+
with:
42+
go-version: ${{ matrix.go-version }}
43+
- name: Go test
44+
run: make test
3245
run-hadolint:
3346
# The type of runner that the job will run on
3447
runs-on: ubuntu-latest
@@ -46,6 +59,10 @@ jobs:
4659
uses: hadolint/hadolint-action@master
4760
with:
4861
dockerfile: deploy/etos-sse/Dockerfile
62+
- name: Run hadolint for LogArea
63+
uses: hadolint/hadolint-action@master
64+
with:
65+
dockerfile: deploy/etos-logarea/Dockerfile
4966

5067
build-docker-images:
5168
# The type of runner that the job will run on
@@ -66,3 +83,8 @@ jobs:
6683
with:
6784
context: .
6885
file: ./deploy/etos-sse/Dockerfile
86+
- name: Build LogArea image
87+
uses: docker/build-push-action@v2
88+
with:
89+
context: .
90+
file: ./deploy/etos-logarea/Dockerfile

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,5 @@ MANIFEST
5151

5252
# Per-project virtualenvs
5353
.venv*/
54+
.vscode
5455
.python-version

Makefile

+49-19
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,62 @@
11
# Install tools locally instead of in $HOME/go/bin.
22
export GOBIN := $(CURDIR)/bin
3+
export GOBUILD := go build
34
export PATH := $(GOBIN):$(PATH)
45

56
export RELEASE_VERSION ?= $(shell git describe --always)
67
export DOCKER_REGISTRY ?= registry.nordix.org
78
export DOCKER_NAMESPACE ?= eiffel
89
export DEPLOY ?= etos-sse
910

11+
PROGRAMS = sse logarea
1012
COMPILEDAEMON = $(GOBIN)/CompileDaemon
1113
GIT = git
12-
SSE = $(GOBIN)/etos-sse
1314
GOLANGCI_LINT = $(GOBIN)/golangci-lint
1415

1516
GOLANGCI_LINT_VERSION = v1.52.2
1617

17-
.PHONY: all
18-
all: test build start
18+
# Generates a rule for building a single binary from cmd/$1.
19+
#
20+
# $1: Name of the program
21+
define build-binary
22+
.PHONY: $(strip $(1))
23+
$(strip $(1)):
24+
$$(GOBUILD) -ldflags="-w -s -buildid=" -trimpath -o bin/$(strip $(1)) ./cmd/$(strip $(1))
25+
endef
26+
27+
# Generates a rule named $(program_name)-docker to to build the named program
28+
# and copy the locally compiled binary into a Docker image. The image will be
29+
# tagged with the name of the program.
30+
#
31+
# $1: Name of the program
32+
define build-docker-image
33+
.PHONY: $(strip $(1))-docker
34+
# Including the parameter name!
35+
EXTRA_DOCKER_ARGS=
36+
export EXTRA_DOCKER_ARGS
37+
$(strip $(1))-docker: $(strip $(1))
38+
docker build . \
39+
$(EXTRA_DOCKER_ARGS) \
40+
-f deploy/etos-$(strip $(1))/Dockerfile \
41+
-t $(DOCKER_REGISTRY)/$(DOCKER_NAMESPACE)/etos-$(strip $(1)):$(RELEASE_VERSION)
42+
endef
43+
44+
# Generates a rule named $(program_name)-docker-push to push
45+
# a local Docker image to a remote registry.
46+
#
47+
# $1: Name of the program
48+
define push-docker-image
49+
.PHONY: $(strip $(1))-docker-push
50+
$(strip $(1))-docker-push:
51+
echo docker push $(DOCKER_REGISTRY)/$(DOCKER_NAMESPACE)/$(strip $(1))_provider:$(RELEASE_VERSION)
52+
endef
1953

20-
.PHONY: build
21-
build:
22-
go build -ldflags="-w -s -buildid=" -trimpath -o $(SSE) ./cmd/sse
54+
.PHONY: all
55+
all: test $(PROGRAMS)
2356

2457
.PHONY: clean
2558
clean:
26-
$(RM) $(SSE)
59+
$(RM) $(GOBIN)/*
2760
docker compose --project-directory . -f deploy/$(DEPLOY)/docker-compose.yml rm || true
2861

2962
.PHONY: check
@@ -46,18 +79,6 @@ start: $(COMPILEDAEMON)
4679
stop:
4780
docker compose --project-directory . -f deploy/$(DEPLOY)/docker-compose.yml down
4881

49-
# Build a docker using the production Dockerfiler
50-
.PHONY: docker
51-
# Including the parameter name!
52-
EXTRA_DOCKER_ARGS=
53-
export EXTRA_DOCKER_ARGS
54-
docker:
55-
docker build $(EXTRA_DOCKER_ARGS) -t $(DOCKER_REGISTRY)/$(DOCKER_NAMESPACE)/$(DEPLOY):$(RELEASE_VERSION) -f ./deploy/$(DEPLOY)/Dockerfile .
56-
57-
.PHONY: push
58-
push:
59-
docker push $(DOCKER_REGISTRY)/$(DOCKER_NAMESPACE)/$(DEPLOY):$(RELEASE_VERSION)
60-
6182
.PHONY: tidy
6283
tidy:
6384
go mod tidy
@@ -66,6 +87,15 @@ tidy:
6687
check-dirty:
6788
$(GIT) diff --exit-code HEAD
6889

90+
91+
# Setup the dynamic commands
92+
#
93+
$(foreach prog,$(PROGRAMS), \
94+
$(eval $(call build-binary,$(prog))) \
95+
$(eval $(call build-docker-image,$(prog))) \
96+
$(eval $(call push-docker-image,$(prog))) \
97+
)
98+
6999
# Build dependencies
70100

71101
$(COMPILEDAEMON):

cmd/logarea/main.go

+122
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
// Copyright Axis Communications AB.
2+
//
3+
// For a full list of individual contributors, please see the commit history.
4+
//
5+
// Licensed under the Apache License, Version 2.0 (the "License");
6+
// you may not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing, software
12+
// distributed under the License is distributed on an "AS IS" BASIS,
13+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
// See the License for the specific language governing permissions and
15+
// limitations under the License.
16+
package main
17+
18+
import (
19+
"context"
20+
"net/http"
21+
"os"
22+
"os/signal"
23+
"runtime/debug"
24+
"syscall"
25+
"time"
26+
27+
"github.com/eiffel-community/etos-api/internal/config"
28+
"github.com/eiffel-community/etos-api/internal/logging"
29+
"github.com/eiffel-community/etos-api/internal/server"
30+
"github.com/eiffel-community/etos-api/pkg/application"
31+
v1alpha "github.com/eiffel-community/etos-api/pkg/logarea/v1alpha"
32+
"github.com/sirupsen/logrus"
33+
"github.com/snowzach/rotatefilehook"
34+
"go.elastic.co/ecslogrus"
35+
)
36+
37+
// main sets up logging and starts up the logarea webservice.
38+
func main() {
39+
cfg := config.Get()
40+
ctx := context.Background()
41+
42+
var hooks []logrus.Hook
43+
if fileHook := fileLogging(cfg); fileHook != nil {
44+
hooks = append(hooks, fileHook)
45+
}
46+
logger, err := logging.Setup(cfg.LogLevel(), hooks)
47+
if err != nil {
48+
logrus.Fatal(err.Error())
49+
}
50+
51+
hostname, err := os.Hostname()
52+
if err != nil {
53+
logrus.Fatal(err.Error())
54+
}
55+
log := logger.WithFields(logrus.Fields{
56+
"hostname": hostname,
57+
"application": "ETOS API LogArea Server",
58+
"version": vcsRevision(),
59+
"name": "ETOS API",
60+
})
61+
62+
log.Info("Loading logarea routes")
63+
v1AlphaLogArea := v1alpha.New(cfg, log)
64+
defer v1AlphaLogArea.Close()
65+
66+
app := application.New(v1AlphaLogArea)
67+
srv := server.NewWebService(cfg, log, app)
68+
69+
done := make(chan os.Signal, 1)
70+
signal.Notify(done, syscall.SIGINT, syscall.SIGTERM)
71+
72+
go func() {
73+
if err := srv.Start(); err != nil && err != http.ErrServerClosed {
74+
log.Errorf("Webserver shutdown: %+v", err)
75+
}
76+
}()
77+
78+
sig := <-done
79+
log.Infof("%s received", sig.String())
80+
81+
ctx, cancel := context.WithTimeout(ctx, 1*time.Minute)
82+
defer cancel()
83+
84+
if err := srv.Close(ctx); err != nil {
85+
log.Errorf("Webserver shutdown failed: %+v", err)
86+
}
87+
log.Info("Wait for shutdown to complete")
88+
}
89+
90+
// fileLogging adds a hook into a slice of hooks, if the filepath configuration is set
91+
func fileLogging(cfg config.Config) logrus.Hook {
92+
if filePath := cfg.LogFilePath(); filePath != "" {
93+
// TODO: Make these parameters configurable.
94+
// NewRotateFileHook cannot return an error which is why it's set to '_'.
95+
rotateFileHook, _ := rotatefilehook.NewRotateFileHook(rotatefilehook.RotateFileConfig{
96+
Filename: filePath,
97+
MaxSize: 10, // megabytes
98+
MaxBackups: 3,
99+
MaxAge: 0, // days
100+
Level: logrus.DebugLevel,
101+
Formatter: &ecslogrus.Formatter{
102+
DataKey: "labels",
103+
},
104+
})
105+
return rotateFileHook
106+
}
107+
return nil
108+
}
109+
110+
// vcsRevision returns vcs revision from build info, if any. Otherwise '(unknown)'.
111+
func vcsRevision() string {
112+
buildInfo, ok := debug.ReadBuildInfo()
113+
if !ok {
114+
return "(unknown)"
115+
}
116+
for _, val := range buildInfo.Settings {
117+
if val.Key == "vcs.revision" {
118+
return val.Value
119+
}
120+
}
121+
return "(unknown)"
122+
}

deploy/etos-logarea/Dockerfile

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
FROM golang:1.21-alpine AS build
2+
WORKDIR /tmp/logarea
3+
COPY . .
4+
RUN apk add --no-cache make=4.4.1-r2 git=2.45.2-r0 && make logarea
5+
6+
FROM alpine:3.17.3
7+
ARG TZ
8+
ENV TZ=$TZ
9+
10+
LABEL org.opencontainers.image.source=https://github.com/eiffel-community/etos-api
11+
LABEL org.opencontainers.image.authors=etos-maintainers@googlegroups.com
12+
LABEL org.opencontainers.image.licenses=Apache-2.0
13+
14+
RUN apk add --no-cache tzdata=2024a-r0
15+
ENTRYPOINT ["/app/logarea"]
16+
17+
COPY --from=build /tmp/logarea/bin/logarea /app/logarea

deploy/etos-logarea/Dockerfile.dev

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
FROM golang:1.21
2+
WORKDIR /app
3+
4+
COPY ./go.mod ./go.sum ./
5+
RUN go mod tidy
6+
COPY . .
7+
RUN git config --global --add safe.directory /app
8+
EXPOSE 8080
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
version: "3.7"
2+
services:
3+
etos-logarea:
4+
build:
5+
context: .
6+
dockerfile: ./deploy/etos-logarea/Dockerfile.dev
7+
args:
8+
http_proxy: "${http_proxy}"
9+
https_proxy: "${https_proxy}"
10+
volumes:
11+
- ./:/app
12+
ports:
13+
- 8080:8080
14+
env_file:
15+
- ./configs/development.env
16+
entrypoint: ["/bin/bash", "./scripts/entrypoint.sh"]

deploy/etos-sse/Dockerfile

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
FROM golang:1.20-alpine AS build
1+
FROM golang:1.21-alpine AS build
22
WORKDIR /tmp/sse
33
COPY . .
4-
RUN apk add --no-cache make=4.4.1-r2 git=2.43.4-r0 && make build
4+
RUN apk add --no-cache make=4.4.1-r2 git=2.45.2-r0 && make sse
55

66
FROM alpine:3.17.3
77
ARG TZ
@@ -12,6 +12,6 @@ LABEL org.opencontainers.image.authors=etos-maintainers@googlegroups.com
1212
LABEL org.opencontainers.image.licenses=Apache-2.0
1313

1414
RUN apk add --no-cache tzdata=2024a-r0
15-
ENTRYPOINT ["/app/etos-sse"]
15+
ENTRYPOINT ["/app/sse"]
1616

17-
COPY --from=build /tmp/sse/bin/etos-sse /app/etos-sse
17+
COPY --from=build /tmp/sse/bin/sse /app/sse

deploy/etos-sse/Dockerfile.dev

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM golang:1.20
1+
FROM golang:1.21
22
WORKDIR /app
33

44
COPY ./go.mod ./go.sum ./

0 commit comments

Comments
 (0)