Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the msi artifact so we can build msi installers from grafana-build #381

Merged
merged 4 commits into from
Oct 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading