mirror of
https://github.com/imjasonh/terraform-provider-melange
synced 2026-07-08 02:25:13 +00:00
test resource update
Signed-off-by: Jason Hall <jason@chainguard.dev>
This commit is contained in:
parent
d2ad8d1f22
commit
1dad0d8f10
2 changed files with 96 additions and 24 deletions
|
|
@ -92,17 +92,19 @@ func (r *BuildResource) Create(ctx context.Context, req resource.CreateRequest,
|
|||
return
|
||||
}
|
||||
|
||||
id, err := r.doBuild(ctx, data)
|
||||
if err != nil {
|
||||
if err := r.doBuild(ctx, data); err != nil {
|
||||
resp.Diagnostics.AddError("Client Error", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
data.Id = types.StringValue(id)
|
||||
|
||||
// Write logs using the tflog package
|
||||
// Documentation: https://terraform.io/plugin/log
|
||||
tflog.Trace(ctx, "created a resource")
|
||||
// ID is the sha256 of the JSON-serialized input config,
|
||||
// to ensure the resource is updated if the changes.
|
||||
b, err := json.Marshal(data.Config.String())
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddError("Client Error", err.Error())
|
||||
return
|
||||
}
|
||||
data.Id = types.StringValue(fmt.Sprintf("%x", sha256.Sum256(b)))
|
||||
|
||||
// Save data into Terraform state
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
|
||||
|
|
@ -115,6 +117,15 @@ func (r *BuildResource) Read(ctx context.Context, req resource.ReadRequest, resp
|
|||
return
|
||||
}
|
||||
|
||||
// ID is the sha256 of the JSON-serialized input config,
|
||||
// to ensure the resource is updated if the changes.
|
||||
b, err := json.Marshal(data.Config.String())
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddError("Client Error", err.Error())
|
||||
return
|
||||
}
|
||||
data.Id = types.StringValue(fmt.Sprintf("%x", sha256.Sum256(b)))
|
||||
|
||||
// Save updated data into Terraform state
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
|
||||
}
|
||||
|
|
@ -126,6 +137,20 @@ func (r *BuildResource) Update(ctx context.Context, req resource.UpdateRequest,
|
|||
return
|
||||
}
|
||||
|
||||
if err := r.doBuild(ctx, data); err != nil {
|
||||
resp.Diagnostics.AddError("Client Error", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// ID is the sha256 of the JSON-serialized input config,
|
||||
// to ensure the resource is updated if the changes.
|
||||
b, err := json.Marshal(data.Config.String())
|
||||
if err != nil {
|
||||
resp.Diagnostics.AddError("Client Error", err.Error())
|
||||
return
|
||||
}
|
||||
data.Id = types.StringValue(fmt.Sprintf("%x", sha256.Sum256(b)))
|
||||
|
||||
// Save updated data into Terraform state
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
|
||||
}
|
||||
|
|
@ -136,16 +161,17 @@ func (r *BuildResource) Delete(ctx context.Context, req resource.DeleteRequest,
|
|||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
// Nothing to delete.
|
||||
}
|
||||
|
||||
func (r *BuildResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) {
|
||||
resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp)
|
||||
}
|
||||
|
||||
func (r *BuildResource) doBuild(ctx context.Context, data BuildResourceModel) (string, error) {
|
||||
func (r *BuildResource) doBuild(ctx context.Context, data BuildResourceModel) error {
|
||||
var cfg Configuration
|
||||
if diags := reflect.AssignValue(data.Config, &cfg); diags.HasError() {
|
||||
return "", fmt.Errorf("assigning value: %v", diags.Errors())
|
||||
return fmt.Errorf("assigning value: %v", diags.Errors())
|
||||
}
|
||||
|
||||
// TODO: support force-overwrite, so you don't have to rm the package or bump the epoch while testing locally.
|
||||
|
|
@ -164,20 +190,20 @@ func (r *BuildResource) doBuild(ctx context.Context, data BuildResourceModel) (s
|
|||
sdir := filepath.Join(r.popts.dir, cfg.Package.Name)
|
||||
if _, err := os.Stat(sdir); os.IsNotExist(err) {
|
||||
if err := os.MkdirAll(sdir, os.ModePerm); err != nil {
|
||||
return "", fmt.Errorf("creating source directory %s: %v", sdir, err)
|
||||
return fmt.Errorf("creating source directory %s: %v", sdir, err)
|
||||
}
|
||||
} else if err != nil {
|
||||
return "", fmt.Errorf("creating source directory: %v", err)
|
||||
return fmt.Errorf("creating source directory: %v", err)
|
||||
}
|
||||
|
||||
// Write the config to a temp file.
|
||||
// TODO(jason): This is kind of gross, but Melange's build API requires a file path.
|
||||
tmp, err := os.CreateTemp("", fmt.Sprintf("%s-*.yaml", cfg.Package.Name))
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("creating temporary file: %v", err)
|
||||
return fmt.Errorf("creating temporary file: %v", err)
|
||||
}
|
||||
if err := os.WriteFile(tmp.Name(), []byte(data.ConfigContents.ValueString()), 0644); err != nil {
|
||||
return "", fmt.Errorf("writing config to temporary file: %v", err)
|
||||
return fmt.Errorf("writing config to temporary file: %v", err)
|
||||
}
|
||||
|
||||
tflog.Trace(ctx, fmt.Sprintf("will build %s for %s", cfg.Package.Name, arch))
|
||||
|
|
@ -195,7 +221,7 @@ func (r *BuildResource) doBuild(ctx context.Context, data BuildResourceModel) (s
|
|||
build.WithGenerateIndex(true),
|
||||
)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("building %s for %s: %w", cfg.Package.Name, arch, err)
|
||||
return fmt.Errorf("building %s for %s: %w", cfg.Package.Name, arch, err)
|
||||
}
|
||||
bcs = append(bcs, bc)
|
||||
}
|
||||
|
|
@ -207,14 +233,7 @@ func (r *BuildResource) doBuild(ctx context.Context, data BuildResourceModel) (s
|
|||
})
|
||||
}
|
||||
if err := errg.Wait(); err != nil {
|
||||
return "", err
|
||||
return err
|
||||
}
|
||||
|
||||
// ID is the sha256 of the JSON-serialized input config,
|
||||
// to ensure the resource is updated if the changes.
|
||||
b, err := json.Marshal(data.Config)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return fmt.Sprintf("%x", sha256.Sum256(b)), nil
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,7 +49,8 @@ resource "melange_build" "build" {
|
|||
}`,
|
||||
Check: resource.ComposeAggregateTestCheckFunc(
|
||||
resource.TestCheckResourceAttr("melange_build.build", "config.package.name", "minimal"),
|
||||
//resource.TestCheckResourceAttr("melange_build.build", "id", "44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a"),
|
||||
resource.TestCheckResourceAttr("melange_build.build", "config.package.epoch", "3"),
|
||||
resource.TestCheckResourceAttr("melange_build.build", "id", "2966ff23365b2bfb14798021109424102419b989b044778d5484297ade1b201b"),
|
||||
),
|
||||
}},
|
||||
})
|
||||
|
|
@ -90,4 +91,56 @@ resource "melange_build" "build" {
|
|||
t.Errorf("checksum mismatch: %v != %v", idx.Packages[0].Checksum, pkg.Checksum)
|
||||
}
|
||||
// TODO(jason): Check that index is signed with the key.
|
||||
|
||||
// Update the resource to bump the epoch.
|
||||
resource.Test(t, resource.TestCase{
|
||||
ProtoV6ProviderFactories: providerFactories,
|
||||
Steps: []resource.TestStep{{
|
||||
Config: `
|
||||
data "melange_config" "minimal" {
|
||||
config_contents = file("${path.module}/testdata/minimal.yaml")
|
||||
}
|
||||
|
||||
// Simulate bumping the epoch.
|
||||
locals {
|
||||
updated = merge(data.melange_config.minimal.config, {
|
||||
package = {
|
||||
name = "minimal"
|
||||
version = "0.0.1"
|
||||
epoch = 4
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
resource "melange_build" "build" {
|
||||
config = local.updated
|
||||
config_contents = yamlencode(local.updated)
|
||||
}`,
|
||||
Check: resource.ComposeAggregateTestCheckFunc(
|
||||
resource.TestCheckResourceAttr("melange_build.build", "config.package.name", "minimal"),
|
||||
resource.TestCheckResourceAttr("melange_build.build", "config.package.epoch", "4"),
|
||||
resource.TestCheckResourceAttr("melange_build.build", "id", "1e44061d052789d741503299f4bb0fa37311dfb9df24f373994e6b95c0fe664c"),
|
||||
),
|
||||
}},
|
||||
})
|
||||
|
||||
// Check the new apk.
|
||||
{
|
||||
fn := fmt.Sprintf("packages/%s/minimal-0.0.1-r4.apk", arch)
|
||||
f, err := os.Open(fn)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to open apk: %v", err)
|
||||
}
|
||||
defer f.Close()
|
||||
pkg, err := repository.ParsePackage(f)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to parse apk: %v", err)
|
||||
}
|
||||
if pkg.Name != "minimal" {
|
||||
t.Errorf("unexpected package name: %v", pkg.Name)
|
||||
}
|
||||
if pkg.Version != "0.0.1-r4" {
|
||||
t.Errorf("unexpected package version: %v", pkg.Version)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue