2020-05-17 01:31:38 +02:00
|
|
|
// Copyright 2020 The Gitea Authors. All rights reserved.
|
2022-11-27 19:20:29 +01:00
|
|
|
// SPDX-License-Identifier: MIT
|
2020-05-17 01:31:38 +02:00
|
|
|
|
|
|
|
package cron
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"code.gitea.io/gitea/models"
|
2022-06-12 17:51:54 +02:00
|
|
|
git_model "code.gitea.io/gitea/models/git"
|
2021-11-24 10:49:20 +01:00
|
|
|
user_model "code.gitea.io/gitea/models/user"
|
2021-11-10 06:13:16 +01:00
|
|
|
"code.gitea.io/gitea/models/webhook"
|
2022-10-23 16:44:45 +02:00
|
|
|
"code.gitea.io/gitea/modules/git"
|
2020-12-21 15:39:41 +01:00
|
|
|
"code.gitea.io/gitea/modules/setting"
|
2021-07-24 12:16:34 +02:00
|
|
|
"code.gitea.io/gitea/services/auth"
|
2021-11-16 16:25:33 +01:00
|
|
|
"code.gitea.io/gitea/services/migrations"
|
2020-05-17 01:31:38 +02:00
|
|
|
mirror_service "code.gitea.io/gitea/services/mirror"
|
2023-02-05 11:12:31 +01:00
|
|
|
packages_cleanup_service "code.gitea.io/gitea/services/packages/cleanup"
|
2021-12-06 08:19:28 +01:00
|
|
|
repo_service "code.gitea.io/gitea/services/repository"
|
|
|
|
archiver_service "code.gitea.io/gitea/services/repository/archiver"
|
2020-05-17 01:31:38 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
func registerUpdateMirrorTask() {
|
2021-11-23 04:09:35 +01:00
|
|
|
type UpdateMirrorTaskConfig struct {
|
|
|
|
BaseConfig
|
|
|
|
PullLimit int
|
|
|
|
PushLimit int
|
|
|
|
}
|
|
|
|
|
|
|
|
RegisterTaskFatal("update_mirrors", &UpdateMirrorTaskConfig{
|
|
|
|
BaseConfig: BaseConfig{
|
2022-03-26 22:13:04 +01:00
|
|
|
Enabled: true,
|
|
|
|
RunAtStart: false,
|
|
|
|
Schedule: "@every 10m",
|
2021-11-23 04:09:35 +01:00
|
|
|
},
|
|
|
|
PullLimit: 50,
|
|
|
|
PushLimit: 50,
|
2021-11-24 10:49:20 +01:00
|
|
|
}, func(ctx context.Context, _ *user_model.User, cfg Config) error {
|
2021-11-23 04:09:35 +01:00
|
|
|
umtc := cfg.(*UpdateMirrorTaskConfig)
|
|
|
|
return mirror_service.Update(ctx, umtc.PullLimit, umtc.PushLimit)
|
2020-05-17 01:31:38 +02:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func registerRepoHealthCheck() {
|
|
|
|
type RepoHealthCheckConfig struct {
|
|
|
|
BaseConfig
|
|
|
|
Timeout time.Duration
|
|
|
|
Args []string `delim:" "`
|
|
|
|
}
|
|
|
|
RegisterTaskFatal("repo_health_check", &RepoHealthCheckConfig{
|
|
|
|
BaseConfig: BaseConfig{
|
|
|
|
Enabled: true,
|
|
|
|
RunAtStart: false,
|
2021-07-15 17:55:48 +02:00
|
|
|
Schedule: "@midnight",
|
2020-05-17 01:31:38 +02:00
|
|
|
},
|
|
|
|
Timeout: 60 * time.Second,
|
|
|
|
Args: []string{},
|
2021-11-24 10:49:20 +01:00
|
|
|
}, func(ctx context.Context, _ *user_model.User, config Config) error {
|
2020-05-17 01:31:38 +02:00
|
|
|
rhcConfig := config.(*RepoHealthCheckConfig)
|
2022-10-23 16:44:45 +02: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 03:30:43 +01:00
|
|
|
return repo_service.GitFsckRepos(ctx, rhcConfig.Timeout, git.ToTrustedCmdArgs(rhcConfig.Args))
|
2020-05-17 01:31:38 +02:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func registerCheckRepoStats() {
|
|
|
|
RegisterTaskFatal("check_repo_stats", &BaseConfig{
|
|
|
|
Enabled: true,
|
|
|
|
RunAtStart: true,
|
2021-07-15 17:55:48 +02:00
|
|
|
Schedule: "@midnight",
|
2021-11-24 10:49:20 +01:00
|
|
|
}, func(ctx context.Context, _ *user_model.User, _ Config) error {
|
2020-05-17 01:31:38 +02:00
|
|
|
return models.CheckRepoStats(ctx)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func registerArchiveCleanup() {
|
|
|
|
RegisterTaskFatal("archive_cleanup", &OlderThanConfig{
|
|
|
|
BaseConfig: BaseConfig{
|
|
|
|
Enabled: true,
|
|
|
|
RunAtStart: true,
|
2021-07-15 17:55:48 +02:00
|
|
|
Schedule: "@midnight",
|
2020-05-17 01:31:38 +02:00
|
|
|
},
|
|
|
|
OlderThan: 24 * time.Hour,
|
2021-11-24 10:49:20 +01:00
|
|
|
}, func(ctx context.Context, _ *user_model.User, config Config) error {
|
2020-05-17 01:31:38 +02:00
|
|
|
acConfig := config.(*OlderThanConfig)
|
2021-12-06 08:19:28 +01:00
|
|
|
return archiver_service.DeleteOldRepositoryArchives(ctx, acConfig.OlderThan)
|
2020-05-17 01:31:38 +02:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func registerSyncExternalUsers() {
|
|
|
|
RegisterTaskFatal("sync_external_users", &UpdateExistingConfig{
|
|
|
|
BaseConfig: BaseConfig{
|
|
|
|
Enabled: true,
|
|
|
|
RunAtStart: false,
|
2021-07-15 17:55:48 +02:00
|
|
|
Schedule: "@midnight",
|
2020-05-17 01:31:38 +02:00
|
|
|
},
|
|
|
|
UpdateExisting: true,
|
2021-11-24 10:49:20 +01:00
|
|
|
}, func(ctx context.Context, _ *user_model.User, config Config) error {
|
2020-05-17 01:31:38 +02:00
|
|
|
realConfig := config.(*UpdateExistingConfig)
|
2021-07-24 12:16:34 +02:00
|
|
|
return auth.SyncExternalUsers(ctx, realConfig.UpdateExisting)
|
2020-05-17 01:31:38 +02:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func registerDeletedBranchesCleanup() {
|
|
|
|
RegisterTaskFatal("deleted_branches_cleanup", &OlderThanConfig{
|
|
|
|
BaseConfig: BaseConfig{
|
|
|
|
Enabled: true,
|
|
|
|
RunAtStart: true,
|
2021-07-15 17:55:48 +02:00
|
|
|
Schedule: "@midnight",
|
2020-05-17 01:31:38 +02:00
|
|
|
},
|
|
|
|
OlderThan: 24 * time.Hour,
|
2021-11-24 10:49:20 +01:00
|
|
|
}, func(ctx context.Context, _ *user_model.User, config Config) error {
|
2020-05-17 01:31:38 +02:00
|
|
|
realConfig := config.(*OlderThanConfig)
|
2022-06-12 17:51:54 +02:00
|
|
|
git_model.RemoveOldDeletedBranches(ctx, realConfig.OlderThan)
|
2020-05-17 01:31:38 +02:00
|
|
|
return nil
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func registerUpdateMigrationPosterID() {
|
|
|
|
RegisterTaskFatal("update_migration_poster_id", &BaseConfig{
|
|
|
|
Enabled: true,
|
|
|
|
RunAtStart: true,
|
2021-07-15 17:55:48 +02:00
|
|
|
Schedule: "@midnight",
|
2021-11-24 10:49:20 +01:00
|
|
|
}, func(ctx context.Context, _ *user_model.User, _ Config) error {
|
2020-05-17 01:31:38 +02:00
|
|
|
return migrations.UpdateMigrationPosterID(ctx)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-01-26 22:02:42 +01:00
|
|
|
func registerCleanupHookTaskTable() {
|
|
|
|
RegisterTaskFatal("cleanup_hook_task_table", &CleanupHookTaskConfig{
|
|
|
|
BaseConfig: BaseConfig{
|
|
|
|
Enabled: true,
|
|
|
|
RunAtStart: false,
|
2021-07-15 17:55:48 +02:00
|
|
|
Schedule: "@midnight",
|
2021-01-26 22:02:42 +01:00
|
|
|
},
|
|
|
|
CleanupType: "OlderThan",
|
|
|
|
OlderThan: 168 * time.Hour,
|
|
|
|
NumberToKeep: 10,
|
2021-11-24 10:49:20 +01:00
|
|
|
}, func(ctx context.Context, _ *user_model.User, config Config) error {
|
2021-01-26 22:02:42 +01:00
|
|
|
realConfig := config.(*CleanupHookTaskConfig)
|
2021-11-10 06:13:16 +01:00
|
|
|
return webhook.CleanupHookTaskTable(ctx, webhook.ToHookTaskCleanupType(realConfig.CleanupType), realConfig.OlderThan, realConfig.NumberToKeep)
|
2021-01-26 22:02:42 +01:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2022-03-30 10:42:47 +02:00
|
|
|
func registerCleanupPackages() {
|
|
|
|
RegisterTaskFatal("cleanup_packages", &OlderThanConfig{
|
|
|
|
BaseConfig: BaseConfig{
|
|
|
|
Enabled: true,
|
|
|
|
RunAtStart: true,
|
|
|
|
Schedule: "@midnight",
|
|
|
|
},
|
|
|
|
OlderThan: 24 * time.Hour,
|
|
|
|
}, func(ctx context.Context, _ *user_model.User, config Config) error {
|
|
|
|
realConfig := config.(*OlderThanConfig)
|
2023-08-08 02:46:10 +02:00
|
|
|
return packages_cleanup_service.CleanupTask(ctx, realConfig.OlderThan)
|
2022-03-30 10:42:47 +02:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2024-10-01 21:25:08 +02:00
|
|
|
func registerSyncRepoLicenses() {
|
|
|
|
RegisterTaskFatal("sync_repo_licenses", &BaseConfig{
|
|
|
|
Enabled: false,
|
|
|
|
RunAtStart: false,
|
|
|
|
Schedule: "@annually",
|
|
|
|
}, func(ctx context.Context, _ *user_model.User, config Config) error {
|
|
|
|
return repo_service.SyncRepoLicenses(ctx)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2020-05-17 01:31:38 +02:00
|
|
|
func initBasicTasks() {
|
2022-06-04 13:42:17 +02:00
|
|
|
if setting.Mirror.Enabled {
|
|
|
|
registerUpdateMirrorTask()
|
|
|
|
}
|
2020-05-17 01:31:38 +02:00
|
|
|
registerRepoHealthCheck()
|
|
|
|
registerCheckRepoStats()
|
|
|
|
registerArchiveCleanup()
|
|
|
|
registerSyncExternalUsers()
|
|
|
|
registerDeletedBranchesCleanup()
|
2020-12-21 15:39:41 +01:00
|
|
|
if !setting.Repository.DisableMigrations {
|
|
|
|
registerUpdateMigrationPosterID()
|
|
|
|
}
|
2021-01-26 22:02:42 +01:00
|
|
|
registerCleanupHookTaskTable()
|
2022-03-30 10:42:47 +02:00
|
|
|
if setting.Packages.Enabled {
|
|
|
|
registerCleanupPackages()
|
|
|
|
}
|
2024-10-01 21:25:08 +02:00
|
|
|
registerSyncRepoLicenses()
|
2020-05-17 01:31:38 +02:00
|
|
|
}
|