123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 |
- // Copyright 2023 The Gitea Authors. All rights reserved.
- // SPDX-License-Identifier: MIT
-
- package setting
-
- import (
- "errors"
- "os"
- "os/exec"
- "path/filepath"
- "strings"
-
- "code.gitea.io/gitea/modules/log"
- )
-
- var (
- // AppPath represents the path to the gitea binary
- AppPath string
-
- // AppWorkPath is the "working directory" of Gitea. It maps to the: WORK_PATH in app.ini, "--work-path" flag, environment variable GITEA_WORK_DIR.
- // If that is not set it is the default set here by the linker or failing that the directory of AppPath.
- // It is used as the base path for several other paths.
- AppWorkPath string
- CustomPath string // Custom directory path. Env: GITEA_CUSTOM
- CustomConf string
-
- appWorkPathBuiltin string
- customPathBuiltin string
- customConfBuiltin string
-
- AppWorkPathMismatch bool
- )
-
- func getAppPath() (string, error) {
- var appPath string
- var err error
- if IsWindows && filepath.IsAbs(os.Args[0]) {
- appPath = filepath.Clean(os.Args[0])
- } else {
- appPath, err = exec.LookPath(os.Args[0])
- }
- if err != nil {
- if !errors.Is(err, exec.ErrDot) {
- return "", err
- }
- appPath, err = filepath.Abs(os.Args[0])
- }
- if err != nil {
- return "", err
- }
- appPath, err = filepath.Abs(appPath)
- if err != nil {
- return "", err
- }
- // Note: (legacy code) we don't use path.Dir here because it does not handle case which path starts with two "/" in Windows: "//psf/Home/..."
- return strings.ReplaceAll(appPath, "\\", "/"), err
- }
-
- func init() {
- var err error
- if AppPath, err = getAppPath(); err != nil {
- log.Fatal("Failed to get app path: %v", err)
- }
-
- if AppWorkPath == "" {
- AppWorkPath = filepath.Dir(AppPath)
- }
-
- appWorkPathBuiltin = AppWorkPath
- customPathBuiltin = CustomPath
- customConfBuiltin = CustomConf
- }
-
- type ArgWorkPathAndCustomConf struct {
- WorkPath string
- CustomPath string
- CustomConf string
- }
-
- type stringWithDefault struct {
- Value string
- IsSet bool
- }
-
- func (s *stringWithDefault) Set(v string) {
- s.Value = v
- s.IsSet = true
- }
-
- // InitWorkPathAndCommonConfig will set AppWorkPath, CustomPath and CustomConf, init default config provider by CustomConf and load common settings,
- func InitWorkPathAndCommonConfig(getEnvFn func(name string) string, args ArgWorkPathAndCustomConf) {
- InitWorkPathAndCfgProvider(getEnvFn, args)
- LoadCommonSettings()
- }
-
- // InitWorkPathAndCfgProvider will set AppWorkPath, CustomPath and CustomConf, init default config provider by CustomConf
- func InitWorkPathAndCfgProvider(getEnvFn func(name string) string, args ArgWorkPathAndCustomConf) {
- tryAbsPath := func(paths ...string) string {
- s := paths[len(paths)-1]
- for i := len(paths) - 2; i >= 0; i-- {
- if filepath.IsAbs(s) {
- break
- }
- s = filepath.Join(paths[i], s)
- }
- return s
- }
-
- var err error
- tmpWorkPath := stringWithDefault{Value: appWorkPathBuiltin}
- if tmpWorkPath.Value == "" {
- tmpWorkPath.Value = filepath.Dir(AppPath)
- }
- tmpCustomPath := stringWithDefault{Value: customPathBuiltin}
- if tmpCustomPath.Value == "" {
- tmpCustomPath.Value = "custom"
- }
- tmpCustomConf := stringWithDefault{Value: customConfBuiltin}
- if tmpCustomConf.Value == "" {
- tmpCustomConf.Value = "conf/app.ini"
- }
-
- readFromEnv := func() {
- envWorkPath := getEnvFn("GITEA_WORK_DIR")
- if envWorkPath != "" {
- tmpWorkPath.Set(envWorkPath)
- if !filepath.IsAbs(tmpWorkPath.Value) {
- log.Fatal("GITEA_WORK_DIR (work path) must be absolute path")
- }
- }
-
- envCustomPath := getEnvFn("GITEA_CUSTOM")
- if envCustomPath != "" {
- tmpCustomPath.Set(envCustomPath)
- if !filepath.IsAbs(tmpCustomPath.Value) {
- log.Fatal("GITEA_CUSTOM (custom path) must be absolute path")
- }
- }
- }
-
- readFromArgs := func() {
- if args.WorkPath != "" {
- tmpWorkPath.Set(args.WorkPath)
- if !filepath.IsAbs(tmpWorkPath.Value) {
- log.Fatal("--work-path must be absolute path")
- }
- }
- if args.CustomPath != "" {
- tmpCustomPath.Set(args.CustomPath) // if it is not abs, it will be based on work-path, it shouldn't happen
- if !filepath.IsAbs(tmpCustomPath.Value) {
- log.Error("--custom-path must be absolute path")
- }
- }
- if args.CustomConf != "" {
- tmpCustomConf.Set(args.CustomConf)
- if !filepath.IsAbs(tmpCustomConf.Value) {
- // the config path can be relative to the real current working path
- if tmpCustomConf.Value, err = filepath.Abs(tmpCustomConf.Value); err != nil {
- log.Fatal("Failed to get absolute path of config %q: %v", tmpCustomConf.Value, err)
- }
- }
- }
- }
-
- readFromEnv()
- readFromArgs()
-
- if !tmpCustomConf.IsSet {
- tmpCustomConf.Set(tryAbsPath(tmpWorkPath.Value, tmpCustomPath.Value, tmpCustomConf.Value))
- }
-
- // only read the config but do not load/init anything more, because the AppWorkPath and CustomPath are not ready
- InitCfgProvider(tmpCustomConf.Value)
- if HasInstallLock(CfgProvider) {
- ClearEnvConfigKeys() // if the instance has been installed, do not pass the environment variables to sub-processes
- }
- configWorkPath := ConfigSectionKeyString(CfgProvider.Section(""), "WORK_PATH")
- if configWorkPath != "" {
- if !filepath.IsAbs(configWorkPath) {
- log.Fatal("WORK_PATH in %q must be absolute path", configWorkPath)
- }
- configWorkPath = filepath.Clean(configWorkPath)
- if tmpWorkPath.Value != "" && (getEnvFn("GITEA_WORK_DIR") != "" || args.WorkPath != "") {
- fi1, err1 := os.Stat(tmpWorkPath.Value)
- fi2, err2 := os.Stat(configWorkPath)
- if err1 != nil || err2 != nil || !os.SameFile(fi1, fi2) {
- AppWorkPathMismatch = true
- }
- }
- tmpWorkPath.Set(configWorkPath)
- }
-
- tmpCustomPath.Set(tryAbsPath(tmpWorkPath.Value, tmpCustomPath.Value))
-
- AppWorkPath = tmpWorkPath.Value
- CustomPath = tmpCustomPath.Value
- CustomConf = tmpCustomConf.Value
- }
|