Skip to content

Uniform all temporary directories and allow customizing temp path #32352

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

Merged
merged 40 commits into from
Apr 8, 2025
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
7b0f3e6
uniform all temporary directories
lunny Oct 27, 2024
fc25971
Fix unnecessary changes
lunny Oct 27, 2024
b362ffa
use global configuration temp directories
lunny Oct 27, 2024
fafd7b7
Fix recycle dependency
lunny Oct 28, 2024
30621ae
Move all temporary directories under gitea and cleanup it when Gitea …
lunny Oct 28, 2024
cb81214
create temp root directory when startup
lunny Oct 28, 2024
f079b60
Fix temp dir name
lunny Oct 28, 2024
887c8a5
Merge branch 'main' into lunny/uniform-temp-dir
lunny Mar 11, 2025
fc448b5
Fix
lunny Mar 12, 2025
1ad7ee8
Fix
lunny Mar 12, 2025
d4d39dc
Fix test
lunny Mar 13, 2025
aeffcb1
Merge branch 'main' into lunny/uniform-temp-dir
lunny Mar 13, 2025
e03e58f
Remove unnecessary change
lunny Mar 14, 2025
1fd7611
Merge branch 'main' into lunny/uniform-temp-dir
lunny Mar 27, 2025
d41d8b8
Remove cleanup temp dirs
lunny Mar 27, 2025
178da31
Add configuration to allow customize global temp path
lunny Mar 27, 2025
3382a56
improvements
lunny Mar 27, 2025
3fe5cd7
Fix bug
lunny Mar 28, 2025
9afad75
Fix test
lunny Mar 28, 2025
13a4c9b
some improvements
lunny Mar 28, 2025
058edb9
some improvements
lunny Mar 28, 2025
6187ce0
some improvements
lunny Mar 28, 2025
d6c9ed3
Fix test
lunny Mar 28, 2025
9f591e2
Merge branch 'main' into lunny/uniform-temp-dir
lunny Mar 28, 2025
69c9a1e
Fix test
lunny Mar 28, 2025
0726e76
Merge branch 'main' into lunny/uniform-temp-dir
lunny Mar 28, 2025
d1bf10a
Merge branch 'main' into lunny/uniform-temp-dir
lunny Mar 31, 2025
b88c3a6
improvements
lunny Apr 4, 2025
d6f6d77
Merge branch 'main' into lunny/uniform-temp-dir
lunny Apr 4, 2025
85d5fc6
Remove sub temporary path configurations with a fixed sub path
lunny Apr 5, 2025
d3be0fb
Merge branch 'main' into lunny/uniform-temp-dir
lunny Apr 5, 2025
7897bc6
Fix bug
lunny Apr 5, 2025
4d89d56
Fix bug
lunny Apr 5, 2025
8373fff
Merge branch 'main' into lunny/uniform-temp-dir
wxiaoguang Apr 7, 2025
834bb59
revert dump tmp dir, remove SSH_KEYGEN_PATH
wxiaoguang Apr 7, 2025
e40bfb8
refactor
wxiaoguang Apr 7, 2025
47ea426
add APP_TEMP_PATH
wxiaoguang Apr 7, 2025
8483d03
rename
wxiaoguang Apr 7, 2025
a7371fa
add tests
wxiaoguang Apr 8, 2025
9758ee7
Merge branch 'main' into lunny/uniform-temp-dir
lunny Apr 8, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/dump.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ var CmdDump = &cli.Command{
&cli.StringFlag{
Name: "tempdir",
Aliases: []string{"t"},
Value: os.TempDir(),
Value: setting.TempPath,
Usage: "Temporary dir path",
},
&cli.StringFlag{
Expand Down
3 changes: 1 addition & 2 deletions cmd/migrate_storage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ func TestMigratePackages(t *testing.T) {

entries, err := os.ReadDir(p)
assert.NoError(t, err)
assert.Len(t, entries, 2)
assert.Len(t, entries, 1) // tmp directory should not be under storage any more
assert.Equal(t, "01", entries[0].Name())
assert.Equal(t, "tmp", entries[1].Name())
}
16 changes: 10 additions & 6 deletions custom/conf/app.example.ini
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ RUN_USER = ; git
;; The working directory, see the comment of AppWorkPath above
;WORK_PATH =

;; The temporary directory, defaults to a directory named gitea under the system temporary directory
;; All other temporary directories are relative to this directory by default
;TEMP_PATH =

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[server]
Expand Down Expand Up @@ -1075,8 +1079,8 @@ LEVEL = Info
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Path for local repository copy. Defaults to `tmp/local-repo` (content gets deleted on gitea restart)
;LOCAL_COPY_PATH = tmp/local-repo
;; Path for local repository copy. Defaults to `local-repo` under `TEMP_PATH` except it's an absolute path (content gets deleted on gitea restart)
;LOCAL_COPY_PATH = local-repo

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Expand All @@ -1087,8 +1091,8 @@ LEVEL = Info
;; Whether repository file uploads are enabled. Defaults to `true`
;ENABLED = true
;;
;; Path for uploads. Defaults to `data/tmp/uploads` (content gets deleted on gitea restart)
;TEMP_PATH = data/tmp/uploads
;; Path for uploads. Defaults to `uploads` under `TEMP_PATH` except it's an absolute path (content gets deleted on gitea restart)
;TEMP_PATH = uploads
;;
;; Comma-separated list of allowed file extensions (`.zip`), mime types (`text/plain`) or wildcard type (`image/*`, `audio/*`, `video/*`). Empty value or `*/*` allows all types.
;ALLOWED_TYPES =
Expand Down Expand Up @@ -2588,8 +2592,8 @@ LEVEL = Info
;; Currently, only `minio` and `azureblob` is supported.
;SERVE_DIRECT = false
;;
;; Path for chunked uploads. Defaults to APP_DATA_PATH + `tmp/package-upload`
;CHUNKED_UPLOAD_PATH = tmp/package-upload
;; Path for chunked uploads. Defaults to `package-upload` under `TEMP_PATH` except it's an absolute path.
;CHUNKED_UPLOAD_PATH = package-upload
;;
;; Maximum count of package versions a single owner can have (`-1` means no limits)
;LIMIT_TOTAL_OWNER_COUNT = -1
Expand Down
7 changes: 3 additions & 4 deletions models/migrations/base/tests.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"code.gitea.io/gitea/models/unittest"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/temp"
"code.gitea.io/gitea/modules/test"
"code.gitea.io/gitea/modules/testlogger"

Expand Down Expand Up @@ -114,10 +115,11 @@ func MainTest(m *testing.M) {
setting.CustomConf = giteaConf
}

tmpDataPath, err := os.MkdirTemp("", "data")
tmpDataPath, cleanup, err := temp.MkdirTemp("data")
if err != nil {
testlogger.Fatalf("Unable to create temporary data path %v\n", err)
}
defer cleanup()

setting.CustomPath = filepath.Join(setting.AppWorkPath, "custom")
setting.AppDataPath = tmpDataPath
Expand All @@ -134,8 +136,5 @@ func MainTest(m *testing.M) {
if err := removeAllWithRetry(setting.RepoRootPath); err != nil {
fmt.Fprintf(os.Stderr, "os.RemoveAll: %v\n", err)
}
if err := removeAllWithRetry(tmpDataPath); err != nil {
fmt.Fprintf(os.Stderr, "os.RemoveAll: %v\n", err)
}
os.Exit(exitStatus)
}
16 changes: 7 additions & 9 deletions models/unittest/testdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/setting/config"
"code.gitea.io/gitea/modules/storage"
"code.gitea.io/gitea/modules/temp"
"code.gitea.io/gitea/modules/test"
"code.gitea.io/gitea/modules/util"

Expand Down Expand Up @@ -92,15 +93,19 @@ func MainTest(m *testing.M, testOptsArg ...*TestOptions) {
setting.SSH.Domain = "try.gitea.io"
setting.Database.Type = "sqlite3"
setting.Repository.DefaultBranch = "master" // many test code still assume that default branch is called "master"
repoRootPath, err := os.MkdirTemp(os.TempDir(), "repos")
repoRootPath, cleanup1, err := temp.MkdirTemp("repos")
if err != nil {
fatalTestError("TempDir: %v\n", err)
}
defer cleanup1()

setting.RepoRootPath = repoRootPath
appDataPath, err := os.MkdirTemp(os.TempDir(), "appdata")
appDataPath, cleanup2, err := temp.MkdirTemp("appdata")
if err != nil {
fatalTestError("TempDir: %v\n", err)
}
defer cleanup2()

setting.AppDataPath = appDataPath
setting.AppWorkPath = giteaRoot
setting.StaticRootPath = giteaRoot
Expand Down Expand Up @@ -153,13 +158,6 @@ func MainTest(m *testing.M, testOptsArg ...*TestOptions) {
fatalTestError("tear down failed: %v\n", err)
}
}

if err = util.RemoveAll(repoRootPath); err != nil {
fatalTestError("util.RemoveAll: %v\n", err)
}
if err = util.RemoveAll(appDataPath); err != nil {
fatalTestError("util.RemoveAll: %v\n", err)
}
os.Exit(exitStatus)
}

Expand Down
3 changes: 2 additions & 1 deletion modules/git/blame.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"os"

"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/temp"
"code.gitea.io/gitea/modules/util"
)

Expand Down Expand Up @@ -192,7 +193,7 @@ func tryCreateBlameIgnoreRevsFile(commit *Commit) *string {
}
defer r.Close()

f, err := os.CreateTemp("", "gitea_git-blame-ignore-revs")
f, err := temp.CreateTemp("gitea_git-blame-ignore-revs")
if err != nil {
return nil
}
Expand Down
7 changes: 4 additions & 3 deletions modules/git/git_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,19 @@ import (
"testing"

"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/modules/temp"

"github.com/hashicorp/go-version"
"github.com/stretchr/testify/assert"
)

func testRun(m *testing.M) error {
gitHomePath, err := os.MkdirTemp(os.TempDir(), "git-home")
gitHomePath, cleanup, err := temp.MkdirTemp("git-home")
if err != nil {
return fmt.Errorf("unable to create temp dir: %w", err)
}
defer util.RemoveAll(gitHomePath)
defer cleanup()

setting.Git.HomePath = gitHomePath

if err = InitFull(context.Background()); err != nil {
Expand Down
5 changes: 3 additions & 2 deletions modules/git/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"time"

"code.gitea.io/gitea/modules/proxy"
"code.gitea.io/gitea/modules/temp"
)

// GPGSettings represents the default GPG settings for this repository
Expand Down Expand Up @@ -266,11 +267,11 @@ func GetDivergingCommits(ctx context.Context, repoPath, baseBranch, targetBranch

// CreateBundle create bundle content to the target path
func (repo *Repository) CreateBundle(ctx context.Context, commit string, out io.Writer) error {
tmp, err := os.MkdirTemp(os.TempDir(), "gitea-bundle")
tmp, cleanup, err := temp.MkdirTemp("gitea-bundle")
if err != nil {
return err
}
defer os.RemoveAll(tmp)
defer cleanup()

env := append(os.Environ(), "GIT_OBJECT_DIRECTORY="+filepath.Join(repo.Path, "objects"))
_, _, err = NewCommand("init", "--bare").RunStdString(ctx, &RunOpts{Dir: tmp, Env: env})
Expand Down
17 changes: 4 additions & 13 deletions modules/git/repo_index.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ import (
"path/filepath"
"strings"

"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/modules/temp"
)

// ReadTreeToIndex reads a treeish to the index
Expand Down Expand Up @@ -59,26 +58,18 @@ func (repo *Repository) ReadTreeToTemporaryIndex(treeish string) (tmpIndexFilena
}
}()

removeDirFn := func(dir string) func() { // it can't use the return value "tmpDir" directly because it is empty when error occurs
return func() {
if err := util.RemoveAll(dir); err != nil {
log.Error("failed to remove tmp index dir: %v", err)
}
}
}

tmpDir, err = os.MkdirTemp("", "index")
tmpDir, cancel, err = temp.MkdirTemp("index")
if err != nil {
return "", "", nil, err
}

tmpIndexFilename = filepath.Join(tmpDir, ".tmp-index")
cancel = removeDirFn(tmpDir)

err = repo.ReadTreeToIndex(treeish, tmpIndexFilename)
if err != nil {
return "", "", cancel, err
}
return tmpIndexFilename, tmpDir, cancel, err
return tmpIndexFilename, tmpDir, cancel, nil
}

// EmptyIndex empties the index
Expand Down
3 changes: 2 additions & 1 deletion modules/markup/external/external.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/process"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/temp"
"code.gitea.io/gitea/modules/util"
)

Expand Down Expand Up @@ -88,7 +89,7 @@ func (p *Renderer) Render(ctx *markup.RenderContext, input io.Reader, output io.

if p.IsInputFile {
// write to temp file
f, err := os.CreateTemp("", "gitea_input")
f, err := temp.CreateTemp("gitea_input")
if err != nil {
return fmt.Errorf("%s create temp file when rendering %s failed: %w", p.Name(), p.Command, err)
}
Expand Down
29 changes: 14 additions & 15 deletions modules/repository/temp.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package repository

import (
"context"
"fmt"
"os"
"path/filepath"
Expand All @@ -15,30 +16,28 @@ import (

// LocalCopyPath returns the local repository temporary copy path.
func LocalCopyPath() string {
if filepath.IsAbs(setting.Repository.Local.LocalCopyPath) {
return setting.Repository.Local.LocalCopyPath
if setting.Repository.Local.LocalCopyPath == "" {
return filepath.Join(setting.TempPath, "local-repo")
} else if !filepath.IsAbs(setting.Repository.Local.LocalCopyPath) {
return filepath.Join(setting.TempPath, setting.Repository.Local.LocalCopyPath)
}
return filepath.Join(setting.AppDataPath, setting.Repository.Local.LocalCopyPath)
return setting.Repository.Local.LocalCopyPath
}

// CreateTemporaryPath creates a temporary path
func CreateTemporaryPath(prefix string) (string, error) {
func CreateTemporaryPath(prefix string) (string, context.CancelFunc, error) {
if err := os.MkdirAll(LocalCopyPath(), os.ModePerm); err != nil {
log.Error("Unable to create localcopypath directory: %s (%v)", LocalCopyPath(), err)
return "", fmt.Errorf("Failed to create localcopypath directory %s: %w", LocalCopyPath(), err)
return "", func() {}, fmt.Errorf("failed to create localcopypath directory %s: %w", LocalCopyPath(), err)
}
basePath, err := os.MkdirTemp(LocalCopyPath(), prefix+".git")
if err != nil {
log.Error("Unable to create temporary directory: %s-*.git (%v)", prefix, err)
return "", fmt.Errorf("Failed to create dir %s-*.git: %w", prefix, err)
return "", func() {}, fmt.Errorf("failed to create dir %s-*.git: %w", prefix, err)
}
return basePath, nil
}

// RemoveTemporaryPath removes the temporary path
func RemoveTemporaryPath(basePath string) error {
if _, err := os.Stat(basePath); !os.IsNotExist(err) {
return util.RemoveAll(basePath)
}
return nil
return basePath, func() {
if err := util.RemoveAll(basePath); err != nil {
log.Error("Unable to remove temporary directory: %s (%v)", basePath, err)
}
}, nil
}
12 changes: 12 additions & 0 deletions modules/setting/global.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@

package setting

import (
"os"
"path/filepath"
)

// Global settings
var (
// RunUser is the OS user that Gitea is running as. ini:"RUN_USER"
Expand All @@ -15,4 +20,11 @@ var (

// AppName is the Application name, used in the page title. ini: "APP_NAME"
AppName string

// TempPath is the directory used for temporary files. ini: "TEMP_PATH"
TempPath string
)

func init() {
TempPath = filepath.Join(os.TempDir(), "gitea")
}
4 changes: 2 additions & 2 deletions modules/setting/packages.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ func loadPackagesFrom(rootCfg ConfigProvider) (err error) {
return err
}

Packages.ChunkedUploadPath = filepath.ToSlash(sec.Key("CHUNKED_UPLOAD_PATH").MustString("tmp/package-upload"))
Packages.ChunkedUploadPath = filepath.ToSlash(sec.Key("CHUNKED_UPLOAD_PATH").MustString("package-upload"))
if !filepath.IsAbs(Packages.ChunkedUploadPath) {
Packages.ChunkedUploadPath = filepath.ToSlash(filepath.Join(AppDataPath, Packages.ChunkedUploadPath))
Packages.ChunkedUploadPath = filepath.Join(TempPath, Packages.ChunkedUploadPath)
}

if HasInstallLock(rootCfg) {
Expand Down
10 changes: 6 additions & 4 deletions modules/setting/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ var (
MaxFiles int
}{
Enabled: true,
TempPath: "data/tmp/uploads",
TempPath: "uploads",
AllowedTypes: "",
FileMaxSize: 50,
MaxFiles: 5,
Expand All @@ -197,7 +197,7 @@ var (
Local: struct {
LocalCopyPath string
}{
LocalCopyPath: "tmp/local-repo",
LocalCopyPath: "local-repo",
},

// Pull request settings
Expand Down Expand Up @@ -361,8 +361,10 @@ func loadRepositoryFrom(rootCfg ConfigProvider) {
}
}

if !filepath.IsAbs(Repository.Upload.TempPath) {
Repository.Upload.TempPath = filepath.Join(AppWorkPath, Repository.Upload.TempPath)
if Repository.Upload.TempPath == "" {
Repository.Upload.TempPath = filepath.Join(TempPath, "uploads")
} else if !filepath.IsAbs(Repository.Upload.TempPath) {
Repository.Upload.TempPath = filepath.Join(TempPath, Repository.Upload.TempPath)
}

if err := loadRepoArchiveFrom(rootCfg); err != nil {
Expand Down
Loading