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

Add Terraform State Locking/Unlocking Support for Gitea #33277

Open
wants to merge 11 commits into
base: main
Choose a base branch
from

Conversation

shurkys
Copy link

@shurkys shurkys commented Jan 15, 2025

Summary

This PR introduces a new functionality to Gitea's package management system, enabling the use of Terraform state locking and unlocking. The integration is designed to allow Terraform to manage the state of resources stored in Gitea, ensuring that multiple users cannot modify the same state file simultaneously.

Background

To support Terraform's state commands (such as terraform plan, terraform apply, etc.) in a collaborative environment, it's essential to ensure that state files are locked when being updated and unlocked when the operation is complete. This PR allows Gitea to serve as a backend for Terraform's state management system, implementing these critical features.

Key Features

  • State Locking: Prevents multiple users or processes from concurrently modifying the same state file.
  • State Unlocking: Releases the lock after the state has been updated, allowing other users or processes to access it.
  • Custom API Integration: Utilizes Gitea's API to handle state file operations (locking, unlocking, and storing) in a consistent manner.
  • Backend Configuration: Terraform users can configure their terraform init and terraform state commands to interact with Gitea as a backend for state management.

Changes

  1. Lock and Unlock APIs:

    • New endpoints added to Gitea for locking (POST) and unlocking (DELETE) state files.
  2. Terraform Configuration:

    • Users can configure their Terraform setup to use Gitea for managing state files and state locks using custom backend settings.

Terraform Configuration Example

The following configuration demonstrates how to set up Terraform to use Gitea for state locking and unlocking:

export GITEA_USER_PASSWORD=<YOUR-USER-PASSWORD>
export TF_STATE_NAME=your-state.tfstate

terraform init \
    -backend-config="address=http://192.168.1.10:3000/api/packages/username/terraform/state/$TF_STATE_NAME" \
    -backend-config="lock_address=http://192.168.1.10:3000/api/packages/username/terraform/state/$TF_STATE_NAME/lock" \
    -backend-config="unlock_address=http://192.168.1.10:3000/api/packages/username/terraform/state/$TF_STATE_NAME/lock" \
    -backend-config="username=username" \
    -backend-config="password=$GITEA_USER_PASSWORD" \
    -backend-config="lock_method=POST" \
    -backend-config="unlock_method=DELETE" \
    -backend-config="retry_wait_min=5"

Configuration Breakdown

  • Address: The URL where the Terraform state is stored in Gitea.
  • Lock Address: The URL for acquiring a lock on the state file before modifying it.
  • Unlock Address: The URL for releasing the lock after modifications are complete.
  • Lock Method: Specifies the HTTP method (POST) to use for acquiring the lock.
  • Unlock Method: Specifies the HTTP method (DELETE) to use for releasing the lock.
  • Retry Wait: Defines the retry interval (in minutes) before trying to acquire the lock again.

Benefits

  • Ensures state file integrity by preventing race conditions.
  • Provides an easy-to-use Terraform backend solution integrated with Gitea.
  • Improves collaboration in teams working with shared Terraform state files.

Testing

  • Successfully tested with the Terraform CLI on a local setup using the provided configuration.
  • Locking and unlocking operations were verified to work as expected when interacting with Gitea.

Additional Notes

  • The state lock is implemented using a simple in-memory store in Gitea.
  • The lock can be acquired by providing a unique lock ID, preventing conflicts between multiple users or processes.

Reviewers

Please provide your feedback or approval for merging this new functionality into the Gitea codebase.

@GiteaBot GiteaBot added the lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. label Jan 15, 2025
@pull-request-size pull-request-size bot added the size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. label Jan 15, 2025
@github-actions github-actions bot added modifies/api This PR adds API routes or modifies them modifies/go Pull requests that update Go code modifies/templates This PR modifies the template files labels Jan 15, 2025
@techknowlogick
Copy link
Member

Amazing! Thanks! I haven't looked at the code yet, but I was thinking about this the other day so it's very exciting that you were working on this.

@lunny lunny added this to the 1.24.0 milestone Jan 15, 2025
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
@techknowlogick
Copy link
Member

CI status seems related:

 --- FAIL: TestPackageTerraform/Authenticate (0.00s)
        api_packages_terraform_test.go:64: Response:  404 page not found
            
        testlogger.go:62: 2025/01/15 03:04:03 ...eb/routing/logger.go:102:func1() [I] router: completed GET /api/packages/user2/terraform/authenticate for test-mock:12345, 404 Not Found in 0.3ms @ http/server.go:2256(GlobalNotFound)
        api_packages_terraform_test.go:64: 
            	Error Trace:	/home/runner/work/gitea/gitea/tests/integration/integration_test.go:373
            	            				/home/runner/work/gitea/gitea/tests/integration/api_packages_terraform_test.go:64
            	Error:      	Not equal: 
            	            	expected: 401
            	            	actual  : 404
            	Test:       	TestPackageTerraform/Authenticate
            	Messages:   	Request: GET /api/packages/user2/terraform/authenticate
    --- FAIL: TestPackageTerraform/Upload (0.00s)
        api_packages_terraform_test.go:82: Response:  404 page not found
            
        api_packages_terraform_test.go:82: 
            	Error Trace:	/home/runner/work/gitea/gitea/tests/integration/integration_test.go:373
            	            				/home/runner/work/gitea/gitea/tests/integration/api_packages_terraform_test.go:82
            	Error:      	Not equal: 
            	            	expected: 401
            	            	actual  : 404
            	Test:       	TestPackageTerraform/Upload
            	Messages:   	Request: PUT /api/packages/user2/terraform/test_module/1.0.1/terraform_module.tar.gz
    --- FAIL: TestPackageTerraform/Download (0.00s)
        api_packages_terraform_test.go:122: Response:  404 page not found
            
        api_packages_terraform_test.go:122: 
            	Error Trace:	/home/runner/work/gitea/gitea/tests/integration/integration_test.go:373
            	            				/home/runner/work/gitea/gitea/tests/integration/api_packages_terraform_test.go:122
            	Error:      	Not equal: 
            	            	expected: 200
            	            	actual  : 404
            	Test:       	TestPackageTerraform/Download
            	Messages:   	Request: GET /api/packages/user2/terraform/test_module/1.0.1/terraform_module.tar.gz
    --- FAIL: TestPackageTerraform/EnumeratePackageVersions (0.00s)
        api_packages_terraform_test.go:131: Response:  404 page not found
            
        api_packages_terraform_test.go:131: 
            	Error Trace:	/home/runner/work/gitea/gitea/tests/integration/integration_test.go:373
            	            				/home/runner/work/gitea/gitea/tests/integration/api_packages_terraform_test.go:131
            	Error:      	Not equal: 
            	            	expected: 200
            	            	actual  : 404
            	Test:       	TestPackageTerraform/EnumeratePackageVersions
            	Messages:   	Request: GET /api/packages/user2/terraform/test_module

@shurkys
Copy link
Author

shurkys commented Jan 17, 2025

CI status seems related:

Yes, I’m not a programmer and I'm having difficulties with the tests. I haven't been able to figure out what's wrong yet.

@techknowlogick
Copy link
Member

Yes, I’m not a programmer and I'm having difficulties with the tests. I haven't been able to figure out what's wrong yet.

That's quite alright:) If you need any pointers, or have any questions about the codebase please feel free to ask and we'd love to help. Definitely appreciate that you added tests <3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. modifies/api This PR adds API routes or modifies them modifies/go Pull requests that update Go code modifies/templates This PR modifies the template files size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. topic/packages
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants