Skip to content

Commit

Permalink
Merge remote-tracking branch 'giteaofficial/main'
Browse files Browse the repository at this point in the history
* giteaofficial/main:
  Filter inactive auth sources (go-gitea#27870)
  refactor postgres connection string building (go-gitea#27723)
  doc: actions/act-runner: document running as a systemd service (go-gitea#27844)
  Support storage base path as prefix (go-gitea#27827)
  • Loading branch information
zjjhot committed Nov 2, 2023
2 parents 6d8bdf9 + e378545 commit b3c5cb5
Show file tree
Hide file tree
Showing 7 changed files with 149 additions and 34 deletions.
4 changes: 3 additions & 1 deletion docs/content/administration/config-cheat-sheet.en-us.md
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ The following configuration set `Content-Type: application/vnd.android.package-a
## Database (`database`)

- `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.
- `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.
Expand Down Expand Up @@ -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).
- `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
relation to port exhaustion.

Expand Down
34 changes: 34 additions & 0 deletions docs/content/usage/actions/act-runner.en-us.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

## 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

You can create configuration variables on the user, organization and repository level.
Expand Down
40 changes: 26 additions & 14 deletions modules/setting/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package setting
import (
"errors"
"fmt"
"net"
"net/url"
"os"
"path"
Expand Down Expand Up @@ -135,15 +136,18 @@ func DBConnStr() (string, error) {
// parsePostgreSQLHostPort parses given input in various forms defined in
// https://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNSTRING
// and returns proper host and port number.
func parsePostgreSQLHostPort(info string) (string, string) {
host, port := "127.0.0.1", "5432"
if strings.Contains(info, ":") && !strings.HasSuffix(info, "]") {
idx := strings.LastIndex(info, ":")
host = info[:idx]
port = info[idx+1:]
} else if len(info) > 0 {
func parsePostgreSQLHostPort(info string) (host, port string) {
if h, p, err := net.SplitHostPort(info); err == nil {
host, port = h, p
} else {
// treat the "info" as "host", if it's an IPv6 address, remove the wrapper
host = info
if strings.HasPrefix(host, "[") && strings.HasSuffix(host, "]") {
host = host[1 : len(host)-1]
}
}

// set fallback values
if host == "" {
host = "127.0.0.1"
}
Expand All @@ -155,14 +159,22 @@ func parsePostgreSQLHostPort(info string) (string, string) {

func getPostgreSQLConnectionString(dbHost, dbUser, dbPasswd, dbName, dbParam, dbsslMode string) (connStr string) {
host, port := parsePostgreSQLHostPort(dbHost)
if host[0] == '/' { // looks like a unix socket
connStr = fmt.Sprintf("postgres:https://%s:%s@:%s/%s%ssslmode=%s&host=%s",
url.PathEscape(dbUser), url.PathEscape(dbPasswd), port, dbName, dbParam, dbsslMode, host)
} else {
connStr = fmt.Sprintf("postgres:https://%s:%s@%s:%s/%s%ssslmode=%s",
url.PathEscape(dbUser), url.PathEscape(dbPasswd), host, port, dbName, dbParam, dbsslMode)
connURL := url.URL{
Scheme: "postgres",
User: url.UserPassword(dbUser, dbPasswd),
Host: net.JoinHostPort(host, port),
Path: dbName,
OmitHost: false,
RawQuery: dbParam,
}
query := connURL.Query()
if dbHost[0] == '/' { // looks like a unix socket
query.Add("host", dbHost)
connURL.Host = ":" + port
}
return connStr
query.Set("sslmode", dbsslMode)
connURL.RawQuery = query.Encode()
return connURL.String()
}

// ParseMSSQLHostPort splits the host into host and port
Expand Down
33 changes: 18 additions & 15 deletions modules/setting/database_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,46 +10,49 @@ import (
)

func Test_parsePostgreSQLHostPort(t *testing.T) {
tests := []struct {
tests := map[string]struct {
HostPort string
Host string
Port string
}{
{
"host-port": {
HostPort: "127.0.0.1:1234",
Host: "127.0.0.1",
Port: "1234",
},
{
"no-port": {
HostPort: "127.0.0.1",
Host: "127.0.0.1",
Port: "5432",
},
{
"ipv6-port": {
HostPort: "[::1]:1234",
Host: "[::1]",
Host: "::1",
Port: "1234",
},
{
"ipv6-no-port": {
HostPort: "[::1]",
Host: "[::1]",
Host: "::1",
Port: "5432",
},
{
"unix-socket": {
HostPort: "/tmp/pg.sock:1234",
Host: "/tmp/pg.sock",
Port: "1234",
},
{
"unix-socket-no-port": {
HostPort: "/tmp/pg.sock",
Host: "/tmp/pg.sock",
Port: "5432",
},
}
for _, test := range tests {
host, port := parsePostgreSQLHostPort(test.HostPort)
assert.Equal(t, test.Host, host)
assert.Equal(t, test.Port, port)
for k, test := range tests {
t.Run(k, func(t *testing.T) {
t.Log(test.HostPort)
host, port := parsePostgreSQLHostPort(test.HostPort)
assert.Equal(t, test.Host, host)
assert.Equal(t, test.Port, port)
})
}
}

Expand All @@ -72,7 +75,7 @@ func Test_getPostgreSQLConnectionString(t *testing.T) {
Name: "gitea",
Param: "",
SSLMode: "false",
Output: "postgres:https://testuser:space%20space%20%21%23$%25%5E%5E%25%5E%60%60%60-=%3F=@:5432/giteasslmode=false&host=/tmp/pg.sock",
Output: "postgres:https://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",
Expand All @@ -82,7 +85,7 @@ func Test_getPostgreSQLConnectionString(t *testing.T) {
Name: "gitea",
Param: "",
SSLMode: "true",
Output: "postgres:https://pgsqlusername:I%20love%20Gitea%21@localhost:5432/giteasslmode=true",
Output: "postgres:https://pgsqlusername:I%20love%20Gitea%21@localhost:5432/gitea?sslmode=true",
},
}

Expand Down
17 changes: 14 additions & 3 deletions modules/setting/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"errors"
"fmt"
"path/filepath"
"strings"
)

// StorageType is a type of Storage
Expand Down Expand Up @@ -249,14 +250,24 @@ func getStorageForMinio(targetSec, overrideSec ConfigSection, tp targetSecType,
return nil, fmt.Errorf("map minio config failed: %v", err)
}

if storage.MinioConfig.BasePath == "" {
storage.MinioConfig.BasePath = name + "/"
var defaultPath string
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 {
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)
} else {
storage.MinioConfig.BasePath = defaultPath
}
return &storage, nil
}
53 changes: 53 additions & 0 deletions modules/setting/storage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -412,3 +412,56 @@ MINIO_USE_SSL = true
assert.EqualValues(t, true, RepoArchive.Storage.MinioConfig.UseSSL)
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)
}
2 changes: 1 addition & 1 deletion routers/web/user/setting/security/security.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func loadSecurityData(ctx *context.Context) {
// map the provider display name with the AuthSource
sources := make(map[*auth_model.Source]string)
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

type DisplayNamed interface {
Expand Down

0 comments on commit b3c5cb5

Please sign in to comment.