2020-05-17 02:31:38 +03:00
// Copyright 2020 The Gitea Authors. All rights reserved.
2022-11-27 21:20:29 +03:00
// SPDX-License-Identifier: MIT
2020-05-17 02:31:38 +03:00
package cron
import (
"context"
"time"
2022-08-25 05:31:57 +03:00
activities_model "code.gitea.io/gitea/models/activities"
2022-10-17 02:29:26 +03:00
"code.gitea.io/gitea/models/system"
2021-11-24 12:49:20 +03:00
user_model "code.gitea.io/gitea/models/user"
2022-10-23 17:44:45 +03:00
"code.gitea.io/gitea/modules/git"
2023-08-17 17:05:17 +03:00
issue_indexer "code.gitea.io/gitea/modules/indexer/issues"
2020-05-17 02:31:38 +03:00
"code.gitea.io/gitea/modules/setting"
2021-10-21 19:10:49 +03:00
"code.gitea.io/gitea/modules/updatechecker"
2024-03-04 11:57:39 +03:00
asymkey_service "code.gitea.io/gitea/services/asymkey"
2021-11-16 16:30:11 +03:00
repo_service "code.gitea.io/gitea/services/repository"
2021-12-06 10:19:28 +03:00
archiver_service "code.gitea.io/gitea/services/repository/archiver"
2021-11-18 20:42:27 +03:00
user_service "code.gitea.io/gitea/services/user"
2020-05-17 02:31:38 +03:00
)
func registerDeleteInactiveUsers ( ) {
RegisterTaskFatal ( "delete_inactive_accounts" , & OlderThanConfig {
BaseConfig : BaseConfig {
Enabled : false ,
RunAtStart : false ,
Schedule : "@annually" ,
} ,
2022-05-13 15:49:22 +03:00
OlderThan : time . Minute * time . Duration ( setting . Service . ActiveCodeLives ) ,
2021-11-24 12:49:20 +03:00
} , func ( ctx context . Context , _ * user_model . User , config Config ) error {
2020-05-17 02:31:38 +03:00
olderThanConfig := config . ( * OlderThanConfig )
2021-11-18 20:42:27 +03:00
return user_service . DeleteInactiveUsers ( ctx , olderThanConfig . OlderThan )
2020-05-17 02:31:38 +03:00
} )
}
func registerDeleteRepositoryArchives ( ) {
RegisterTaskFatal ( "delete_repo_archives" , & BaseConfig {
Enabled : false ,
RunAtStart : false ,
Schedule : "@annually" ,
2021-11-24 12:49:20 +03:00
} , func ( ctx context . Context , _ * user_model . User , _ Config ) error {
2021-12-06 10:19:28 +03:00
return archiver_service . DeleteRepositoryArchives ( ctx )
2020-05-17 02:31:38 +03:00
} )
}
func registerGarbageCollectRepositories ( ) {
type RepoHealthCheckConfig struct {
BaseConfig
Timeout time . Duration
Args [ ] string ` delim:" " `
}
RegisterTaskFatal ( "git_gc_repos" , & RepoHealthCheckConfig {
BaseConfig : BaseConfig {
Enabled : false ,
RunAtStart : false ,
Schedule : "@every 72h" ,
} ,
Timeout : time . Duration ( setting . Git . Timeout . GC ) * time . Second ,
Args : setting . Git . GCArgs ,
2021-11-24 12:49:20 +03:00
} , func ( ctx context . Context , _ * user_model . User , config Config ) error {
2020-05-17 02:31:38 +03:00
rhcConfig := config . ( * RepoHealthCheckConfig )
2022-10-23 17:44:45 +03:00
// the git args are set by config, they can be safe to be trusted
Refactor git command package to improve security and maintainability (#22678)
This PR follows #21535 (and replace #22592)
## Review without space diff
https://github.com/go-gitea/gitea/pull/22678/files?diff=split&w=1
## Purpose of this PR
1. Make git module command completely safe (risky user inputs won't be
passed as argument option anymore)
2. Avoid low-level mistakes like
https://github.com/go-gitea/gitea/pull/22098#discussion_r1045234918
3. Remove deprecated and dirty `CmdArgCheck` function, hide the `CmdArg`
type
4. Simplify code when using git command
## The main idea of this PR
* Move the `git.CmdArg` to the `internal` package, then no other package
except `git` could use it. Then developers could never do
`AddArguments(git.CmdArg(userInput))` any more.
* Introduce `git.ToTrustedCmdArgs`, it's for user-provided and already
trusted arguments. It's only used in a few cases, for example: use git
arguments from config file, help unit test with some arguments.
* Introduce `AddOptionValues` and `AddOptionFormat`, they make code more
clear and simple:
* Before: `AddArguments("-m").AddDynamicArguments(message)`
* After: `AddOptionValues("-m", message)`
* -
* Before: `AddArguments(git.CmdArg(fmt.Sprintf("--author='%s <%s>'",
sig.Name, sig.Email)))`
* After: `AddOptionFormat("--author='%s <%s>'", sig.Name, sig.Email)`
## FAQ
### Why these changes were not done in #21535 ?
#21535 is mainly a search&replace, it did its best to not change too
much logic.
Making the framework better needs a lot of changes, so this separate PR
is needed as the second step.
### The naming of `AddOptionXxx`
According to git's manual, the `--xxx` part is called `option`.
### How can it guarantee that `internal.CmdArg` won't be not misused?
Go's specification guarantees that. Trying to access other package's
internal package causes compilation error.
And, `golangci-lint` also denies the git/internal package. Only the
`git/command.go` can use it carefully.
### There is still a `ToTrustedCmdArgs`, will it still allow developers
to make mistakes and pass untrusted arguments?
Generally speaking, no. Because when using `ToTrustedCmdArgs`, the code
will be very complex (see the changes for examples). Then developers and
reviewers can know that something might be unreasonable.
### Why there was a `CmdArgCheck` and why it's removed?
At the moment of #21535, to reduce unnecessary changes, `CmdArgCheck`
was introduced as a hacky patch. Now, almost all code could be written
as `cmd := NewCommand(); cmd.AddXxx(...)`, then there is no need for
`CmdArgCheck` anymore.
### Why many codes for `signArg == ""` is deleted?
Because in the old code, `signArg` could never be empty string, it's
either `-S[key-id]` or `--no-gpg-sign`. So the `signArg == ""` is just
dead code.
---------
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
2023-02-04 05:30:43 +03:00
return repo_service . GitGcRepos ( ctx , rhcConfig . Timeout , git . ToTrustedCmdArgs ( rhcConfig . Args ) )
2020-05-17 02:31:38 +03:00
} )
}
func registerRewriteAllPublicKeys ( ) {
RegisterTaskFatal ( "resync_all_sshkeys" , & BaseConfig {
Enabled : false ,
RunAtStart : false ,
Schedule : "@every 72h" ,
2023-09-25 16:17:37 +03:00
} , func ( ctx context . Context , _ * user_model . User , _ Config ) error {
2024-03-04 11:57:39 +03:00
return asymkey_service . RewriteAllPublicKeys ( ctx )
2020-05-17 02:31:38 +03:00
} )
}
2020-10-11 03:38:09 +03:00
func registerRewriteAllPrincipalKeys ( ) {
RegisterTaskFatal ( "resync_all_sshprincipals" , & BaseConfig {
Enabled : false ,
RunAtStart : false ,
Schedule : "@every 72h" ,
2023-09-25 16:17:37 +03:00
} , func ( ctx context . Context , _ * user_model . User , _ Config ) error {
2024-03-04 11:57:39 +03:00
return asymkey_service . RewriteAllPrincipalKeys ( ctx )
2020-10-11 03:38:09 +03:00
} )
}
2020-05-17 02:31:38 +03:00
func registerRepositoryUpdateHook ( ) {
RegisterTaskFatal ( "resync_all_hooks" , & BaseConfig {
Enabled : false ,
RunAtStart : false ,
Schedule : "@every 72h" ,
2021-11-24 12:49:20 +03:00
} , func ( ctx context . Context , _ * user_model . User , _ Config ) error {
2021-11-17 18:17:31 +03:00
return repo_service . SyncRepositoryHooks ( ctx )
2020-05-17 02:31:38 +03:00
} )
}
func registerReinitMissingRepositories ( ) {
RegisterTaskFatal ( "reinit_missing_repos" , & BaseConfig {
Enabled : false ,
RunAtStart : false ,
Schedule : "@every 72h" ,
2021-11-24 12:49:20 +03:00
} , func ( ctx context . Context , _ * user_model . User , _ Config ) error {
2021-11-24 10:56:24 +03:00
return repo_service . ReinitMissingRepositories ( ctx )
2020-05-17 02:31:38 +03:00
} )
}
func registerDeleteMissingRepositories ( ) {
RegisterTaskFatal ( "delete_missing_repos" , & BaseConfig {
Enabled : false ,
RunAtStart : false ,
Schedule : "@every 72h" ,
2021-11-24 12:49:20 +03:00
} , func ( ctx context . Context , user * user_model . User , _ Config ) error {
2021-11-24 10:56:24 +03:00
return repo_service . DeleteMissingRepositories ( ctx , user )
2020-05-17 02:31:38 +03:00
} )
}
func registerRemoveRandomAvatars ( ) {
RegisterTaskFatal ( "delete_generated_repository_avatars" , & BaseConfig {
Enabled : false ,
RunAtStart : false ,
Schedule : "@every 72h" ,
2021-11-24 12:49:20 +03:00
} , func ( ctx context . Context , _ * user_model . User , _ Config ) error {
2021-12-12 18:48:20 +03:00
return repo_service . RemoveRandomAvatars ( ctx )
2020-05-17 02:31:38 +03:00
} )
}
2021-05-01 15:17:02 +03:00
func registerDeleteOldActions ( ) {
RegisterTaskFatal ( "delete_old_actions" , & OlderThanConfig {
BaseConfig : BaseConfig {
Enabled : false ,
RunAtStart : false ,
Schedule : "@every 168h" ,
} ,
OlderThan : 365 * 24 * time . Hour ,
2021-11-24 12:49:20 +03:00
} , func ( ctx context . Context , _ * user_model . User , config Config ) error {
2021-05-01 15:17:02 +03:00
olderThanConfig := config . ( * OlderThanConfig )
2023-09-29 15:12:54 +03:00
return activities_model . DeleteOldActions ( ctx , olderThanConfig . OlderThan )
2021-05-01 15:17:02 +03:00
} )
}
2021-10-16 09:14:34 +03:00
func registerUpdateGiteaChecker ( ) {
type UpdateCheckerConfig struct {
BaseConfig
HTTPEndpoint string
}
RegisterTaskFatal ( "update_checker" , & UpdateCheckerConfig {
BaseConfig : BaseConfig {
Enabled : true ,
RunAtStart : false ,
Schedule : "@every 168h" ,
} ,
2023-06-21 06:11:17 +03:00
HTTPEndpoint : "https://dl.gitea.com/gitea/version.json" ,
2021-11-24 12:49:20 +03:00
} , func ( ctx context . Context , _ * user_model . User , config Config ) error {
2021-10-16 09:14:34 +03:00
updateCheckerConfig := config . ( * UpdateCheckerConfig )
2021-10-21 19:10:49 +03:00
return updatechecker . GiteaUpdateChecker ( updateCheckerConfig . HTTPEndpoint )
2021-10-16 09:14:34 +03:00
} )
}
2022-03-28 15:54:59 +03:00
func registerDeleteOldSystemNotices ( ) {
RegisterTaskFatal ( "delete_old_system_notices" , & OlderThanConfig {
BaseConfig : BaseConfig {
Enabled : false ,
RunAtStart : false ,
Schedule : "@every 168h" ,
} ,
OlderThan : 365 * 24 * time . Hour ,
} , func ( ctx context . Context , _ * user_model . User , config Config ) error {
olderThanConfig := config . ( * OlderThanConfig )
2023-09-25 16:17:37 +03:00
return system . DeleteOldSystemNotices ( ctx , olderThanConfig . OlderThan )
2022-03-28 15:54:59 +03:00
} )
}
2023-01-16 22:50:53 +03:00
func registerGCLFS ( ) {
if ! setting . LFS . StartServer {
return
}
type GCLFSConfig struct {
OlderThanConfig
LastUpdatedMoreThanAgo time . Duration
NumberToCheckPerRepo int64
ProportionToCheckPerRepo float64
}
RegisterTaskFatal ( "gc_lfs" , & GCLFSConfig {
OlderThanConfig : OlderThanConfig {
BaseConfig : BaseConfig {
Enabled : false ,
RunAtStart : false ,
Schedule : "@every 24h" ,
} ,
// Only attempt to garbage collect lfs meta objects older than a week as the order of git lfs upload
// and git object upload is not necessarily guaranteed. It's possible to imagine a situation whereby
// an LFS object is uploaded but the git branch is not uploaded immediately, or there are some rapid
// changes in new branches that might lead to lfs objects becoming temporarily unassociated with git
// objects.
//
// It is likely that a week is potentially excessive but it should definitely be enough that any
// unassociated LFS object is genuinely unassociated.
OlderThan : 24 * time . Hour * 7 ,
} ,
// Only GC things that haven't been looked at in the past 3 days
LastUpdatedMoreThanAgo : 24 * time . Hour * 3 ,
NumberToCheckPerRepo : 100 ,
ProportionToCheckPerRepo : 0.6 ,
} , func ( ctx context . Context , _ * user_model . User , config Config ) error {
gcLFSConfig := config . ( * GCLFSConfig )
return repo_service . GarbageCollectLFSMetaObjects ( ctx , repo_service . GarbageCollectLFSMetaObjectsOptions {
AutoFix : true ,
OlderThan : time . Now ( ) . Add ( - gcLFSConfig . OlderThan ) ,
UpdatedLessRecentlyThan : time . Now ( ) . Add ( - gcLFSConfig . LastUpdatedMoreThanAgo ) ,
} )
} )
}
2023-08-17 17:05:17 +03:00
func registerRebuildIssueIndexer ( ) {
RegisterTaskFatal ( "rebuild_issue_indexer" , & BaseConfig {
Enabled : false ,
RunAtStart : false ,
Schedule : "@annually" ,
} , func ( ctx context . Context , _ * user_model . User , config Config ) error {
2023-10-15 21:56:57 +03:00
return issue_indexer . PopulateIssueIndexer ( ctx )
2023-08-17 17:05:17 +03:00
} )
}
2020-05-17 02:31:38 +03:00
func initExtendedTasks ( ) {
registerDeleteInactiveUsers ( )
registerDeleteRepositoryArchives ( )
registerGarbageCollectRepositories ( )
registerRewriteAllPublicKeys ( )
2020-10-11 03:38:09 +03:00
registerRewriteAllPrincipalKeys ( )
2020-05-17 02:31:38 +03:00
registerRepositoryUpdateHook ( )
registerReinitMissingRepositories ( )
registerDeleteMissingRepositories ( )
registerRemoveRandomAvatars ( )
2021-05-01 15:17:02 +03:00
registerDeleteOldActions ( )
2021-10-16 09:14:34 +03:00
registerUpdateGiteaChecker ( )
2022-03-28 15:54:59 +03:00
registerDeleteOldSystemNotices ( )
2023-01-16 22:50:53 +03:00
registerGCLFS ( )
2023-08-17 17:05:17 +03:00
registerRebuildIssueIndexer ( )
2020-05-17 02:31:38 +03:00
}