Compare commits

..

27 Commits

Author SHA1 Message Date
16a59fe027 feat: update arcad/edge dependency
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-12-05 14:32:43 +01:00
8d42bf0b34 feat: update arcad/edge dependency
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-12-03 14:28:52 +01:00
3c3d7fe82d feat: update arcad/edge dependency
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-12-01 15:21:29 +01:00
ddddbbc895 feat: replace github.com/allegro/bigcache/v3 by github.com/Bornholm/bigcache
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-12-01 14:26:59 +01:00
32ce5a206f feat(packaging): rotate logs daily on alpine
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-12-01 13:53:19 +01:00
6a7945d05c feat: update arcad/edge dependency
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-12-01 12:26:27 +01:00
86ddb6a4c1 feat(packaging): compress rotated log files on alpine linux
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-11-30 19:53:22 +01:00
a6da1be3bf chore: fix goreleaser task
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-11-30 19:47:00 +01:00
5c2d128e8c feat: update arcad/edge dependency
Some checks failed
arcad/emissary/pipeline/head There was a failure building this commit
2023-11-30 19:14:37 +01:00
144fdd8bf3 chore: update app spec sample
Some checks reported errors
arcad/emissary/pipeline/head Something is wrong with the build of this commit
2023-11-30 19:13:22 +01:00
8b33bacbd5 chore: improve update-edge-lib task 2023-11-30 19:13:05 +01:00
b842dd5263 feat: update edge library
Some checks failed
arcad/emissary/pipeline/head There was a failure building this commit
2023-11-30 16:01:35 +01:00
0c9d86b850 feat: add docker recipe + environment with default interpolation in config
Some checks failed
arcad/emissary/pipeline/head There was a failure building this commit
2023-10-30 20:05:00 +01:00
b2b839cab4 feat: update arcad/edge dependency
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-10-25 21:28:19 +02:00
7fa3011ab2 feat(app-controller): import cache driver
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-10-24 22:55:12 +02:00
17e06ce19b feat: update arcad/edge dependency
Some checks reported errors
arcad/emissary/pipeline/head Something is wrong with the build of this commit
2023-10-24 22:53:39 +02:00
0d2aac41a8 feat: update arcad/edge dependency
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-10-22 23:18:22 +02:00
38795a9767 feat: update arcad/edge dependency
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-10-22 23:05:35 +02:00
327226aa74 feat: update arcad/edge dependency
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-10-22 10:48:56 +02:00
fbf818e423 feat(storage): retry transaction when sqlite database is busy
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-10-22 09:50:22 +02:00
46a853a3f7 feat: update arcad/edge dependency
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-10-21 21:47:18 +02:00
f31a63efdc feat: update arcad/edge dependency
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-10-21 21:39:09 +02:00
c8a2303ff3 feat(spec): add 'zim' to apps allowed formats
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-10-20 17:39:28 +02:00
ced2658eec feat: update arcad/edge dependency
All checks were successful
arcad/emissary/pipeline/head This commit looks good
2023-10-19 22:22:40 +02:00
ce9b3003fe feat: use new logger.CapturedE() api 2023-10-19 22:09:18 +02:00
b0898eefc3 feat: update arcad/edge dependency 2023-10-19 21:47:38 +02:00
4da723e908 feat(edge): update lib 2023-10-19 20:12:46 +02:00
38 changed files with 499 additions and 241 deletions

14
.dockerignore Normal file
View File

