forgejo: init, admins: add emilylange #62
|
@ -9,5 +9,6 @@ in {
|
||||||
keys.users.jade ++
|
keys.users.jade ++
|
||||||
keys.users.janik ++
|
keys.users.janik ++
|
||||||
keys.users.lukegb ++
|
keys.users.lukegb ++
|
||||||
|
keys.users.emilylange ++
|
||||||
keys.users.yuka;
|
keys.users.yuka;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
meta01 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM5t9gYorOWgpCFDJgb24pyCKIabGpeI2H/UfdvXODcT";
|
meta01 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM5t9gYorOWgpCFDJgb24pyCKIabGpeI2H/UfdvXODcT";
|
||||||
gerrit01 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA+eSZu+u9sCynrMlsmFzQHLIELQAuVg0Cs1pBvwb4+A";
|
gerrit01 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA+eSZu+u9sCynrMlsmFzQHLIELQAuVg0Cs1pBvwb4+A";
|
||||||
fodwatch = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFRyTNfvKl5FcSyzGzw+h+bNFNOxdhvI67WdUZ2iIJ1L";
|
fodwatch = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFRyTNfvKl5FcSyzGzw+h+bNFNOxdhvI67WdUZ2iIJ1L";
|
||||||
|
git = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEQJcpkCUOx8+5oukMX6lxrYcIX8FyHu8Mc/3+ieKMUn";
|
||||||
builder-0 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBHSNcDGctvlG6BHcJuYIzW9WsBJsts2vpwSketsbXoL";
|
builder-0 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBHSNcDGctvlG6BHcJuYIzW9WsBJsts2vpwSketsbXoL";
|
||||||
builder-1 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIQOGUjERK7Mx8UPM/rbOdMqVyn1sbWqYOG6CbOzH2wm";
|
builder-1 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIQOGUjERK7Mx8UPM/rbOdMqVyn1sbWqYOG6CbOzH2wm";
|
||||||
builder-2 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMKzXIqCoYElEKIYgjbSpqEcDeOvV+Wo3Agq3jba83cB";
|
builder-2 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMKzXIqCoYElEKIYgjbSpqEcDeOvV+Wo3Agq3jba83cB";
|
||||||
|
@ -40,6 +41,7 @@
|
||||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBLZxVITpJ8xbiCa/u2gjSSIupeiqOnRh+8tFIoVhCON"
|
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBLZxVITpJ8xbiCa/u2gjSSIupeiqOnRh+8tFIoVhCON"
|
||||||
];
|
];
|
||||||
lukegb = [ ''cert-authority,principals="lukegb" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEqNOwlR7Qa8cbGpDfSCOweDPbAGQOZIcoRgh6s/J8DR'' ];
|
lukegb = [ ''cert-authority,principals="lukegb" ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEqNOwlR7Qa8cbGpDfSCOweDPbAGQOZIcoRgh6s/J8DR'' ];
|
||||||
|
emilylange = [ "no-touch-required sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIL7jgq3i+N3gVJhs4shm7Kmw6dIocs2OuR0GBMG1RxfKAAAABHNzaDo=" ];
|
||||||
yuka = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKath4/fDnlv/4fzxkPrQN1ttmoPRNu/m9bEtdPJBDfY cardno:16_933_242" ];
|
yuka = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKath4/fDnlv/4fzxkPrQN1ttmoPRNu/m9bEtdPJBDfY cardno:16_933_242" ];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,6 +99,7 @@
|
||||||
meta01.imports = commonModules ++ [ ./hosts/meta01 ];
|
meta01.imports = commonModules ++ [ ./hosts/meta01 ];
|
||||||
gerrit01.imports = commonModules ++ [ ./hosts/gerrit01 ];
|
gerrit01.imports = commonModules ++ [ ./hosts/gerrit01 ];
|
||||||
fodwatch.imports = commonModules ++ [ ./hosts/fodwatch ];
|
fodwatch.imports = commonModules ++ [ ./hosts/fodwatch ];
|
||||||
|
git.imports = commonModules ++ [ ./hosts/git ];
|
||||||
wob-vpn-gw.imports = commonModules ++ [ ./hosts/wob-vpn-gw ];
|
wob-vpn-gw.imports = commonModules ++ [ ./hosts/wob-vpn-gw ];
|
||||||
} // builders;
|
} // builders;
|
||||||
|
|
||||||
|
|
43
hosts/git/default.nix
Normal file
43
hosts/git/default.nix
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
let
|
||||||
|
ipv6 = {
|
||||||
|
openssh ="2001:bc8:38ee:100:1000::41";
|
||||||
|
forgejo = "2001:bc8:38ee:100:1000::40";
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
networking.hostName = "git";
|
||||||
|
networking.domain = "infra.forkos.org";
|
||||||
|
|
||||||
|
time.timeZone = "Europe/Paris";
|
||||||
|
|
||||||
|
bagel.sysadmin.enable = true;
|
||||||
|
# Forgejo will be proxied.
|
||||||
|
bagel.raito.v6-proxy-awareness.enable = true;
|
||||||
|
bagel.hardware.raito-vm = {
|
||||||
|
enable = true;
|
||||||
|
networking = {
|
||||||
|
nat-lan-mac = "BC:24:11:83:71:56";
|
||||||
|
wan = {
|
||||||
|
address = "${ipv6.forgejo}/64";
|
||||||
|
mac = "BC:24:11:0B:8A:81";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Add one additional IPv6, so we can have both OpenSSH and
|
||||||
|
# Forgejo's built-in server bind on port :22.
|
||||||
|
systemd.network.networks."10-wan".networkConfig.Address = [ "${ipv6.openssh}/64" ];
|
||||||
|
services.openssh.listenAddresses = [{
|
||||||
|
addr = "[${ipv6.openssh}]";
|
||||||
|
}];
|
||||||
|
|
||||||
|
bagel.services.forgejo = {
|
||||||
|
enable = true;
|
||||||
|
sshBindAddr = ipv6.forgejo;
|
||||||
|
};
|
||||||
|
|
||||||
|
i18n.defaultLocale = "en_US.UTF-8";
|
||||||
|
|
||||||
|
system.stateVersion = "24.05";
|
||||||
|
deployment.targetHost = "git.infra.forkos.org";
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
diff --git a/services/repository/branch.go b/services/repository/branch.go
|
||||||
|
index e1a313749f..5a8d823eef 100644
|
||||||
|
--- a/services/repository/branch.go
|
||||||
|
+++ b/services/repository/branch.go
|
||||||
|
@@ -26,7 +26,6 @@ import (
|
||||||
|
"code.gitea.io/gitea/modules/timeutil"
|
||||||
|
webhook_module "code.gitea.io/gitea/modules/webhook"
|
||||||
|
notify_service "code.gitea.io/gitea/services/notify"
|
||||||
|
- files_service "code.gitea.io/gitea/services/repository/files"
|
||||||
|
|
||||||
|
"xorm.io/builder"
|
||||||
|
)
|
||||||
|
@@ -129,21 +128,7 @@ func loadOneBranch(ctx context.Context, repo *repo_model.Repository, dbBranch *g
|
||||||
|
p := protectedBranches.GetFirstMatched(branchName)
|
||||||
|
isProtected := p != nil
|
||||||
|
|
||||||
|
- var divergence *git.DivergeObject
|
||||||
|
-
|
||||||
|
- // it's not default branch
|
||||||
|
- if repo.DefaultBranch != dbBranch.Name && !dbBranch.IsDeleted {
|
||||||
|
- var err error
|
||||||
|
- divergence, err = files_service.CountDivergingCommits(ctx, repo, git.BranchPrefix+branchName)
|
||||||
|
- if err != nil {
|
||||||
|
- return nil, fmt.Errorf("CountDivergingCommits: %v", err)
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if divergence == nil {
|
||||||
|
- // tolerate the error that we cannot get divergence
|
||||||
|
- divergence = &git.DivergeObject{Ahead: -1, Behind: -1}
|
||||||
|
- }
|
||||||
|
+ divergence := &git.DivergeObject{Ahead: -1, Behind: -1}
|
||||||
|
|
||||||
|
pr, err := issues_model.GetLatestPullRequestByHeadInfo(ctx, repo.ID, branchName)
|
||||||
|
if err != nil {
|
||||||
|
diff --git a/templates/repo/branch/list.tmpl b/templates/repo/branch/list.tmpl
|
||||||
|
index a577fed450..e102796315 100644
|
||||||
|
--- a/templates/repo/branch/list.tmpl
|
||||||
|
+++ b/templates/repo/branch/list.tmpl
|
||||||
|
@@ -102,19 +102,6 @@
|
||||||
|
{{end}}
|
||||||
|
</td>
|
||||||
|
<td class="two wide ui">
|
||||||
|
- {{if and (not .DBBranch.IsDeleted) $.DefaultBranchBranch}}
|
||||||
|
- <div class="commit-divergence">
|
||||||
|
- <div class="bar-group">
|
||||||
|
- <div class="count count-behind">{{.CommitsBehind}}</div>
|
||||||
|
- {{/* old code bears 0/0.0 = NaN output, so it might output invalid "width: NaNpx", it just works and doesn't caues any problem. */}}
|
||||||
|
- <div class="bar bar-behind" style="width: {{Eval 100 "*" .CommitsBehind "/" "(" .CommitsBehind "+" .CommitsAhead "+" 0.0 ")"}}%"></div>
|
||||||
|
- </div>
|
||||||
|
- <div class="bar-group">
|
||||||
|
- <div class="count count-ahead">{{.CommitsAhead}}</div>
|
||||||
|
- <div class="bar bar-ahead" style="width: {{Eval 100 "*" .CommitsAhead "/" "(" .CommitsBehind "+" .CommitsAhead "+" 0.0 ")"}}%"></div>
|
||||||
|
- </div>
|
||||||
|
- </div>
|
||||||
|
- {{end}}
|
||||||
|
</td>
|
||||||
|
<td class="two wide right aligned">
|
||||||
|
{{if not .LatestPullRequest}}
|
|
@ -0,0 +1,32 @@
|
||||||
|
diff --git a/routers/web/repo/commit.go b/routers/web/repo/commit.go
|
||||||
|
index 718454e063..8fa299710c 100644
|
||||||
|
--- a/routers/web/repo/commit.go
|
||||||
|
+++ b/routers/web/repo/commit.go
|
||||||
|
@@ -408,12 +408,6 @@ func Diff(ctx *context.Context) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- ctx.Data["BranchName"], err = commit.GetBranchName()
|
||||||
|
- if err != nil {
|
||||||
|
- ctx.ServerError("commit.GetBranchName", err)
|
||||||
|
- return
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
ctx.HTML(http.StatusOK, tplCommitPage)
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/templates/repo/commit_page.tmpl b/templates/repo/commit_page.tmpl
|
||||||
|
index c37fb46975..18c9cf18f8 100644
|
||||||
|
--- a/templates/repo/commit_page.tmpl
|
||||||
|
+++ b/templates/repo/commit_page.tmpl
|
||||||
|
@@ -71,8 +71,8 @@
|
||||||
|
"branchForm" "branch-dropdown-form"
|
||||||
|
"branchURLPrefix" (printf "%s/_cherrypick/%s/" $.RepoLink .CommitID) "branchURLSuffix" ""
|
||||||
|
"setAction" true "submitForm" true}}
|
||||||
|
- <form method="get" action="{{$.RepoLink}}/_cherrypick/{{.CommitID}}/{{if $.BranchName}}{{PathEscapeSegments $.BranchName}}{{else}}{{PathEscapeSegments $.Repository.DefaultBranch}}{{end}}" id="branch-dropdown-form">
|
||||||
|
- <input type="hidden" name="ref" value="{{if $.BranchName}}{{$.BranchName}}{{else}}{{$.Repository.DefaultBranch}}{{end}}">
|
||||||
|
+ <form method="get" action="{{$.RepoLink}}/_cherrypick/{{.CommitID}}/{{PathEscapeSegments $.Repository.DefaultBranch}}" id="branch-dropdown-form">
|
||||||
|
+ <input type="hidden" name="ref" value="{{$.Repository.DefaultBranch}}">
|
||||||
|
<input type="hidden" name="refType" value="branch">
|
||||||
|
<input type="hidden" id="cherry-pick-type" name="cherry-pick-type"><br>
|
||||||
|
<button type="submit" id="cherry-pick-submit" class="ui primary button"></button>
|
40
pkgs/forgejo/default.nix
Normal file
40
pkgs/forgejo/default.nix
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
{ forgejo }:
|
||||||
|
|
||||||
|
forgejo.overrideAttrs (prev: {
|
||||||
|
patches = [
|
||||||
|
# Branch divergence calculations for a single branch may take 100-200ms on something as big
|
||||||
|
# as nixpkgs. The branch view defaults to 20 branches for each page, taking roughtly 3s to
|
||||||
|
# calculate each branch sequentially and render, while consuming a single core at 100%.
|
||||||
|
# The idea is to look into making this less expensive or async.
|
||||||
|
# But for now, to get this going, we will simply drop that metric.
|
||||||
|
./branch-view_remove-expensive-commit-divergence-metric.patch
|
||||||
|
|
||||||
|
# This is literally broken and eats resources for nothing of value.
|
||||||
|
# We should upstream this.
|
||||||
|
# The tl;dr is: It calculates the nearest branch for the requested commit at
|
||||||
|
# /:owner/:repo/commit/:commit to use it as the default cherry-pick target branch
|
||||||
|
# selection in a drop-down only users with commit perms can actually view and use.
|
||||||
|
# It's expensive to calculate and happens on every request to /commit/:commit.
|
||||||
|
# To add insult to injury, it's hardly of any use: The nearest branch of a commit
|
||||||
|
# will almost always be a branch that already carries the commit. The branch you
|
||||||
|
# most likely don't want to cherry-pick to.
|
||||||
|
./commit-view_fix-broken-and-expensive-cherry-pick-default-branch-selection.patch
|
||||||
|
|
||||||
|
# Disable various /:owner/:repo/activity/ sub-views. They are expensive, which is
|
||||||
|
# totally fine and expected. There is even proper caching in place.
|
||||||
|
# However, on a scale of nixpkgs, those calculations take ages, while, of course,
|
||||||
|
# pinning a single CPU core at 100%.
|
||||||
|
# For now, we will simply disable this feature.
|
||||||
|
# Due to the 501 status code it returns, the frontend prints a "Not implemented"
|
||||||
|
# error, saving us from patching the frontend while still providing a helpful
|
||||||
|
# user-facing error text.
|
||||||
|
# It should be noted that this particular status code has the downside of being
|
||||||
|
# in the 5xx range, meaning it will show up as such in our prometheus metrics.
|
||||||
|
./disable-expensive-repository-activity-stats.patch
|
||||||
|
|
||||||
|
# Migrations and pull-mirrors are something easily abused to bring a public instance to a complete halt.
|
||||||
|
# Both features can be disabled via repository.DISABLE_MIGRATIONS and mirror.ENABLE, but we want to keep
|
||||||
|
# this functionality for admins.
|
||||||
|
./limit-migrations-and-pull-mirrors-to-admins.patch
|
||||||
|
];
|
||||||
|
})
|
|
@ -0,0 +1,34 @@
|
||||||
|
diff --git a/routers/web/web.go b/routers/web/web.go
|
||||||
|
index ee9694f41c..f55b8d6f62 100644
|
||||||
|
--- a/routers/web/web.go
|
||||||
|
+++ b/routers/web/web.go
|
||||||
|
@@ -57,6 +57,10 @@ import (
|
||||||
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
)
|
||||||
|
|
||||||
|
+func endpointNotImplemented(ctx *context.Context) {
|
||||||
|
+ ctx.JSON(http.StatusNotImplemented, "This endpoint has been removed due to performance issues with it and as such is not longer implemented.")
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
// optionsCorsHandler return a http handler which sets CORS options if enabled by config, it blocks non-CORS OPTIONS requests.
|
||||||
|
func optionsCorsHandler() func(next http.Handler) http.Handler {
|
||||||
|
var corsHandler func(next http.Handler) http.Handler
|
||||||
|
@@ -1425,15 +1429,15 @@ func registerRoutes(m *web.Route) {
|
||||||
|
m.Get("/{period}", repo.Activity)
|
||||||
|
m.Group("/contributors", func() {
|
||||||
|
m.Get("", repo.Contributors)
|
||||||
|
- m.Get("/data", repo.ContributorsData)
|
||||||
|
+ m.Get("/data", endpointNotImplemented)
|
||||||
|
}, repo.MustBeNotEmpty, context.RequireRepoReaderOr(unit.TypeCode))
|
||||||
|
m.Group("/code-frequency", func() {
|
||||||
|
m.Get("", repo.CodeFrequency)
|
||||||
|
- m.Get("/data", repo.CodeFrequencyData)
|
||||||
|
+ m.Get("/data", endpointNotImplemented)
|
||||||
|
}, repo.MustBeNotEmpty, context.RequireRepoReaderOr(unit.TypeCode))
|
||||||
|
m.Group("/recent-commits", func() {
|
||||||
|
m.Get("", repo.RecentCommits)
|
||||||
|
- m.Get("/data", repo.RecentCommitsData)
|
||||||
|
+ m.Get("/data", endpointNotImplemented)
|
||||||
|
}, repo.MustBeNotEmpty, context.RequireRepoReaderOr(unit.TypeCode))
|
||||||
|
}, context.RepoRef(), context.RequireRepoReaderOr(unit.TypeCode, unit.TypePullRequests, unit.TypeIssues, unit.TypeReleases))
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
diff --git a/routers/api/v1/repo/migrate.go b/routers/api/v1/repo/migrate.go
|
||||||
|
index 2caaa130e8..455e89e93e 100644
|
||||||
|
--- a/routers/api/v1/repo/migrate.go
|
||||||
|
+++ b/routers/api/v1/repo/migrate.go
|
||||||
|
@@ -12,7 +12,6 @@ import (
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/models"
|
||||||
|
"code.gitea.io/gitea/models/db"
|
||||||
|
- "code.gitea.io/gitea/models/organization"
|
||||||
|
"code.gitea.io/gitea/models/perm"
|
||||||
|
access_model "code.gitea.io/gitea/models/perm/access"
|
||||||
|
repo_model "code.gitea.io/gitea/models/repo"
|
||||||
|
@@ -86,22 +85,7 @@ func Migrate(ctx *context.APIContext) {
|
||||||
|
}
|
||||||
|
|
||||||
|
if !ctx.Doer.IsAdmin {
|
||||||
|
- if !repoOwner.IsOrganization() && ctx.Doer.ID != repoOwner.ID {
|
||||||
|
- ctx.Error(http.StatusForbidden, "", "Given user is not an organization.")
|
||||||
|
- return
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if repoOwner.IsOrganization() {
|
||||||
|
- // Check ownership of organization.
|
||||||
|
- isOwner, err := organization.OrgFromUser(repoOwner).IsOwnedBy(ctx, ctx.Doer.ID)
|
||||||
|
- if err != nil {
|
||||||
|
- ctx.Error(http.StatusInternalServerError, "IsOwnedBy", err)
|
||||||
|
- return
|
||||||
|
- } else if !isOwner {
|
||||||
|
- ctx.Error(http.StatusForbidden, "", "Given user is not owner of organization.")
|
||||||
|
- return
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
+ ctx.Error(http.StatusForbidden, "", "You need to be administrator of this Forgejo instance to be able to create mirrors.")
|
||||||
|
}
|
||||||
|
|
||||||
|
remoteAddr, err := forms.ParseRemoteAddr(form.CloneAddr, form.AuthUsername, form.AuthPassword)
|
||||||
|
diff --git a/routers/web/repo/migrate.go b/routers/web/repo/migrate.go
|
||||||
|
index 97b0c425ea..554a470eab 100644
|
||||||
|
--- a/routers/web/repo/migrate.go
|
||||||
|
+++ b/routers/web/repo/migrate.go
|
||||||
|
@@ -150,6 +150,12 @@ func handleMigrateRemoteAddrError(ctx *context.Context, err error, tpl base.TplN
|
||||||
|
// MigratePost response for migrating from external git repository
|
||||||
|
func MigratePost(ctx *context.Context) {
|
||||||
|
form := web.GetForm(ctx).(*forms.MigrateRepoForm)
|
||||||
|
+
|
||||||
|
+ if !ctx.Doer.IsAdmin {
|
||||||
|
+ ctx.Error(http.StatusForbidden, "MigratePost: you need to be site administrator to use migrations and mirrors")
|
||||||
|
+ return
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if setting.Repository.DisableMigrations {
|
||||||
|
ctx.Error(http.StatusForbidden, "MigratePost: the site administrator has disabled migrations")
|
||||||
|
return
|
|
@ -6,6 +6,7 @@
|
||||||
./netbox
|
./netbox
|
||||||
./ofborg
|
./ofborg
|
||||||
./postgres
|
./postgres
|
||||||
|
./forgejo
|
||||||
./baremetal-builder
|
./baremetal-builder
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
139
services/forgejo/default.nix
Normal file
139
services/forgejo/default.nix
Normal file
|
@ -0,0 +1,139 @@
|
||||||
|
{ pkgs, lib, config, ... }:
|
||||||
|
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.bagel.services.forgejo;
|
||||||
|
inherit (lib) mkIf mkEnableOption mkOption types;
|
||||||
|
|
||||||
|
domain = "git.forkos.org";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.bagel.services.forgejo = {
|
||||||
|
enable = mkEnableOption "Forgejo";
|
||||||
|
sshBindAddr = mkOption {
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
services.forgejo = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
package = pkgs.callPackage ../../pkgs/forgejo { };
|
||||||
|
|
||||||
|
database = {
|
||||||
|
type = "postgres";
|
||||||
|
createDatabase = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
lfs.enable = true;
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
DEFAULT = {
|
||||||
|
APP_NAME = "ForkOS";
|
||||||
|
};
|
||||||
|
|
||||||
|
server = {
|
||||||
|
PROTOCOL = "http+unix";
|
||||||
|
ROOT_URL = "https://${domain}/";
|
||||||
|
DOMAIN = "${domain}";
|
||||||
|
|
||||||
|
BUILTIN_SSH_SERVER_USER = "git";
|
||||||
|
SSH_PORT = 22;
|
||||||
|
SSH_LISTEN_HOST = cfg.sshBindAddr;
|
||||||
|
START_SSH_SERVER = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
session = {
|
||||||
|
PROVIDER = "redis";
|
||||||
|
PROVIDER_CONFIG = "network=unix,addr=${config.services.redis.servers.forgejo.unixSocket},db=0";
|
||||||
|
COOKIE_NAME = "session";
|
||||||
|
};
|
||||||
|
|
||||||
|
service = {
|
||||||
|
DISABLE_REGISTRATION = true;
|
||||||
|
DEFAULT_KEEP_EMAIL_PRIVATE = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
oauth2_client = {
|
||||||
|
REGISTER_EMAIL_CONFIRM = false;
|
||||||
|
ENABLE_AUTO_REGISTRATION = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
# TODO: transactional mails
|
||||||
|
|
||||||
|
cache = {
|
||||||
|
ADAPTER = "redis";
|
||||||
|
HOST = "network=unix,addr=${config.services.redis.servers.forgejo.unixSocket},db=1";
|
||||||
|
ITEM_TTL = "72h"; # increased from default 16h
|
||||||
|
};
|
||||||
|
|
||||||
|
ui = {
|
||||||
|
SHOW_USER_EMAIL = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
repository = {
|
||||||
|
# Forks in forgejo are suprisingly expensive because they are full git clones.
|
||||||
|
# If we do want to enable forks, we can write a small patch that disables
|
||||||
|
# only for repositories that are as large as nixpkgs.
|
||||||
|
DISABLE_FORKS = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
packages = {
|
||||||
|
# Forgejo's various package registries can easily take up a lot of space.
|
||||||
|
# We could either store the blobs on some slower disks but larger, or even
|
||||||
|
# better, use an s3 bucket for it. But until we actually have a use-case for
|
||||||
|
# this feature, we will simply keep it disabled for now.
|
||||||
|
ENABLED = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
indexer = {
|
||||||
|
REPO_INDEXER_REPO_TYPES = "sources,mirrors,templates"; # skip forks
|
||||||
|
REPO_INDEXER_ENABLED = true;
|
||||||
|
ISSUE_INDEXER_TYPE = "bleve";
|
||||||
|
};
|
||||||
|
|
||||||
|
"git.timeout" = {
|
||||||
|
MIGRATE = 3600; # increase from default 600 (seconds) for something as large as nixpkgs on a slow uplink
|
||||||
|
};
|
||||||
|
|
||||||
|
log = {
|
||||||
|
LEVEL = "Warn";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.forgejo = {
|
||||||
|
serviceConfig = lib.optionalAttrs (config.services.forgejo.settings.server.SSH_PORT < 1024) {
|
||||||
|
AmbientCapabilities = lib.mkForce "CAP_NET_BIND_SERVICE";
|
||||||
|
CapabilityBoundingSet = lib.mkForce "CAP_NET_BIND_SERVICE";
|
||||||
|
PrivateUsers = lib.mkForce false;
|
||||||
|
};
|
||||||
|
|
||||||
|
# start Forgejo *after* sshd.service, so in case Forgejo tries to wildcard bind :22 due to
|
||||||
|
# a bug or whatever, we don't lose OpenSSH in a race.
|
||||||
|
wants = [ "sshd.service" "redis-forgejo.service" ];
|
||||||
|
requires = [ "sshd.service" "redis-forgejo.service" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
services.redis.servers.forgejo = {
|
||||||
|
enable = true;
|
||||||
|
user = "forgejo";
|
||||||
|
};
|
||||||
|
|
||||||
|
services.nginx = {
|
||||||
|
enable = true;
|
||||||
|
virtualHosts.${domain} = {
|
||||||
|
enableACME = true;
|
||||||
|
forceSSL = true;
|
||||||
|
locations."/".proxyPass = "http://unix:${config.services.forgejo.settings.server.HTTP_ADDR}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.firewall.allowedTCPPorts = [
|
||||||
|
80
|
||||||
|
443
|
||||||
|
config.services.forgejo.settings.server.SSH_PORT
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in a new issue