8b370bb6a5
* Add grafana-build action and workflow * Fix the --verify flag stalling on tar.gz builds * Add event sources for main / release branches * Update CODEOWNERS
140 lines
4.7 KiB
Go
140 lines
4.7 KiB
Go
package fpm
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"dagger.io/dagger"
|
|
"github.com/grafana/grafana/pkg/build/daggerbuild/backend"
|
|
"github.com/grafana/grafana/pkg/build/daggerbuild/packages"
|
|
"github.com/grafana/grafana/pkg/build/daggerbuild/versions"
|
|
)
|
|
|
|
type PackageType string
|
|
|
|
const (
|
|
PackageTypeDeb PackageType = "deb"
|
|
PackageTypeRPM PackageType = "rpm"
|
|
)
|
|
|
|
type BuildOpts struct {
|
|
Name packages.Name
|
|
Enterprise bool
|
|
Version string
|
|
BuildID string
|
|
Distribution backend.Distribution
|
|
NameOverride string
|
|
PackageType PackageType
|
|
ConfigFiles [][]string
|
|
AfterInstall string
|
|
BeforeRemove string
|
|
Depends []string
|
|
EnvFolder string
|
|
ExtraArgs []string
|
|
RPMSign bool
|
|
}
|
|
|
|
func Build(builder *dagger.Container, opts BuildOpts, targz *dagger.File) *dagger.File {
|
|
var (
|
|
destination = fmt.Sprintf("/src/package.%s", opts.PackageType)
|
|
fpmArgs = []string{
|
|
"fpm",
|
|
"--input-type=dir",
|
|
"--chdir=/pkg",
|
|
fmt.Sprintf("--output-type=%s", opts.PackageType),
|
|
"--vendor=\"Grafana Labs\"",
|
|
"--url=https://grafana.com",
|
|
"--maintainer=contact@grafana.com",
|
|
fmt.Sprintf("--version=%s", strings.TrimPrefix(opts.Version, "v")),
|
|
fmt.Sprintf("--package=%s", destination),
|
|
}
|
|
|
|
vopts = versions.OptionsFor(opts.Version)
|
|
)
|
|
|
|
// If this is a debian installer and this version had a prerm script (introduced in v9.5)...
|
|
// TODO: this logic means that rpms can't also have a beforeremove. Not important at the moment because it's static (in pipelines/rpm.go) and it doesn't have beforeremove set.
|
|
if vopts.DebPreRM.IsSet && vopts.DebPreRM.Value && opts.PackageType == "deb" {
|
|
if opts.BeforeRemove != "" {
|
|
fpmArgs = append(fpmArgs, fmt.Sprintf("--before-remove=%s", opts.BeforeRemove))
|
|
}
|
|
}
|
|
|
|
// These paths need to be absolute when installed on the machine and not the package structure.
|
|
for _, c := range opts.ConfigFiles {
|
|
fpmArgs = append(fpmArgs, fmt.Sprintf("--config-files=%s", strings.TrimPrefix(c[1], "/pkg")))
|
|
}
|
|
|
|
if opts.AfterInstall != "" {
|
|
fpmArgs = append(fpmArgs, fmt.Sprintf("--after-install=%s", opts.AfterInstall))
|
|
}
|
|
|
|
for _, d := range opts.Depends {
|
|
fpmArgs = append(fpmArgs, fmt.Sprintf("--depends=%s", d))
|
|
}
|
|
|
|
fpmArgs = append(fpmArgs, opts.ExtraArgs...)
|
|
|
|
if arch := backend.PackageArch(opts.Distribution); arch != "" {
|
|
fpmArgs = append(fpmArgs, fmt.Sprintf("--architecture=%s", arch))
|
|
}
|
|
|
|
packageName := string(opts.Name)
|
|
// Honestly we don't care about making fpm installers for non-enterprise or non-grafana flavors of grafana
|
|
if opts.Enterprise {
|
|
fpmArgs = append(fpmArgs, "--description=\"Grafana Enterprise\"")
|
|
fpmArgs = append(fpmArgs, "--conflicts=grafana")
|
|
} else {
|
|
fpmArgs = append(fpmArgs, "--description=Grafana")
|
|
fpmArgs = append(fpmArgs, "--license=AGPLv3")
|
|
}
|
|
|
|
if n := opts.NameOverride; n != "" {
|
|
packageName = n
|
|
}
|
|
|
|
fpmArgs = append(fpmArgs, fmt.Sprintf("--name=%s", packageName))
|
|
|
|
// The last fpm arg which is required to say, "use the PWD to build the package".
|
|
fpmArgs = append(fpmArgs, ".")
|
|
|
|
var (
|
|
// fpm is going to create us a package that is going to essentially rsync the folders from the package into the filesystem.
|
|
// These paths are the paths where grafana package contents will be placed.
|
|
packagePaths = []string{
|
|
"/pkg/usr/sbin",
|
|
"/pkg/usr/share",
|
|
// holds default environment variables for the grafana-server service
|
|
opts.EnvFolder,
|
|
// /etc/grafana is empty in the installation, but is set up by the postinstall script and must be created first.
|
|
"/pkg/etc/grafana",
|
|
// these are our systemd unit files that allow systemd to start/stop/restart/enable the grafana service.
|
|
"/pkg/usr/lib/systemd/system",
|
|
}
|
|
)
|
|
|
|
// init.d scripts are service management scripts that start/stop/restart/enable the grafana service without systemd.
|
|
// these are likely to be deprecated as systemd is now the default pretty much everywhere.
|
|
if opts.PackageType != PackageTypeRPM {
|
|
packagePaths = append(packagePaths, "/pkg/etc/init.d")
|
|
}
|
|
|
|
container := builder.
|
|
WithFile("/src/grafana.tar.gz", targz).
|
|
WithEnvVariable("XZ_DEFAULTS", "-T0").
|
|
WithExec([]string{"tar", "--exclude=storybook", "--strip-components=1", "-xf", "/src/grafana.tar.gz", "-C", "/src"}).
|
|
WithExec([]string{"rm", "/src/grafana.tar.gz"})
|
|
|
|
container = container.
|
|
WithExec(append([]string{"mkdir", "-p"}, packagePaths...)).
|
|
// the "wrappers" scripts are the same as grafana-cli/grafana-server but with some extra shell commands before/after execution.
|
|
WithExec([]string{"cp", "/src/packaging/wrappers/grafana-server", "/src/packaging/wrappers/grafana-cli", "/pkg/usr/sbin"}).
|
|
WithExec([]string{"cp", "-r", "/src", "/pkg/usr/share/grafana"})
|
|
|
|
for _, conf := range opts.ConfigFiles {
|
|
container = container.WithExec(append([]string{"cp", "-r"}, conf...))
|
|
}
|
|
|
|
return container.WithExec(fpmArgs).File(destination)
|
|
}
|