@ -0,0 +1,14 @@
/apps
/bin
/dist
/out
/tmp
/tools
/.emissary-token
/.env
/agent-key.json
/server-key.json
/CHANGELOG.md
/state.json
/*.sqlite*
/.mktools

View File

@ -1,4 +1,12 @@
FROM golang:1.19 AS BUILD
FROM alpine as certs
RUN apk update && apk add ca-certificates curl openssl bash
RUN curl -k https://forge.cadoles.com/Cadoles/Jenkins/raw/branch/master/resources/com/cadoles/common/add-letsencrypt-ca.sh | bash
#####################################
# Emissary Server #
#####################################
FROM golang:1.21 AS build-emissary-server
RUN apt-get update \
&& apt-get install -y make
@ -7,9 +15,9 @@ COPY . /src
WORKDIR /src
RUN make GORELEASER_ARGS='build --rm-dist --single-target --snapshot' release
RUN make mktools && make GORELEASER_ARGS="build --snapshot --clean --single-target --id emissary-server" goreleaser
FROM busybox:latest AS RUNTIME
FROM busybox:latest AS emissary-server
ARG DUMB_INIT_VERSION=1.2.5
@ -19,11 +27,47 @@ RUN mkdir -p /usr/local/bin \
ENTRYPOINT ["/usr/local/bin/dumb-init", "--"]
COPY --from=BUILD /src/dist/emissary_linux_amd64_v1 /app
COPY --from=BUILD /src/tmp/config.yml /etc/emissary/config.yml
COPY --from=build-emissary-server /src/dist/emissary-server_linux_amd64_v1 /app
COPY misc/docker/server.yml /etc/emissary/server.yml
COPY --from=certs /etc/ssl/certs /etc/ssl/certs
EXPOSE 3000
ENTRYPOINT ["/app/emissary"]
RUN mkdir -p /data
CMD ["server", "run", "-c", "/etc/emissary/config.yml"]
CMD [ "/app/emissary", "-c", "/etc/emissary/config.yml", "server", "run"]
#####################################
# Emissary Agent #
#####################################
FROM golang:1.21 AS build-emissary-agent
RUN apt-get update \
&& apt-get install -y make
COPY . /src
WORKDIR /src
RUN make mktools && make GORELEASER_ARGS="build --snapshot --clean --single-target --id emissary-agent" goreleaser
FROM busybox:latest AS emissary-agent
ARG DUMB_INIT_VERSION=1.2.5
RUN mkdir -p /usr/local/bin \
&& wget -O /usr/local/bin/dumb-init https://github.com/Yelp/dumb-init/releases/download/v${DUMB_INIT_VERSION}/dumb-init_${DUMB_INIT_VERSION}_x86_64 \
&& chmod +x /usr/local/bin/dumb-init
ENTRYPOINT ["/usr/local/bin/dumb-init", "--"]
COPY --from=build-emissary-agent /src/dist/emissary-agent_linux_amd64_v1 /app
COPY --chmod=777 misc/docker/docker-agent-wrapper.sh /usr/local/bin/docker-agent-wrapper
COPY misc/docker/agent.yml /etc/emissary/agent.yml
COPY --from=certs /etc/ssl/certs /etc/ssl/certs
RUN mkdir -p /data
CMD [ "/usr/local/bin/docker-agent-wrapper", "/app/emissary", "-c", "/etc/emissary/agent.yml", "agent", "run" ]

View File

@ -1,12 +1,11 @@
LINT_ARGS ?= --timeout 5m
GORELEASER_VERSION ?= v1.13.1
GORELEASER_ARGS ?= release --snapshot --rm-dist
GORELEASER_ARGS ?= release --snapshot --clean
GITCHLOG_ARGS ?=
SHELL := /bin/bash
EMISSARY_VERSION ?=
DOCKER_IMAGE_NAME ?= bornholm/emissary
DOCKER_IMAGE_NAME ?= reg.cadoles.com/cadoles/emissary
DOCKER_IMAGE_TAG ?= $(MKT_PROJECT_VERSION)
GOTEST_ARGS ?= -short
@ -71,17 +70,23 @@ dump-config: build-emissary
./bin/emissary config dump > tmp/config.yml
.PHONY: goreleaser
goreleaser: .mktools
( set -o allexport && source .env && set +o allexport && VERSION=$(GORELEASER_VERSION) curl -sfL https://goreleaser.com/static/run | GORELEASER_CURRENT_TAG="$(MKT_PROJECT_VERSION)" bash /dev/stdin $(GORELEASER_ARGS) )
goreleaser: .env .mktools
( set -o allexport && source .env && set +o allexport && curl -sfL https://goreleaser.com/static/run | GORELEASER_CURRENT_TAG="$(MKT_PROJECT_VERSION)" bash /dev/stdin $(GORELEASER_ARGS) )
install-git-hooks:
git config core.hooksPath .githooks
docker-build:
docker build -t $(DOCKER_IMAGE_NAME):$(DOCKER_IMAGE_TAG) .
docker-build: docker-build-agent docker-build-server
docker-release:
docker push $(DOCKER_IMAGE_NAME):$(DOCKER_IMAGE_TAG)
docker-build-%:
docker build --target emissary-$* -t $(DOCKER_IMAGE_NAME)-$*:latest .
docker-release: docker-release-agent docker-release-server
docker-release-%:
docker tag $(DOCKER_IMAGE_NAME)-$*:latest $(DOCKER_IMAGE_NAME)-$*:$(DOCKER_IMAGE_TAG)
docker push $(DOCKER_IMAGE_NAME)-$*:latest
docker push $(DOCKER_IMAGE_NAME)-$*:$(DOCKER_IMAGE_TAG)
deploy-openwrt-agent:
$(MAKE) GOARCH="arm" GORELEASER_ARGS='build --single-target --snapshot --clean' goreleaser
@ -133,7 +138,8 @@ version: .mktools
update-edge-lib:
git pull --rebase
GOPROXY=direct GOPRIVATE=forge.cadoles.com/arcad/edge go get -u forge.cadoles.com/arcad/edge
go clean -modcache
GONOPROXY=forge.cadoles.com/arcad/edge GOPRIVATE=forge.cadoles.com/arcad/edge go get -v -u forge.cadoles.com/arcad/edge
go mod tidy
$(MAKE) test
git add go.mod go.sum

View File

@ -7,6 +7,7 @@
- (FR) - [Premiers pas](./tutorials/fr/first-steps.md)
- (FR) - [Déployer un serveur mandataire inverse sur un agent](./tutorials/fr/deploy-reverse-proxy.md)
- (FR) - [Déployer une configuration UCI personnalisée sur un agent](./tutorials/fr/deploy-uci-configuration.md)
- (FR) - [Démarrer un agent avec Docker](./tutorials/fr/docker-agent.md)
## References

View File

@ -0,0 +1,10 @@
# Lancer un agent avec Docker
```shell
docker run \
--rm -it \
--network bridge \
-v emissary-agent-data:/data \
-e EMISSARY_AGENT_SERVER_URL=<server_url> \
reg.cadoles.com/cadoles/emissary-agent:latest
```

29
go.mod
View File

@ -1,9 +1,11 @@
module forge.cadoles.com/Cadoles/emissary
go 1.19
go 1.21
toolchain go1.21.2
require (
forge.cadoles.com/arcad/edge v0.0.0-20231003032536-4c6e979bb6bf
forge.cadoles.com/arcad/edge v0.0.0-20231205131822-753a6c9708c6
github.com/Masterminds/sprig/v3 v3.2.3
github.com/alecthomas/participle/v2 v2.0.0-beta.5
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883
@ -14,7 +16,7 @@ require (
github.com/denisbrodbeck/machineid v1.0.1
github.com/dop251/goja v0.0.0-20230304130813-e2f543bf4b4c
github.com/evanphx/json-patch/v5 v5.6.0
github.com/go-chi/chi v4.1.2+incompatible
github.com/getsentry/sentry-go v0.25.0
github.com/go-chi/cors v1.2.1
github.com/golang-migrate/migrate/v4 v4.15.2
github.com/jackc/pgx/v5 v5.3.1
@ -26,7 +28,7 @@ require (
github.com/pkg/errors v0.9.1
github.com/qri-io/jsonschema v0.2.1
github.com/urfave/cli/v2 v2.24.4
gitlab.com/wpetit/goweb v0.0.0-20230419082146-a94d9ed7202b
gitlab.com/wpetit/goweb v0.0.0-20231019192040-4c72331a7648
gopkg.in/yaml.v3 v3.0.1
modernc.org/sqlite v1.21.0
)
@ -34,19 +36,21 @@ require (
require (
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver/v3 v3.2.0 // indirect
github.com/allegro/bigcache/v3 v3.1.0 // indirect
github.com/barnybug/go-cast v0.0.0-20201201064555-a87ccbc26692 // indirect
github.com/dop251/goja_nodejs v0.0.0-20230320130059-dcf93ba651dd // indirect
github.com/gabriel-vasile/mimetype v1.4.1 // indirect
github.com/getsentry/sentry-go v0.25.0 // indirect
github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/google/pprof v0.0.0-20230309165930-d61513b1440d // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
github.com/hashicorp/mdns v1.0.5 // indirect
github.com/huandu/xstrings v1.3.3 // indirect
github.com/igm/sockjs-go/v3 v3.0.2 // indirect
github.com/imdario/mergo v0.3.12 // indirect
github.com/keegancsmith/rpc v1.3.0 // indirect
github.com/klauspost/compress v1.16.6 // indirect
github.com/miekg/dns v1.1.53 // indirect
github.com/mitchellh/copystructure v1.0.0 // indirect
github.com/mitchellh/reflectwalk v1.0.0 // indirect
@ -54,7 +58,8 @@ require (
github.com/orcaman/concurrent-map v1.0.0 // indirect
github.com/shopspring/decimal v1.2.0 // indirect
github.com/spf13/cast v1.3.1 // indirect
golang.org/x/net v0.9.0 // indirect
github.com/ulikunitz/xz v0.5.11 // indirect
golang.org/x/net v0.11.0 // indirect
google.golang.org/genproto v0.0.0-20220728213248-dd149ef739b9 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)
@ -77,7 +82,7 @@ require (
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
github.com/jackc/puddle/v2 v2.2.0 // indirect
github.com/jackc/puddle/v2 v2.2.1 // indirect
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
github.com/leodido/go-urn v1.2.2 // indirect
github.com/lestrrat-go/blackmagic v1.0.1 // indirect
@ -98,15 +103,14 @@ require (
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
go.opencensus.io v0.24.0 // indirect
go.uber.org/atomic v1.10.0 // indirect
golang.org/x/crypto v0.7.0 // indirect
golang.org/x/crypto v0.10.0 // indirect
golang.org/x/mod v0.10.0 // indirect
golang.org/x/sync v0.1.0 // indirect
golang.org/x/sys v0.7.0 // indirect
golang.org/x/term v0.7.0 // indirect
golang.org/x/text v0.9.0 // indirect
golang.org/x/sys v0.9.0 // indirect
golang.org/x/term v0.9.0 // indirect
golang.org/x/text v0.10.0 // indirect
golang.org/x/tools v0.8.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/protobuf v1.29.1 // indirect
gopkg.in/go-playground/validator.v9 v9.31.0 // indirect
lukechampine.com/uint128 v1.2.0 // indirect
modernc.org/cc/v3 v3.40.0 // indirect
@ -120,3 +124,4 @@ require (
)
// replace forge.cadoles.com/arcad/edge => ../edge
replace github.com/allegro/bigcache/v3 v3.1.0 => github.com/Bornholm/bigcache v0.0.0-20231201111725-1ddf51584cad

68
go.sum
View File

@ -54,8 +54,8 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
forge.cadoles.com/arcad/edge v0.0.0-20231003032536-4c6e979bb6bf h1:jiQt6WdXCQlgMm+cC/vFd7aEibaXQUVZKB+tpLzyVao=
forge.cadoles.com/arcad/edge v0.0.0-20231003032536-4c6e979bb6bf/go.mod h1:cHbSOTFy09i2RD+EpE76q/rZfTzxZLFD+iHxVfE6QxA=
forge.cadoles.com/arcad/edge v0.0.0-20231205131822-753a6c9708c6 h1:FYIYQK7zF6MrPM+MME+lb+RkkivLyytC225yyNaw6AA=
forge.cadoles.com/arcad/edge v0.0.0-20231205131822-753a6c9708c6/go.mod h1:tMysrBPkzPFZAi89qD4TioDjcP3L2hadBJ5Eoij8GcA=
gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8=
github.com/AdaLogics/go-fuzz-headers v0.0.0-20210715213245-6c3934b029d8/go.mod h1:CzsSbkDixRphAF5hS6wbMKq0eI6ccJRb7/A0M6JBnwg=
github.com/Azure/azure-pipeline-go v0.2.3/go.mod h1:x841ezTBIMG6O3lAcl8ATHnsOPVl2bqk7S3ta6S6u4k=
@ -79,6 +79,8 @@ github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935
github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
github.com/Bornholm/bigcache v0.0.0-20231201111725-1ddf51584cad h1:PTOf0L/YjiVis5LYzJmi7WqttJ/h/DU6h06aJ24Kpbg=
github.com/Bornholm/bigcache v0.0.0-20231201111725-1ddf51584cad/go.mod h1:+q+mA6jGsjfsZ2HzhVSk38qDbX2/ZBJ7Yyciv75Ruo0=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/ClickHouse/clickhouse-go v1.4.3/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI=
@ -128,6 +130,7 @@ github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkK
github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38 h1:smF2tmSOzy2Mm+0dGI2AIUHY+w0BUc+4tn40djz7+6U=
github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38/go.mod h1:r7bzyVFMNntcxPZXK3/+KdruV1H5KSlyVY0gc+NgInI=
github.com/alecthomas/assert/v2 v2.0.3 h1:WKqJODfOiQG0nEJKFKzDIG3E29CN2/4zR9XGJzKIkbg=
github.com/alecthomas/assert/v2 v2.0.3/go.mod h1:b/+1DI2Q6NckYi+3mXyH3wFb8qG37K/DuK80n7WefXA=
github.com/alecthomas/chroma v0.7.0/go.mod h1:1U/PfCsTALWWYHDnsIQkxEBM0+6LLe0v8+RSVMOwxeY=
github.com/alecthomas/chroma v0.10.0 h1:7XDcGkCQopCNKjZHfYrNLraA+M7e0fMiJ/Mfikbfjek=
github.com/alecthomas/chroma v0.10.0/go.mod h1:jtJATyUxlIORhUOFNA9NZDWGAQ8wpxQQqNSB4rjA/1s=
@ -139,6 +142,7 @@ github.com/alecthomas/participle/v2 v2.0.0-beta.5 h1:y6dsSYVb1G5eK6mgmy+BgI3Mw35
github.com/alecthomas/participle/v2 v2.0.0-beta.5/go.mod h1:RC764t6n4L8D8ITAJv0qdokritYSNR3wV5cVwmIEaMM=
github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ=
github.com/alecthomas/repr v0.1.0 h1:ENn2e1+J3k09gyj2shc0dHr/yjaWSHRlrJ4DPMevDqE=
github.com/alecthomas/repr v0.1.0/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
@ -509,12 +513,12 @@ github.com/getsentry/sentry-go v0.25.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-chi/chi v4.0.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
github.com/go-chi/chi v4.1.2+incompatible h1:fGFk2Gmi/YKXk0OmGfBh0WgmN3XB8lVnEyNz34tQRec=
github.com/go-chi/chi v4.1.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
github.com/go-chi/chi/v5 v5.0.8 h1:lD+NLqFcAi1ovnVZpsnObHGW4xb4J8lNmoYVfECH1Y0=
github.com/go-chi/chi/v5 v5.0.8/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4=
github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g=
github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks=
github.com/go-fonts/liberation v0.1.1/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY=
@ -552,10 +556,10 @@ github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dp
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM=
github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY=
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU=
@ -675,6 +679,7 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/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/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-containerregistry v0.5.1/go.mod h1:Ct15B4yir3PLOP5jsy0GNeYVaIZs/MK/Jz5any1wFW0=
github.com/google/go-github/v39 v39.2.0/go.mod h1:C1s8C5aCC9L+JXIYpJM5GYytdX52vC1bLvHEF1IhBrE=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
@ -763,6 +768,8 @@ github.com/hashicorp/go.net v0.0.0-20151006203346-104dcad90073/go.mod h1:hjKkEWc
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
github.com/hashicorp/mdns v0.0.0-20151206042412-9d85cf22f9f8/go.mod h1:aa76Av3qgPeIQp9Y3qIkTBPieQYNkQ13Kxe7pze9Wb0=
@ -772,6 +779,7 @@ github.com/hashicorp/mdns v1.0.5/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/huandu/xstrings v1.3.3 h1:/Gcsuc1x8JVbJ9/rlye4xZnVAbEkGauT8lbebqcQws4=
github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
@ -839,8 +847,8 @@ github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0f
github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jackc/puddle/v2 v2.2.0 h1:RdcDk92EJBuBS55nQMMYFXTxwstHug4jkhT5pq8VxPk=
github.com/jackc/puddle/v2 v2.2.0/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
github.com/jedib0t/go-pretty/v6 v6.4.4 h1:N+gz6UngBPF4M288kiMURPHELDMIhF/Em35aYuKrsSc=
github.com/jedib0t/go-pretty/v6 v6.4.4/go.mod h1:MgmISkTWDSFu0xOqiZ0mKNntMQ2mDgOcwOkwBEkMDJI=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
@ -893,6 +901,8 @@ github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdY
github.com/klauspost/compress v1.13.1/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/klauspost/compress v1.16.6 h1:91SKEy4K37vkp255cJ8QesJhjyRO0hn9i9G0GoUwLsk=
github.com/klauspost/compress v1.16.6/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@ -910,7 +920,7 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/ktrysmt/go-bitbucket v0.6.4/go.mod h1:9u0v3hsd2rqCHRIpbir1oP7F58uo5dq19sBYvuMoyQ4=
github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw=
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
github.com/leodido/go-urn v1.2.2 h1:7z68G0FCGvDk646jz1AelTYNYWrTNm0bEcFAo147wt4=
github.com/leodido/go-urn v1.2.2/go.mod h1:kUaIbLZWttglzwNuG0pgsh5vuV6u2YcGBYz1hIPjtOQ=
github.com/lestrrat-go/blackmagic v1.0.1 h1:lS5Zts+5HIC/8og6cGHb0uCcNCa3OUt1ygh3Qz2Fe80=
@ -980,6 +990,7 @@ github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOq
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/go-sqlite3 v1.14.10/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY=
@ -1115,8 +1126,11 @@ github.com/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2
github.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pierrec/lz4/v4 v4.1.8/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4=
github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@ -1178,6 +1192,7 @@ github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
@ -1213,9 +1228,9 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
@ -1276,6 +1291,8 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8=
github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
@ -1317,8 +1334,8 @@ github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPS
github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b/go.mod h1:T3BPAOm2cqquPa0MKWeNkmOM5RQsRhkrwMWonFMN7fE=
gitlab.com/wpetit/goweb v0.0.0-20230419082146-a94d9ed7202b h1:nkvOl8TCj/mErADnwFFynjxBtC+hHsrESw6rw56JGmg=
gitlab.com/wpetit/goweb v0.0.0-20230419082146-a94d9ed7202b/go.mod h1:3sus4zjoUv1GB7eDLL60QaPkUnXJCWBpjvbe0jWifeY=
gitlab.com/wpetit/goweb v0.0.0-20231019192040-4c72331a7648 h1:t2UQmCmUoElIBBuVTqxqo8DcTJA/exQ/Q7XycfLqCZo=
gitlab.com/wpetit/goweb v0.0.0-20231019192040-4c72331a7648/go.mod h1:WdxGjM3HJWgBkUa4TwaTXUqY2BnRKlNSyUIv1aF4jxk=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
@ -1372,6 +1389,8 @@ go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
@ -1406,8 +1425,9 @@ golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM=
golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@ -1536,8 +1556,8 @@ golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU=
golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
golang.org/x/oauth2 v0.0.0-20180227000427-d7d64896b5ff/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@ -1702,8 +1722,8 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
@ -1713,8 +1733,8 @@ golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
golang.org/x/term v0.7.0 h1:BEvjmm5fURWqcfbSKTdpkDXYBrUS1c0m8agp14W48vQ=
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28=
golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -1729,8 +1749,8 @@ golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@ -1985,6 +2005,7 @@ google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ5
google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
google.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w=
google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
@ -1999,8 +2020,6 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.29.1 h1:7QBf+IK2gx70Ap/hDsOmam3GE0v9HicjfEdAxE62UoM=
google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
@ -2113,6 +2132,7 @@ modernc.org/ccgo/v3 v3.9.2/go.mod h1:gnJpy6NIVqkETT+L5zPsQFj7L2kkhfPMzOghRNv/CFo
modernc.org/ccgo/v3 v3.16.13 h1:Mkgdzl46i5F/CNR/Kj80Ri59hC8TKAhZrYSaqvkwzUw=
modernc.org/ccgo/v3 v3.16.13/go.mod h1:2Quk+5YgpImhPjv2Qsob1DnZ/4som1lJTodubIcoUkY=
modernc.org/ccorpus v1.11.6 h1:J16RXiiqiCgua6+ZvQot4yUuUy8zxgqbqEEUuGPlISk=
modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ=
modernc.org/db v1.0.0/go.mod h1:kYD/cO29L/29RM0hXYl4i3+Q5VojL31kTUVpVJDw0s8=
modernc.org/file v1.0.0/go.mod h1:uqEokAEn1u6e+J45e54dsEA/pw4o7zLrA2GwyntZzjw=
modernc.org/fileutil v1.0.0/go.mod h1:JHsWpkrk/CnVV1H/eGlFf85BEpfkrp56ro8nojIq9Q8=
@ -2146,12 +2166,14 @@ modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY=
modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw=
modernc.org/tcl v1.5.2/go.mod h1:pmJYOLgpiys3oI4AeAafkcUfE+TKKilminxNyU/+Zlo=
modernc.org/tcl v1.15.1 h1:mOQwiEK4p7HruMZcwKTZPw/aqtGM4aY00uzWhlKKYws=
modernc.org/tcl v1.15.1/go.mod h1:aEjeGJX2gz1oWKOLDVZ2tnEWLUrIn8H+GFu+akoDhqs=
modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
modernc.org/z v1.0.1-0.20210308123920-1f282aa71362/go.mod h1:8/SRk5C/HgiQWCgXdfpb+1RvhORdkz5sw72d3jjtyqA=
modernc.org/z v1.0.1/go.mod h1:8/SRk5C/HgiQWCgXdfpb+1RvhORdkz5sw72d3jjtyqA=
modernc.org/z v1.7.0 h1:xkDw/KepgEjeizO2sNco+hqYkU12taxQFqPEmgm1GWE=
modernc.org/z v1.7.0/go.mod h1:hVdgNMh8ggTuRG1rGU8x+xGRFfiQUIAw0ZqlPy8+HyQ=
modernc.org/zappy v1.0.0/go.mod h1:hHe+oGahLVII/aTTyWK/b53VDHMAGCBYYeZ9sn83HC4=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=

View File

@ -8,7 +8,6 @@ import (
"forge.cadoles.com/Cadoles/emissary/internal/auth/agent"
"forge.cadoles.com/Cadoles/emissary/internal/jwk"
"forge.cadoles.com/Cadoles/emissary/pkg/client"
"github.com/getsentry/sentry-go"
"github.com/pkg/errors"
"gitlab.com/wpetit/goweb/api"
"gitlab.com/wpetit/goweb/logger"
@ -45,16 +44,14 @@ func (a *Agent) Run(ctx context.Context) error {
if err := a.registerAgent(ctx, client, state); err != nil {
err = errors.WithStack(err)
logger.Error(ctx, "could not register agent", logger.E(err))
sentry.CaptureException(err)
logger.Error(ctx, "could not register agent", logger.CapturedE(err))
}
logger.Debug(ctx, "state before reconciliation", logger.F("state", state))
if err := a.Reconcile(ctx, state); err != nil {
err = errors.WithStack(err)
logger.Error(ctx, "could not reconcile node with state", logger.E(err))
sentry.CaptureException(err)
logger.Error(ctx, "could not reconcile node with state", logger.CapturedE(err))
return
}
@ -85,8 +82,7 @@ func (a *Agent) Reconcile(ctx context.Context, state *State) error {
if err := ctrl.Reconcile(ctrlCtx, state); err != nil {
err = errors.WithStack(err)
logger.Error(ctx, "could not reconcile", logger.E(err))
sentry.CaptureException(err)
logger.Error(ctx, "could not reconcile", logger.CapturedE(err))
}
}
@ -120,9 +116,8 @@ func (a *Agent) collectMetadata(ctx context.Context) (map[string]any, error) {
err = errors.WithStack(err)
logger.Error(
ctx, "could not collect metadata",
logger.E(err), logger.F("name", name),
logger.CapturedE(err), logger.F("name", name),
)
sentry.CaptureException(err)
continue
}

View File

@ -16,20 +16,22 @@ import (
appModule "forge.cadoles.com/arcad/edge/pkg/module/app"
"forge.cadoles.com/arcad/edge/pkg/module/blob"
"forge.cadoles.com/arcad/edge/pkg/module/cast"
"forge.cadoles.com/arcad/edge/pkg/module/fetch"
fetchModule "forge.cadoles.com/arcad/edge/pkg/module/fetch"
netModule "forge.cadoles.com/arcad/edge/pkg/module/net"
"forge.cadoles.com/arcad/edge/pkg/module/rpc"
shareModule "forge.cadoles.com/arcad/edge/pkg/module/share"
"forge.cadoles.com/arcad/edge/pkg/storage"
"forge.cadoles.com/arcad/edge/pkg/storage/driver"
"forge.cadoles.com/arcad/edge/pkg/storage/share"
"github.com/Masterminds/sprig/v3"
"github.com/getsentry/sentry-go"
"github.com/go-chi/chi/v5"
"github.com/lestrrat-go/jwx/v2/jwa"
"github.com/pkg/errors"
"gitlab.com/wpetit/goweb/logger"
// Register storage drivers
_ "forge.cadoles.com/arcad/edge/pkg/storage/driver/cache"
_ "forge.cadoles.com/arcad/edge/pkg/storage/driver/rpc"
_ "forge.cadoles.com/arcad/edge/pkg/storage/driver/sqlite"
)
@ -86,7 +88,12 @@ func (c *Controller) getHandlerOptions(ctx context.Context, appKey string, specs
mounts = append(mounts, authMount)
}
mounts = append(mounts, appModule.Mount(c.appRepository))
mounts = append(
mounts,
appModule.Mount(c.appRepository),
blob.Mount(10<<(10*2)), // 10Mb
fetch.Mount(),
)
deps := Dependencies{
Bus: memory.NewBus(),
@ -201,9 +208,8 @@ func createResolveAppURL(specs *spec.Spec) (ResolveAppURLFunc, error) {
err = errors.WithStack(err)
logger.Warn(
ctx, "could not find interface",
logger.E(err), logger.F("iface", ifaceName),
logger.CapturedE(err), logger.F("iface", ifaceName),
)
sentry.CaptureException(err)
continue
}
@ -213,10 +219,9 @@ func createResolveAppURL(specs *spec.Spec) (ResolveAppURLFunc, error) {
err = errors.WithStack(err)
logger.Error(
ctx, "could not list interface addresses",
logger.E(err),
logger.CapturedE(err),
logger.F("iface", iface.Name),
)
sentry.CaptureException(err)
continue
}
@ -227,10 +232,9 @@ func createResolveAppURL(specs *spec.Spec) (ResolveAppURLFunc, error) {
err = errors.WithStack(err)
logger.Error(
ctx, "could not parse interface ip",
logger.E(err),
logger.CapturedE(err),
logger.F("iface", iface.Name),
)
sentry.CaptureException(err)
continue
}
@ -303,7 +307,7 @@ func (c *Controller) getAppModules(deps Dependencies) []app.ServerModuleFactory
cast.CastModuleFactory(),
module.LifecycleModuleFactory(),
netModule.ModuleFactory(deps.Bus),
module.RPCModuleFactory(deps.Bus),
rpc.ModuleFactory(deps.Bus),
module.StoreModuleFactory(deps.DocumentStore),
blob.ModuleFactory(deps.Bus, deps.BlobStore),
authModuleFactory(deps.KeySet),

View File

@ -8,7 +8,6 @@ import (
"forge.cadoles.com/arcad/edge/pkg/app"
"forge.cadoles.com/arcad/edge/pkg/bundle"
appModule "forge.cadoles.com/arcad/edge/pkg/module/app"
"github.com/getsentry/sentry-go"
"github.com/pkg/errors"
"gitlab.com/wpetit/goweb/logger"
)
@ -65,8 +64,7 @@ func (r *AppRepository) List(ctx context.Context) ([]*app.Manifest, error) {
bundle, err := bundle.FromPath(path)
if err != nil {
err = errors.WithStack(err)
logger.Error(bundleCtx, "could not load bundle", logger.E(err))
sentry.CaptureException(err)
logger.Error(bundleCtx, "could not load bundle", logger.CapturedE(err))
continue
}
@ -74,8 +72,7 @@ func (r *AppRepository) List(ctx context.Context) ([]*app.Manifest, error) {
manifest, err := app.LoadManifest(bundle)
if err != nil {
err = errors.WithStack(err)
logger.Error(bundleCtx, "could not load manifest", logger.E(err))
sentry.CaptureException(err)
logger.Error(bundleCtx, "could not load manifest", logger.CapturedE(err))
continue
}
@ -103,8 +100,7 @@ func (r *AppRepository) findManifest(ctx context.Context, id app.ID) (*app.Manif
bundle, err := bundle.FromPath(path)
if err != nil {
err = errors.WithStack(err)
logger.Error(bundleCtx, "could not load bundle", logger.E(err))
sentry.CaptureException(err)
logger.Error(bundleCtx, "could not load bundle", logger.CapturedE(err))
continue
}
@ -112,8 +108,7 @@ func (r *AppRepository) findManifest(ctx context.Context, id app.ID) (*app.Manif
manifest, err := app.LoadManifest(bundle)
if err != nil {
err = errors.WithStack(err)
logger.Error(bundleCtx, "could not load manifest", logger.E(err))
sentry.CaptureException(err)
logger.Error(bundleCtx, "could not load manifest", logger.CapturedE(err))
continue
}

View File

@ -11,7 +11,6 @@ import (
"forge.cadoles.com/Cadoles/emissary/internal/agent/controller/app/spec"
"forge.cadoles.com/arcad/edge/pkg/app"
"forge.cadoles.com/arcad/edge/pkg/bundle"
"github.com/getsentry/sentry-go"
"github.com/mitchellh/hashstructure/v2"
"github.com/pkg/errors"
"gitlab.com/wpetit/goweb/logger"
@ -71,9 +70,8 @@ func (c *Controller) stopAllApps(ctx context.Context, spec *spec.Spec) {
logger.Error(
ctx, "error while stopping app",
logger.F("appID", appID),
logger.E(err),
logger.CapturedE(err),
)
sentry.CaptureException(err)
delete(c.servers, appID)
}
@ -94,9 +92,8 @@ func (c *Controller) updateApps(ctx context.Context, specs *spec.Spec) {
logger.Error(
ctx, "error while stopping app",
logger.F("appKey", appKey),
logger.E(err),
logger.CapturedE(err),
)
sentry.CaptureException(err)
delete(c.servers, appKey)
}
@ -106,9 +103,8 @@ func (c *Controller) updateApps(ctx context.Context, specs *spec.Spec) {
err = errors.WithStack(err)
logger.Error(
ctx, "could not update app repository",
logger.E(err),
logger.CapturedE(err),
)
sentry.CaptureException(err)
return
}
@ -119,8 +115,7 @@ func (c *Controller) updateApps(ctx context.Context, specs *spec.Spec) {
if err := c.updateApp(ctx, specs, appKey); err != nil {
err = errors.WithStack(err)
logger.Error(appCtx, "could not update app", logger.E(err))
sentry.CaptureException(err)
logger.Error(appCtx, "could not update app", logger.CapturedE(err))
continue
}
}
@ -209,11 +204,13 @@ func (c *Controller) updateApp(ctx context.Context, specs *spec.Spec, appKey str
return nil
}
ctx = logger.With(ctx,
logger.F("appKey", appKey),
logger.F("address", appEntry.Address),
)
if defChanged && server.AppDefHash != 0 {
logger.Info(
ctx, "restarting app",
logger.F("address", appEntry.Address),
)
logger.Info(ctx, "restarting app")
if err := server.Server.Stop(); err != nil {
return errors.WithStack(err)
@ -226,10 +223,7 @@ func (c *Controller) updateApp(ctx context.Context, specs *spec.Spec, appKey str
c.servers[appKey] = serverEntry
} else {
logger.Info(
ctx, "starting app",
logger.F("address", appEntry.Address),
)
logger.Info(ctx, "starting app")
}
if err := server.Server.Start(ctx, appEntry.Address); err != nil {

View File

@ -14,9 +14,8 @@ import (
"gitlab.com/wpetit/goweb/logger"
"forge.cadoles.com/arcad/edge/pkg/bundle"
"github.com/getsentry/sentry-go"
"github.com/go-chi/chi/middleware"
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
"github.com/pkg/errors"
_ "forge.cadoles.com/Cadoles/emissary/internal/imports/passwd"
@ -49,7 +48,7 @@ func (s *Server) Start(ctx context.Context, addr string) (err error) {
router.Use(middleware.Compress(5))
handler := edgeHTTP.NewHandler(s.handlerOptions...)
if err := handler.Load(s.bundle); err != nil {
if err := handler.Load(ctx, s.bundle); err != nil {
return errors.Wrap(err, "could not load app bundle")
}
@ -74,8 +73,7 @@ func (s *Server) Start(ctx context.Context, addr string) (err error) {
if recovered := recover(); recovered != nil {
if err, ok := recovered.(error); ok {
err = errors.WithStack(err)
logger.Error(ctx, err.Error(), logger.E(err))
sentry.CaptureException(err)
logger.Error(ctx, err.Error(), logger.CapturedE(err))
return
}

View File

@ -24,7 +24,8 @@
"type": "string",
"enum": [
"zip",
"tar.gz"
"tar.gz",
"zim"
]
},
"storage": {

View File

@ -8,7 +8,6 @@ import (
"forge.cadoles.com/Cadoles/emissary/internal/agent"
mdns "forge.cadoles.com/Cadoles/emissary/internal/agent/controller/mdns/spec"
"github.com/brutella/dnssd"
"github.com/getsentry/sentry-go"
"github.com/mitchellh/hashstructure/v2"
"github.com/pkg/errors"
"gitlab.com/wpetit/goweb/logger"
@ -119,8 +118,7 @@ func (c *Controller) updateResponder(ctx context.Context, spec *mdns.Spec) error
service, err := dnssd.NewService(config)
if err != nil {
err = errors.WithStack(err)
logger.Error(ctx, "could not create mdns service", logger.E(err))
sentry.CaptureException(err)
logger.Error(ctx, "could not create mdns service", logger.CapturedE(err))
continue
}
@ -136,8 +134,7 @@ func (c *Controller) updateResponder(ctx context.Context, spec *mdns.Spec) error
for _, service := range services {
if _, err := responder.Add(service); err != nil {
err = errors.WithStack(err)
logger.Error(ctx, "could not add mdns service", logger.E(err))
sentry.CaptureException(err)
logger.Error(ctx, "could not add mdns service", logger.CapturedE(err))
continue
}
@ -154,8 +151,7 @@ func (c *Controller) updateResponder(ctx context.Context, spec *mdns.Spec) error
if err := responder.Respond(ctx); err != nil && !errors.Is(err, context.Canceled) {
err = errors.WithStack(err)
logger.Error(ctx, "could not respond to mdns queries", logger.E(err))
sentry.CaptureException(err)
logger.Error(ctx, "could not respond to mdns queries", logger.CapturedE(err))
}
}()

View File

@ -11,7 +11,6 @@ import (
"forge.cadoles.com/Cadoles/emissary/internal/agent"
"forge.cadoles.com/Cadoles/emissary/internal/agent/controller/openwrt/spec/sysupgrade"
"github.com/getsentry/sentry-go"
"github.com/pkg/errors"
"gitlab.com/wpetit/goweb/logger"
)
@ -68,10 +67,9 @@ func (c *SysUpgradeController) Reconcile(ctx context.Context, state *agent.State
err = errors.WithStack(err)
logger.Error(
ctx, "could not remove download direction",
logger.E(err),
logger.CapturedE(err),
logger.F("downloadDir", downloadDir),
)
sentry.CaptureException(err)
}
}()

View File

@ -9,7 +9,6 @@ import (
"forge.cadoles.com/Cadoles/emissary/internal/agent"
"forge.cadoles.com/Cadoles/emissary/internal/openwrt/uci"
ucispec "forge.cadoles.com/Cadoles/emissary/internal/spec/uci"
"github.com/getsentry/sentry-go"
"github.com/pkg/errors"
"gitlab.com/wpetit/goweb/logger"
)
@ -48,8 +47,7 @@ func (c *UCIController) Reconcile(ctx context.Context, state *agent.State) error
if err := c.updateConfiguration(ctx, uciSpec); err != nil {
err = errors.WithStack(err)
logger.Error(ctx, "could not update configuration", logger.E(err))
sentry.CaptureException(err)
logger.Error(ctx, "could not update configuration", logger.CapturedE(err))
return nil
}

View File

@ -10,7 +10,6 @@ import (
"forge.cadoles.com/Cadoles/emissary/internal/agent"
"forge.cadoles.com/Cadoles/emissary/internal/spec"
"github.com/getsentry/sentry-go"
"github.com/pkg/errors"
"gitlab.com/wpetit/goweb/logger"
)
@ -147,8 +146,7 @@ func (c *Controller) writeState(ctx context.Context, state *agent.State) error {
}
err = errors.WithStack(err)
logger.Error(ctx, "could not remove temporary file", logger.E(err))
sentry.CaptureException(err)
logger.Error(ctx, "could not remove temporary file", logger.CapturedE(err))
}
}()
@ -159,8 +157,7 @@ func (c *Controller) writeState(ctx context.Context, state *agent.State) error {
}
err = errors.WithStack(err)
logger.Error(ctx, "could not close temporary file", logger.E(err))
sentry.CaptureException(err)
logger.Error(ctx, "could not close temporary file", logger.CapturedE(err))
}
}()

View File

@ -7,7 +7,6 @@ import (
"forge.cadoles.com/Cadoles/emissary/internal/agent"
"forge.cadoles.com/Cadoles/emissary/internal/proxy"
spec "forge.cadoles.com/Cadoles/emissary/internal/spec/proxy"
"github.com/getsentry/sentry-go"
"github.com/mitchellh/hashstructure/v2"
"github.com/pkg/errors"
"gitlab.com/wpetit/goweb/logger"
@ -63,9 +62,8 @@ func (c *Controller) stopAllProxies(ctx context.Context) {
logger.Error(
ctx, "error while stopping proxy",
logger.F("proxyID", proxyID),
logger.E(err),
logger.CapturedE(err),
)
sentry.CaptureException(err)
delete(c.proxies, proxyID)
}
@ -86,9 +84,8 @@ func (c *Controller) updateProxies(ctx context.Context, spec *spec.Spec) {
logger.Error(
ctx, "error while stopping proxy",
logger.F("proxyID", proxyID),
logger.E(err),
logger.CapturedE(err),
)
sentry.CaptureException(err)
delete(c.proxies, proxyID)
}
@ -100,8 +97,7 @@ func (c *Controller) updateProxies(ctx context.Context, spec *spec.Spec) {
if err := c.updateProxy(ctx, proxyID, proxySpec); err != nil {
err = errors.WithStack(err)
logger.Error(proxyCtx, "could not update proxy", logger.E(err))
sentry.CaptureException(err)
logger.Error(proxyCtx, "could not update proxy", logger.CapturedE(err))
continue
}
}

View File

@ -6,7 +6,6 @@ import (
"sync"
"forge.cadoles.com/Cadoles/emissary/internal/proxy"
"github.com/getsentry/sentry-go"
"github.com/pkg/errors"
"gitlab.com/wpetit/goweb/logger"
)
@ -40,15 +39,13 @@ func (p *ReverseProxy) Start(ctx context.Context, addr string, funcs ...proxy.Op
defer func() {
if err := p.Stop(); err != nil {
err = errors.WithStack(err)
logger.Error(ctx, "error while stopping gateway", logger.E(err))
sentry.CaptureException(err)
logger.Error(ctx, "error while stopping gateway", logger.CapturedE(err))
}
}()
if err := server.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
err = errors.WithStack(err)
logger.Error(ctx, "error while listening", logger.E(err))
sentry.CaptureException(err)
logger.Error(ctx, "error while listening", logger.CapturedE(err))
}
}()

View File

@ -6,7 +6,6 @@ import (
"forge.cadoles.com/Cadoles/emissary/internal/agent"
"forge.cadoles.com/Cadoles/emissary/internal/datastore"
"forge.cadoles.com/Cadoles/emissary/pkg/client"
"github.com/getsentry/sentry-go"
"github.com/pkg/errors"
"gitlab.com/wpetit/goweb/logger"
)
@ -49,8 +48,7 @@ func (c *Controller) reconcileAgent(ctx context.Context, client *client.Client,
specs, err := client.GetAgentSpecs(ctx, agent.ID)
if err != nil {
err = errors.WithStack(err)
logger.Error(ctx, "could not retrieve agent specs", logger.E(err))
sentry.CaptureException(err)
logger.Error(ctx, "could not retrieve agent specs", logger.CapturedE(err))
return nil
}

View File

@ -64,6 +64,10 @@ func Main(buildDate, projectVersion, gitRef, defaultConfigPath string, commands
if err != nil {
logger.Error(ctx.Context, "could not initialize sentry", logger.E(errors.WithStack(err)))
}
logger.SetCaptureFunc(func(err error) {
sentry.CaptureException(err)
})
}
return nil

View File

@ -5,7 +5,6 @@ import (
"forge.cadoles.com/Cadoles/emissary/internal/command/common"
"github.com/getsentry/sentry-go"
"github.com/pkg/errors"
"github.com/urfave/cli/v2"
"gitlab.com/wpetit/goweb/logger"
@ -34,8 +33,7 @@ func PingCommand() *cli.Command {
defer func() {
if err := db.Close(); err != nil {
err = errors.WithStack(err)
logger.Error(ctx.Context, "error while closing database connection", logger.E(err))
sentry.CaptureException(err)
logger.Error(ctx.Context, "error while closing database connection", logger.CapturedE(err))
}
}()

View File

@ -15,6 +15,6 @@ type DatabaseConfig struct {
func NewDefaultDatabaseConfig() DatabaseConfig {
return DatabaseConfig{
Driver: "sqlite",
DSN: "sqlite://emissary.sqlite?_pragma=foreign_keys(1)&_pragma=busy_timeout=60000",
DSN: "sqlite://emissary.sqlite?_pragma=foreign_keys(1)&_pragma=busy_timeout=150000&_pragma=journal_mode=WAL",
}
}

View File

@ -10,7 +10,41 @@ import (
"gopkg.in/yaml.v3"
)
var reVar = regexp.MustCompile(`^\${(\w+)}$`)
var (
interpolationRegExp = regexp.MustCompile(`^\${((?P<varName>\w+)|((?P<varNameWithDefault>\w+):-(?P<defaultValue>[^}]+)))}$`)
varNameGroupIndex = interpolationRegExp.SubexpIndex("varName")
varNameWithDefaultGroupIndex = interpolationRegExp.SubexpIndex("varNameWithDefault")
defaultValueGroupIndex = interpolationRegExp.SubexpIndex("defaultValue")
)
func interpolate(str string, getValueFunc func(name string) string) string {
for _, match := range interpolationRegExp.FindAllStringSubmatch(str, -1) {
varName := match[varNameWithDefaultGroupIndex]
if varName == "" {
varName = match[varNameGroupIndex]
}
if varName == "" {
continue
}
defaultValue := ""
if defaultValueGroupIndex < len(match) {
defaultValue = match[defaultValueGroupIndex]
}
str = getValueFunc(varName)
if str == "" {
str = defaultValue
}
}
return str
}
func interpolateEnv(str string) string {
return interpolate(str, os.Getenv)
}
type InterpolatedString string
@ -21,11 +55,7 @@ func (is *InterpolatedString) UnmarshalYAML(value *yaml.Node) error {
return errors.WithStack(err)
}
if match := reVar.FindStringSubmatch(str); len(match) > 0 {
*is = InterpolatedString(os.Getenv(match[1]))
} else {
*is = InterpolatedString(str)
}
*is = InterpolatedString(interpolateEnv(str))
return nil
}
@ -39,9 +69,7 @@ func (ii *InterpolatedInt) UnmarshalYAML(value *yaml.Node) error {
return errors.Wrapf(err, "could not decode value '%v' (line '%d') into string", value.Value, value.Line)
}
if match := reVar.FindStringSubmatch(str); len(match) > 0 {
str = os.Getenv(match[1])
}
str = interpolateEnv(str)
intVal, err := strconv.ParseInt(str, 10, 32)
if err != nil {
@ -62,9 +90,7 @@ func (ib *InterpolatedBool) UnmarshalYAML(value *yaml.Node) error {
return errors.Wrapf(err, "could not decode value '%v' (line '%d') into string", value.Value, value.Line)
}
if match := reVar.FindStringSubmatch(str); len(match) > 0 {
str = os.Getenv(match[1])
}
str = interpolateEnv(str)
boolVal, err := strconv.ParseBool(str)
if err != nil {
@ -91,9 +117,7 @@ func (im *InterpolatedMap) UnmarshalYAML(value *yaml.Node) error {
continue
}
if match := reVar.FindStringSubmatch(strVal); len(match) > 0 {
strVal = os.Getenv(match[1])
}
strVal = interpolateEnv(strVal)
data[key] = strVal
}
@ -113,9 +137,7 @@ func (iss *InterpolatedStringSlice) UnmarshalYAML(value *yaml.Node) error {
}
for index, value := range data {
if match := reVar.FindStringSubmatch(value); len(match) > 0 {
value = os.Getenv(match[1])
}
value = interpolateEnv(value)
data[index] = value
}
@ -134,9 +156,7 @@ func (id *InterpolatedDuration) UnmarshalYAML(value *yaml.Node) error {
return errors.Wrapf(err, "could not decode value '%v' (line '%d') into string", value.Value, value.Line)
}
if match := reVar.FindStringSubmatch(str); len(match) > 0 {
str = os.Getenv(match[1])
}
str = interpolateEnv(str)
duration, err := time.ParseDuration(str)
if err != nil {

View File

@ -0,0 +1,63 @@
package config
import (
"fmt"
"testing"
)
type interpolateTestCase struct {
String string
Data map[string]string
Expected string
}
var interpolateTestCases = []interpolateTestCase{
{
String: "${foo}",
Data: map[string]string{
"foo": "bar",
},
Expected: "bar",
},
{
String: "${hello:-world}",
Data: map[string]string{},
Expected: "world",
},
{
String: "${hello:-}",
Data: map[string]string{},
Expected: "${hello:-}",
},
{
String: "foo",
Data: map[string]string{},
Expected: "foo",
},
{
String: "",
Data: map[string]string{},
Expected: "",
},
}
func TestInterpolate(t *testing.T) {
for idx, tc := range interpolateTestCases {
func(idx int, tc interpolateTestCase) {
t.Run(fmt.Sprintf("Case_%d", idx), func(t *testing.T) {
result := interpolate(tc.String, func(name string) string {
value, exists := tc.Data[name]
if !exists {
return ""
}
return value
})
if e, g := tc.Expected, result; e != g {
t.Errorf("result: expected '%v', got '%v'", tc.Expected, result)
}
})
}(idx, tc)
}
}

View File

@ -5,23 +5,24 @@ import (
"database/sql"
"encoding/json"
"fmt"
"strings"
"time"
"forge.cadoles.com/Cadoles/emissary/internal/datastore"
"github.com/getsentry/sentry-go"
"github.com/lestrrat-go/jwx/v2/jwk"
"github.com/pkg/errors"
"gitlab.com/wpetit/goweb/logger"
)
type AgentRepository struct {
db *sql.DB
db *sql.DB
sqliteBusyRetryMaxAttempts int
}
// DeleteSpec implements datastore.AgentRepository.
func (r *AgentRepository) DeleteSpec(ctx context.Context, agentID datastore.AgentID, name string) error {
err := r.withTx(ctx, func(tx *sql.Tx) error {
err := r.withTxRetry(ctx, func(tx *sql.Tx) error {
exists, err := r.agentExists(ctx, tx, agentID)
if err != nil {
return errors.WithStack(err)
@ -50,7 +51,7 @@ func (r *AgentRepository) DeleteSpec(ctx context.Context, agentID datastore.Agen
func (r *AgentRepository) GetSpecs(ctx context.Context, agentID datastore.AgentID) ([]*datastore.Spec, error) {
specs := make([]*datastore.Spec, 0)
err := r.withTx(ctx, func(tx *sql.Tx) error {
err := r.withTxRetry(ctx, func(tx *sql.Tx) error {
exists, err := r.agentExists(ctx, tx, agentID)
if err != nil {
return errors.WithStack(err)
@ -74,8 +75,7 @@ func (r *AgentRepository) GetSpecs(ctx context.Context, agentID datastore.AgentI
defer func() {
if err := rows.Close(); err != nil {
err = errors.WithStack(err)
logger.Error(ctx, "could not close rows", logger.E(err))
sentry.CaptureException(err)
logger.Error(ctx, "could not close rows", logger.CapturedE(err))
}
}()
@ -110,7 +110,7 @@ func (r *AgentRepository) GetSpecs(ctx context.Context, agentID datastore.AgentI
func (r *AgentRepository) UpdateSpec(ctx context.Context, agentID datastore.AgentID, name string, revision int, data map[string]any) (*datastore.Spec, error) {
spec := &datastore.Spec{}
err := r.withTx(ctx, func(tx *sql.Tx) error {
err := r.withTxRetry(ctx, func(tx *sql.Tx) error {
exists, err := r.agentExists(ctx, tx, agentID)
if err != nil {
return errors.WithStack(err)
@ -169,7 +169,7 @@ func (r *AgentRepository) Query(ctx context.Context, opts ...datastore.AgentQuer
agents := make([]*datastore.Agent, 0)
count := 0
err := r.withTx(ctx, func(tx *sql.Tx) error {
err := r.withTxRetry(ctx, func(tx *sql.Tx) error {
query := `SELECT id, label, thumbprint, status, contacted_at, created_at, updated_at FROM agents`
limit := 10
@ -222,7 +222,7 @@ func (r *AgentRepository) Query(ctx context.Context, opts ...datastore.AgentQuer
logger.Debug(ctx, "executing query", logger.F("query", query), logger.F("args", args))
rows, err := r.db.QueryContext(ctx, query, args...)
rows, err := tx.QueryContext(ctx, query, args...)
if err != nil {
return errors.WithStack(err)
}
@ -230,8 +230,7 @@ func (r *AgentRepository) Query(ctx context.Context, opts ...datastore.AgentQuer
defer func() {
if err := rows.Close(); err != nil {
err = errors.WithStack(err)
logger.Error(ctx, "could not close rows", logger.E(errors.WithStack(err)))
sentry.CaptureException(err)
logger.Error(ctx, "could not close rows", logger.CapturedE(err))
}
}()
@ -275,7 +274,7 @@ func (r *AgentRepository) Query(ctx context.Context, opts ...datastore.AgentQuer
func (r *AgentRepository) Create(ctx context.Context, thumbprint string, keySet jwk.Set, metadata map[string]any) (*datastore.Agent, error) {
agent := &datastore.Agent{}
err := r.withTx(ctx, func(tx *sql.Tx) error {
err := r.withTxRetry(ctx, func(tx *sql.Tx) error {
query := `SELECT count(id) FROM agents WHERE thumbprint = $1`
row := tx.QueryRowContext(ctx, query, thumbprint)
@ -334,15 +333,15 @@ func (r *AgentRepository) Create(ctx context.Context, thumbprint string, keySet
// Delete implements datastore.AgentRepository
func (r *AgentRepository) Delete(ctx context.Context, id datastore.AgentID) error {
err := r.withTx(ctx, func(tx *sql.Tx) error {
err := r.withTxRetry(ctx, func(tx *sql.Tx) error {
query := `DELETE FROM agents WHERE id = $1`
_, err := r.db.ExecContext(ctx, query, id)
_, err := tx.ExecContext(ctx, query, id)
if err != nil {
return errors.WithStack(err)
}
query = `DELETE FROM specs WHERE agent_id = $1`
_, err = r.db.ExecContext(ctx, query, id)
_, err = tx.ExecContext(ctx, query, id)
if err != nil {
return errors.WithStack(err)
}
@ -362,14 +361,14 @@ func (r *AgentRepository) Get(ctx context.Context, id datastore.AgentID) (*datas
ID: id,
}
err := r.withTx(ctx, func(tx *sql.Tx) error {
err := r.withTxRetry(ctx, func(tx *sql.Tx) error {
query := `
SELECT "id", "label", "thumbprint", "keyset", "metadata", "status", "contacted_at", "created_at", "updated_at"
FROM agents
WHERE id = $1
`
row := r.db.QueryRowContext(ctx, query, id)
row := tx.QueryRowContext(ctx, query, id)
metadata := JSONMap{}
contactedAt := sql.NullTime{}
@ -413,7 +412,7 @@ func (r *AgentRepository) Update(ctx context.Context, id datastore.AgentID, opts
agent := &datastore.Agent{}
err := r.withTx(ctx, func(tx *sql.Tx) error {
err := r.withTxRetry(ctx, func(tx *sql.Tx) error {
query := `
UPDATE agents SET id = $1
`
@ -537,6 +536,59 @@ func (r *AgentRepository) agentExists(ctx context.Context, tx *sql.Tx, agentID d
return true, nil
}
func (r *AgentRepository) withTxRetry(ctx context.Context, fn func(*sql.Tx) error) error {
attempts := 0
max := r.sqliteBusyRetryMaxAttempts
ctx = logger.With(ctx, logger.F("max", max))
var err error
for {
ctx = logger.With(ctx)
if attempts >= max {
logger.Debug(ctx, "transaction retrying failed", logger.F("attempts", attempts))
return errors.Wrapf(err, "transaction failed after %d attempts", max)
}
err = r.withTx(ctx, fn)
if err != nil {
if !strings.Contains(err.Error(), "(5) (SQLITE_BUSY)") {
return errors.WithStack(err)
}
err = errors.WithStack(err)
logger.Warn(ctx, "database is busy", logger.E(err))
wait := time.Duration(8<<(attempts+1)) * time.Millisecond
logger.Debug(
ctx, "database is busy, waiting before retrying transaction",
logger.F("wait", wait.String()),
logger.F("attempts", attempts),
)
timer := time.NewTimer(wait)
select {
case <-timer.C:
attempts++
continue
case <-ctx.Done():
if err := ctx.Err(); err != nil {
return errors.WithStack(err)
}
return nil
}
}
return nil
}
}
func (r *AgentRepository) withTx(ctx context.Context, fn func(*sql.Tx) error) error {
tx, err := r.db.BeginTx(ctx, nil)
if err != nil {
@ -550,8 +602,7 @@ func (r *AgentRepository) withTx(ctx context.Context, fn func(*sql.Tx) error) er
}
err = errors.WithStack(err)
logger.Error(ctx, "could not rollback transaction", logger.E(err))
sentry.CaptureException(err)
logger.Error(ctx, "could not rollback transaction", logger.CapturedE(err))
}
}()
@ -566,8 +617,8 @@ func (r *AgentRepository) withTx(ctx context.Context, fn func(*sql.Tx) error) er
return nil
}
func NewAgentRepository(db *sql.DB) *AgentRepository {
return &AgentRepository{db}
func NewAgentRepository(db *sql.DB, sqliteBusyRetryMaxAttempts int) *AgentRepository {
return &AgentRepository{db, sqliteBusyRetryMaxAttempts}
}
var _ datastore.AgentRepository = &AgentRepository{}

View File

@ -40,7 +40,7 @@ func TestSQLiteAgentRepository(t *testing.T) {
t.Fatalf("%+v", errors.WithStack(err))
}
repo := NewAgentRepository(db)
repo := NewAgentRepository(db, 5)
testsuite.TestAgentRepository(t, repo)
}

View File

@ -9,8 +9,7 @@ import (
"forge.cadoles.com/Cadoles/emissary/internal/agent/metadata"
"forge.cadoles.com/Cadoles/emissary/internal/datastore"
"forge.cadoles.com/Cadoles/emissary/internal/jwk"
"github.com/getsentry/sentry-go"
"github.com/go-chi/chi"
"github.com/go-chi/chi/v5"
"github.com/pkg/errors"
"gitlab.com/wpetit/goweb/api"
"gitlab.com/wpetit/goweb/logger"
@ -41,8 +40,7 @@ func (s *Server) registerAgent(w http.ResponseWriter, r *http.Request) {
keySet, err := jwk.Parse(registerAgentReq.KeySet)
if err != nil {
err = errors.WithStack(err)
logger.Error(ctx, "could not parse key set", logger.E(err))
sentry.CaptureException(err)
logger.Error(ctx, "could not parse key set", logger.CapturedE(err))
api.ErrorResponse(w, http.StatusInternalServerError, ErrCodeUnknownError, nil)
return
@ -55,8 +53,7 @@ func (s *Server) registerAgent(w http.ResponseWriter, r *http.Request) {
validSignature, err := jwk.Verify(keySet, registerAgentReq.Signature, registerAgentReq.Thumbprint, registerAgentReq.Metadata)
if err != nil {
err = errors.WithStack(err)
logger.Error(ctx, "could not validate signature", logger.E(err))
sentry.CaptureException(err)
logger.Error(ctx, "could not validate signature", logger.CapturedE(err))
api.ErrorResponse(w, http.StatusInternalServerError, ErrCodeUnknownError, nil)
return
@ -80,8 +77,7 @@ func (s *Server) registerAgent(w http.ResponseWriter, r *http.Request) {
if err != nil {
if !errors.Is(err, datastore.ErrAlreadyExist) {
err = errors.WithStack(err)
logger.Error(ctx, "could not create agent", logger.E(err))
sentry.CaptureException(err)
logger.Error(ctx, "could not create agent", logger.CapturedE(err))
api.ErrorResponse(w, http.StatusInternalServerError, ErrCodeUnknownError, nil)
return
@ -94,8 +90,7 @@ func (s *Server) registerAgent(w http.ResponseWriter, r *http.Request) {
)
if err != nil {
err = errors.WithStack(err)
logger.Error(ctx, "could not retrieve agents", logger.E(err))
sentry.CaptureException(err)
logger.Error(ctx, "could not retrieve agents", logger.CapturedE(err))
api.ErrorResponse(w, http.StatusInternalServerError, ErrCodeUnknownError, nil)
return
@ -103,9 +98,7 @@ func (s *Server) registerAgent(w http.ResponseWriter, r *http.Request) {
if len(agents) == 0 {
err = errors.WithStack(err)
logger.Error(ctx, "could not retrieve matching agent", logger.E(err))
sentry.CaptureException(err)
logger.Error(ctx, "could not retrieve matching agent", logger.CapturedE(err))
api.ErrorResponse(w, http.StatusInternalServerError, ErrCodeNotFound, nil)
return
@ -118,9 +111,8 @@ func (s *Server) registerAgent(w http.ResponseWriter, r *http.Request) {
err = errors.WithStack(err)
logger.Error(
ctx, "could not retrieve agent",
logger.E(err), logger.F("agentID", agentID),
logger.CapturedE(err), logger.F("agentID", agentID),
)
sentry.CaptureException(err)
api.ErrorResponse(w, http.StatusInternalServerError, ErrCodeUnknownError, nil)
@ -130,8 +122,7 @@ func (s *Server) registerAgent(w http.ResponseWriter, r *http.Request) {
validSignature, err = jwk.Verify(agent.KeySet.Set, registerAgentReq.Signature, registerAgentReq.Thumbprint, registerAgentReq.Metadata)
if err != nil {
err = errors.WithStack(err)
logger.Error(ctx, "could not validate signature using previous keyset", logger.E(err))
sentry.CaptureException(err)
logger.Error(ctx, "could not validate signature using previous keyset", logger.CapturedE(err))
api.ErrorResponse(w, http.StatusConflict, ErrCodeConflict, nil)
@ -146,8 +137,7 @@ func (s *Server) registerAgent(w http.ResponseWriter, r *http.Request) {
)
if err != nil {
err = errors.WithStack(err)
logger.Error(ctx, "could not update agent", logger.E(err))
sentry.CaptureException(err)
logger.Error(ctx, "could not update agent", logger.CapturedE(err))
api.ErrorResponse(w, http.StatusInternalServerError, ErrCodeUnknownError, nil)
@ -197,9 +187,7 @@ func (s *Server) updateAgent(w http.ResponseWriter, r *http.Request) {
)
if err != nil {
err = errors.WithStack(err)
logger.Error(ctx, "could not update agent", logger.E(err))
sentry.CaptureException(err)
logger.Error(ctx, "could not update agent", logger.CapturedE(err))
api.ErrorResponse(w, http.StatusInternalServerError, ErrCodeUnknownError, nil)
return
@ -281,9 +269,7 @@ func (s *Server) queryAgents(w http.ResponseWriter, r *http.Request) {
)
if err != nil {
err = errors.WithStack(err)
logger.Error(ctx, "could not list agents", logger.E(err))
sentry.CaptureException(err)
logger.Error(ctx, "could not list agents", logger.CapturedE(err))
api.ErrorResponse(w, http.StatusInternalServerError, ErrCodeUnknownError, nil)
return
@ -318,9 +304,7 @@ func (s *Server) deleteAgent(w http.ResponseWriter, r *http.Request) {
}
err = errors.WithStack(err)
logger.Error(ctx, "could not delete agent", logger.E(err))
sentry.CaptureException(err)
logger.Error(ctx, "could not delete agent", logger.CapturedE(err))
api.ErrorResponse(w, http.StatusInternalServerError, ErrCodeUnknownError, nil)
return
@ -353,9 +337,7 @@ func (s *Server) getAgent(w http.ResponseWriter, r *http.Request) {
}
err = errors.WithStack(err)
logger.Error(ctx, "could not get agent", logger.E(err))
sentry.CaptureException(err)
logger.Error(ctx, "could not get agent", logger.CapturedE(err))
api.ErrorResponse(w, http.StatusInternalServerError, ErrCodeUnknownError, nil)
return
@ -373,7 +355,7 @@ func getAgentID(w http.ResponseWriter, r *http.Request) (datastore.AgentID, bool
agentID, err := strconv.ParseInt(rawAgentID, 10, 64)
if err != nil {
logger.Error(r.Context(), "could not parse agent id", logger.E(errors.WithStack(err)))
logger.Error(r.Context(), "could not parse agent id", logger.CapturedE(errors.WithStack(err)))
api.ErrorResponse(w, http.StatusBadRequest, api.ErrCodeMalformedRequest, nil)
return 0, false
@ -388,9 +370,7 @@ func getIntQueryParam(w http.ResponseWriter, r *http.Request, param string, defa
value, err := strconv.ParseInt(rawValue, 10, 64)
if err != nil {
err = errors.WithStack(err)
logger.Error(r.Context(), "could not parse int param", logger.F("param", param), logger.E(err))
sentry.CaptureException(err)
logger.Error(r.Context(), "could not parse int param", logger.F("param", param), logger.CapturedE(err))
api.ErrorResponse(w, http.StatusBadRequest, api.ErrCodeMalformedRequest, nil)
return 0, false
@ -424,9 +404,7 @@ func getIntSliceValues(w http.ResponseWriter, r *http.Request, param string, def
value, err := strconv.ParseInt(rv, 10, 64)
if err != nil {
err = errors.WithStack(err)
logger.Error(r.Context(), "could not parse int slice param", logger.F("param", param), logger.E(err))
sentry.CaptureException(err)
logger.Error(r.Context(), "could not parse int slice param", logger.F("param", param), logger.CapturedE(err))
api.ErrorResponse(w, http.StatusBadRequest, api.ErrCodeMalformedRequest, nil)
return nil, false

View File

@ -8,7 +8,6 @@ import (
"forge.cadoles.com/Cadoles/emissary/internal/auth"
"forge.cadoles.com/Cadoles/emissary/internal/auth/agent"
"forge.cadoles.com/Cadoles/emissary/internal/auth/thirdparty"
"github.com/getsentry/sentry-go"
"github.com/pkg/errors"
"gitlab.com/wpetit/goweb/api"
"gitlab.com/wpetit/goweb/logger"
@ -126,8 +125,7 @@ func assertRequestUser(w http.ResponseWriter, r *http.Request) (auth.User, bool)
user, err := auth.CtxUser(ctx)
if err != nil {
err = errors.WithStack(err)
logger.Error(ctx, "could not retrieve user", logger.E(err))
sentry.CaptureException(err)
logger.Error(ctx, "could not retrieve user", logger.CapturedE(err))
forbidden(w, r)

View File

@ -18,8 +18,8 @@ import (
"forge.cadoles.com/Cadoles/emissary/internal/jwk"
"github.com/antonmedv/expr"
"github.com/antonmedv/expr/vm"
"github.com/go-chi/chi"
"github.com/go-chi/chi/middleware"
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
"github.com/go-chi/cors"
"github.com/lestrrat-go/jwx/v2/jwa"
"github.com/lestrrat-go/jwx/v2/jwt"

View File

@ -6,8 +6,7 @@ import (
"forge.cadoles.com/Cadoles/emissary/internal/datastore"
"forge.cadoles.com/Cadoles/emissary/internal/spec"
"github.com/getsentry/sentry-go"
"github.com/go-chi/chi"
"github.com/go-chi/chi/v5"
"github.com/pkg/errors"
"gitlab.com/wpetit/goweb/api"
"gitlab.com/wpetit/goweb/logger"
@ -46,8 +45,7 @@ func (s *Server) updateSpec(w http.ResponseWriter, r *http.Request) {
}
err = errors.WithStack(err)
logger.Error(ctx, "could not validate spec", logger.E(err))
sentry.CaptureException(err)
logger.Error(ctx, "could not validate spec", logger.CapturedE(err))
api.ErrorResponse(w, http.StatusBadRequest, api.ErrCodeInvalidRequest, data)
@ -75,8 +73,7 @@ func (s *Server) updateSpec(w http.ResponseWriter, r *http.Request) {
}
err = errors.WithStack(err)
logger.Error(ctx, "could not update spec", logger.E(err))
sentry.CaptureException(err)
logger.Error(ctx, "could not update spec", logger.CapturedE(err))
api.ErrorResponse(w, http.StatusInternalServerError, ErrCodeUnknownError, nil)
@ -107,8 +104,7 @@ func (s *Server) getAgentSpecs(w http.ResponseWriter, r *http.Request) {
}
err = errors.WithStack(err)
logger.Error(ctx, "could not list specs", logger.E(err))
sentry.CaptureException(err)
logger.Error(ctx, "could not list specs", logger.CapturedE(err))
api.ErrorResponse(w, http.StatusInternalServerError, ErrCodeUnknownError, nil)
@ -152,8 +148,7 @@ func (s *Server) deleteSpec(w http.ResponseWriter, r *http.Request) {
}
err = errors.WithStack(err)
logger.Error(ctx, "could not delete spec", logger.E(err))
sentry.CaptureException(err)
logger.Error(ctx, "could not delete spec", logger.CapturedE(err))
api.ErrorResponse(w, http.StatusInternalServerError, ErrCodeUnknownError, nil)
@ -173,8 +168,7 @@ func getSpecID(w http.ResponseWriter, r *http.Request) (datastore.SpecID, bool)
specID, err := strconv.ParseInt(rawSpecID, 10, 64)
if err != nil {
err = errors.WithStack(err)
logger.Error(r.Context(), "could not parse spec id", logger.E(err))
sentry.CaptureException(err)
logger.Error(r.Context(), "could not parse spec id", logger.CapturedE(err))
api.ErrorResponse(w, http.StatusBadRequest, api.ErrCodeMalformedRequest, nil)

View File

@ -59,7 +59,7 @@ func NewAgentRepository(ctx context.Context, conf config.DatabaseConfig) (datast
return nil, errors.WithStack(err)
}
agentRepository = sqlite.NewAgentRepository(db)
agentRepository = sqlite.NewAgentRepository(db, 5)
default:
return nil, errors.Errorf("unsupported database driver '%s'", driver)

32
misc/docker/agent.yml Normal file
View File

@ -0,0 +1,32 @@
logger:
level: ${EMISSARY_AGENT_LOGGER_LEVEL:-1}
format: ${EMISSARY_AGENT_LOGGER_FORMAT:-human}
sentry:
dsn: ${EMISSARY_AGENT_SENTRY_DSN}
agent:
serverUrl: ${EMISSARY_AGENT_SERVER_URL:-http://127.0.0.1:3000}
privateKeyPath: ${EMISSARY_AGENT_PRIVATE_KEY_PATH:-/data/agent-key.json}
reconciliationInterval: ${EMISSARY_AGENT_RECONCILIATION_INTERVAL:-30}
controllers:
persistence:
enabled: true
stateFile: ${EMISSARY_AGENT_CONTROLLERS_PERSISTENCE_STATE_FILE:-/data/state.json}
spec:
enabled: true
proxy:
enabled: true
uci:
enabled: false
app:
enabled: true
dataDir: ${EMISSARY_AGENT_CONTROLLERS_APP_DATA_DIR:-/data/apps/data}
downloadDir: ${EMISSARY_AGENT_CONTROLLERS_APP_DOWNLOAD_DIR:-/data/apps/bundles}
sysupgrade:
enabled: false
mdns:
enabled: true
collectors:
- name: uname
command: uname
args:
- -a

View File

@ -0,0 +1,10 @@
#!/bin/sh
set -e
# Generate machine id if not exists
if [ ! -f /etc/machine-id ]; then
cat /proc/sys/kernel/random/uuid > /etc/machine-id
fi
exec $@

35
misc/docker/server.yml Normal file
View File

@ -0,0 +1,35 @@
logger:
level: ${EMISSARY_SERVER_LOGGER_LEVEL:-1}
format: ${EMISSARY_SERVER_LOGGER_FORMAT:-human}
sentry:
dsn: ${EMISSARY_SERVER_SENTRY_DSN}
server:
http:
host: ${EMISSARY_SERVER_HTTP_HOST:-0.0.0.0}
port: ${EMISSARY_SERVER_HTTP_HOST:-3000}
database:
driver: ${EMISSARY_SERVER_DATABASE_DRIVER:-sqlite}
dsn: ${EMISSARY_SERVER_DATABASE_DSN:-sqlite:///data/emissary.sqlite?_pragma=foreign_keys(1)&_pragma=busy_timeout=150000&_pragma=journal_mode=WAL}
cors:
allowedOrigins:
- ${EMISSARY_SERVER_CORS_ALLOWED_ORIGINS:-http://localhost:3001}
allowCredentials: ${EMISSARY_SERVER_CORS_ALLOW_CREDENTIALS:-true}
allowMethods:
- POST
- GET
- PUT
- DELETE
allowedHeaders:
- Origin
- Accept
- Content-Type
- Authorization
- Sentry-Trace
debug: ${EMISSARY_SERVER_CORS_DEBUG:-false}
auth:
local:
privateKeyPath: ${EMISSARY_SERVER_AUTH_LOCAL_PRIVATE_KEY_PATH:-/data/server-key.json}
remote:
jwksUrl: "${EMISSARY_SERVER_AUTH_REMOTE_JWKS_URL}"
roleExtractionRules:
- "${EMISSARY_SERVER_AUTH_ROLE_EXTRACTION_RULES_0:-jwt.role != nil ? str(jwt.role) : ''}"

View File

@ -1,6 +1,9 @@
/var/log/emissary/agent.log {
missingok
sharedscripts
compress
rotate 7
daily
postrotate
/etc/init.d/emissary-agent restart
endscript

View File

@ -1,6 +1,9 @@
/var/log/emissary/server.log {
missingok
sharedscripts
compress
rotate 7
daily
postrotate
/etc/init.d/emissary-server restart
endscript

View File

@ -12,8 +12,8 @@
}
},
"edge.sdk.client.test": {
"url": "https://emissary.cadol.es/files/apps/edge.sdk.client.test_2023.10.11-stable.943.4d064de.zip",
"sha256sum": "5419054e09342f5b9834771c087385b0fb425ebdbca3d91aa69eab98d909ca57",
"url": "https://emissary.cadol.es/files/apps/edge.sdk.client.test_2023.10.22-stable.847.22a3326.zip",
"sha256sum": "37aa6c4af57b647dc5cae4ec7d36f4289d99c1f090e533997e0d59188a0a04f4",
"address": ":8084",
"format": "zip",
"storage": {