Skip to content

Commit

Permalink
Add the msi artifact so we can build msi installers from `grafana-b…
Browse files Browse the repository at this point in the history
…uild` (#381)
  • Loading branch information
kminehart authored Oct 24, 2024
1 parent 4cfa9c3 commit 842fd59
Show file tree
Hide file tree
Showing 26 changed files with 3,098 additions and 100 deletions.
52 changes: 26 additions & 26 deletions artifacts/package_exe.go → artifacts/package_msi.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,23 @@ import (

"dagger.io/dagger"
"github.com/grafana/grafana-build/backend"
"github.com/grafana/grafana-build/exe"
"github.com/grafana/grafana-build/msi"
"github.com/grafana/grafana-build/packages"
"github.com/grafana/grafana-build/pipeline"
)

var (
ExeArguments = TargzArguments
ExeFlags = TargzFlags
MSIArguments = TargzArguments
MSIFlags = TargzFlags
)

var ExeInitializer = Initializer{
InitializerFunc: NewExeFromString,
var MSIInitializer = Initializer{
InitializerFunc: NewMSIFromString,
Arguments: TargzArguments,
}

// PacakgeExe uses a built tar.gz package to create a .exe installer for exeian based Linux distributions.
type Exe struct {
// PacakgeMSI uses a built tar.gz package to create a .exe installer for exeian based Linux distributions.
type MSI struct {
Name packages.Name
Version string
BuildID string
Expand All @@ -33,39 +33,39 @@ type Exe struct {
Tarball *pipeline.Artifact
}

func (d *Exe) Dependencies(ctx context.Context) ([]*pipeline.Artifact, error) {
func (d *MSI) Dependencies(ctx context.Context) ([]*pipeline.Artifact, error) {
return []*pipeline.Artifact{
d.Tarball,
}, nil
}

func (d *Exe) Builder(ctx context.Context, opts *pipeline.ArtifactContainerOpts) (*dagger.Container, error) {
return exe.Builder(opts.Client)
func (d *MSI) Builder(ctx context.Context, opts *pipeline.ArtifactContainerOpts) (*dagger.Container, error) {
return msi.Builder(opts.Client)
}

func (d *Exe) BuildFile(ctx context.Context, builder *dagger.Container, opts *pipeline.ArtifactContainerOpts) (*dagger.File, error) {
func (d *MSI) BuildFile(ctx context.Context, builder *dagger.Container, opts *pipeline.ArtifactContainerOpts) (*dagger.File, error) {
targz, err := opts.Store.File(ctx, d.Tarball)
if err != nil {
return nil, err
}

return exe.Build(opts.Client, builder, targz, d.Enterprise), nil
return msi.Build(opts.Client, builder, targz, d.Version, d.Enterprise)
}

func (d *Exe) BuildDir(ctx context.Context, builder *dagger.Container, opts *pipeline.ArtifactContainerOpts) (*dagger.Directory, error) {
func (d *MSI) BuildDir(ctx context.Context, builder *dagger.Container, opts *pipeline.ArtifactContainerOpts) (*dagger.Directory, error) {
// Not a directory so this shouldn't be called
return nil, nil
}

func (d *Exe) Publisher(ctx context.Context, opts *pipeline.ArtifactContainerOpts) (*dagger.Container, error) {
func (d *MSI) Publisher(ctx context.Context, opts *pipeline.ArtifactContainerOpts) (*dagger.Container, error) {
return nil, nil
}

func (d *Exe) PublishFile(ctx context.Context, opts *pipeline.ArtifactPublishFileOpts) error {
func (d *MSI) PublishFile(ctx context.Context, opts *pipeline.ArtifactPublishFileOpts) error {
panic("not implemented") // TODO: Implement
}

func (d *Exe) PublishDir(ctx context.Context, opts *pipeline.ArtifactPublishDirOpts) error {
func (d *MSI) PublishDir(ctx context.Context, opts *pipeline.ArtifactPublishDirOpts) error {
// Not a directory so this shouldn't be called
return nil
}
Expand All @@ -75,24 +75,24 @@ func (d *Exe) PublishDir(ctx context.Context, opts *pipeline.ArtifactPublishDirO
// also affect the filename to ensure that there are no collisions.
// For example, the backend for `linux/amd64` and `linux/arm64` should not both produce a `bin` folder, they should produce a
// `bin/linux-amd64` folder and a `bin/linux-arm64` folder. Callers can mount this as `bin` or whatever if they want.
func (d *Exe) Filename(ctx context.Context) (string, error) {
return packages.FileName(d.Name, d.Version, d.BuildID, d.Distribution, "exe")
func (d *MSI) Filename(ctx context.Context) (string, error) {
return packages.FileName(d.Name, d.Version, d.BuildID, d.Distribution, "msi")
}

func (d *Exe) VerifyFile(ctx context.Context, client *dagger.Client, file *dagger.File) error {
func (d *MSI) VerifyFile(ctx context.Context, client *dagger.Client, file *dagger.File) error {
return nil
}

func (d *Exe) VerifyDirectory(ctx context.Context, client *dagger.Client, dir *dagger.Directory) error {
func (d *MSI) VerifyDirectory(ctx context.Context, client *dagger.Client, dir *dagger.Directory) error {
panic("not implemented") // TODO: Implement
}

func NewExeFromString(ctx context.Context, log *slog.Logger, artifact string, state pipeline.StateHandler) (*pipeline.Artifact, error) {
tarball, err := NewTarballFromString(ctx, log, artifact, state)
func NewMSIFromString(ctx context.Context, log *slog.Logger, artifact string, state pipeline.StateHandler) (*pipeline.Artifact, error) {
targz, err := NewTarballFromString(ctx, log, artifact, state)
if err != nil {
return nil, err
}
options, err := pipeline.ParseFlags(artifact, ExeFlags)
options, err := pipeline.ParseFlags(artifact, MSIFlags)
if err != nil {
return nil, err
}
Expand All @@ -107,15 +107,15 @@ func NewExeFromString(ctx context.Context, log *slog.Logger, artifact string, st

return pipeline.ArtifactWithLogging(ctx, log, &pipeline.Artifact{
ArtifactString: artifact,
Handler: &Exe{
Handler: &MSI{
Name: p.Name,
Version: p.Version,
BuildID: p.BuildID,
Distribution: p.Distribution,
Enterprise: p.Enterprise,
Tarball: tarball,
Tarball: targz,
},
Type: pipeline.ArtifactTypeFile,
Flags: TargzFlags,
Flags: ZipFlags,
})
}
2 changes: 1 addition & 1 deletion cmd/artifacts.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ var Artifacts = map[string]artifacts.Initializer{
"docker-pro": artifacts.ProDockerInitializer,
"docker-enterprise": artifacts.EntDockerInitializer,
"storybook": artifacts.StorybookInitializer,
"exe": artifacts.ExeInitializer,
"msi": artifacts.MSIInitializer,
}
41 changes: 0 additions & 41 deletions exe/build.go

This file was deleted.

26 changes: 0 additions & 26 deletions exe/builder.go

This file was deleted.

67 changes: 67 additions & 0 deletions msi/build.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package msi

import (
"fmt"

"dagger.io/dagger"
"github.com/grafana/grafana-build/containers"
)

func Build(d *dagger.Client, builder *dagger.Container, targz *dagger.File, version string, enterprise bool) (*dagger.File, error) {
wxsFiles, err := WXSFiles(version, enterprise)
if err != nil {
return nil, fmt.Errorf("error generating wxs files: %w", err)
}

f := containers.ExtractedArchive(d, targz)
builder = builder.WithDirectory("/src/grafana", f, dagger.ContainerWithDirectoryOpts{
// Hack from grafana/build-pipeline: Remove files with names too long...
Exclude: []string{
"public/app/plugins/datasource/grafana-azure-monitor-datasource/app_insights/app_insights_querystring_builder.test.ts",
"public/app/plugins/datasource/grafana-azure-monitor-datasource/app_insights/app_insights_querystring_builder.ts",
"public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_log_analytics/azure_log_analytics_datasource.test.ts",
"public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_log_analytics/azure_log_analytics_datasource.ts",
"public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/azure_monitor_datasource.test.ts",
"public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/azure_monitor_datasource.ts",
"public/app/plugins/datasource/grafana-azure-monitor-datasource/app_insights/app_insights_datasource.ts",
"public/app/plugins/datasource/grafana-azure-monitor-datasource/app_insights/app_insights_datasource.test.ts",
"public/app/plugins/datasource/grafana-azure-monitor-datasource/insights_analytics/insights_analytics_datasource.ts",
"public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/azure_monitor_filter_builder.test.ts",
"public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_monitor/azure_monitor_filter_builder.ts",
"public/app/plugins/datasource/grafana-azure-monitor-datasource/components/AnalyticsConfig.test.tsx",
"public/app/plugins/datasource/grafana-azure-monitor-datasource/components/AzureCredentialsForm.test.tsx",
"public/app/plugins/datasource/grafana-azure-monitor-datasource/components/InsightsConfig.test.tsx",
"public/app/plugins/datasource/grafana-azure-monitor-datasource/components/__snapshots__/AnalyticsConfig.test.tsx.snap",
"public/app/plugins/datasource/grafana-azure-monitor-datasource/components/__snapshots__/AzureCredentialsForm.test.tsx.snap",
"public/app/plugins/datasource/grafana-azure-monitor-datasource/components/__snapshots__/InsightsConfig.test.tsx.snap",
"public/app/plugins/datasource/grafana-azure-monitor-datasource/components/__snapshots__/ConfigEditor.test.tsx.snap",
"storybook",
},
}).WithWorkdir("/src")

for _, v := range wxsFiles {
builder = builder.WithNewFile(v.Name, v.Contents)
}

// 1. `heat`: create 'grafana.wxs'
// 2. 'candle': Compile .wxs files into .wixobj
// 3. `light`: assembles the MSI
builder = builder.
WithExec([]string{"/bin/sh", "-c", "cp -r /src/resources/resources/* /src && rm -rf /src/resources"}).
WithExec([]string{"/bin/sh", "-c", `WINEPATH=$(winepath /src/wix3) wine heat dir /src -platform x64 -sw5150 -srd -cg GrafanaX64 -gg -sfrag -dr GrafanaX64Dir -template fragment -out $(winepath -w grafana.wxs)`}).
WithExec([]string{"winepath"}).
WithExec([]string{"mkdir", "/root/.wine/drive_c/temp"})

for _, name := range []string{
"grafana-service.wxs",
"grafana-firewall.wxs",
"grafana.wxs",
"grafana-product.wxs",
} {
builder = builder.WithExec([]string{"/bin/sh", "-c", fmt.Sprintf(`WINEPATH=$(winepath /src/wix3) wine candle -ext WixFirewallExtension -ext WixUtilExtension -v -arch x64 $(winepath -w %s)`, name)})
}
builder = builder.
WithExec([]string{"/bin/bash", "-c", "WINEPATH=$(winepath /src/wix3) wine light -cultures:en-US -ext WixUIExtension.dll -ext WixFirewallExtension -ext WixUtilExtension -v -sval -spdb grafana-service.wixobj grafana-firewall.wixobj grafana.wixobj grafana-product.wixobj -out $(winepath -w /src/grafana.msi)"})

return builder.File("/src/grafana.msi"), nil
}
28 changes: 28 additions & 0 deletions msi/builder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package msi

import (
"dagger.io/dagger"
"github.com/grafana/grafana-build/containers"
)

func Builder(d *dagger.Client) (*dagger.Container, error) {
nssm := d.Container().From("busybox").
WithExec([]string{"wget", "https://nssm.cc/release/nssm-2.24.zip"}).
WithExec([]string{"unzip", "nssm-2.24.zip"}).
Directory("nssm-2.24")

wix3 := d.Container().From("busybox").
WithWorkdir("/src").
WithExec([]string{"wget", "https://github.com/wixtoolset/wix3/releases/download/wix3141rtm/wix314-binaries.zip"}).
WithExec([]string{"unzip", "wix314-binaries.zip"}).
WithExec([]string{"rm", "wix314-binaries.zip"}).
Directory("/src")

builder := d.Container().From("scottyhardy/docker-wine:stable-9.0").
WithEntrypoint([]string{}).
WithMountedDirectory("/src/nssm-2.24", nssm).
WithMountedDirectory("/src/wix3", wix3).
WithWorkdir("/src")

return containers.WithEmbeddedFS(d, builder, "/src/resources", resources)
}
6 changes: 6 additions & 0 deletions msi/embed.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package msi

import "embed"

//go:embed resources/*
var resources embed.FS
Loading

0 comments on commit 842fd59

Please sign in to comment.