Skip to content

Commit

Permalink
Merge remote-tracking branch 'giteaofficial/main'
Browse files Browse the repository at this point in the history
* giteaofficial/main:
  Support optional/configurable IAMEndpoint for Minio Client (go-gitea#32581) (go-gitea#32581)
  Update the list of watchers and stargazers when clicking watch/unwatch or star/unstar (go-gitea#32570)
  Apply to became a maintainer (go-gitea#32614)
  • Loading branch information
zjjhot committed Nov 23, 2024
2 parents 5fdcb5d + 713364f commit 9cd5b44
Show file tree
Hide file tree
Showing 9 changed files with 61 additions and 15 deletions.
1 change: 1 addition & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,4 @@ Tim-Niclas Oelschläger <[email protected]> (@zokkis)
Yu Liu <[email protected]> (@HEREYUA)
Kemal Zebari <[email protected]> (@kemzeb)
Rowan Bohde <[email protected]> (@bohde)
hiifong <[email protected]> (@hiifong)
14 changes: 14 additions & 0 deletions custom/conf/app.example.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1944,6 +1944,13 @@ LEVEL = Info
;; Minio secretAccessKey to connect only available when STORAGE_TYPE is `minio`
;MINIO_SECRET_ACCESS_KEY =
;;
;; Preferred IAM Endpoint to override Minio's default IAM Endpoint resolution only available when STORAGE_TYPE is `minio`.
;; If not provided and STORAGE_TYPE is `minio`, will search for and derive endpoint from known environment variables
;; (AWS_CONTAINER_AUTHORIZATION_TOKEN, AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE, AWS_CONTAINER_CREDENTIALS_RELATIVE_URI,
;; AWS_CONTAINER_CREDENTIALS_FULL_URI, AWS_WEB_IDENTITY_TOKEN_FILE, AWS_ROLE_ARN, AWS_ROLE_SESSION_NAME, AWS_REGION),
;; or the DefaultIAMRoleEndpoint if not provided otherwise.
;MINIO_IAM_ENDPOINT =
;;
;; Minio bucket to store the attachments only available when STORAGE_TYPE is `minio`
;MINIO_BUCKET = gitea
;;
Expand Down Expand Up @@ -2688,6 +2695,13 @@ LEVEL = Info
;; Minio secretAccessKey to connect only available when STORAGE_TYPE is `minio`
;MINIO_SECRET_ACCESS_KEY =
;;
;; Preferred IAM Endpoint to override Minio's default IAM Endpoint resolution only available when STORAGE_TYPE is `minio`.
;; If not provided and STORAGE_TYPE is `minio`, will search for and derive endpoint from known environment variables
;; (AWS_CONTAINER_AUTHORIZATION_TOKEN, AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE, AWS_CONTAINER_CREDENTIALS_RELATIVE_URI,
;; AWS_CONTAINER_CREDENTIALS_FULL_URI, AWS_WEB_IDENTITY_TOKEN_FILE, AWS_ROLE_ARN, AWS_ROLE_SESSION_NAME, AWS_REGION),
;; or the DefaultIAMRoleEndpoint if not provided otherwise.
;MINIO_IAM_ENDPOINT =
;;
;; Minio bucket to store the attachments only available when STORAGE_TYPE is `minio`
;MINIO_BUCKET = gitea
;;
Expand Down
1 change: 1 addition & 0 deletions modules/setting/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ type MinioStorageConfig struct {
Endpoint string `ini:"MINIO_ENDPOINT" json:",omitempty"`
AccessKeyID string `ini:"MINIO_ACCESS_KEY_ID" json:",omitempty"`
SecretAccessKey string `ini:"MINIO_SECRET_ACCESS_KEY" json:",omitempty"`
IamEndpoint string `ini:"MINIO_IAM_ENDPOINT" json:",omitempty"`
Bucket string `ini:"MINIO_BUCKET" json:",omitempty"`
Location string `ini:"MINIO_LOCATION" json:",omitempty"`
BasePath string `ini:"MINIO_BASE_PATH" json:",omitempty"`
Expand Down
13 changes: 13 additions & 0 deletions modules/setting/storage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,19 @@ MINIO_BASE_PATH = /prefix
cfg, err = NewConfigProviderFromData(`
[storage]
STORAGE_TYPE = minio
MINIO_IAM_ENDPOINT = 127.0.0.1
MINIO_USE_SSL = true
MINIO_BASE_PATH = /prefix
`)
assert.NoError(t, err)
assert.NoError(t, loadRepoArchiveFrom(cfg))
assert.EqualValues(t, "127.0.0.1", RepoArchive.Storage.MinioConfig.IamEndpoint)
assert.EqualValues(t, true, RepoArchive.Storage.MinioConfig.UseSSL)
assert.EqualValues(t, "/prefix/repo-archive/", RepoArchive.Storage.MinioConfig.BasePath)

cfg, err = NewConfigProviderFromData(`
[storage]
STORAGE_TYPE = minio
MINIO_ACCESS_KEY_ID = my_access_key
MINIO_SECRET_ACCESS_KEY = my_secret_key
MINIO_USE_SSL = true
Expand Down
8 changes: 5 additions & 3 deletions modules/storage/minio.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ func NewMinioStorage(ctx context.Context, cfg *setting.Storage) (ObjectStorage,
}

minioClient, err := minio.New(config.Endpoint, &minio.Options{
Creds: buildMinioCredentials(config, credentials.DefaultIAMRoleEndpoint),
Creds: buildMinioCredentials(config),
Secure: config.UseSSL,
Transport: &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: config.InsecureSkipVerify}},
Region: config.Location,
Expand Down Expand Up @@ -164,7 +164,7 @@ func (m *MinioStorage) buildMinioDirPrefix(p string) string {
return p
}

func buildMinioCredentials(config setting.MinioStorageConfig, iamEndpoint string) *credentials.Credentials {
func buildMinioCredentials(config setting.MinioStorageConfig) *credentials.Credentials {
// If static credentials are provided, use those
if config.AccessKeyID != "" {
return credentials.NewStaticV4(config.AccessKeyID, config.SecretAccessKey, "")
Expand All @@ -184,7 +184,9 @@ func buildMinioCredentials(config setting.MinioStorageConfig, iamEndpoint string
&credentials.FileAWSCredentials{},
// read IAM role from EC2 metadata endpoint if available
&credentials.IAM{
Endpoint: iamEndpoint,
// passing in an empty Endpoint lets the IAM Provider
// decide which endpoint to resolve internally
Endpoint: config.IamEndpoint,
Client: &http.Client{
Transport: http.DefaultTransport,
},
Expand Down
21 changes: 13 additions & 8 deletions modules/storage/minio_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,9 @@ func TestMinioCredentials(t *testing.T) {
cfg := setting.MinioStorageConfig{
AccessKeyID: ExpectedAccessKey,
SecretAccessKey: ExpectedSecretAccessKey,
IamEndpoint: FakeEndpoint,
}
creds := buildMinioCredentials(cfg, FakeEndpoint)
creds := buildMinioCredentials(cfg)
v, err := creds.Get()

assert.NoError(t, err)
Expand All @@ -117,13 +118,15 @@ func TestMinioCredentials(t *testing.T) {
})

t.Run("Chain", func(t *testing.T) {
cfg := setting.MinioStorageConfig{}
cfg := setting.MinioStorageConfig{
IamEndpoint: FakeEndpoint,
}

t.Run("EnvMinio", func(t *testing.T) {
t.Setenv("MINIO_ACCESS_KEY", ExpectedAccessKey+"Minio")
t.Setenv("MINIO_SECRET_KEY", ExpectedSecretAccessKey+"Minio")

creds := buildMinioCredentials(cfg, FakeEndpoint)
creds := buildMinioCredentials(cfg)
v, err := creds.Get()

assert.NoError(t, err)
Expand All @@ -135,7 +138,7 @@ func TestMinioCredentials(t *testing.T) {
t.Setenv("AWS_ACCESS_KEY", ExpectedAccessKey+"AWS")
t.Setenv("AWS_SECRET_KEY", ExpectedSecretAccessKey+"AWS")

creds := buildMinioCredentials(cfg, FakeEndpoint)
creds := buildMinioCredentials(cfg)
v, err := creds.Get()

assert.NoError(t, err)
Expand All @@ -144,11 +147,11 @@ func TestMinioCredentials(t *testing.T) {
})

t.Run("FileMinio", func(t *testing.T) {
t.Setenv("MINIO_SHARED_CREDENTIALS_FILE", "testdata/minio.json")
// prevent loading any actual credentials files from the user
t.Setenv("MINIO_SHARED_CREDENTIALS_FILE", "testdata/minio.json")
t.Setenv("AWS_SHARED_CREDENTIALS_FILE", "testdata/fake")

creds := buildMinioCredentials(cfg, FakeEndpoint)
creds := buildMinioCredentials(cfg)
v, err := creds.Get()

assert.NoError(t, err)
Expand All @@ -161,7 +164,7 @@ func TestMinioCredentials(t *testing.T) {
t.Setenv("MINIO_SHARED_CREDENTIALS_FILE", "testdata/fake.json")
t.Setenv("AWS_SHARED_CREDENTIALS_FILE", "testdata/aws_credentials")

creds := buildMinioCredentials(cfg, FakeEndpoint)
creds := buildMinioCredentials(cfg)
v, err := creds.Get()

assert.NoError(t, err)
Expand All @@ -187,7 +190,9 @@ func TestMinioCredentials(t *testing.T) {
defer server.Close()

// Use the provided EC2 Instance Metadata server
creds := buildMinioCredentials(cfg, server.URL)
creds := buildMinioCredentials(setting.MinioStorageConfig{
IamEndpoint: server.URL,
})
v, err := creds.Get()

assert.NoError(t, err)
Expand Down
3 changes: 3 additions & 0 deletions routers/web/repo/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,9 @@ func Action(ctx *context.Context) {
ctx.Data["IsStaringRepo"] = repo_model.IsStaring(ctx, ctx.Doer.ID, ctx.Repo.Repository.ID)
}

// see the `hx-trigger="refreshUserCards ..."` comments in tmpl
ctx.RespHeader().Add("hx-trigger", "refreshUserCards")

switch ctx.PathParam(":action") {
case "watch", "unwatch", "star", "unstar":
// we have to reload the repository because NumStars or NumWatching (used in the templates) has just changed
Expand Down
3 changes: 0 additions & 3 deletions routers/web/repo/view.go
Original file line number Diff line number Diff line change
Expand Up @@ -1123,8 +1123,6 @@ func RenderUserCards(ctx *context.Context, total int, getter func(opts db.ListOp
func Watchers(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("repo.watchers")
ctx.Data["CardsTitle"] = ctx.Tr("repo.watchers")
ctx.Data["PageIsWatchers"] = true

RenderUserCards(ctx, ctx.Repo.Repository.NumWatches, func(opts db.ListOptions) ([]*user_model.User, error) {
return repo_model.GetRepoWatchers(ctx, ctx.Repo.Repository.ID, opts)
}, tplWatchers)
Expand All @@ -1134,7 +1132,6 @@ func Watchers(ctx *context.Context) {
func Stars(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("repo.stargazers")
ctx.Data["CardsTitle"] = ctx.Tr("repo.stargazers")
ctx.Data["PageIsStargazers"] = true
RenderUserCards(ctx, ctx.Repo.Repository.NumStars, func(opts db.ListOptions) ([]*user_model.User, error) {
return repo_model.GetStargazers(ctx, ctx.Repo.Repository, opts)
}, tplWatchers)
Expand Down
12 changes: 11 additions & 1 deletion templates/repo/user_cards.tmpl
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
<div class="user-cards">
<!-- Refresh the content if a htmx response contains "HX-Trigger" header.
This usually happens when a user stays on the watchers/stargazers page
when they watched/unwatched/starred/unstarred and the list should be refreshed.
To test go to the watchers page and click the watch button. The user cards should reload.
At the moment, no JS initialization would re-trigger (fortunately there is no JS for this page).
-->
<div class="no-loading-indicator tw-hidden"></div>
<div class="user-cards"
hx-trigger="refreshUserCards from:body" hx-indicator=".no-loading-indicator"
hx-get="{{$.CurrentURL}}" hx-swap="outerHTML" hx-select=".user-cards"
>
{{if .CardsTitle}}
<h2 class="ui dividing header">
{{.CardsTitle}}
Expand Down

0 comments on commit 9cd5b44

Please sign in to comment.