1{
2 system ? builtins.currentSystem,
3 config ? { },
4 giteaPackage ? pkgs.gitea,
5 pkgs ? import ../.. { inherit system config; },
6}:
7
8with import ../lib/testing-python.nix { inherit system pkgs; };
9with pkgs.lib;
10
11let
12 ## gpg --faked-system-time='20230301T010000!' --quick-generate-key snakeoil ed25519 sign
13 signingPrivateKey = ''
14 -----BEGIN PGP PRIVATE KEY BLOCK-----
15
16 lFgEY/6jkBYJKwYBBAHaRw8BAQdADXiZRV8RJUyC9g0LH04wLMaJL9WTc+szbMi7
17 5fw4yP8AAQCl8EwGfzSLm/P6fCBfA3I9znFb3MEHGCCJhJ6VtKYyRw7ktAhzbmFr
18 ZW9pbIiUBBMWCgA8FiEE+wUM6VW/NLtAdSixTWQt6LZ4x50FAmP+o5ACGwMFCQPC
19 ZwAECwkIBwQVCgkIBRYCAwEAAh4FAheAAAoJEE1kLei2eMedFTgBAKQs1oGFZrCI
20 TZP42hmBTKxGAI1wg7VSdDEWTZxut/2JAQDGgo2sa4VHMfj0aqYGxrIwfP2B7JHO
21 GCqGCRf9O/hzBA==
22 =9Uy3
23 -----END PGP PRIVATE KEY BLOCK-----
24 '';
25 signingPrivateKeyId = "4D642DE8B678C79D";
26
27 supportedDbTypes = [
28 "mysql"
29 "postgres"
30 "sqlite3"
31 ];
32 makeGiteaTest =
33 type:
34 nameValuePair type (makeTest {
35 name = "${giteaPackage.pname}-${type}";
36 meta.maintainers = with maintainers; [
37 aanderse
38 kolaente
39 ];
40
41 nodes = {
42 server =
43 { config, pkgs, ... }:
44 {
45 virtualisation.memorySize = 2047;
46 services.gitea = {
47 enable = true;
48 database = { inherit type; };
49 package = giteaPackage;
50 metricsTokenFile = (pkgs.writeText "metrics_secret" "fakesecret").outPath;
51 settings.service.DISABLE_REGISTRATION = true;
52 settings."repository.signing".SIGNING_KEY = signingPrivateKeyId;
53 settings.actions.ENABLED = true;
54 settings.metrics.ENABLED = true;
55 };
56 environment.systemPackages = [
57 giteaPackage
58 pkgs.gnupg
59 pkgs.jq
60 ];
61 services.openssh.enable = true;
62
63 specialisation.runner = {
64 inheritParentConfig = true;
65
66 configuration.services.gitea-actions-runner.instances."test" = {
67 enable = true;
68 name = "ci";
69 url = "http://localhost:3000";
70 labels = [
71 # don't require docker/podman
72 "native:host"
73 ];
74 tokenFile = "/var/lib/gitea/runner_token";
75 };
76 };
77 };
78 client1 =
79 { config, pkgs, ... }:
80 {
81 environment.systemPackages = [ pkgs.git ];
82 };
83 client2 =
84 { config, pkgs, ... }:
85 {
86 environment.systemPackages = [ pkgs.git ];
87 };
88 };
89
90 testScript =
91 { nodes, ... }:
92 let
93 inherit (import ./ssh-keys.nix pkgs) snakeOilPrivateKey snakeOilPublicKey;
94 serverSystem = nodes.server.system.build.toplevel;
95 in
96 ''
97 GIT_SSH_COMMAND = "ssh -i $HOME/.ssh/privk -o StrictHostKeyChecking=no"
98 REPO = "gitea@server:test/repo"
99 PRIVK = "${snakeOilPrivateKey}"
100
101 start_all()
102
103 client1.succeed("mkdir /tmp/repo")
104 client1.succeed("mkdir -p $HOME/.ssh")
105 client1.succeed(f"cat {PRIVK} > $HOME/.ssh/privk")
106 client1.succeed("chmod 0400 $HOME/.ssh/privk")
107 client1.succeed("git -C /tmp/repo init")
108 client1.succeed("echo hello world > /tmp/repo/testfile")
109 client1.succeed("git -C /tmp/repo add .")
110 client1.succeed("git config --global user.email test@localhost")
111 client1.succeed("git config --global user.name test")
112 client1.succeed("git -C /tmp/repo commit -m 'Initial import'")
113 client1.succeed(f"git -C /tmp/repo remote add origin {REPO}")
114
115 server.wait_for_unit("gitea.service")
116 server.wait_for_open_port(3000)
117 server.wait_for_open_port(22)
118 server.succeed("curl --fail http://localhost:3000/")
119
120 server.succeed(
121 "su -l gitea -c 'gpg --homedir /var/lib/gitea/data/home/.gnupg "
122 + "--import ${toString (pkgs.writeText "gitea.key" signingPrivateKey)}'"
123 )
124
125 assert "BEGIN PGP PUBLIC KEY BLOCK" in server.succeed("curl http://localhost:3000/api/v1/signing-key.gpg")
126
127 server.succeed(
128 "curl --fail http://localhost:3000/user/sign_up | grep 'Registration is disabled. "
129 + "Please contact your site administrator.'"
130 )
131 server.succeed(
132 "su -l gitea -c 'GITEA_WORK_DIR=/var/lib/gitea gitea admin user create "
133 + "--username test --password totallysafe --email test@localhost'"
134 )
135
136 api_token = server.succeed(
137 "curl --fail -X POST http://test:totallysafe@localhost:3000/api/v1/users/test/tokens "
138 + "-H 'Accept: application/json' -H 'Content-Type: application/json' -d "
139 + "'{\"name\":\"token\",\"scopes\":[\"all\"]}' | jq '.sha1' | xargs echo -n"
140 )
141
142 server.succeed(
143 "curl --fail -X POST http://localhost:3000/api/v1/user/repos "
144 + "-H 'Accept: application/json' -H 'Content-Type: application/json' "
145 + f"-H 'Authorization: token {api_token}'"
146 + ' -d \'{"auto_init":false, "description":"string", "license":"mit", "name":"repo", "private":false}\'''
147 )
148
149 server.succeed(
150 "curl --fail -X POST http://localhost:3000/api/v1/user/keys "
151 + "-H 'Accept: application/json' -H 'Content-Type: application/json' "
152 + f"-H 'Authorization: token {api_token}'"
153 + ' -d \'{"key":"${snakeOilPublicKey}","read_only":true,"title":"SSH"}\'''
154 )
155
156 client1.succeed(
157 f"GIT_SSH_COMMAND='{GIT_SSH_COMMAND}' git -C /tmp/repo push origin master"
158 )
159
160 client2.succeed("mkdir -p $HOME/.ssh")
161 client2.succeed(f"cat {PRIVK} > $HOME/.ssh/privk")
162 client2.succeed("chmod 0400 $HOME/.ssh/privk")
163 client2.succeed(f"GIT_SSH_COMMAND='{GIT_SSH_COMMAND}' git clone {REPO}")
164 client2.succeed('test "$(cat repo/testfile | xargs echo -n)" = "hello world"')
165
166 server.wait_until_succeeds(
167 'test "$(curl http://localhost:3000/api/v1/repos/test/repo/commits '
168 + '-H "Accept: application/json" | jq length)" = "1"'
169 )
170
171 with subtest("Testing metrics endpoint"):
172 server.succeed('curl '
173 + '-H "Authorization: Bearer fakesecret" '
174 + 'http://localhost:3000/metrics '
175 + '| grep gitea_accesses')
176
177 with subtest("Testing runner registration"):
178 server.succeed(
179 "su -l gitea -c 'GITEA_WORK_DIR=/var/lib/gitea gitea actions generate-runner-token' | sed 's/^/TOKEN=/' | tee /var/lib/gitea/runner_token"
180 )
181 server.succeed("${serverSystem}/specialisation/runner/bin/switch-to-configuration test")
182 server.wait_for_unit("gitea-runner-test.service")
183 server.succeed("journalctl -o cat -u gitea-runner-test.service | grep -q 'Runner registered successfully'")
184 '';
185 });
186in
187
188listToAttrs (map makeGiteaTest supportedDbTypes)