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:
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user