Skip to content
This repository has been archived by the owner on Aug 15, 2023. It is now read-only.

Add a simple GCS storage impl #3

Merged
merged 5 commits into from
Aug 24, 2022
Merged

Conversation

KengoTODA
Copy link
Contributor

Hello, thanks for sharing so great product with us, and keep it open for contribution! 🙌
Here I want to share my idea to add a simple storage implementation for GCS (Google Cloud Storage).

Unlike minamijoyo/tfmigrate#23, this PR keeps its feature very simple. There are only three configurations, and the credential must be provided via GOOGLE_APPLICATION_CREDENTIALS. There is no way to bypass the authentication.
I confirm that this implementation is working with actual GCS service, you may refer my diff in the tfmigrate repo to grasp how I edit tfmigrate core to integrate.

I hope that this PR will be an enough small start for the community, to enjoy daily hacking with GCP.
Thanks for your review! 😄

gcStorage "cloud.google.com/go/storage"
)

type Client interface {
Copy link
Owner

Choose a reason for hiding this comment

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

Add GoDoc style comments to all public interfaces, types, and methods.

gcs/client.go Outdated Show resolved Hide resolved
gcs/client.go Outdated Show resolved Hide resolved
if err != nil {
return fmt.Errorf("failed writing to gcs://%s/%s: %w", a.config.Bucket, a.config.Name, err)
}
return w.Close()
Copy link
Owner

Choose a reason for hiding this comment

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

I think we need to use defer w.Close() to close the Writer on error. Is there any reason to implement it differently than Read?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is because:

  1. We do not care the error returned by r.Close() because io.readAll(r) has already handled its responsibility. In other words, after io.readAll(r) worked properlly, we do not care that r.Close() returns error or not.
  2. We do care the error returned by w.Close(), because it may mean that we failed to write/flush data to storage (GCS in this case). Even when w.Write(...) completed successfully, it may buffer the written data internally so we cannot say it is successfully saved onto the storage.

For reference, a sample code in the official document handles error in the same manner:

// Write some text to obj. This will either create the object or overwrite whatever is there already.
if _, err := fmt.Fprintf(w, "This object contains text.\n"); err != nil {
    // TODO: Handle error.
}
// Close, just like writing a file.
if err := w.Close(); err != nil {
    // TODO: Handle error.
}

// Read it back.
r, err := obj.NewReader(ctx)
if err != nil {
    // TODO: Handle error.
}
defer r.Close()

Copy link
Owner

Choose a reason for hiding this comment

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

Got it.

Though it’s technically possible to return an error from a defer function by using a named return value in general, I don’t have much knowledge about the GCS library implementation. It’s better to follow an official example unless we hit an actual issue.

@minamijoyo
Copy link
Owner

@KengoTODA Thank you for working on this!

I agree with you that it's reasonable to start with the minimum options you need.
For implementations, I have left some review comments. Please check them.

@KengoTODA
Copy link
Contributor Author

Thanks for your feedback, @minamijoyo!
I've reflected you review onto this implementation, please check it later :)

@KengoTODA KengoTODA requested a review from minamijoyo August 24, 2022 01:53
Copy link
Owner

@minamijoyo minamijoyo left a comment

Choose a reason for hiding this comment

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

LGTM 👍

@minamijoyo minamijoyo merged commit 6dd8f2f into minamijoyo:master Aug 24, 2022
@minamijoyo
Copy link
Owner

@KengoTODA I’ve merged the storage part. Thank you!
Could you open a pull request to the tfmigrate repository to expose the new feature?

@KengoTODA
Copy link
Contributor Author

Could you open a pull request to the tfmigrate repository to expose the new feature?

I've created minamijoyo/tfmigrate#103
Please check when you have time!

minamijoyo added a commit that referenced this pull request Aug 15, 2023
I originally wrote the local and s3 storage implementation for tfmigrate
as the MIT license. Next, someone sent me a patch for gcs storage
implementation minamijoyo/tfmigrate#23, copied
from the upstream terraform backend implementation. I was concerned it
would violate the MPL2 license because the tfmigrate' license is MIT,
and terraform's is MPL2.

So I split the storage implementations
minamijoyo/tfmigrate#80 into a separate
https://github.com/minamijoyo/tfmigrate-storage repository and
relicensed it as MPL2 so that someone could easily copy snippets from
the upstream. However, we could not contact that patch's author and the
initial patch was not merged finally.

Time passed, KengoTODA sent me another patch
#3 for gcs support
which contained minimal functionality and was not copied from upstream.
This patch has finally been accepted and merged.

That is, I've changed the license of the storage implementation with the
intention that it will contain a derivative work of terraform that can
be easily copied from terraform's backend implementation to extend
various storage types, but this has yet to happen. It's clearly far from
the terraform's implementation at the time of writing.

Recently, HashiCorp announced that it would change the license of its
products, including Terraform, from MPL2 to BSL1.1.
https://www.hashicorp.com/blog/hashicorp-adopts-business-source-license

If, as I originally intended, we allow contributors to copy code from
upstream terraform, the tfmigrate-storage repository must also be
changed to BSL. This means that the tfmigrate source can continue to be
distributed as MIT, but the tfmigrate's binary will be bounded by BSL.
Even though HashiCorp's BSL is a reasonably permissive license with no
restrictions other than HashiCorp's competitors, it is no longer
open-source by OSI definition. I want to continue to keep tfmigrate as
an open-source project.

Technically, it is possible to keep the tfmigrate-storage repository as
MPL2. Still, I no longer have a solid reason to do so; it is just
inconvenient to have a separate repository.

Fortunately, KengoTODA and I are still the only contributors to the
tfmigrate-storage repository, and I got permission from KengoTODA to
re-license his patch as MIT in
minamijoyo/tfmigrate#146.

So, I'm going to change the license of the tfmigrate-storage repository
to MIT and will merge it into the tfmigrate repository.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants