chore (asset): Use //go:embed over vfsgen#5028
Conversation
a19b816 to
a70d6c5
Compare
|
Below some additional information, which does not need to be reviewed, but might come in handy while reviewing: I verified the lack of compression like so ❯ curl -s -D - -o /dev/null -H "Accept-Encoding: gzip, deflate, br" http://localhost:9093/script.js
HTTP/1.1 200 OK
Accept-Ranges: bytes
Cache-Control: no-cache, no-store, must-revalidate
Content-Length: 111355
Content-Type: text/javascript; charset=utf-8
Expires: 0
Pragma: no-cache
Date: Sat, 21 Feb 2026 08:57:27 GMTMoreover, for changes to heap memory, I did following: ❯ cat main_test.go
package main
import (
"testing"
"github.com/prometheus/alertmanager/template"
"github.com/prometheus/alertmanager/ui"
"github.com/prometheus/common/route"
)
func TestMain(t *testing.T) {
router := route.New()
ui.Register(router, nil, nil)
template.FromGlobs([]string{})
}
❯ go test -memprofile mem.vfsgen.profile main_test.go
ok command-line-arguments 0.005s
❯ go tool pprof -text -diff_base mem.embed.profile mem.vfsgen.profile
File: main.test
Build ID: b13f5fb94f4571159937af2558ae82332b043b02
Type: alloc_space
Time: 2026-02-21 08:58:46 CET
Showing nodes accounting for 2228.94kB, 108.59% of 2052.65kB total
flat flat% sum% cum cum%
1714.52kB 83.53% 83.53% 1714.52kB 83.53% github.com/prometheus/alertmanager/asset.init.func1
515.38kB 25.11% 108.64% 515.38kB 25.11% io.ReadAll
-513kB 24.99% 83.64% -513kB 24.99% runtime.allocm
512.05kB 24.95% 108.59% 512.05kB 24.95% github.com/prometheus/client_golang/prometheus.(*goCollector).Describe
-512.02kB 24.94% 83.65% -512.02kB 24.94% github.com/prometheus/client_golang/prometheus.(*Registry).Register
512.01kB 24.94% 108.59% 512.01kB 24.94% text/template/parse.(*ListNode).append (inline)
0 0% 108.59% 1027.39kB 50.05% command-line-arguments.TestMain
0 0% 108.59% 1714.52kB 83.53% github.com/prometheus/alertmanager/asset.init
0 0% 108.59% 1027.39kB 50.05% github.com/prometheus/alertmanager/template.(*Template).Parse
0 0% 108.59% 1027.39kB 50.05% github.com/prometheus/alertmanager/template.FromGlobs
0 0% 108.59% -512.02kB 24.94% github.com/prometheus/client_golang/prometheus.(*Registry).MustRegister
0 0% 108.59% 512.05kB 24.95% github.com/prometheus/client_golang/prometheus.(*Registry).Register.func1
0 0% 108.59% -512.02kB 24.94% github.com/prometheus/client_golang/prometheus.MustRegister (inline)
0 0% 108.59% -512.02kB 24.94% github.com/prometheus/client_golang/prometheus.init.0
0 0% 108.59% 1202.51kB 58.58% runtime.doInit (inline)
0 0% 108.59% 1202.51kB 58.58% runtime.doInit1
0 0% 108.59% 1202.51kB 58.58% runtime.main
0 0% 108.59% -513kB 24.99% runtime.mstart
0 0% 108.59% -513kB 24.99% runtime.mstart0
0 0% 108.59% -513kB 24.99% runtime.mstart1
0 0% 108.59% -513kB 24.99% runtime.newm
0 0% 108.59% -513kB 24.99% runtime.resetspinning
0 0% 108.59% -513kB 24.99% runtime.schedule
0 0% 108.59% -513kB 24.99% runtime.startm
0 0% 108.59% -513kB 24.99% runtime.wakep
0 0% 108.59% 1027.39kB 50.05% testing.tRunner
0 0% 108.59% 512.01kB 24.94% text/template.(*Template).Parse
0 0% 108.59% 512.01kB 24.94% text/template/parse.(*Tree).Parse
0 0% 108.59% 512.01kB 24.94% text/template/parse.(*Tree).action
0 0% 108.59% 512.01kB 24.94% text/template/parse.(*Tree).itemList
0 0% 108.59% 512.01kB 24.94% text/template/parse.(*Tree).parse
0 0% 108.59% 512.01kB 24.94% text/template/parse.(*Tree).parseControl
0 0% 108.59% 512.01kB 24.94% text/template/parse.(*Tree).parseDefinition
0 0% 108.59% 512.01kB 24.94% text/template/parse.(*Tree).rangeControl
0 0% 108.59% 512.01kB 24.94% text/template/parse.(*Tree).textOrAction
0 0% 108.59% 512.01kB 24.94% text/template/parse.ParseWe can see a slight performance (which does not matter in whole scheme of things). For checking that our builds are reproducible, I used this script. #!/bin/bash
# 1. Freeze the build environment so Promu doesn't inject a new
# timestamp or username into the binary on the second run.
export SOURCE_DATE_EPOCH=$(date +%s)
echo "Building Alertmanager (First Run)..."
make build
echo "Computing SHA256 of the first binary..."
HASH1=$(sha256sum alertmanager | awk '{print $1}')
echo "Hash 1: $HASH1"
stat ui/app/script.js
echo "Changing modification time of ui/app/script.js..."
touch ui/app/script.js
stat ui/app/script.js
echo "Building Alertmanager (Second Run)..."
make build
echo "Computing SHA256 of the second binary..."
HASH2=$(sha256sum alertmanager | awk '{print $1}')
echo "Hash 2: $HASH2"
echo "-----------------------------------"
if [ "$HASH1" == "$HASH2" ]; then
echo "SUCCESS: The hashes match. The file modification time does not break reproducibility."
else
echo "FAILED: The hashes differ. The build is not reproducible."
fiThus, the modification times are still not part of the build. |
vfsgen//go:embed over vfsgen
|
A sad site note: This change does not remove the checked in build artefacts, it simply replaces At the moment, we are forced to check-in any build artefact, which uses docker. The reason are our github workflows, .github/workflows/ci.yml and .github/workflows/golangci-lint.yml . We use |
a70d6c5 to
0dc51bf
Compare
| @@ -1,5 +0,0 @@ | |||
| a1: ./alertmanager --log.level=debug --storage.path=$TMPDIR/a1 --web.listen-address=:9093 --cluster.listen-address=127.0.0.1:8001 --config.file=examples/ha/alertmanager.yml | |||
There was a problem hiding this comment.
is it right to remove this Procfile? I always thought this was there as an example for users.
There was a problem hiding this comment.
Good catch, thanks! I did not mean to commit that change.
0dc51bf to
3ed9a57
Compare
|
Fixed a documentation line too. |
Maybe we can get rid of docker here too with this https://github.com/prometheus/alertmanager/pull/4896/changes#diff-e607ec0aa5cc1bb54b418caa5ae0f5d10116ed19a4d016748dff76b68a11f8d4R22 |
This change removes the dependency of `package template` on `shurcool/vfsgen`. We don't require extra tests, because most acceptance tests as well as some explicit tests in `template_test.go` cover this functionality. See part 2/2 for the full consequences of this change. Signed-off-by: Solomon Jacobs <solomonjacobs@protonmail.com>
This change removes `shurcooL/vfsgen`. The change has a couple of
benefits:
* Fewer dependencies.
* Simplifies the build process for downstream distributions such as
Debian.
* Removes logic around different build targets.
A few additional differences between `vfsgen` and `embed` now follow.
1) `embed` does not compress files, whereas `vfsgen` compresses the files
before adding them to the binary. However, the files are decompressed
before sending them. This means that the binary size in this change
slightly increases:
```sh
❯ du alertmanager-vfsgen
40540 alertmanager-vfsgen
❯ du alertmanager-embed
41756 alertmanager-embed
```
In the future, we should ensure that we only send compressed files over
the network. Moreover, we should compress the files before the build.
2) `vfsgen` will memory map the files on startup, i.e.,
```go
var Assets = func() http.FileSystem {
fs := vfsgen۰FS{ // map-like type
```
`embed` serves files from read-only section of the binary, see
https://github.com/golang/go/blob/9d828e80fa1f3cc52de60428cae446b35b576de8/src/embed/embed.go#L151
For this reason, this change should reduce the overall heap usage and
startup time.
3) The build still appears to be reproducible, tested by touching
`ui/app/script.js`. This is a deliberate decision in `embed`, i.e.,
golang/go#44854
4) With this change, we no longer send the `Last-Modified: Thu, 01 Jan
1970 00:00:01 GMT` HTTP header. Since we have disabled all caching,
this seems fair. In the future, we should enable caching.
Closes: prometheus#3115
Signed-off-by: Solomon Jacobs <solomonjacobs@protonmail.com>
3ed9a57 to
1409e54
Compare
|
Great to see this merged! Apologies for missing the pings on the old PR. If you're still interested in reducing the binary size: |
|
Ah, thank you for the links. I will definitely implement some sort of compression, once I have a bit time. |
Previously, bootstrap and font-awesome were manually vendored under
`ui/app/lib/`. They are now fetched via `npm`. Vite bundles these two
and the elm-datepicker at build time into a single file.
URL changes:
- /script.js → /assets/index-[hash].js (content-hashed)
- /lib/bootstrap-*/css/bootstrap.min.css{,.map} → merged into /assets/index-[hash].css
- /lib/elm-datepicker/css/elm-datepicker.css → merged into /assets/index-[hash].css
- /lib/font-awesome-*/css/font-awesome{,.min}.css → merged into /assets/index-[hash].css
- /lib/font-awesome-*/fonts/{woff,woff2,ttf,eot,svg} → /assets/fontawesome-webfont-[hash].{ext}
FontAwesome.otf was removed entirely, this is not a web font.
Files under /assets/ are served with "Cache-Control: public,
max-age=31536000, immutable" (content-hashed filenames make them safe to
cache forever).
In a previous PR (prometheus#5028), `Alertmanager` stopped sending "Last-Modified:
Thu, 01 Jan 1970 00:00:01 GMT". I introduced this behaviour by accident,
but consider this correct behaviour. The findings are documented via a
test.
This change removes various build artifacts, most importantly
`ui/app/script.js`. The following command no longer works in isolation:
```sh
go get github.com/prometheus/alertmanager/ui
```
Users now must build `ui/app/dist` from source.
The MIME types are now hard-coded, removing the dependency on the OS
MIME database. In practice, this would only affect `FontAwesome.otf`,
which we no longer serve anyway.
Signed-off-by: Solomon Jacobs <solomonjacobs@protonmail.com>
Previously, bootstrap and font-awesome were manually vendored under
`ui/app/lib/`. They are now fetched via `npm`. Vite bundles these two
and the elm-datepicker at build time into a single file.
URL changes:
- /script.js → /assets/index-[hash].js (content-hashed)
- /lib/bootstrap-*/css/bootstrap.min.css{,.map} → merged into /assets/index-[hash].css
- /lib/elm-datepicker/css/elm-datepicker.css → merged into /assets/index-[hash].css
- /lib/font-awesome-*/css/font-awesome{,.min}.css → merged into /assets/index-[hash].css
- /lib/font-awesome-*/fonts/{woff,woff2,ttf,eot,svg} → /assets/fontawesome-webfont-[hash].{ext}
FontAwesome.otf was removed entirely, this is not a web font.
Files under /assets/ are served with "Cache-Control: public,
max-age=31536000, immutable" (content-hashed filenames make them safe to
cache forever).
In a previous PR (prometheus#5028), `Alertmanager` stopped sending "Last-Modified:
Thu, 01 Jan 1970 00:00:01 GMT". I introduced this behaviour by accident,
but consider this correct behaviour. The findings are documented via a
test.
This change removes various build artifacts, most importantly
`ui/app/script.js`. The following command no longer works in isolation:
```sh
go get github.com/prometheus/alertmanager/ui
```
Users now must build `ui/app/dist` from source.
The MIME types are now hard-coded, removing the dependency on the OS
MIME database. In practice, this would only affect `FontAwesome.otf`,
which we no longer serve anyway.
Signed-off-by: Solomon Jacobs <solomonjacobs@protonmail.com>
Previously, bootstrap and font-awesome were manually vendored under
`ui/app/lib/`. They are now fetched via `npm`. Vite bundles these two
and the elm-datepicker at build time into a single file.
URL changes:
- /script.js → /assets/index-[hash].js (content-hashed)
- /lib/bootstrap-*/css/bootstrap.min.css{,.map} → merged into /assets/index-[hash].css
- /lib/elm-datepicker/css/elm-datepicker.css → merged into /assets/index-[hash].css
- /lib/font-awesome-*/css/font-awesome{,.min}.css → merged into /assets/index-[hash].css
- /lib/font-awesome-*/fonts/{woff,woff2,ttf,eot,svg} → /assets/fontawesome-webfont-[hash].{ext}
FontAwesome.otf was removed entirely, this is not a web font.
Files under /assets/ are served with "Cache-Control: public,
max-age=31536000, immutable" (content-hashed filenames make them safe to
cache forever).
In a previous PR (prometheus#5028), `Alertmanager` stopped sending "Last-Modified:
Thu, 01 Jan 1970 00:00:01 GMT". I introduced this behaviour by accident,
but consider this correct behaviour. The findings are documented via a
test.
This change removes various build artifacts, most importantly
`ui/app/script.js`. The following command no longer works in isolation:
```sh
go get github.com/prometheus/alertmanager/ui
```
Users now must build `ui/app/dist` from source.
The MIME types are now hard-coded, removing the dependency on the OS
MIME database. In practice, this would only affect `FontAwesome.otf`,
which we no longer serve anyway.
Signed-off-by: Solomon Jacobs <solomonjacobs@protonmail.com>
Previously, bootstrap and font-awesome were manually vendored under
`ui/app/lib/`. They are now fetched via `npm`. Vite bundles these two
and the elm-datepicker at build time into a single file.
URL changes:
- /script.js → /assets/index-[hash].js (content-hashed)
- /lib/bootstrap-*/css/bootstrap.min.css{,.map} → merged into /assets/index-[hash].css
- /lib/elm-datepicker/css/elm-datepicker.css → merged into /assets/index-[hash].css
- /lib/font-awesome-*/css/font-awesome{,.min}.css → merged into /assets/index-[hash].css
- /lib/font-awesome-*/fonts/{woff,woff2,ttf,eot,svg} → /assets/fontawesome-webfont-[hash].{ext}
FontAwesome.otf was removed entirely, this is not a web font.
Files under /assets/ are served with "Cache-Control: public,
max-age=31536000, immutable" (content-hashed filenames make them safe to
cache forever).
In a previous PR (prometheus#5028), `Alertmanager` stopped sending "Last-Modified:
Thu, 01 Jan 1970 00:00:01 GMT". I introduced this behaviour by accident,
but consider this correct behaviour. The findings are documented via a
test.
This change removes various build artifacts, most importantly
`ui/app/script.js`. The following command no longer works in isolation:
```sh
go get github.com/prometheus/alertmanager/ui
```
Users now must build `ui/app/dist` from source.
The MIME types are now hard-coded, removing the dependency on the OS
MIME database. In practice, this would only affect `FontAwesome.otf`,
which we no longer serve anyway.
Signed-off-by: Solomon Jacobs <solomonjacobs@protonmail.com>
Previously, bootstrap and font-awesome were manually vendored under
`ui/app/lib/`. They are now fetched via `npm`. Vite bundles these two
and the elm-datepicker at build time into a single file.
URL changes:
- /script.js → /assets/index-[hash].js (content-hashed)
- /lib/bootstrap-*/css/bootstrap.min.css{,.map} → merged into /assets/index-[hash].css
- /lib/elm-datepicker/css/elm-datepicker.css → merged into /assets/index-[hash].css
- /lib/font-awesome-*/css/font-awesome{,.min}.css → merged into /assets/index-[hash].css
- /lib/font-awesome-*/fonts/{woff,woff2,ttf,eot,svg} → /assets/fontawesome-webfont-[hash].{ext}
FontAwesome.otf was removed entirely, this is not a web font.
Files under /assets/ are served with "Cache-Control: public,
max-age=31536000, immutable" (content-hashed filenames make them safe to
cache forever).
In a previous PR (prometheus#5028), `Alertmanager` stopped sending "Last-Modified:
Thu, 01 Jan 1970 00:00:01 GMT". I introduced this behaviour by accident,
but consider this correct behaviour. The findings are documented via a
test.
This change removes various build artifacts, most importantly
`ui/app/script.js`. The following command no longer works in isolation:
```sh
go get github.com/prometheus/alertmanager/ui
```
Users now must build `ui/app/dist` from source.
The MIME types are now hard-coded, removing the dependency on the OS
MIME database. In practice, this would only affect `FontAwesome.otf`,
which we no longer serve anyway.
Signed-off-by: Solomon Jacobs <solomonjacobs@protonmail.com>
Previously, bootstrap and font-awesome were manually vendored under
`ui/app/lib/`. They are now fetched via `npm`. Vite bundles these two
and the elm-datepicker at build time into a single file.
URL changes:
- /script.js → /assets/index-[hash].js (content-hashed)
- /lib/bootstrap-*/css/bootstrap.min.css{,.map} → merged into /assets/index-[hash].css
- /lib/elm-datepicker/css/elm-datepicker.css → merged into /assets/index-[hash].css
- /lib/font-awesome-*/css/font-awesome{,.min}.css → merged into /assets/index-[hash].css
- /lib/font-awesome-*/fonts/{woff,woff2,ttf,eot,svg} → /assets/fontawesome-webfont-[hash].{ext}
FontAwesome.otf was removed entirely, this is not a web font.
Files under /assets/ are served with "Cache-Control: public,
max-age=31536000, immutable" (content-hashed filenames make them safe to
cache forever).
In a previous PR (prometheus#5028), `Alertmanager` stopped sending "Last-Modified:
Thu, 01 Jan 1970 00:00:01 GMT". I introduced this behaviour by accident,
but consider this correct behaviour. The findings are documented via a
test.
This change removes various build artifacts, most importantly
`ui/app/script.js`. The following command no longer works in isolation:
```sh
go get github.com/prometheus/alertmanager/ui
```
Users now must build `ui/app/dist` from source.
The MIME types are now hard-coded, removing the dependency on the OS
MIME database. In practice, this would only affect `FontAwesome.otf`,
which we no longer serve anyway.
Signed-off-by: Solomon Jacobs <solomonjacobs@protonmail.com>
Previously, bootstrap and font-awesome were manually vendored under
`ui/app/lib/`. They are now fetched via `npm`. Vite bundles these two
and the elm-datepicker at build time into a single file.
URL changes:
- /script.js → /assets/index-[hash].js (content-hashed)
- /lib/bootstrap-*/css/bootstrap.min.css{,.map} → merged into /assets/index-[hash].css
- /lib/elm-datepicker/css/elm-datepicker.css → merged into /assets/index-[hash].css
- /lib/font-awesome-*/css/font-awesome{,.min}.css → merged into /assets/index-[hash].css
- /lib/font-awesome-*/fonts/{woff,woff2,ttf,eot,svg} → /assets/fontawesome-webfont-[hash].{ext}
FontAwesome.otf was removed entirely, this is not a web font.
Files under /assets/ are served with "Cache-Control: public,
max-age=31536000, immutable" (content-hashed filenames make them safe to
cache forever).
In a previous PR (prometheus#5028), `Alertmanager` stopped sending "Last-Modified:
Thu, 01 Jan 1970 00:00:01 GMT". I introduced this behaviour by accident,
but consider this correct behaviour. The findings are documented via a
test.
This change removes various build artifacts, most importantly
`ui/app/script.js`. The following command no longer works in isolation:
```sh
go get github.com/prometheus/alertmanager/ui
```
Users now must build `ui/app/dist` from source.
The MIME types are now hard-coded, removing the dependency on the OS
MIME database. In practice, this would only affect `FontAwesome.otf`,
which we no longer serve anyway.
Signed-off-by: Solomon Jacobs <solomonjacobs@protonmail.com>
Previously, bootstrap and font-awesome were manually vendored under
`ui/app/lib/`. They are now fetched via `npm`. Vite bundles these two
and the elm-datepicker at build time into a single file.
URL changes:
- /script.js → /assets/index-[hash].js (content-hashed)
- /lib/bootstrap-*/css/bootstrap.min.css{,.map} → merged into /assets/index-[hash].css
- /lib/elm-datepicker/css/elm-datepicker.css → merged into /assets/index-[hash].css
- /lib/font-awesome-*/css/font-awesome{,.min}.css → merged into /assets/index-[hash].css
- /lib/font-awesome-*/fonts/{woff,woff2,ttf,eot,svg} → /assets/fontawesome-webfont-[hash].{ext}
FontAwesome.otf was removed entirely, this is not a web font.
Files under /assets/ are served with "Cache-Control: public,
max-age=31536000, immutable" (content-hashed filenames make them safe to
cache forever).
In a previous PR (#5028), `Alertmanager` stopped sending "Last-Modified:
Thu, 01 Jan 1970 00:00:01 GMT". I introduced this behaviour by accident,
but consider this correct behaviour. The findings are documented via a
test.
This change removes various build artifacts, most importantly
`ui/app/script.js`. The following command no longer works in isolation:
```sh
go get github.com/prometheus/alertmanager/ui
```
Users now must build `ui/app/dist` from source.
The MIME types are now hard-coded, removing the dependency on the OS
MIME database. In practice, this would only affect `FontAwesome.otf`,
which we no longer serve anyway.
Signed-off-by: Solomon Jacobs <solomonjacobs@protonmail.com>
Stacked commit, see #5027
This change removes
shurcooL/vfsgen. The change has a couple of benefits:A few additional differences between
vfsgenandembednow follow.embeddoes not compress files, whereasvfsgencompresses the files before adding them to the binary. However, the files are decompressed before sending them. This means that the binary size in this change slightly increases:In the future, we should ensure that we only send compressed files over the network. Moreover, we should compress the files before the build.
vfsgenwill memory map the files on startup, i.e.,embedserves files from read-only section of the binary, see https://github.com/golang/go/blob/9d828e80fa1f3cc52de60428cae446b35b576de8/src/embed/embed.go#L151 For this reason, this change should reduce the overall heap usage and startup time.The build still appears to be reproducible, tested by touching
ui/app/script.js. This is a deliberate decision inembed, i.e., embed: modification time not set for embedded files golang/go#44854With this change, we no longer send the
Last-Modified: Thu, 01 Jan 1970 00:00:01 GMTHTTP header. Since we have disabled all caching, this seems fair. In the future, we should enable caching.Closes: #3115
Pull Request Checklist
Please check all the applicable boxes.
benchstatto compare benchmarksWhich user-facing changes does this PR introduce?