Initial provider implementation (#18)

This brings over the initial buildx prototype from pulumi/pulumi-docker
and fixes various build and release issues.
This commit is contained in:
Bryce Lampe
2024-04-25 11:03:59 -07:00
committed by GitHub
parent 2545dd3089
commit 26c144c916
398 changed files with 65361 additions and 1702 deletions

View File

@@ -1,4 +1,4 @@
// Copyright 2016-2023, Pulumi Corporation.
// Copyright 2024, Pulumi Corporation.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -15,129 +15,65 @@
package provider
import (
"math/rand"
"time"
"context"
"fmt"
p "github.com/pulumi/pulumi-go-provider"
"github.com/pulumi/pulumi-go-provider/infer"
"github.com/pulumi/pulumi-go-provider/middleware/schema"
"github.com/pulumi/pulumi-java/pkg/codegen/java"
csgen "github.com/pulumi/pulumi/pkg/v3/codegen/dotnet"
gogen "github.com/pulumi/pulumi/pkg/v3/codegen/go"
tsgen "github.com/pulumi/pulumi/pkg/v3/codegen/nodejs"
pygen "github.com/pulumi/pulumi/pkg/v3/codegen/python"
"github.com/pulumi/pulumi/sdk/v3/go/common/tokens"
"github.com/pulumi/pulumi-docker-build/provider/internal"
"github.com/pulumi/pulumi-docker-build/provider/internal/deprecated"
gp "github.com/pulumi/pulumi-go-provider"
"github.com/pulumi/pulumi/pkg/v3/resource/provider"
"github.com/pulumi/pulumi/sdk/v3/go/common/resource/plugin"
rpc "github.com/pulumi/pulumi/sdk/v3/proto/go"
)
// Version is initialized by the Go linker to contain the semver of this build.
var Version string
var Version = "0.0.1"
const Name string = "dockerbuild" // Needs to match $PACK in Makefile.
// Name needs to match $PACK in Makefile.
const Name string = "docker-build"
func Provider() p.Provider {
// We tell the provider what resources it needs to support.
// In this case, a single custom resource.
return infer.Provider(infer.Options{
Metadata: schema.Metadata{
DisplayName: "dockerbuild",
LanguageMap: map[string]any{
"go": gogen.GoPackageInfo{
// GenerateResourceContainerTypes: true,
Generics: gogen.GenericsSettingGenericsOnly,
PackageImportAliases: map[string]string{
"github.com/pulumi/pulumi-dockerbuild/sdk/go/dockerbuild": "dockerbuild",
},
ImportBasePath: "github.com/pulumi/pulumi-dockerbuild/sdk/go/dockerbuild",
},
"csharp": csgen.CSharpPackageInfo{
PackageReferences: map[string]string{
"Pulumi": "3.*",
},
},
"java": java.PackageInfo{
BuildFiles: "gradle",
GradleNexusPublishPluginVersion: "1.1.0",
Dependencies: map[string]string{
"com.pulumi:pulumi": "0.9.9",
"com.google.code.gson:gson": "2.8.9",
"com.google.code.findbugs:jsr305": "3.0.2",
},
},
"nodejs": tsgen.NodePackageInfo{
Dependencies: map[string]string{
"@pulumi/pulumi": "^3.0.0",
},
},
"python": pygen.PackageInfo{
PyProject: struct {
Enabled bool `json:"enabled,omitempty"`
}{Enabled: true},
Requires: map[string]string{
"pulumi": ">=3.0.0,<4.0.0",
},
},
},
Description: "Description",
Keywords: []string{"keywords"},
Homepage: "pulumi.com",
Publisher: "pulumi",
Repository: "https://github.com/pulumi/pulumi-dockerbuild",
PluginDownloadURL: "github.com/pulumi/pulumi-dockerbuild",
},
Resources: []infer.InferredResource{
infer.Resource[Random, RandomArgs, RandomState](),
},
ModuleMap: map[tokens.ModuleName]tokens.ModuleName{
"provider": "index",
},
})
// Serve launches the gRPC server for the resource provider.
func Serve() error {
return provider.Main(Name, New)
}
// Each resource has a controlling struct.
// Resource behavior is determined by implementing methods on the controlling struct.
// The `Create` method is mandatory, but other methods are optional.
// - Check: Remap inputs before they are typed.
// - Diff: Change how instances of a resource are compared.
// - Update: Mutate a resource in place.
// - Read: Get the state of a resource from the backing provider.
// - Delete: Custom logic when the resource is deleted.
// - Annotate: Describe fields and set defaults for a resource.
// - WireDependencies: Control how outputs and secrets flows through values.
type Random struct{}
// Each resource has an input struct, defining what arguments it accepts.
type RandomArgs struct {
// Fields projected into Pulumi must be public and hava a `pulumi:"..."` tag.
// The pulumi tag doesn't need to match the field name, but it's generally a
// good idea.
Length int `pulumi:"length"`
}
// Each resource has a state, describing the fields that exist on the created resource.
type RandomState struct {
// It is generally a good idea to embed args in outputs, but it isn't strictly necessary.
RandomArgs
// Here we define a required output called result.
Result string `pulumi:"result" provider:"output"`
}
// All resources must implement Create at a minimum.
func (Random) Create(ctx p.Context, name string, input RandomArgs, preview bool) (string, RandomState, error) {
state := RandomState{RandomArgs: input}
if preview {
return name, state, nil
// New creates a new provider.
func New(host *provider.HostClient) (rpc.ResourceProviderServer, error) {
server, err := gp.RawServer(Name, Version, internal.NewBuildxProvider())(host)
if err != nil {
return nil, fmt.Errorf("building raw server: %w", err)
}
state.Result = makeRandom(input.Length)
return name, state, nil
return &configurableProvider{ResourceProviderServer: server}, nil
}
func makeRandom(length int) string {
seededRand := rand.New(rand.NewSource(time.Now().UnixNano())) //nolint: gosec
charset := []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
// configurableProvider is a workaround for
// https://github.com/pulumi/pulumi-go-provider/issues/171 and
// In short, our SDKs send provider Configure requests as simple strings
// instead of rich objects. We don't want to preserve this behavior in
// pulumi-go-provider, but we also haven't updated SDKs yet to send rich types.
//
// If you find yourself in a position where you need to copy this -- STOP!
// https://github.com/pulumi/pulumi/pull/15032 should be merged with this fix.
type configurableProvider struct {
rpc.ResourceProviderServer
}
result := make([]rune, length)
for i := range result {
result[i] = charset[seededRand.Intn(len(charset))]
func (p configurableProvider) Configure(
ctx context.Context,
request *rpc.ConfigureRequest,
) (*rpc.ConfigureResponse, error) {
schema := internal.Schema(ctx, Version)
ce := deprecated.New(schema.Config)
buildxReq := request
if props, err := ce.UnmarshalProperties(request.Args); err == nil {
args, _ := plugin.MarshalProperties(props, plugin.MarshalOptions{
Label: "config",
KeepUnknowns: true,
SkipNulls: true,
KeepSecrets: true,
RejectAssets: true,
})
buildxReq.Args = args
}
return string(result)
return p.ResourceProviderServer.Configure(ctx, buildxReq)
}