mirror of
https://github.com/go-gitea/gitea.git
synced 2025-07-22 00:01:17 -04:00
Compare commits
4 Commits
a4b242ae7a
...
e378545f30
Author | SHA1 | Date | |
---|---|---|---|
|
e378545f30 | ||
|
9b6e77c489 | ||
|
665d12cf84 | ||
|
d519a39302 |
@ -424,7 +424,7 @@ The following configuration set `Content-Type: application/vnd.android.package-a
|
|||||||
## Database (`database`)
|
## Database (`database`)
|
||||||
|
|
||||||
- `DB_TYPE`: **mysql**: The database type in use \[mysql, postgres, mssql, sqlite3\].
|
- `DB_TYPE`: **mysql**: The database type in use \[mysql, postgres, mssql, sqlite3\].
|
||||||
- `HOST`: **127.0.0.1:3306**: Database host address and port or absolute path for unix socket \[mysql, postgres\] (ex: /var/run/mysqld/mysqld.sock).
|
- `HOST`: **127.0.0.1:3306**: Database host address and port or absolute path for unix socket \[mysql, postgres[^1]\] (ex: /var/run/mysqld/mysqld.sock).
|
||||||
- `NAME`: **gitea**: Database name.
|
- `NAME`: **gitea**: Database name.
|
||||||
- `USER`: **root**: Database username.
|
- `USER`: **root**: Database username.
|
||||||
- `PASSWD`: **_empty_**: Database user password. Use \`your password\` or """your password""" for quoting if you use special characters in the password.
|
- `PASSWD`: **_empty_**: Database user password. Use \`your password\` or """your password""" for quoting if you use special characters in the password.
|
||||||
@ -455,6 +455,8 @@ The following configuration set `Content-Type: application/vnd.android.package-a
|
|||||||
- `CONN_MAX_LIFETIME` **0 or 3s**: Sets the maximum amount of time a DB connection may be reused - default is 0, meaning there is no limit (except on MySQL where it is 3s - see #6804 & #7071).
|
- `CONN_MAX_LIFETIME` **0 or 3s**: Sets the maximum amount of time a DB connection may be reused - default is 0, meaning there is no limit (except on MySQL where it is 3s - see #6804 & #7071).
|
||||||
- `AUTO_MIGRATION` **true**: Whether execute database models migrations automatically.
|
- `AUTO_MIGRATION` **true**: Whether execute database models migrations automatically.
|
||||||
|
|
||||||
|
[^1]: It may be necessary to specify a hostport even when listening on a unix socket, as the port is part of the socket name. see [#24552](https://github.com/go-gitea/gitea/issues/24552#issuecomment-1681649367) for additional details.
|
||||||
|
|
||||||
Please see #8540 & #8273 for further discussion of the appropriate values for `MAX_OPEN_CONNS`, `MAX_IDLE_CONNS` & `CONN_MAX_LIFETIME` and their
|
Please see #8540 & #8273 for further discussion of the appropriate values for `MAX_OPEN_CONNS`, `MAX_IDLE_CONNS` & `CONN_MAX_LIFETIME` and their
|
||||||
relation to port exhaustion.
|
relation to port exhaustion.
|
||||||
|
|
||||||
|
@ -268,6 +268,40 @@ The runner will fetch jobs from the Gitea instance and run them automatically.
|
|||||||
|
|
||||||
Since act runner is still in development, it is recommended to check the latest version and upgrade it regularly.
|
Since act runner is still in development, it is recommended to check the latest version and upgrade it regularly.
|
||||||
|
|
||||||
|
## Systemd service
|
||||||
|
|
||||||
|
It is also possible to run act-runner as a [systemd](https://en.wikipedia.org/wiki/Systemd) service. Create an unprivileged `act_runner` user on your system, and the following file in `/etc/systemd/system/act_runner.service`. The paths in `ExecStart` and `WorkingDirectory` may need to be adjusted depending on where you installed the `act_runner` binary, its configuration file, and the home directory of the `act_runner` user.
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[Unit]
|
||||||
|
Description=Gitea Actions runner
|
||||||
|
Documentation=https://gitea.com/gitea/act_runner
|
||||||
|
After=docker.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
ExecStart=/usr/local/bin/act_runner daemon --config /etc/act_runner/config.yaml
|
||||||
|
ExecReload=/bin/kill -s HUP $MAINPID
|
||||||
|
WorkingDirectory=/var/lib/act_runner
|
||||||
|
TimeoutSec=0
|
||||||
|
RestartSec=10
|
||||||
|
Restart=always
|
||||||
|
User=act_runner
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
```
|
||||||
|
|
||||||
|
Then:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# load the new systemd unit file
|
||||||
|
sudo systemctl daemon-reload
|
||||||
|
# start the service and enable it at boot
|
||||||
|
sudo systemctl enable act_runner --now
|
||||||
|
```
|
||||||
|
|
||||||
|
If using Docker, the `act_runner` user should also be added to the `docker` group before starting the service. Keep in mind that this effectively gives `act_runner` root access to the system [[1]](https://docs.docker.com/engine/security/#docker-daemon-attack-surface).
|
||||||
|
|
||||||
## Configuration variable
|
## Configuration variable
|
||||||
|
|
||||||
You can create configuration variables on the user, organization and repository level.
|
You can create configuration variables on the user, organization and repository level.
|
||||||
|
@ -6,6 +6,7 @@ package setting
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
@ -135,15 +136,18 @@ func DBConnStr() (string, error) {
|
|||||||
// parsePostgreSQLHostPort parses given input in various forms defined in
|
// parsePostgreSQLHostPort parses given input in various forms defined in
|
||||||
// https://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNSTRING
|
// https://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNSTRING
|
||||||
// and returns proper host and port number.
|
// and returns proper host and port number.
|
||||||
func parsePostgreSQLHostPort(info string) (string, string) {
|
func parsePostgreSQLHostPort(info string) (host, port string) {
|
||||||
host, port := "127.0.0.1", "5432"
|
if h, p, err := net.SplitHostPort(info); err == nil {
|
||||||
if strings.Contains(info, ":") && !strings.HasSuffix(info, "]") {
|
host, port = h, p
|
||||||
idx := strings.LastIndex(info, ":")
|
} else {
|
||||||
host = info[:idx]
|
// treat the "info" as "host", if it's an IPv6 address, remove the wrapper
|
||||||
port = info[idx+1:]
|
|
||||||
} else if len(info) > 0 {
|
|
||||||
host = info
|
host = info
|
||||||
|
if strings.HasPrefix(host, "[") && strings.HasSuffix(host, "]") {
|
||||||
|
host = host[1 : len(host)-1]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set fallback values
|
||||||
if host == "" {
|
if host == "" {
|
||||||
host = "127.0.0.1"
|
host = "127.0.0.1"
|
||||||
}
|
}
|
||||||
@ -155,14 +159,22 @@ func parsePostgreSQLHostPort(info string) (string, string) {
|
|||||||
|
|
||||||
func getPostgreSQLConnectionString(dbHost, dbUser, dbPasswd, dbName, dbParam, dbsslMode string) (connStr string) {
|
func getPostgreSQLConnectionString(dbHost, dbUser, dbPasswd, dbName, dbParam, dbsslMode string) (connStr string) {
|
||||||
host, port := parsePostgreSQLHostPort(dbHost)
|
host, port := parsePostgreSQLHostPort(dbHost)
|
||||||
if host[0] == '/' { // looks like a unix socket
|
connURL := url.URL{
|
||||||
connStr = fmt.Sprintf("postgres://%s:%s@:%s/%s%ssslmode=%s&host=%s",
|
Scheme: "postgres",
|
||||||
url.PathEscape(dbUser), url.PathEscape(dbPasswd), port, dbName, dbParam, dbsslMode, host)
|
User: url.UserPassword(dbUser, dbPasswd),
|
||||||
} else {
|
Host: net.JoinHostPort(host, port),
|
||||||
connStr = fmt.Sprintf("postgres://%s:%s@%s:%s/%s%ssslmode=%s",
|
Path: dbName,
|
||||||
url.PathEscape(dbUser), url.PathEscape(dbPasswd), host, port, dbName, dbParam, dbsslMode)
|
OmitHost: false,
|
||||||
|
RawQuery: dbParam,
|
||||||
}
|
}
|
||||||
return connStr
|
query := connURL.Query()
|
||||||
|
if dbHost[0] == '/' { // looks like a unix socket
|
||||||
|
query.Add("host", dbHost)
|
||||||
|
connURL.Host = ":" + port
|
||||||
|
}
|
||||||
|
query.Set("sslmode", dbsslMode)
|
||||||
|
connURL.RawQuery = query.Encode()
|
||||||
|
return connURL.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseMSSQLHostPort splits the host into host and port
|
// ParseMSSQLHostPort splits the host into host and port
|
||||||
|
@ -10,46 +10,49 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func Test_parsePostgreSQLHostPort(t *testing.T) {
|
func Test_parsePostgreSQLHostPort(t *testing.T) {
|
||||||
tests := []struct {
|
tests := map[string]struct {
|
||||||
HostPort string
|
HostPort string
|
||||||
Host string
|
Host string
|
||||||
Port string
|
Port string
|
||||||
}{
|
}{
|
||||||
{
|
"host-port": {
|
||||||
HostPort: "127.0.0.1:1234",
|
HostPort: "127.0.0.1:1234",
|
||||||
Host: "127.0.0.1",
|
Host: "127.0.0.1",
|
||||||
Port: "1234",
|
Port: "1234",
|
||||||
},
|
},
|
||||||
{
|
"no-port": {
|
||||||
HostPort: "127.0.0.1",
|
HostPort: "127.0.0.1",
|
||||||
Host: "127.0.0.1",
|
Host: "127.0.0.1",
|
||||||
Port: "5432",
|
Port: "5432",
|
||||||
},
|
},
|
||||||
{
|
"ipv6-port": {
|
||||||
HostPort: "[::1]:1234",
|
HostPort: "[::1]:1234",
|
||||||
Host: "[::1]",
|
Host: "::1",
|
||||||
Port: "1234",
|
Port: "1234",
|
||||||
},
|
},
|
||||||
{
|
"ipv6-no-port": {
|
||||||
HostPort: "[::1]",
|
HostPort: "[::1]",
|
||||||
Host: "[::1]",
|
Host: "::1",
|
||||||
Port: "5432",
|
Port: "5432",
|
||||||
},
|
},
|
||||||
{
|
"unix-socket": {
|
||||||
HostPort: "/tmp/pg.sock:1234",
|
HostPort: "/tmp/pg.sock:1234",
|
||||||
Host: "/tmp/pg.sock",
|
Host: "/tmp/pg.sock",
|
||||||
Port: "1234",
|
Port: "1234",
|
||||||
},
|
},
|
||||||
{
|
"unix-socket-no-port": {
|
||||||
HostPort: "/tmp/pg.sock",
|
HostPort: "/tmp/pg.sock",
|
||||||
Host: "/tmp/pg.sock",
|
Host: "/tmp/pg.sock",
|
||||||
Port: "5432",
|
Port: "5432",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, test := range tests {
|
for k, test := range tests {
|
||||||
host, port := parsePostgreSQLHostPort(test.HostPort)
|
t.Run(k, func(t *testing.T) {
|
||||||
assert.Equal(t, test.Host, host)
|
t.Log(test.HostPort)
|
||||||
assert.Equal(t, test.Port, port)
|
host, port := parsePostgreSQLHostPort(test.HostPort)
|
||||||
|
assert.Equal(t, test.Host, host)
|
||||||
|
assert.Equal(t, test.Port, port)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,7 +75,7 @@ func Test_getPostgreSQLConnectionString(t *testing.T) {
|
|||||||
Name: "gitea",
|
Name: "gitea",
|
||||||
Param: "",
|
Param: "",
|
||||||
SSLMode: "false",
|
SSLMode: "false",
|
||||||
Output: "postgres://testuser:space%20space%20%21%23$%25%5E%5E%25%5E%60%60%60-=%3F=@:5432/giteasslmode=false&host=/tmp/pg.sock",
|
Output: "postgres://testuser:space%20space%20%21%23$%25%5E%5E%25%5E%60%60%60-=%3F=@:5432/gitea?host=%2Ftmp%2Fpg.sock&sslmode=false",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Host: "localhost",
|
Host: "localhost",
|
||||||
@ -82,7 +85,7 @@ func Test_getPostgreSQLConnectionString(t *testing.T) {
|
|||||||
Name: "gitea",
|
Name: "gitea",
|
||||||
Param: "",
|
Param: "",
|
||||||
SSLMode: "true",
|
SSLMode: "true",
|
||||||
Output: "postgres://pgsqlusername:I%20love%20Gitea%21@localhost:5432/giteasslmode=true",
|
Output: "postgres://pgsqlusername:I%20love%20Gitea%21@localhost:5432/gitea?sslmode=true",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// StorageType is a type of Storage
|
// StorageType is a type of Storage
|
||||||
@ -249,14 +250,24 @@ func getStorageForMinio(targetSec, overrideSec ConfigSection, tp targetSecType,
|
|||||||
return nil, fmt.Errorf("map minio config failed: %v", err)
|
return nil, fmt.Errorf("map minio config failed: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if storage.MinioConfig.BasePath == "" {
|
var defaultPath string
|
||||||
storage.MinioConfig.BasePath = name + "/"
|
if storage.MinioConfig.BasePath != "" {
|
||||||
|
if tp == targetSecIsStorage || tp == targetSecIsDefault {
|
||||||
|
defaultPath = strings.TrimSuffix(storage.MinioConfig.BasePath, "/") + "/" + name + "/"
|
||||||
|
} else {
|
||||||
|
defaultPath = storage.MinioConfig.BasePath
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if defaultPath == "" {
|
||||||
|
defaultPath = name + "/"
|
||||||
}
|
}
|
||||||
|
|
||||||
if overrideSec != nil {
|
if overrideSec != nil {
|
||||||
storage.MinioConfig.ServeDirect = ConfigSectionKeyBool(overrideSec, "SERVE_DIRECT", storage.MinioConfig.ServeDirect)
|
storage.MinioConfig.ServeDirect = ConfigSectionKeyBool(overrideSec, "SERVE_DIRECT", storage.MinioConfig.ServeDirect)
|
||||||
storage.MinioConfig.BasePath = ConfigSectionKeyString(overrideSec, "MINIO_BASE_PATH", storage.MinioConfig.BasePath)
|
storage.MinioConfig.BasePath = ConfigSectionKeyString(overrideSec, "MINIO_BASE_PATH", defaultPath)
|
||||||
storage.MinioConfig.Bucket = ConfigSectionKeyString(overrideSec, "MINIO_BUCKET", storage.MinioConfig.Bucket)
|
storage.MinioConfig.Bucket = ConfigSectionKeyString(overrideSec, "MINIO_BUCKET", storage.MinioConfig.Bucket)
|
||||||
|
} else {
|
||||||
|
storage.MinioConfig.BasePath = defaultPath
|
||||||
}
|
}
|
||||||
return &storage, nil
|
return &storage, nil
|
||||||
}
|
}
|
||||||
|
@ -412,3 +412,56 @@ MINIO_USE_SSL = true
|
|||||||
assert.EqualValues(t, true, RepoArchive.Storage.MinioConfig.UseSSL)
|
assert.EqualValues(t, true, RepoArchive.Storage.MinioConfig.UseSSL)
|
||||||
assert.EqualValues(t, "repo-archive/", RepoArchive.Storage.MinioConfig.BasePath)
|
assert.EqualValues(t, "repo-archive/", RepoArchive.Storage.MinioConfig.BasePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_getStorageConfiguration28(t *testing.T) {
|
||||||
|
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
|
||||||
|
MINIO_BASE_PATH = /prefix
|
||||||
|
`)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NoError(t, loadRepoArchiveFrom(cfg))
|
||||||
|
assert.EqualValues(t, "my_access_key", RepoArchive.Storage.MinioConfig.AccessKeyID)
|
||||||
|
assert.EqualValues(t, "my_secret_key", RepoArchive.Storage.MinioConfig.SecretAccessKey)
|
||||||
|
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
|
||||||
|
MINIO_BASE_PATH = /prefix
|
||||||
|
|
||||||
|
[lfs]
|
||||||
|
MINIO_BASE_PATH = /lfs
|
||||||
|
`)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NoError(t, loadLFSFrom(cfg))
|
||||||
|
assert.EqualValues(t, "my_access_key", LFS.Storage.MinioConfig.AccessKeyID)
|
||||||
|
assert.EqualValues(t, "my_secret_key", LFS.Storage.MinioConfig.SecretAccessKey)
|
||||||
|
assert.EqualValues(t, true, LFS.Storage.MinioConfig.UseSSL)
|
||||||
|
assert.EqualValues(t, "/lfs", LFS.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
|
||||||
|
MINIO_BASE_PATH = /prefix
|
||||||
|
|
||||||
|
[storage.lfs]
|
||||||
|
MINIO_BASE_PATH = /lfs
|
||||||
|
`)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NoError(t, loadLFSFrom(cfg))
|
||||||
|
assert.EqualValues(t, "my_access_key", LFS.Storage.MinioConfig.AccessKeyID)
|
||||||
|
assert.EqualValues(t, "my_secret_key", LFS.Storage.MinioConfig.SecretAccessKey)
|
||||||
|
assert.EqualValues(t, true, LFS.Storage.MinioConfig.UseSSL)
|
||||||
|
assert.EqualValues(t, "/lfs", LFS.Storage.MinioConfig.BasePath)
|
||||||
|
}
|
||||||
|
@ -82,7 +82,7 @@ func loadSecurityData(ctx *context.Context) {
|
|||||||
// map the provider display name with the AuthSource
|
// map the provider display name with the AuthSource
|
||||||
sources := make(map[*auth_model.Source]string)
|
sources := make(map[*auth_model.Source]string)
|
||||||
for _, externalAccount := range accountLinks {
|
for _, externalAccount := range accountLinks {
|
||||||
if authSource, err := auth_model.GetSourceByID(ctx, externalAccount.LoginSourceID); err == nil {
|
if authSource, err := auth_model.GetSourceByID(ctx, externalAccount.LoginSourceID); err == nil && authSource.IsActive {
|
||||||
var providerDisplayName string
|
var providerDisplayName string
|
||||||
|
|
||||||
type DisplayNamed interface {
|
type DisplayNamed interface {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user