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

[sdk/go] Ensure Assets of AssetArchive are non-nil when creating and deserializing #14007

Merged
merged 1 commit into from Sep 22, 2023

Conversation

Zaid-Ajaj
Copy link
Contributor

@Zaid-Ajaj Zaid-Ajaj commented Sep 21, 2023

Fixes #11103

The problem in the issue the distinction between Assets or an archive being nil vs. being an empty map of assets. When creating and deserializing Archives, nil was allowed which leads to panics when asserting archive.IsAssets() because the Assets is nil even though it is a proper archive.

This PR fixes the issue by ensuring that an instance of Archive will have a non-nil Assets field whether that is during construction or marshalling.

Checklist

  • I have run make tidy to update any new dependencies
  • I have run make lint to verify my code passes the lint check
    • I have formatted my code using gofumpt
  • I have added tests that prove my fix is effective or that my feature works
  • I have run make changelog and committed the changelog/pending/<file> documenting my change
  • Yes, there are changes in this PR that warrants bumping the Pulumi Cloud API version

@Zaid-Ajaj Zaid-Ajaj requested a review from a team September 21, 2023 14:24
@pulumi-bot
Copy link
Contributor

pulumi-bot commented Sep 21, 2023

Changelog

[uncommitted] (2023-09-22)

Bug Fixes

  • [sdk/go] Ensure Assets of AssetArchive are non-nil when creating and deserializing
    #14007

Copy link
Member

@Frassle Frassle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should do a similar fix for Asset


emptyArchive, err := NewAssetArchive(nil)
assert.True(t, emptyArchive.IsAssets(), "even empty archives should be have empty assets")
assert.NoError(t, err, "Creating an empty archive should work")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A) Do the err check first
B) Use require.NoError, generally if we have an error the other asserts will just end up panic'ing (due to like nil access exceptions and the like)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -577,6 +582,10 @@ func (a *Archive) Serialize() map[string]interface{} {
}
}
result[ArchiveAssetsProperty] = assets
} else {
// Ensure that the assets property is always present, even if empty.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The JSON/YAML attributes have omitempty so this would just get dropped anyway. But that's expected we only want the field when this is an asset archive, and if assets is nil then it isn't. i.e. just remove this block.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't notice those since we are dealing with a custom serialization/deserialization here but indeed, this seems redundant so removed this block

if !ok {
return &Archive{}, false, fmt.Errorf("unexpected archive contents of type %T", v)
}
assets := make(map[string]interface{})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure this is safe? Looks like we could create an Archive with assets and path set?

Copy link
Contributor Author

@Zaid-Ajaj Zaid-Ajaj Sep 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated the DeserializeArchive method such that it is not possible to construct conflicting fields:

  • When we check for the path property and it exists, we immediately return NewPathArchive
  • When we check for the uri property and it exists, we immediately return NewURIArchive
  • Finally if we didn't find path nor uri, we get the assets and default to an empty map

At the start of the function, we check that the input object must have one of path, uri or assets

Edit: no longer using New{...}Archive functions, because they recompute the hash, instead just constructing the archive using the deserialized values

@Zaid-Ajaj Zaid-Ajaj force-pushed the zaid/ensure-archive-assets-are-non-nil branch from a31308e to 936d415 Compare September 22, 2023 00:22
@Zaid-Ajaj Zaid-Ajaj changed the title [sdk/go] Ensure Assets of AssetArchive are non-nil when creating, serializing and deserializing [sdk/go] Ensure Assets of AssetArchive are non-nil when creating and deserializing Sep 22, 2023
@Zaid-Ajaj Zaid-Ajaj force-pushed the zaid/ensure-archive-assets-are-non-nil branch 2 times, most recently from 173898a to 320ccd5 Compare September 22, 2023 09:39
@Zaid-Ajaj Zaid-Ajaj force-pushed the zaid/ensure-archive-assets-are-non-nil branch from b689485 to cd259a1 Compare September 22, 2023 13:04
a := &Archive{Sig: ArchiveSig, URI: uri}
err := a.EnsureHash()
return a, err
}

func (a *Archive) IsAssets() bool { return a.Assets != nil }
func (a *Archive) IsAssets() bool { return !a.IsPath() && !a.IsURI() }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should just be a.Assets != nil. Whenever we construct an Archive object we'll ensure it's a non-nil map.

@Zaid-Ajaj Zaid-Ajaj force-pushed the zaid/ensure-archive-assets-are-non-nil branch from 21d4297 to 662301d Compare September 22, 2023 13:18
@Zaid-Ajaj Zaid-Ajaj added this pull request to the merge queue Sep 22, 2023
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Sep 22, 2023
@Zaid-Ajaj Zaid-Ajaj added this pull request to the merge queue Sep 22, 2023
Merged via the queue into master with commit a44a536 Sep 22, 2023
44 checks passed
@Zaid-Ajaj Zaid-Ajaj deleted the zaid/ensure-archive-assets-are-non-nil branch September 22, 2023 16:33
github-merge-queue bot pushed a commit that referenced this pull request Mar 21, 2024
<!--- 
Thanks so much for your contribution! If this is your first time
contributing, please ensure that you have read the
[CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md)
documentation.
-->

# Description

<!--- Please include a summary of the change and which issue is fixed.
Please also include relevant motivation and context. -->

Fixes #15729.

This fixes Assets and Archives to allow four states, as opposed to the
three that #14007 had enforced.

An asset can either be Text, Path, Uri, or none. That is `IsText`,
`IsPath`, and `IsURI` can all return false. Similarly for archives
except with Assets instead of Text.
This happens when a provider returns an Assert (or Archive) with a hash
value set, but no other contents.

The Asset and Archive objects have been updated to handle this case, and
a number of places in the CLI that asserted that one of
IsText/IsPath/IsURI were true have been fixed up to handle the case of
all three being false.

## Checklist

- [x] I have run `make tidy` to update any new dependencies
- [x] I have run `make lint` to verify my code passes the lint check
  - [x] I have formatted my code using `gofumpt`

<!--- Please provide details if the checkbox below is to be left
unchecked. -->
- [x] I have added tests that prove my fix is effective or that my
feature works
<!--- 
User-facing changes require a CHANGELOG entry.
-->
- [x] I have run `make changelog` and committed the
`changelog/pending/<file>` documenting my change
<!--
If the change(s) in this PR is a modification of an existing call to the
Pulumi Cloud,
then the service should honor older versions of the CLI where this
change would not exist.
You must then bump the API version in
/pkg/backend/httpstate/client/api.go, as well as add
it to the service.
-->
- [ ] Yes, there are changes in this PR that warrants bumping the Pulumi
Cloud API version
<!-- @pulumi employees: If yes, you must submit corresponding changes in
the service repo. -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

fatal error while looking into the details of a preview
3 participants