List of commits:
Subject Hash Author Date (UTC)
Big changes to add rpm packages repositories 5e07ff440d6ad7f0ef9900a634b2f39f0e7fa1e4 Catalin(ux) M. BOIE 2021-10-21 05:59:26
Cosmetic 02376344f7d7d321d824ab7978de2ad49c007167 Catalin(ux) M. BOIE 2021-05-23 12:57:06
Added FIDO2 support for SSH 04186abe13896ad4f4ea7126691d0a2b1798de1a Catalin(ux) M. BOIE 2021-05-23 12:30:43
ssh: show the id of the key both on web and when connecting ab95ccfa2819d6ac9f427209ee61c75aad8a3661 Catalin(ux) M. BOIE 2021-05-23 10:52:44
Some events are doing some queries, and we need to cover them in transaction, not only the subevents 4768ffec303961971cc0c3732a24e858f47dd381 Catalin(ux) M. BOIE 2020-12-15 07:33:36
Added rate limit for ssh and git connections b667130e6c5721a3d30193863a5defd8bbff50f1 Catalin(ux) M. BOIE 2020-11-30 10:49:27
cosmetic abe44edadda9da7c639b7bd8c9e13e6058555669 Catalin(ux) M. BOIE 2020-11-30 10:21:01
gpg functions and test ecb9e05c99a2b73edfba5014329e362d8c6e9246 Catalin(ux) M. BOIE 2020-11-09 07:38:11
Stats page is not rendered for bots. 29ca3f62ac460b64eb0a10fbb8bdfdf4a1767dc5 Catalin(ux) M. BOIE 2020-10-13 05:48:43
Added rate limit options 60e939a52577a01603f9f386ffaf1a9712f99ab6 Catalin(ux) M. BOIE 2020-10-07 05:02:25
Improved bots list and clean old entries 9da0a014040753734beabfecb298b8956fc25fe3 Catalin(ux) M. BOIE 2020-10-05 06:34:43
builder: use secrets only if available 4fe47afc60435508ad90f62c51d489ac3c20b4d0 Catalin(ux) M. BOIE 2020-08-28 07:29:14
worker: use secrets only if available 5371e918e294a46cc38c765371a1caf7a3083eef Catalin(ux) M. BOIE 2020-08-28 07:28:12
builder: do not break meta variable 1d8207b1a782ab039406dbd087cdc9bb5ea0b898 Catalin(ux) M. BOIE 2020-08-28 07:27:48
Whitespace 86086337c5323b073f517bc59c18aba0808fb4f3 Catalin(ux) M. BOIE 2020-08-24 07:22:13
Bump version to 0.73 7cac4d7a31116ac9ad86e0babeb0c1aace5dd852 Catalin(ux) M. BOIE 2020-08-23 15:32:03
duilder update f691d84aa0aa70ef60a7487f247ed1a9ab1e3ab1 Catalin(ux) M. BOIE 2020-08-23 15:31:38
Bot prevention should not be active for edit operation 371c60a486ea989fafb66266cab71ea9f7db0269 Catalin(ux) M. BOIE 2020-08-23 15:02:13
TODO update 32591f3b1cf054bd70411592e5a82f5898d7da2f Catalin(ux) M. BOIE 2020-08-23 15:01:51
Show also by which protocol a user is connecting d35b5b12103f9a72a3e8788e7c48532b9c1e5b89 Catalin(ux) M. BOIE 2020-08-23 15:01:30
Commit 5e07ff440d6ad7f0ef9900a634b2f39f0e7fa1e4 - Big changes to add rpm packages repositories
Author: Catalin(ux) M. BOIE
Author date (UTC): 2021-10-21 05:59
Committer name: Catalin(ux) M. BOIE
Committer date (UTC): 2021-10-21 05:59
Parent(s): 02376344f7d7d321d824ab7978de2ad49c007167
Signer:
Signing key:
Signing status: N
Tree: e937c2a7d9ef569775583cebc41be4828cda1702
File Lines added Lines deleted
docker/dev.sh 18 0
docker/docker-compose-dev.yml 34 0
docker/inspect_pg.sh 3 0
inc/admin/distros.inc.php 90 0
inc/mime.inc.php 27 24
inc/user/packages.inc.php 612 0
inc/user/packages_rpm.inc.php 558 0
inc/user/pkg_map.inc.php 563 0
inc/user/pkg_repo.inc.php 738 0
inc/user/pkg_rights.inc.php 84 0
inc/user/pkg_subrepo.inc.php 879 0
inc/util2.inc.php 261 0
inc/webhooks.inc.php 30 17
inc/wh/build.inc.php 90 41
root/themes/default/admin/distros/list/footer.html 8 0
root/themes/default/admin/distros/list/header.html 17 0
root/themes/default/admin/distros/list/line.html 8 0
root/themes/default/admin/distros/list/nodata.html 1 1
root/themes/default/admin/distros/menu.html 5 0
root/themes/default/admin/distros/update_ok.html 3 0
root/themes/default/doc/demo/demos/packages/0/main.html 31 0
root/themes/default/doc/demo/demos/packages/0/name.html 1 0
root/themes/default/doc/demo/demos/packages/create/main.html 55 0
root/themes/default/doc/demo/demos/packages/create/main.html.oldway 42 0
root/themes/default/doc/demo/demos/packages/create/name.html 1 0
root/themes/default/doc/demo/demos/packages/global/main.html 19 0
root/themes/default/doc/demo/demos/packages/global/name.html 1 0
root/themes/default/doc/demo/demos/packages/name.html 1 0
root/themes/default/doc/demo/demos/packages/see/main.html 9 0
root/themes/default/doc/demo/demos/packages/see/name.html 0 0
root/themes/default/hints/repo/edit_repo_path_rights.html 0 37
root/themes/default/hints/repo/edit_repo_refs_rights.html 0 56
root/themes/default/hints/repo/edit_repo_rights.html 0 2
root/themes/default/hints/repo/edit_rights.html 0 16
root/themes/default/pkg_repos/welcome_begin.html 4 0
root/themes/default/pkg_repos/welcome_end.html 0 0
root/themes/default/rights/form_pkgrepo.html 6 4
root/themes/default/rights/list_pkgrepo/footer.html 0 0
root/themes/default/rights/list_pkgrepo/header.html 0 0
root/themes/default/rights/list_pkgrepo/line.html 1 1
root/themes/default/rights/list_pkgrepo/nodata.html 0 0
root/themes/default/user/pkg/list/footer.html 0 0
root/themes/default/user/pkg/list/header.html 15 0
root/themes/default/user/pkg/list/line.html 13 0
root/themes/default/user/pkg/list/nodata.html 3 0
root/themes/default/user/pkg/no_packages.html 1 1
root/themes/default/user/pkg/redhat/priv_download.html 14 0
root/themes/default/user/pkg/redhat/pub_download.html 9 0
root/themes/default/user/repo/rights/delete_ok.html 0 3
root/themes/default/user/repo/rights/deny.html 0 3
root/themes/default/user/repo/rights/form_repo_path.html 0 46
root/themes/default/user/repo/rights/form_repo_refs.html 0 46
root/themes/default/user/repo/rights/grant_ok.html 0 3
root/themes/default/user/repo/rights/list_repo_path/header.html 0 24
root/themes/default/user/repo/rights/list_repo_path/line.html 0 12
root/themes/default/user/repo/rights/list_repo_path/nodata.html 0 0
root/themes/default/user/repo/rights/list_repo_refs/header.html 0 24
root/themes/default/user/repo/rights/list_repo_refs/line.html 0 12
root/themes/default/user/repo/rights/list_repo_refs/nodata.html 0 0
root/themes/default/user/settings/packages/map/add_edit.html 37 0
root/themes/default/user/settings/packages/map/add_edit_err.html 1 0
root/themes/default/user/settings/packages/map/add_ok.html 3 0
root/themes/default/user/settings/packages/map/delete_err.html 1 0
root/themes/default/user/settings/packages/map/delete_ok.html 3 0
root/themes/default/user/settings/packages/map/hints.html 2 0
root/themes/default/user/settings/packages/map/id_invalid.html 1 0
root/themes/default/user/settings/packages/map/list/footer.html 0 0
root/themes/default/user/settings/packages/map/list/header.html 22 0
root/themes/default/user/settings/packages/map/list/line.html 11 0
root/themes/default/user/settings/packages/map/list/nodata.html 3 0
root/themes/default/user/settings/packages/map/list_err.html 1 0
root/themes/default/user/settings/packages/map/menu.html 6 0
root/themes/default/user/settings/packages/menu.html 8 0
root/themes/default/user/settings/packages/repo/add_edit.html 28 0
root/themes/default/user/settings/packages/repo/add_edit_err.html 1 0
root/themes/default/user/settings/packages/repo/add_ok.html 3 0
root/themes/default/user/settings/packages/repo/delete_ok.html 3 0
root/themes/default/user/settings/packages/repo/hints.html 2 2
root/themes/default/user/settings/packages/repo/id_invalid.html 1 0
root/themes/default/user/settings/packages/repo/is_public.html 3 0
root/themes/default/user/settings/packages/repo/list/footer.html 0 0
root/themes/default/user/settings/packages/repo/list/header.html 6 8
root/themes/default/user/settings/packages/repo/list/line.html 15 0
root/themes/default/user/settings/packages/repo/list/nodata.html 3 0
root/themes/default/user/settings/packages/repo/list_err.html 3 0
root/themes/default/user/settings/packages/repo/menu.html 6 0
root/themes/default/user/settings/packages/repo/name_duplicate.html 1 0
root/themes/default/user/settings/packages/repo/name_empty.html 1 0
root/themes/default/user/settings/packages/repo/name_invalid.html 1 0
root/themes/default/user/settings/packages/repo/rights_head.html 3 0
root/themes/default/user/settings/packages/subrepo/add_edit.html 29 0
root/themes/default/user/settings/packages/subrepo/add_edit_err.html 1 0
root/themes/default/user/settings/packages/subrepo/add_ok.html 3 0
root/themes/default/user/settings/packages/subrepo/delete_ok.html 3 0
root/themes/default/user/settings/packages/subrepo/hints.html 2 2
root/themes/default/user/settings/packages/subrepo/id_invalid.html 1 0
root/themes/default/user/settings/packages/subrepo/list/footer.html 0 0
root/themes/default/user/settings/packages/subrepo/list/header.html 21 0
root/themes/default/user/settings/packages/subrepo/list/line.html 10 0
root/themes/default/user/settings/packages/subrepo/list/nodata.html 3 0
root/themes/default/user/settings/packages/subrepo/list_err.html 3 0
root/themes/default/user/settings/packages/subrepo/menu.html 6 0
root/themes/default/user/settings/packages/subrepo/name_duplicate.html 1 0
root/themes/default/user/settings/packages/subrepo/name_empty.html 1 0
root/themes/default/user/settings/packages/subrepo/name_invalid.html 1 0
tests/pkg_rpm.php 42 0
tests/pkg_subrepo.php 66 0
tests/wh_build.c 4 0
tests/wh_build.conf 3 0
tests/wh_build.git.sh 31 0
tests/wh_build.make 11 0
tests/wh_build.php 341 0
tests/wh_cloud.git.sh 3 3
File docker/dev.sh added (mode: 100755) (index 0000000..586ce56)
1 #!/bin/bash
2
3 if [ "${1}" = "" ]; then
4 cmd="up"
5 else
6 cmd=${1}
7 fi
8
9 echo "Cleaning..."
10 podman-compose -f docker-compose-dev.yml down
11
12 if [ "${cmd}" != "down" ]; then
13 ./build.sh dev || exit 1
14 echo "Running [${cmd}]..."
15 podman-compose -f docker-compose-dev.yml ${cmd} -d
16 fi
17
18 podman exec -it docker_web_1 /bin/bash
File docker/docker-compose-dev.yml added (mode: 100644) (index 0000000..4507b51)
1 services:
2 web:
3 image: rocketgit/rocketgit:dev
4 restart: always
5 links:
6 - rp
7 ports:
8 - "30022:22"
9 - "30080:80"
10 - "30443:443"
11 - "39418:9418"
12 volumes:
13 - ..:/usr/share/rocketgit
14 - ../samples/cron:/etc/cron.d/rocketgit
15 - ../samples/php-fpm.conf:/etc/rocketgit/php-fpm.conf
16 - ../samples/pool.conf:/etc/rocketgit/pool.conf
17 - ../samples/nginx.conf:/etc/nginx/conf.d/rg.conf
18 - ../samples/config.php:/etc/rocketgit/config.php
19 - ../samples/sshd-akc.conf:/etc/ssh/sshd_config.d/90-rocketgit-akc.conf
20 environment:
21 RG_DEBUG: 1
22 RG_SQL_ADD: host=rp password=rock
23
24 rp:
25 image: postgres
26 restart: always
27 environment:
28 LC_ALL: en_US.UTF-8
29 LC_CTYPE: en_US.UTF-8
30 POSTGRES_INITDB_ARGS: "--data-checksums --auth-host=scram-sha-256"
31 POSTGRES_PASSWORD: rock
32 volumes:
33 - ./init-pg.sh:/docker-entrypoint-initdb.d/rg.sh
34
File docker/inspect_pg.sh added (mode: 100755) (index 0000000..15ae08d)
1 docker run -t -i --rm --volumes-from rocketgit-postgresql:/data \
2 fedora:31 bash
3
File inc/admin/distros.inc.php added (mode: 100644) (index 0000000..a48b868)
1 <?php
2
3 function rg_admin_distros_list($db, $rg, $paras)
4 {
5 rg_log_enter('admin_distros_list paras=' . rg_array2string($paras));
6
7 $ret = '';
8 do {
9 $en = rg_state_get_array($db, 'distros');
10 if ($en === FALSE) {
11 $ret = rg_warning('Cannot load enabled distros!');
12 break;
13 }
14 rg_log_debug('en: ' . print_r($en, TRUE));
15
16 $errmsg = array();
17 $update = rg_var_uint('update');
18 while ($update == 1) {
19 if (!rg_valid_referer()) {
20 $errmsg[] = 'invalid referer; try again';
21 break;
22 }
23
24 if (!rg_token_valid($db, $rg, 'distros', FALSE)) {
25 $errmsg[] = 'invalid token; try again';
26 break;
27 }
28
29 $list = rg_var_str('list');
30 rg_log_debug('list: ' . print_r($list, TRUE));
31
32 $do_update = FALSE;
33 foreach ($en as $env => $enabled) {
34 $v = isset($list[$env]) ? 1 : 0;
35 if ($v == $enabled)
36 continue;
37
38 $en[$env] = $v;
39 $do_update = TRUE;
40 }
41 rg_log_debug('en (after update): ' . print_r($en, TRUE));
42 if ($do_update) {
43 $r = rg_state_set_array($db, 'distros', $en);
44 if ($r !== TRUE) {
45 $errmsg[] = rg_state_error();
46 break;
47 }
48 }
49 $ret .= rg_template('admin/distros/update_ok.html', $rg, TRUE /*xss*/);
50 break;
51 }
52
53 $list = array();
54 foreach ($en as $env => $enabled) {
55 $a = rg_env_info($env);
56 $a['env'] = $env;
57 $a['enabled'] = $enabled;
58 $list[] = $a;
59 }
60 $list = rg_distro_sort($list);
61 //rg_log_debug('list for template: ' . print_r($list, TRUE));
62
63 $ret .= rg_template_errmsg($errmsg);
64
65 $rg['rg_form_token'] = rg_token_get($db, $rg, 'distros');
66 $ret .= rg_template_table('admin/distros/list', $list, $rg);
67 } while (0);
68
69 rg_log_exit();
70 return $ret;
71 }
72
73 function rg_admin_distros($db, &$rg, $paras)
74 {
75 rg_log_enter('admin_distros paras=' . rg_array2string($paras));
76
77 $_op = empty($paras) ? 'list' : array_shift($paras);
78
79 $rg['admin_distros_menu'][$_op] = 1;
80 $rg['HTML:menu_level2'] = rg_template('admin/distros/menu.html', $rg, TRUE /*xss*/);
81
82 switch ($_op) {
83 case 'list': $ret = rg_admin_distros_list($db, $rg, $paras); break;
84 default: $ret = rg_warning('invalid operation'); break;
85 }
86
87 rg_log_exit();
88 return $ret;
89 }
90
File inc/mime.inc.php changed (mode: 100644) (index c1765b5..d406ad8)
1 1 <?php <?php
2 2
3 3 /* /*
4 * Sets a content type based on extention
4 * Sets a content type based on extension
5 5 */ */
6 6 function rg_content_type_by_ext($f) function rg_content_type_by_ext($f)
7 7 { {
 
... ... function rg_content_type_by_ext($f)
16 16 if (strcasecmp($e, 'apng') == 0) if (strcasecmp($e, 'apng') == 0)
17 17 return 'text/png'; return 'text/png';
18 18
19 if (strcasecmp($e, 'txt') == 0)
20 return 'text/plain';
19 if (strcasecmp($e, 'doc') == 0)
20 return 'application/msword';
21
22 if (strcasecmp($e, 'gz') == 0)
23 return 'application/gzip';
21 24
22 25 if (strcasecmp($e, 'html') == 0) if (strcasecmp($e, 'html') == 0)
23 26 return 'text/html'; return 'text/html';
24 27
25 if (strcasecmp($e, 'xls') == 0)
26 return 'application/vnd.ms-excel';
28 if (strcasecmp($e, 'jpg') == 0)
29 return 'image/jpeg';
30 if (strcasecmp($e, 'jpeg') == 0)
31 return 'image/jpeg';
27 32
28 if (strcasecmp($e, 'doc') == 0)
29 return 'application/msword';
33 if (strcasecmp($e, 'json') == 0)
34 return 'application/json';
30 35
31 36 if (strcasecmp($e, 'ods') == 0) if (strcasecmp($e, 'ods') == 0)
32 37 return 'application/vnd.oasis.opendocument.spreadsheet'; return 'application/vnd.oasis.opendocument.spreadsheet';
 
... ... function rg_content_type_by_ext($f)
34 39 if (strcasecmp($e, 'odt') == 0) if (strcasecmp($e, 'odt') == 0)
35 40 return 'application/vnd.oasis.opendocument.text'; return 'application/vnd.oasis.opendocument.text';
36 41
37 if (strcasecmp($e, 'gz') == 0)
38 return 'application/gzip';
39
40 42 if (strcasecmp($e, 'pdf') == 0) if (strcasecmp($e, 'pdf') == 0)
41 43 return 'application/pdf'; return 'application/pdf';
42 44
43 if (strcasecmp($e, 'zip') == 0)
44 return 'application/zip';
45 if (strcasecmp($e, 'png') == 0)
46 return 'image/png';
45 47
46 if (strcasecmp($e, 'xml') == 0)
47 return 'application/xml';
48 if (strcasecmp($e, 'rpm') == 0)
49 return 'application/x-rpm';
48 50
49 if (strcasecmp($e, 'json') == 0)
50 return 'application/json';
51 if (strcasecmp($e, 'svg') == 0)
52 return 'image/svg+xml';
53
54 if (strcasecmp($e, 'txt') == 0)
55 return 'text/plain';
51 56
52 57 if (strcasecmp($e, 'whl') == 0) if (strcasecmp($e, 'whl') == 0)
53 58 return 'application/zip'; return 'application/zip';
54 59
55 if (strcasecmp($e, 'png') == 0)
56 return 'image/png';
60 if (strcasecmp($e, 'xls') == 0)
61 return 'application/vnd.ms-excel';
57 62
58 if (strcasecmp($e, 'jpg') == 0)
59 return 'image/jpeg';
60 if (strcasecmp($e, 'jpeg') == 0)
61 return 'image/jpeg';
63 if (strcasecmp($e, 'xml') == 0)
64 return 'text/xml';
62 65
63 if (strcasecmp($e, 'svg') == 0)
64 return 'image/svg+xml';
66 if (strcasecmp($e, 'zip') == 0)
67 return 'application/zip';
65 68
66 69 return $b; return $b;
67 70 } }
File inc/user/packages.inc.php added (mode: 100644) (index 0000000..144a3a8)
1 <?php
2 include_once(__DIR__ . '/pkg_repo.inc.php');
3 include_once(__DIR__ . '/pkg_subrepo.inc.php');
4 include_once(__DIR__ . '/pkg_map.inc.php');
5 include_once(__DIR__ . '/packages_rpm.inc.php');
6
7 /*
8 * This is called from rgfs.php to validate a creation of a path
9 */
10 function rg_packages_validate_path($db, $path, $allow_paths)
11 {
12 $ret = array('ok' => 0, 'user_path' => '');
13 do {
14 $r = rg_envs_tree($db, TRUE /*only enabled*/);
15 if ($r['ok'] != 1) {
16 $ret['errmsg'] = 'cannot load envs: ' . $r['errmsg'];
17 break;
18 }
19 $d = $r['tree'];
20
21 $x = explode('/', $path);
22 $junk = array_shift($x); // because path starts with '/', we ignore the empty element
23
24 $distro = array_shift($x);
25 if (!isset($d[$distro])) {
26 $ret['errmsg'] = 'invalid distro [' . $distro . ']';
27 break;
28 }
29
30 if (empty($x)) {
31 $ret['ok'] = 1;
32 break;
33 }
34
35 $major = array_shift($x);
36 if (!isset($d[$distro]['versions'][$major])) {
37 $ret['errmsg'] = 'invalid major [' . $major . ']';
38 break;
39 }
40
41 if (empty($x)) {
42 $ret['ok'] = 1;
43 break;
44 }
45
46 $arch = array_shift($x);
47 if (!isset($d[$distro]['versions'][$major]['archs'][$arch])) {
48 $ret['errmsg'] = 'invalid arch [' . $arch . ']';
49 break;
50 }
51
52 if (empty($x)) {
53 $ret['ok'] = 1;
54 break;
55 }
56
57 if (strcmp($d[$distro]['pkg_type'], 'rpm') != 0) {
58 $ret['errmsg'] = 'unsupported pkg type';
59 break;
60 }
61
62 $type = array_shift($x);
63 $allow = array('os', 'debug', 'src');
64 if (!in_array($type, $allow)) {
65 $ret['errmsg'] = 'invalid type [' . $type . ']';
66 break;
67 }
68
69 if (empty($x)) {
70 $ret['ok'] = 1;
71 break;
72 }
73
74 $ret['user_path'] = implode('/', $x);
75
76 $match = FALSE;
77 $next1 = array_shift($x);
78 $next2 = !empty($x) ? array_shift($x) : '';
79 foreach ($allow_paths as $i) {
80 rg_log_debug('[' . $next1 . ']/[' . $next2 . '] vs [' . $i['next1'] . ']/[' . $i['next2'] . ']');
81
82 if (preg_match('/^' . $i['next1'] . '$/uD', $next1) !== 1)
83 continue;
84
85 if (!empty($next2)
86 && preg_match('/^' . $i['next2'] . '$/uD', $next2) !== 1)
87 continue;
88
89 $match = TRUE;
90 break;
91 }
92 if (!$match) {
93 $ret['errmsg'] = 'not allowed path [' . $next1 . ']/[' . $next2 . ']';
94 break;
95 }
96
97 $ret['ok'] = 1;
98 } while (0);
99
100 return $ret;
101 }
102
103 function rg_packages_get_link($db, $a)
104 {
105 if (strcmp($a['distro_pkg_type'], 'rpm') == 0)
106 return rg_packages_rpm_get_link($db, $a);
107
108 return FALSE;
109 }
110
111 /*
112 * Instructions (distro dependent) on how to install a package
113 */
114 function rg_packages_howto($a, $user, $repo_name, $meta)
115 {
116 if (strcmp($a['distro_pkg_type'], 'rpm') == 0)
117 return rg_packages_rpm_howto($a, $user, $repo_name, $meta);
118
119 return 'TODO';
120 }
121
122 /*
123 * Splits meta info in a digerable form
124 */
125 function rg_packages_meta_split($meta)
126 {
127 $ret = array();
128 foreach ($meta as $path => $i) {
129 $a = explode('/', $path, 5);
130 $distro = $a[1];
131 $major = $a[2];
132 $arch = $a[3];
133 $rest = $a[4];
134
135 if (!isset($ret[$distro]))
136 $ret[$distro] = array();
137
138 if (!isset($ret[$distro][$major]))
139 $ret[$distro][$major] = array();
140
141 if (!isset($ret[$distro][$major][$arch]))
142 $ret[$distro][$major][$arch] = array();
143
144 $ret[$distro][$major][$arch][$rest] = $i;
145 }
146
147 return $ret;
148 }
149
150 /*
151 * Checks metadata to see if a package was built.
152 * Why? Because we do not want to show links to packages
153 * which are not built yet.
154 */
155 function rg_packages_are_available($a, $repo_id)
156 {
157 rg_log_enter_ml('packages_are_available: '
158 . ' pr=' . $a['pkg_repo_info']['id']
159 . ' psr=' . $a['pkg_subrepo_info']['id']
160 . ' repo_id=' . $repo_id);
161
162 $ret = FALSE;
163 do {
164 $d = '/var/lib/rocketgit/pkg_repos'
165 . '/' . $a['pkg_repo_info']['id']
166 . '/' . $a['pkg_subrepo_info']['id'];
167 $f = $d . '/meta/' . $repo_id . '.json';
168 $c = @file_get_contents($f);
169 if ($c === FALSE) {
170 rg_log_debug('file [' . $f . ' cannot be opened');
171 break;
172 }
173
174 $u = rg_unserialize($c);
175 if ($u === FALSE)
176 break; // TODO: return a temporary error?
177
178 // Load more info about files (size and nlink)
179 foreach ($u as $subpath => &$i) {
180 $s = @stat($d . $subpath);
181 if ($s === FALSE) {
182 rg_log('cannot stat ' . $d . '/' . $subpath);
183 unset($u[$subpath]);
184 continue;
185 }
186
187 $i['size'] = $s['size'];
188 $i['size_nice'] = rg_1024($i['size']);
189 $i['nlink'] = $s['nlink'];
190 }
191 unset($i);
192
193 $ret = rg_packages_meta_split($u);
194 rg_log_debug('meta: ' . print_r($ret, TRUE));
195 } while (0);
196
197 rg_log_exit();
198 return $ret;
199 }
200
201 /*
202 * Sorts package meta array
203 */
204 function rg_packages_sort_meta($a, $b)
205 {
206 $r = strcmp($a['subsubtype'], $b['subsubtype']);
207 if ($r != 0)
208 return $r;
209
210 if ($a['ctime'] < $b['ctime'])
211 return 1;
212
213 if ($a['ctime'] > $b['ctime'])
214 return -1;
215
216 return 0;
217 }
218
219 function rg_packages_prepare_meta(&$m, $repo_url)
220 {
221 foreach ($m as $f => &$i) {
222 $url = $repo_url . '/source/log/commit/' . rawurlencode($i['head']);
223 $i['head_link'] = '<a href="' . $url . '" target="_blank">' . rg_xss_safe($i['head']) . '</a>';
224
225 // TODO: this may be different for Debian!
226 $p = explode('/', $f, 3);
227 $i['subsubtype'] = $p[0];
228 }
229
230 uasort($m, 'rg_packages_sort_meta');
231 }
232
233 /*
234 * Returns a tree table with all available repositories+distro+major+arch
235 * for @uid.
236 * TODO: get rid of $rg?
237 */
238 function rg_packages_info($db, $uid, $rg, $needed_flags)
239 {
240 rg_log_enter('packages_info needed_flags=' . $needed_flags);
241
242 $ret = array('ok' => 0);
243 do {
244 $ui_page = rg_ui_page();
245 //rg_log_debug('ui_page: ' . print_r($ui_page, TRUE));
246
247 // Load available pkg repos for an uid (including global ones)
248 $repo_list = rg_pkg_repo_list($db, $uid);
249 if ($repo_list === FALSE) {
250 $ret['errmsg'] = rg_pkg_repo_error();
251 break;
252 }
253 //rg_log_debug('pkg_repo_list returned: ' . print_r($repo_list, TRUE));
254
255 // Filter repo_list based by @flags/rights
256 foreach ($repo_list as $pri => &$ri) {
257 $skip = FALSE;
258 $nf = $needed_flags;
259 while (1) {
260 $f = substr($nf, 0, 1);
261 if (empty($f))
262 break;
263
264 if (strstr($ri['flags'], $f) === FALSE) {
265 rg_log_debug('skip ' . $ri['name']
266 . ' because it does not contain flag ' . $f);
267 $skip = TRUE;
268 break;
269 }
270 $nf = substr($nf, 1);
271 }
272 if ($skip && rg_pkg_has_rights($db, $ri, $rg, 'A'))
273 $skip = FALSE;
274 if ($skip) {
275 unset($repo_list[$pri]);
276 continue;
277 }
278
279 // We do not need this variables
280 unset($ri['gpg_priv_key']);
281 unset($ri['gpg_pub_key']);
282 unset($ri['rgfs_key']);
283
284 if ($ri['uid'] > 0) { // is a user repo
285 $ui = rg_user_info($db, $ri['uid'], '', '');
286 if ($ui['exists'] != 1) {
287 rg_internal_error('user missing for a repo');
288 unset($repo_list[$pri]);
289 continue;
290 }
291 $repo_list[$pri]['username'] = $ui['username'];
292 }
293
294 $repo_list[$pri]['subrepos'] = array();
295 }
296 unset($ri);
297
298 // Load available subrepos for an uid (including global ones)
299 $subrepo_list = rg_pkg_subrepo_list($db, $uid);
300 if ($subrepo_list === FALSE) {
301 $ret['errmsg'] = $list['errmsg'];
302 break;
303 }
304
305 // Filter subrepo list and split subrepos per repo
306 foreach ($subrepo_list as $pkg_subrepo_id => $si) {
307 if (!isset($repo_list[$si['pkg_repo_id']])) {
308 rg_log_debug('skip pkg_subrepo ['
309 . $si['name']
310 . '] because pkg_repo '
311 . $si['pkg_repo_id']
312 . ' does not exists');
313 unset($subrepo_list[$pkg_subrepo_id]);
314 continue;
315 }
316
317 $repo_list[$si['pkg_repo_id']]['subrepos'][$pkg_subrepo_id] = $si;
318 }
319 unset($subrepo_list);
320
321 $ret['ok'] = 1;
322 $ret['list'] = array();
323 $a = array();
324 $list = array();
325 foreach ($repo_list as $pkg_repo_id => $ri) {
326 rg_log_enter('pkg_repo_id: ' . $pkg_repo_id . ' [' . $ri['name'] . ']');
327
328 $subrepos = $ri['subrepos']; unset($ri['subrepos']);
329 $a['pkg_repo_info'] = $ri;
330 $global = $ri['uid'] == 0 ? 1 : 0;
331
332 $list_subrepo = array();
333 foreach ($subrepos as $pkg_subrepo_id => $sri) {
334 rg_log_enter('pkg_subrepo_id: ' . $pkg_subrepo_id . ' [' . $sri['name'] . ']');
335 rg_log_debug('sri[distro_info]: ' . print_r($sri['distro_info'], TRUE));
336
337 if (empty($sri['distro_info'])) {
338 rg_log_debug('empty sri distros => skip it');
339 rg_log_exit();
340 continue;
341 }
342 $distros = rg_distro_info2tree($sri['distro_info']);
343
344 $a['pkg_subrepo_info'] = $sri;
345
346 // If we are on /opt/pkg_repos, we do not have a repo
347 if ($ui_page['uid'] > 0)
348 $meta = rg_packages_are_available($a, $rg['ri']['repo_id']);
349
350 $list_distro = array();
351 foreach ($distros as $distro => $per_distro) {
352 rg_log_enter('distro ' . $distro);
353
354 $env_info = rg_env_info($distro);
355 $a['distro'] = $distro;
356
357 $list_major = array();
358 foreach ($per_distro['versions'] as $major => $per_major) {
359 rg_log_enter('major: ' . $major);
360
361 $a['major'] = $major;
362
363 $list_arch = array();
364 foreach ($per_major['archs'] as $arch => $per_arch) {
365 rg_log_enter('arch ' . $arch);
366
367 if ($ui_page['uid'] > 0) {
368 if (empty($meta[$distro][$major][$arch])) {
369 rg_log_debug('skip arch ' . $arch
370 . ' because meta[distro][major][arch] is empty');
371 rg_log_exit();
372 continue;
373 }
374
375 $m = $meta[$distro][$major][$arch];
376 } else {
377 $m = FALSE;
378 }
379
380 $a['arch'] = $arch;
381 foreach ($per_arch as $k => $v)
382 $a[$k] = $v;
383 $r = rg_packages_get_link($db, $a);
384 $a['dotrepo_pkg_name'] = $r['dotrepo_pkg_name'];
385 $a['dotrepo_pkg_url'] = $r['dotrepo_pkg_url'];
386
387 if ($ui_page['uid'] > 0) {
388 $_user = $ui_page['username'];
389 $_repo_name = $rg['ri']['name'];
390 $repo_url = rg_re_repopage($ui_page, $_repo_name);
391
392 // Filter meta
393 $p = $_user . '+' . $_repo_name . '-';
394 $p_len = strlen($p);
395 $m2 = array();
396 foreach ($m as $f => $i) {
397 $f2 = basename($f);
398 if (strncmp($f2, $p, $p_len) != 0) {
399 rg_log_debug('no match [' . $f2 . '] [' . $p . ']');
400 continue;
401 }
402
403 $i['f2'] = $f2;
404 $m2[$f] = $i;
405 }
406 $m = $m2;
407 if (empty($m)) {
408 rg_log_debug('empty meta after filtering');
409 rg_log_exit();
410 continue;
411 }
412 rg_packages_prepare_meta($m, $repo_url);
413 } else {
414 $_user = '';
415 $_repo_name = '';
416 }
417
418 $list_arch[$arch] = array(
419 'howto' => rg_packages_howto($a, $_user, $_repo_name, $m),
420 'meta' => $m
421 );
422 rg_log_exit();
423 }
424 if (!empty($list_arch))
425 $list_major[$major] = $list_arch;
426 rg_log_exit();
427 }
428 if (!empty($list_major))
429 $list_distro[$distro] =
430 array('info' => $env_info, 'list' => $list_major);
431 rg_log_exit();
432 }
433 if (!empty($list_distro))
434 $list_subrepo[$pkg_subrepo_id] =
435 array('info' => $sri, 'list' => $list_distro);
436 rg_log_exit();
437 }
438 if (!empty($list_subrepo))
439 $list[$pkg_repo_id] =
440 array('info' => $ri, 'list' => $list_subrepo);
441 rg_log_exit();
442 }
443 if (!empty($list))
444 $ret['list'][$global] = $list;
445 } while (0);
446
447 rg_log_exit();
448 return $ret;
449 }
450
451 /*
452 * This is called from the repo page
453 * TODO: use a HTML template
454 */
455 function rg_packages_repo_page($db, $rg)
456 {
457 rg_log_enter('packages_repo_page');
458 //rg_log_ml('rg: ' . rg_array2string($rg));
459
460 do {
461 // We list only public repos if a user has no access.
462 // TODO: We must switch to normal rights check!
463 $ui_page = rg_ui_page();
464 $uid = $ui_page['uid'];
465 $ui_login = rg_ui_login();
466 $flags = $ui_login['uid'] == $uid ? '' : 'P';
467
468 $r = rg_packages_info($db, $uid, $rg, $flags);
469 if ($r['ok'] != 1) {
470 $rg['errmsg'] = $r['errmsg'];
471 $ret = rg_template('internal_err.html', $rg, TRUE /*xss*/);
472 break;
473 }
474 rg_log_debug('packages_info returned: ' . print_r($r['list'], TRUE));
475
476 if (empty($r['list'])) {
477 $ret = rg_template('user/pkg/no_packages.html', $rg, TRUE /*xss*/);
478 break;
479 }
480
481 $ret = '<div class="pkg">' . "\n";
482 foreach ($r['list'] as $global => $per_type) {
483 $ret .= '<details open><summary>Type: <b>' . ($global == 1 ? 'Global' : 'User') . '</b></summary>';
484 foreach ($per_type as $pkg_repo_id => $per_repo) {
485 // TODO: remove this: rg_pkg_repo_cosmetic($per_repo['info']);
486 $ret .= '<details open>'
487 . '<summary>Repo: <b>' . rg_xss_safe($per_repo['info']['name']) . '</b>'
488 . ' - ' . (strstr($per_repo['info']['flags'], 'P') ? 'public' : 'private')
489 . '</summary>';
490
491 foreach ($per_repo['list'] as $pkg_subrepo_id => $per_subrepo) {
492 $ret .= '<details open><summary>Subrepo: <b>' . rg_xss_safe($per_subrepo['info']['name']) . '</b></summary>';
493 foreach ($per_subrepo['list'] as $distro => $per_distro) {
494 $ret .= '<details open><summary>Distribution: <b>' . rg_xss_safe($per_distro['info']['distro_nice']) . '</b></summary>';
495 foreach ($per_distro['list'] as $major => $per_major) {
496 $ret .= '<details open><summary>Major version: <b>' . rg_xss_safe($major) . '</b></summary>';
497 foreach ($per_major as $arch => $per_arch) {
498 $ret .= '<details open><summary>Architecture: <b>' . rg_xss_safe($arch) . '</b></summary>';
499 $ret .= $per_arch['howto'];
500 $ret .= '</details>' . "\n";
501 }
502 $ret .= '</details>' . "\n";
503 }
504 $ret .= '</details>' . "\n";
505 }
506 $ret .= '</details>' . "\n";
507 }
508 $ret .= '</details>' . "\n";
509 }
510 $ret .= '</details>' . "\n";
511 }
512 $ret .= '</div>' . "\n";
513 } while (0);
514
515 rg_log_exit();
516 return $ret;
517 }
518
519 /*
520 * Main high level function for packages
521 */
522 function rg_packages_high_level($db, &$rg, $paras)
523 {
524 rg_prof_start('packages_high_level');
525 rg_log_enter('packages_high_level');
526
527 $ret = '';
528 while (1) {
529 $op = empty($paras) ? 'repo' : array_shift($paras);
530 $rg['menu2']['packages'] = array($op => 1);
531
532 switch ($op) {
533 case 'repo':
534 $ret .= rg_pkg_repo_high_level($db, $rg, $paras);
535 break;
536
537 case 'subrepo':
538 $ret .= rg_pkg_subrepo_high_level($db, $rg, $paras);
539 break;
540
541 case 'map':
542 $ret .= rg_pkg_maps_high_level($db, $rg, $paras);
543 break;
544 }
545
546 $rg['HTML:menu_level2'] =
547 rg_template('user/settings/packages/menu.html', $rg, TRUE /*xss*/);
548
549 break;
550 }
551
552 rg_log_exit();
553 rg_prof_end('packages_high_level');
554 return $ret;
555 }
556
557 /*
558 * Called from index.php when a 'yum'/'dnf' etc. command is invoked
559 * Example paras for rpm: 0=[global] 1=[testing] 2=[fedora] 3=[33] 4=[x86_64] 5=[os] 6=[rocketgit-global-testing-1.9.noarch.rpm
560 * @pass - password provided by the yum/dnf/apt
561 * TODO: Not clear if the repo and subrepo name should appear in rpm name.
562 */
563 function rg_packages_web($db, $rg, $paras, $pass)
564 {
565 rg_log_enter('packages_web paras=' . rg_array2string($paras));
566 do {
567 $a = array();
568 $type = @array_shift($paras);
569 if (strcmp($type, 'user') == 0)
570 $a['username'] = @array_shift($paras);
571 else
572 $a['username'] = '';
573 $a['pkg_repo_name'] = @array_shift($paras);
574 $a['pkg_subrepo_name'] = @array_shift($paras);
575 $a['distro'] = @array_shift($paras);
576 $a['sent_pass'] = $pass;
577
578 $r = rg_envs_tree($db, TRUE /*only enabled*/);
579 if ($r['ok'] != 1) {
580 rg_log('cannot load envs: ' . $r['errmsg']);
581 header($rg['proto'] . ' 500 internal error');
582 echo 'cannot load envs tree' . "\n";
583 break;
584 }
585 $distros = $r['tree'];
586 rg_log_debug('distros: ' . rg_array2string($distros));
587
588 if (!isset($distros[$a['distro']])) {
589 rg_log('unsupported distro [' . $a['distro'] . ']');
590 header($rg['proto'] . ' 404 unsupported distro');
591 echo 'unsupported distro' . "\n";
592 break;
593 }
594 $di = $distros[$a['distro']];
595
596 if (strcmp($di['pkg_type'], 'rpm') != 0) {
597 rg_log('unsupported pkg repo type');
598 header($rg['proto'] . ' 404 unsupported pkg repo type');
599 echo 'unsupported pkg repo type' . "\n";
600 break;
601 }
602
603 $a['major'] = preg_replace('/[^0-9]/', '', @array_shift($paras));
604 $a['arch'] = preg_replace('/[^-_0-9a-zA-Z]/', '', @array_shift($paras));
605 $a['type'] = @array_shift($paras);
606 $a['path'] = implode('/', $paras);
607
608 rg_packages_rpm_helper($db, $rg, $a);
609 } while (0);
610
611 rg_log_exit();
612 }
File inc/user/packages_rpm.inc.php added (mode: 100644) (index 0000000..5600724)
1 <?php
2 require_once(__DIR__ . '/../events.inc.php');
3 require_once(__DIR__ . '/../mime.inc.php');
4
5 /*
6 * Event functions
7 */
8 $_f = array(
9 'pkg_generate_dotrepo_rpm_callback' => 'rg_pkg_event_generate_dotrepo_rpm_callback',
10 'pkg_generate_dotrepo_rpm' => 'rg_pkg_event_generate_dotrepo_rpm'
11 );
12 rg_event_register_functions($_f);
13
14 /*
15 * Called when a dotrepo was done
16 * TODO: what happens when there is an error building the dotrepo?
17 */
18 function rg_pkg_event_generate_dotrepo_rpm_callback($db, $ev)
19 {
20 rg_log_enter('pkg_event_generate_dotrepo_rpm_callback');
21 //rg_log_debug('req: ' . rg_array2string($ev['job']['request']));
22
23 $ret = FALSE;
24 do {
25 $req = $ev['job']['request'];
26
27 $err = FALSE;
28 foreach ($req['rpm_repo_files'] as $pkg_subrepo_id => $junk) {
29 $sri = $req['pkg_subrepos'][$pkg_subrepo_id];
30 $ver = $sri['version'];
31 $di = array($req['env'] => array('dotrepo' => $ver));
32 $r = rg_pkg_subrepo_update_distro_info($db,
33 $req['uid'], $pkg_subrepo_id, $di);
34 if ($r['ok'] != 1) {
35 $err = TRUE;
36 break;
37 }
38 }
39 if ($err)
40 break;
41
42 $ret = array();
43
44 $s = $ev['status'];
45 //rg_log_debug('status: ' . rg_array2string($s));
46 if (!empty($s['pkg_subrepo_dirty'])) {
47 rg_log_debug('trigger ev pkg_subrepo_regenerate');
48 $a = array(
49 'category' => 'pkg_subrepo_regenerate',
50 'prio' => 100,
51 'uid' => 0,
52 'repo_id' => $req['repo_id'],
53 'repo_username' => $req['repo_username'],
54 'head' => $req['head'],
55 'orig_job_id' => $ev['job']['id'],
56 'log_sid' => $req['log_sid'],
57 'pkg_subrepo_id_list' => $s['pkg_subrepo_dirty'],
58 'env' => $req['env']
59 );
60 $ret[] = $a;
61 }
62 } while (0);
63
64 rg_log_exit();
65 return $ret;
66 }
67
68 /*
69 * Prepares 'ev' for dotrepo building.
70 * Helper for rg_pkg_subrepo_event_regenerate and
71 * rg_pkg_event_generate_dotrepo_rpm.
72 * TODO: add a generic function which will call this function for rpm.
73 */
74 function rg_pkg_prepare_ev_for_dotrepo($db, &$ev)
75 {
76 rg_log_enter('rg_pkg_prepare_ev_for_dotrepo');
77
78 $ret = array('ok' => 0);
79 do {
80 $r = rg_envs_tree($db, TRUE /*only_enabled*/);
81 if ($r['ok'] != 1) {
82 $ret['errmsg'] = $r['errmsg'];
83 break;
84 }
85 rg_log_debug('tree: ' . print_r($r['tree'], TRUE));
86
87 if (!rg_envs_tree_is_enabled($r['tree'], $ev['env'])) {
88 rg_log_debug('env ' . $ev['env'] . ' is not enabled in rg_envs_tree!');
89 $ret['ok'] = 1;
90 break;
91 }
92
93 $ti = rg_envs_tree_info($r['tree'], $ev['env']);
94 if (strcmp($ti['pkg_type'], 'rpm') != 0) {
95 $ret['ok'] = 1;
96 break;
97 }
98
99 rg_log_debug('adding rpm_repo_files...');
100 $files = array();
101 foreach ($ev['pkg_maps'] as $mi) {
102 $pkg_subrepo_id = $mi['pkg_subrepo_id'];
103 $sri = $ev['pkg_subrepos'][$pkg_subrepo_id];
104 $pkg_repo_id = $sri['pkg_repo_id'];
105
106 $ri = $ev['pkg_repos'][$pkg_repo_id];
107 //rg_log_debug('ri: ' . rg_array2string($ri));
108 if ($ev['uid'] != $ri['uid']) {
109 rg_log_debug('we cannot build this'
110 . ' dotrepo because ri[uid](' . $ri['uid']
111 . ') != ev[uid](' . $ev['uid'] . ')');
112 continue;
113 }
114
115 if (!isset($ev['force_regenerate_dotrepo'])) {
116 $di = $sri['distro_info'];
117 rg_log_debug('di: ' . rg_array2string($di));
118 if (isset($di[$ev['env']]['dotrepo'])
119 && ($di[$ev['env']]['dotrepo'] == $sri['version'])) {
120 rg_log_debug('dotrepo for '
121 . $ev['env'] . ' already generated; skip it');
122 continue;
123 }
124 }
125
126 // TODO: replace $di (used above) with below $d?
127 $di = rg_env_info($ev['env']);
128
129 $r = rg_packages_rpm_dotrepo_files($db, $ev['uid'],
130 $pkg_subrepo_id, $di['distro']);
131 if ($r['ok'] != 1) {
132 $ret['errmsg'] = $r['errmsg'];
133 break;
134 }
135 unset($r['ok']);
136 $files[$pkg_subrepo_id] = $r;
137 }
138 $ev['rpm_repo_files'] = $files;
139
140 $ev['event_callbacks'] = array('pkg_generate_dotrepo_rpm_callback');
141
142 $ev['exec']['prepare_rpms'] = 1;
143 $ev['exec']['copy_to_rgfs'] = 1;
144
145 $ret['ok'] = 1;
146 } while (0);
147
148 rg_log_exit();
149 return $ret;
150 }
151
152 /*
153 * This is called when a (sub)repo is created/updated to generate the dotrepo rpm.
154 * It is also called when the first package is added to a pkg subrepo.
155 */
156 function rg_pkg_event_generate_dotrepo_rpm($db, $ev)
157 {
158 rg_log_enter('pkg_event_generate_dotrepo_rpm');
159 rg_log_debug('ev: ' . rg_array2string($ev));
160
161 $ret = FALSE;
162 do {
163 // Clean not needed stuff
164 unset($ev['head']);
165 unset($ev['repo_id']);
166 unset($ev['repo_username']);
167
168 $ev['exec'] = array();
169 // For security: we do not want to allow a malformed repo.
170 $ev['worker_must_be_global'] = 1;
171
172 $ev['pkg_maps'] = array();
173 $ev['pkg_repos'] = array();
174 $ev['pkg_subrepos'] = array();
175
176 $pkg_subrepo_id = $ev['pkg_subrepo_id'];
177 $sri = rg_pkg_subrepo_info($db, $ev['uid'], $pkg_subrepo_id);
178 if ($sri['ok'] != 1)
179 break;
180 $ev['pkg_subrepos'][$pkg_subrepo_id] = $sri;
181
182 $pkg_repo_id = $sri['pkg_repo_id'];
183 $ri = rg_pkg_repo_info($db, $ev['uid'], $pkg_repo_id);
184 if ($ri['ok'] != 1)
185 break;
186 $ev['pkg_repos'][$pkg_repo_id] = $ri;
187
188 // Fake pkg_maps
189 $ev['pkg_maps'][] = array(
190 'pkg_subrepo_id' => $pkg_subrepo_id,
191 'flags' => ''
192 );
193
194 $r = rg_pkg_prepare_ev_for_dotrepo($db, $ev);
195 if ($r['ok'] != 1) {
196 rg_log('Cannot prepare ev: ' . $r['errmsg']);
197 break;
198 }
199
200 // Prio is 2 less than normal (10)
201 $r = rg_builder_add($db, 0 /*repo_id*/, 8 /*prio*/, $ev);
202 if ($r['ok'] != 1) {
203 rg_log('Cannot add builder job: ' . $r['errmsg']);
204 $ret = FALSE;
205 break;
206 }
207
208 $ret = array();
209 } while (0);
210
211 rg_log_exit();
212 return $ret;
213 }
214
215 $spec_template = ''
216 . 'Summary: @@nice_name@@ package repository' . "\n"
217 . 'Name: @@name@@' . "\n"
218 . 'Source: https://rocketgit.com/bla/%{name}-%{version}.tar.gz' . "\n"
219 . 'Version: @@version@@' . "\n"
220 . 'Release: 1' . "\n"
221 . 'License: GPL' . "\n"
222 . 'URL: https://rocketgit.com' . "\n"
223 . 'BuildArch: noarch' . "\n"
224 . "\n"
225 . '%description' . "\n"
226 . '@@nice_name@@ repository; check https://rocketgit.com for more info' . "\n"
227 . "\n"
228 . '%prep' . "\n"
229 . '%setup' . "\n"
230 . "\n"
231 . '%install' . "\n"
232 . 'make install DESTDIR=${RPM_BUILD_ROOT}' . "\n"
233 . "\n"
234 . '%files' . "\n"
235 . '%attr (-,root,root)' . "\n"
236 . '%attr (@@chmod@@,root,root) /etc/yum.repos.d/*' . "\n" // because we store the password
237 . '%config(noreplace) /etc/yum.repos.d/*' . "\n"
238 . '/etc/pki/rpm-gpg/*' . "\n";
239
240 $make_template = ''
241 . 'install:' . "\n"
242 . ' cp -a etc $(DESTDIR)' . "\n"
243 . "\n";
244
245 // See: https://dnf.readthedocs.io/en/latest/conf_ref.html
246 $_base_url = '@@base_url@@/op/pkgrepo@@global_or_user@@/@@pkg_repo_name@@'
247 . '/@@pkg_subrepo_name@@/@@distro@@/$releasever/$basearch';
248 $repo_template = ''
249 . '[@@name@@]' . "\n"
250 . 'name = @@nice_name@@' . "\n"
251 . 'baseurl = ' . $_base_url . '/os/' . "\n"
252 . 'type = rpm' . "\n"
253 . 'enabled = 1' . "\n"
254 . 'gpgcheck = 1' . "\n"
255 . 'metadata_expire = 1h' . "\n"
256 . 'repo_gpgcheck = 0' . "\n"
257 . 'gpgkey = file:///etc/pki/rpm-gpg/@@name@@.key' . "\n"
258 . 'skip_if_unavailable = True' . "\n"
259 . "\n"
260 . '[@@name@@-debuginfo]' . "\n"
261 . 'name = @@nice_name@@ - debug' . "\n"
262 . 'baseurl = ' . $_base_url . '/debug/' . "\n"
263 . 'type = rpm' . "\n"
264 . 'enabled = 0' . "\n"
265 . 'gpgcheck = 1' . "\n"
266 . 'metadata_expire = 1h' . "\n"
267 . 'repo_gpgcheck = 0' . "\n"
268 . 'gpgkey = file:///etc/pki/rpm-gpg/@@name@@.key' . "\n"
269 . 'skip_if_unavailable = True' . "\n"
270 . "\n"
271 . '[@@name@@-source]' . "\n"
272 . 'name = @@nice_name@@ - source' . "\n"
273 . 'baseurl = ' . $_base_url . '/src/' . "\n"
274 . 'type = rpm' . "\n"
275 . 'enabled = 0' . "\n"
276 . 'gpgcheck = 1' . "\n"
277 . 'metadata_expire = 1h' . "\n"
278 . 'repo_gpgcheck = 0' . "\n"
279 . 'gpgkey = file:///etc/pki/rpm-gpg/@@name@@.key' . "\n"
280 . 'skip_if_unavailable = True' . "\n";
281
282 /*
283 * Helper for 'packages_rpm'
284 */
285 function rg_packages_rpm_helper($db, $rg, $a)
286 {
287 rg_log_enter('packages_rpm_helper');
288 rg_log_debug('a: ' . print_r($a, TRUE));
289
290 do {
291 if (!in_array($a['type'], array('os', 'src', 'debug'))) {
292 rg_log('invalid type ' . $a['type']);
293 header($rg['proto'] . ' 404 Not found');
294 echo 'invalid type' . "\n";
295 break;
296 }
297
298 if (!empty($a['username'])) {
299 $ui = rg_user_info($db, 0, $a['username'], '');
300 if ($ui['exists'] != 1) {
301 rg_log('invalid user ' . $a['username']);
302 header($rg['proto'] . ' 404 Not found');
303 echo 'invalid user' . "\n";
304 break;
305 }
306 $uid = $ui['uid'];
307 } else {
308 $uid = 0;
309 }
310
311 // TODO: this must be in generic code; but we may be missing user?
312 $ri = rg_pkg_repo_info_by_name($db, $uid, $a['pkg_repo_name']);
313 if ($ri['exists'] != 1) {
314 rg_log('Cannot find pkg repo ' . $a['pkg_repo_name']);
315 header($rg['proto'] . ' 404 Not found');
316 echo 'invalid repo' . "\n";
317 break;
318 }
319
320 $sri = rg_pkg_subrepo_info_by_name($db, $uid,
321 $ri['id'], $a['pkg_subrepo_name']);
322 if ($sri['exists'] != 1) {
323 rg_log('Cannot find pkg subrepo ' . $a['pkg_subrepo_name']);
324 header($rg['proto'] . ' 404 Not found');
325 echo 'invalid subrepo' . "\n";
326 break;
327 }
328
329 // TODO: should be this in generic code?
330 if (!strstr($ri['flags'], 'P')) { // pkg repo is private
331 if (!rg_pkg_has_rights($db, $ri, $rg, 'A')) {
332 if (strcmp($a['sent_pass'], $ri['password']) != 0) {
333 rg_log('provided password is not correct!');
334 header($rg['proto'] . ' 404 Not found');
335 echo 'pkg repository not found or you do not'
336 . ' have access' . "\n";
337 break;
338 }
339 }
340 }
341
342 $dir = '/var/lib/rocketgit/pkg_repos'
343 . '/' . $ri['id']
344 . '/' . $sri['id']
345 . '/' . $a['distro']
346 . '/' . $a['major']
347 . '/' . $a['arch']
348 . '/' . $a['type'];
349
350 $r = rg_path_validate($dir, $a['path']);
351 if ($r === FALSE) {
352 rg_security_violation_no_exit('path=' . $a['path']);
353 header($rg['proto'] . ' 404 Not found');
354 echo 'invalid file' . "\n";
355 break;
356 }
357
358 $s = @stat($dir . '/' . $a['path']);
359 if ($s === FALSE) {
360 rg_log('Cannot stat file: ' . rg_php_err());
361 header($rg['proto'] . ' 404 Not found');
362 echo 'missing file' . "\n";
363 break;
364 }
365 header('Content-Length: ' . $s['size']);
366
367 $ext = strrchr($a['path'], '.');
368 $ct = rg_content_type_by_ext($ext);
369 header('Content-Type: ' . $ct);
370
371 $r = @readfile($dir . '/' . $a['path']);
372 if ($r === FALSE) {
373 rg_log('Cannot send file: ' . rg_php_err());
374 header($rg['proto'] . ' 404 Not found');
375 echo 'missing file' . "\n";
376 break;
377 }
378
379 rg_stats_conns_set('bytes_out', $r);
380 } while (0);
381
382 rg_log_exit();
383 }
384
385 /*
386 * Builds a link to a pkg repo
387 */
388 function rg_packages_rpm_get_link($db, $a)
389 {
390 //rg_log_debug('get_link: a: ' . rg_array2string($a));
391
392 $ret = array();
393
394 // Both pkg repo and subrepo names cannot contain '+' and '-'.
395
396 if ($a['pkg_repo_info']['uid'] == 0) {
397 $type_and_username = 'main';
398 $username = '';
399 } else {
400 $type_and_username = 'user/' . $a['pkg_repo_info']['username'];
401 $username = $a['pkg_repo_info']['username'] . '-';
402 }
403
404 $ret['dotrepo_pkg_name'] = 'rocketgit-' . $username
405 . $a['pkg_repo_info']['name']
406 . '-' . $a['pkg_subrepo_info']['name']
407 . '-' . $a['pkg_repo_info']['version'] . '.' . $a['dotrepo']
408 . '-1.noarch.rpm';
409
410 $ret['dotrepo_pkg_url'] = rg_base_url($db, '', '')
411 . '/op/pkgrepo'
412 . '/' . $type_and_username
413 . '/' . $a['pkg_repo_info']['name']
414 . '/' . $a['pkg_subrepo_info']['name']
415 . '/' . $a['distro']
416 . '/' . $a['major']
417 . '/' . $a['arch']
418 . '/os';
419
420 return $ret;
421 }
422
423 /*
424 * Populates the returned array with files and content needed to build a
425 * subrepo rpm (.repo & co. files).
426 */
427 function rg_packages_rpm_dotrepo_files($db, $uid, $pkg_subrepo_id, $distro)
428 {
429 global $spec_template, $make_template, $repo_template;
430
431 rg_log_enter('packages_rpm_repo_files');
432
433 $ret = array('ok' => 0);
434 do {
435 $sri = rg_pkg_subrepo_info($db, $uid, $pkg_subrepo_id);
436 if ($sri['exists'] != 1) {
437 $ret['errmsg'] = 'cannot find subrepo ' . $pkg_subrepo_id;
438 break;
439 }
440
441 $pri = rg_pkg_repo_info($db, $uid, $sri['pkg_repo_id']);
442 if ($pri['exists'] != 1) {
443 $ret['errmsg'] = 'cannot find repo ' . $sri['pkg_repo_id'];
444 break;
445 }
446
447 if ($uid > 0) { // user repos
448 $ui = rg_user_info($db, $uid, '', '');
449 if ($ui['exists'] != 1) {
450 $ret['errmsg'] = 'uknown user';
451 break;
452 }
453 }
454
455 if (($uid == 0) || ($ui['is_admin'] == 1)) {
456 $global_or_user = '/main';
457 $username = '';
458 $name = 'rocketgit-' . $pri['name'] . '-' . $sri['name'];
459 } else {
460 $global_or_user = '/user/' . $ui['username'];
461 $username = $ui['username'] . ' - ';
462 $name = 'rocketgit-' . $ui['username'] . '-'
463 . $pri['name'] . '-' . $sri['name'];
464 }
465
466 $nice_name = 'RocketGit - ' . $username . $pri['name'] . ' - ' . $sri['name'];
467
468 if (strstr($pri['flags'], 'P')) {
469 $_base_url = rg_base_url($db, '', '');
470 $chmod = '644';
471 } else {
472 $_base_url = rg_base_url($db, 'rg', $pri['password']);
473 $chmod = '600';
474 }
475
476 $k = array('/@@name@@/', '/@@version@@/',
477 '/@@distro@@/', '/@@pkg_repo_name@@/',
478 '/@@pkg_subrepo_name@@/', '/@@base_url@@/u',
479 '/@@nice_name@@/u', '/@@global_or_user@@/u',
480 '/@@chmod@@/u');
481 $v = array($name, $pri['version'] . '.' . $sri['version'],
482 $distro, $pri['name'],
483 $sri['name'], $_base_url,
484 $nice_name, $global_or_user,
485 $chmod);
486
487 $spec = preg_replace($k, $v, $spec_template);
488 $ret[$name . '.spec'] = $spec;
489
490 $make = preg_replace($k, $v, $make_template);
491 $ret['Makefile'] = $make;
492
493 $ret['etc/pki/rpm-gpg/' . $name . '.key'] = $pri['gpg_pub_key'];
494
495 $repo = preg_replace($k, $v, $repo_template);
496 $ret['etc/yum.repos.d/' . $name . '.repo'] = $repo;
497
498 $ret['ok'] = 1;
499 } while (0);
500
501 rg_log_exit();
502 return $ret;
503 }
504
505 /*
506 * Instructions on how to install a package
507 * TODO: Showing the details of older packages has no place here!
508 */
509 function rg_packages_rpm_howto($a, $user, $repo_name, $meta)
510 {
511 rg_log_debug('packages_rpm_howto: a: ' . print_r($a, TRUE));
512
513 $private = !strstr($a['pkg_repo_info']['flags'], 'P');
514
515 $other = '';
516 if ($meta) {
517 $other .= "\n";
518 $other .= '<details><summary>Details about all versions</summary>' . "\n";
519 $other .= '<table><tr><th>Name</th><th>Size</th><th>Copies</th><th>Job</th><th>Head</th><th>Worker</th><th>Date (UTC)</th></tr>' . "\n";
520 foreach ($meta as $f => $i) {
521 $other .= '<tr><td>' . rg_xss_safe($f) . '</td>'
522 . '<td>' . $i['size_nice'] . '</td>'
523 . '<td>' . $i['nlink'] . '</td>'
524 . '<td>' . rg_xss_safe($i['job_id']) . '</td>'
525 . '<td>' . $i['head_link'] . '</td>'
526 . '<td>' . rg_xss_safe($i['worker_name']) . '</td>'
527 . '<td>' . gmdate('Y-m-d H:i', $i['ctime']) . '</td>'
528 . '</tr>' . "\n";
529 }
530 $other .= '</table>';
531 $other .= '</details>';
532 }
533
534 // TODO: move this in distro array!
535 $cmd = 'dnf';
536 if (strcmp($a['distro'], 'centos') == 0)
537 if ($a['major'] < 8)
538 $cmd = 'yum';
539
540 $a['user'] = $user;
541 $a['repo_name'] = $repo_name;
542 $a['user_repo_name'] = $user . '+' . $repo_name;
543 $a['cmd'] = $cmd;
544 $a['HTML:other'] = $other;
545
546 $rg['pkg'] = $a;
547
548 if ($private) {
549 // We cannot do it like with the private pkg repo.
550 // We do not want to put the password on the screen.
551 return rg_template('user/pkg/redhat/priv_download.html',
552 $rg, TRUE /*xss*/);
553 } else {
554 return rg_template('user/pkg/redhat/pub_download.html',
555 $rg, TRUE /*xss*/);
556 }
557 }
558
File inc/user/pkg_map.inc.php added (mode: 100644) (index 0000000..ac751e1)
1 <?php
2 require_once(__DIR__ . '/pkg_subrepo.inc.php');
3 require_once(__DIR__ . '/pkg_repo.inc.php');
4
5 $rg_pkg_maps_error = '';
6 function rg_pkg_maps_set_error($str)
7 {
8 global $rg_pkg_maps_error;
9 $rg_pkg_maps_error = $str;
10 rg_log($str);
11 }
12
13 function rg_pkg_maps_error()
14 {
15 global $rg_pkg_maps_error;
16 return $rg_pkg_maps_error;
17 }
18
19 /*
20 * Event functions
21 */
22 $rg_pkg_map_functions = array(
23 'pkg_map_add' => 'rg_pkg_map_event_add',
24 'pkg_map_edit' => 'rg_pkg_map_event_edit'
25 );
26 rg_event_register_functions($rg_pkg_map_functions);
27
28 function rg_pkg_map_event_add($db, $ev)
29 {
30 rg_prof_start('pkg_map_event_add');
31 rg_log_enter('pkg_map_event_add');
32 rg_log_ml('ev: ' . print_r($ev ,TRUE));
33
34 $ret = FALSE;
35 do {
36 $ret = array();
37 } while (0);
38
39 rg_log_exit();
40 rg_prof_end('pkg_map_event_add');
41 return $ret;
42 }
43
44 function rg_pkg_map_event_edit($db, $ev)
45 {
46 rg_prof_start('pkg_map_event_edit');
47 rg_log_enter('pkg_map_event_edit');
48 rg_log_ml('ev: ' . print_r($ev ,TRUE));
49
50 $ret = FALSE;
51 do {
52 // TODO: regenerate sub-repositories
53 $ret = array();
54 } while (0);
55
56 rg_log_exit();
57 rg_prof_end('pkg_map_event_edit');
58 return $ret;
59 }
60
61 /*
62 * Add/edit a packages map
63 * If uid > 0 - edit, else, add
64 */
65 function rg_pkg_maps_edit($db, $d)
66 {
67 rg_prof_start('pkg_maps_edit');
68 rg_log_enter('pkg_maps_edit: d: ' . rg_array2string($d));
69
70 $ret = FALSE;
71 while (1) {
72 if ($d['id'] == 0) { // add
73 $d['itime'] = time();
74 $d['flags'] = '';
75 $sql = 'INSERT INTO pkg_maps (uid, itime, flags'
76 . ', prio, repo, ref, pkg_subrepo_id)'
77 . ' VALUES (@@uid@@, @@itime@@, @@flags@@'
78 . ', @@prio@@, @@repo@@, @@ref@@, @@pkg_subrepo_id@@)'
79 . ' RETURNING id';
80 } else { // edit
81 $sql = 'UPDATE pkg_maps'
82 . ' SET flags = @@flags@@'
83 . ', prio = @@prio@@'
84 . ', repo = @@repo@@'
85 . ', ref = @@ref@@'
86 . ', pkg_subrepo_id = @@pkg_subrepo_id@@'
87 . ' WHERE uid = @@uid@@ AND id = @@id@@'
88 . ' RETURNING id';
89 }
90
91 $res = rg_sql_query_params($db, $sql, $d);
92 if ($res === FALSE) {
93 rg_pkg_maps_set_error('cannot insert/update packages map');
94 break;
95 }
96 $row = rg_sql_fetch_array($res);
97 rg_sql_free_result($res);
98
99 // invalidate cache (think about prio change)
100 $k = 'uid::' . $d['uid'] . '::pkg_maps';
101 rg_cache_unset($k, RG_SOCKET_NO_WAIT);
102
103 rg_debug_html_set('pkg_map', $row);
104
105 $ret = $row['id'];
106 break;
107 }
108
109 rg_log_exit();
110 rg_prof_end('pkg_maps_edit');
111 return $ret;
112 }
113
114 /*
115 * Delete packages_maps; list is array('<id>' => '<junk>, ...)
116 */
117 function rg_pkg_maps_remove($db, $uid, $list)
118 {
119 rg_prof_start('pkg_maps_remove');
120 rg_log_enter('pkg_maps_remove: list=' . rg_array2string($list));
121
122 $ret = FALSE;
123 while (1) {
124 $my_list = array();
125 foreach ($list as $id => $junk)
126 $my_list[] = sprintf('%u', $id);
127
128 $params = array('uid' => $uid);
129 $sql_list = implode(', ', $my_list);
130 $sql = 'DELETE FROM pkg_maps'
131 . ' WHERE uid = @@uid@@'
132 . ' AND id IN (' . $sql_list . ')';
133 $res = rg_sql_query_params($db, $sql, $params);
134 if ($res === FALSE) {
135 rg_pkg_maps_set_error('cannot remove packages map(s) (query error)');
136 break;
137 }
138 rg_sql_free_result($res);
139
140 // invalidate cache
141 $k = 'uid::' . $uid . '::pkg_maps::';
142 foreach ($my_list as $id)
143 rg_cache_unset($k . $id, RG_SOCKET_NO_WAIT);
144
145 $ret = TRUE;
146 break;
147 }
148
149 rg_log_exit();
150 rg_prof_end('pkg_maps_remove');
151 return $ret;
152 }
153
154 function rg_pkg_maps_cosmetic($db, &$row)
155 {
156 $row['itime_nice'] = gmdate('Y-m-d H:i', $row['itime']);
157
158 if ($row['pkg_subrepo_id'] == 0) {
159 $row['pkg_subrepo_info'] = array(
160 'name' => 'no subrepo',
161 'pkg_repo_info' => array('name' => 'No repo')
162 );
163 } else {
164 $row['pkg_subrepo_info'] = array(
165 'name' => 'n/a',
166 'pkg_repo_info' => array('name' => 'n/a')
167 );
168
169 $sr = rg_pkg_subrepo_info($db, $row['uid'], $row['pkg_subrepo_id']);
170 if ($sr['exists'] == 1) {
171 rg_pkg_subrepo_cosmetic($db, $sr);
172 $row['pkg_subrepo_info'] = $sr;
173 }
174 }
175 }
176
177 function rg_pkg_maps_cosmetic_list($db, &$a)
178 {
179 foreach ($a as $id => &$row)
180 rg_pkg_maps_cosmetic($db, $row);
181 }
182
183 /*
184 * Return the list of packages_maps
185 */
186 function rg_pkg_maps_list($db, $uid)
187 {
188 rg_prof_start('pkg_maps_list');
189 rg_log_enter('pkg_maps_list');
190
191 $ret = FALSE;
192 while (1) {
193 $k = 'uid::' . $uid . '::pkg_maps';
194
195 $ret = rg_cache_get($k);
196 if ($ret !== FALSE)
197 break;
198
199 $params = array('uid' => $uid);
200 $sql = 'SELECT * FROM pkg_maps'
201 . ' WHERE uid = @@uid@@'
202 . ' ORDER BY prio, itime DESC';
203 $res = rg_sql_query_params($db, $sql, $params);
204 if ($res === FALSE) {
205 rg_pkg_maps_set_error('cannot get packages map list');
206 break;
207 }
208
209 $ret = array();
210 while (($row = rg_sql_fetch_array($res))) {
211 $id = $row['id'];
212 $ret[$id] = $row;
213 }
214 rg_sql_free_result($res);
215
216 rg_cache_set($k, $ret, RG_SOCKET_NO_WAIT);
217 break;
218 }
219
220 rg_log_exit();
221 rg_prof_end('pkg_maps_list');
222 return $ret;
223 }
224
225 /*
226 * Returns info about a packages map (by id)
227 */
228 function rg_pkg_maps_info($db, $uid, $id)
229 {
230 rg_prof_start('pkg_maps_info');
231 rg_log_enter('pkg_maps_info: uid=' . $uid . ' id=' . $id);
232
233 $ret = array();
234 $ret['ok'] = 0;
235 $ret['exists'] = 0;
236 while (1) {
237 $list = rg_pkg_maps_list($db, $uid);
238 if ($list === FALSE)
239 break;
240
241 $ret['ok'] = 1;
242
243 $id = sprintf('%u', $id);
244 if (!isset($list[$id]))
245 break;
246
247 $ret = array_merge($ret, $list[$id]);
248 $ret['exists'] = 1;
249 break;
250 }
251
252 rg_log_exit();
253 rg_prof_end('pkg_maps_info');
254 return $ret;
255 }
256
257 /*
258 * Returns relevant mappings for a repo/ref.
259 * It is called by the build webhook.
260 */
261 function rg_pkg_maps_get($db, $uid, $repo_name, $ref)
262 {
263 $ret = array('ok' => 0);
264 do {
265 $ml = rg_pkg_maps_list($db, $uid);
266 if ($ml === FALSE)
267 break;
268
269 $maps = array();
270 $repos = array();
271 $subrepos = array();
272 $err = FALSE;
273 foreach ($ml as $id => $info) {
274 if (!empty($info['repo'])) {
275 $r = @preg_match('`' . $info['repo'] . '`uD', $repo_name);
276 if ($r === FALSE) {
277 $ret['errmsg'] = 'repo name regex error';
278 $err = TRUE;
279 break;
280 }
281 if ($r !== 1)
282 continue;
283 }
284
285 if (!empty($info['ref'])) {
286 $r = @preg_match('`' . $info['ref'] . '`uD', $ref);
287 if ($r === FALSE) {
288 $ret['errmsg'] = 'ref regex error';
289 $err = TRUE;
290 break;
291 }
292 if ($r !== 1)
293 continue;
294 }
295
296 if ($info['pkg_subrepo_id'] == 0) // 0 = "No repo / no subrepo"
297 break;
298
299 $si = $info['pkg_subrepo_id'];
300 if (!isset($subrepos[$si])) {
301 $r = rg_pkg_subrepo_info($db, $uid, $si);
302 if ($r['exists'] != 1) {
303 $ret['errmsg'] = 'non existing pkg subrepo ' . $si;
304 $err = TRUE;
305 break;
306 }
307 $subrepos[$si] = $r;
308 }
309
310 $ri = $subrepos[$si]['pkg_repo_id'];
311 if (!isset($repos[$ri])) {
312 $r = rg_pkg_repo_info($db, $uid, $ri);
313 if ($r['exists'] != 1) {
314 $ret['errmsg'] = 'non existing pkg repo ' . $ri;
315 $err = TRUE;
316 break;
317 }
318 $repos[$ri] = $r;
319 }
320
321 $maps[] = array(
322 'pkg_subrepo_id' => $si,
323 'flags' => $info['flags']
324 );
325 }
326 if ($err)
327 break;
328
329 $ret['pkg_maps'] = $maps;
330 $ret['pkg_repos'] = $repos;
331 $ret['pkg_subrepos'] = $subrepos;
332 $ret['ok'] = 1;
333 } while (0);
334
335 return $ret;
336 }
337
338 /*
339 * High-level function for rg_pkg_maps_list
340 */
341 function rg_pkg_maps_list_high_level($db, $rg)
342 {
343 rg_log_enter('pkg_maps_list_high_level');
344
345 $ret = '';
346 while (1) {
347 $errmsg = array();
348
349 $ui_login = rg_ui_login();
350 $list = rg_pkg_maps_list($db, $ui_login['uid']);
351 if ($list === FALSE) {
352 $rg['errmsg'] = rg_pkg_maps_error();
353 $ret .= rg_template('user/settings/packages/map/list_err.html',
354 $rg, TRUE /*xss*/);
355 break;
356 }
357 rg_pkg_maps_cosmetic_list($db, $list);
358
359 $xlist = rg_var_str('delete_list');
360 while (!empty($xlist)) {
361 $del_errmsg = array();
362 if (!rg_valid_referer())
363 $del_errmsg[] = 'invalid referer; try again';
364
365 if (!rg_token_valid($db, $rg, 'pkg_maps_list', FALSE))
366 $del_errmsg[] = 'invalid token; try again.';
367
368 if (empty($del_errmsg)) {
369 $r = rg_pkg_maps_remove($db, $ui_login['uid'], $xlist);
370 if ($r !== TRUE)
371 $del_errmsg[] = rg_pkg_maps_error();
372 }
373
374 if (empty($del_errmsg)) {
375 $ret .= rg_template('user/settings/packages/map/delete_ok.html',
376 $rg, TRUE /*xss*/);
377 foreach ($xlist as $_id => $junk)
378 unset($list[$_id]);
379 break;
380 }
381
382 $ret .= rg_template_errmsg($del_errmsg);
383 break;
384 }
385
386 $rg['rg_form_token'] = rg_token_get($db, $rg, 'pkg_maps_list');
387 $rg['HTML:errmsg'] = rg_template_errmsg($errmsg);
388 $ret .= rg_template_table('user/settings/packages/map/list', $list, $rg);
389 break;
390 }
391
392 rg_log_exit();
393 return $ret;
394 }
395
396 /*
397 * Returns a select list
398 * @name - the variable name
399 */
400 function rg_pkg_map_repo_subrepo_select($db, $name, $uid, $pkg_subrepo_id)
401 {
402 $list = rg_pkg_subrepo_list($db, $uid);
403 if ($list === FALSE)
404 return rg_warning('Could not load packages maps (subrepo list).');
405
406 rg_pkg_subrepo_cosmetic_list($db, $list);
407
408 // Add fake subrepo
409 $a = array(
410 'id' => 0,
411 'pkg_repo_info' => array('name' => 'No repo'),
412 'name' => 'no subrepo'
413 );
414 $list[] = $a;
415
416 $ret = '<select name=\'' . $name . '\' id=\'pkg_subrepo_id\'>' . "\n";
417 foreach ($list as $row) {
418 $add = '';
419 if ($row['id'] == $pkg_subrepo_id)
420 $add = ' selected';
421 $ret .= '<option value=\'' . $row['id'] . '\'' . $add . '>'
422 . rg_xss_safe($row['pkg_repo_info']['name'])
423 . ' / '
424 . rg_xss_safe($row['name'])
425 . '</option>' . "\n";
426 }
427
428 $ret .= '</select>' . "\n";
429
430 return $ret;
431 }
432
433 /*
434 * High-level function for rg_pkg_maps_edit.
435 */
436 function rg_pkg_maps_edit_high_level($db, &$rg, $op, $paras)
437 {
438 rg_log_enter('pkg_maps_edit_high_level paras:' . rg_array2string($paras));
439
440 $ret = '';
441
442 $mi = array();
443 $mi['id'] = isset($paras[0]) ? sprintf('%u', $paras[0]) : 0;
444
445 $ui_login = rg_ui_login();
446
447 $errmsg = array();
448 $load_form = TRUE;
449 while ($rg['doit'] == 0) {
450 if ($mi['id'] > 0) {
451 $mi = rg_pkg_maps_info($db, $ui_login['uid'], $mi['id']);
452 if ($mi['ok'] != 1) {
453 $ret .= rg_template_blind('internal_err.html');
454 $load_form = FALSE;
455 break;
456 }
457 if ($mi['exists'] != 1) {
458 $m = rg_template_blind('user/settings/packages/map/id_invalid.html');
459 $ret .= rg_warning($m);
460 $load_form = FALSE;
461 break;
462 }
463
464 rg_pkg_maps_cosmetic($db, $mi);
465 } else {
466 // Defaults
467 $mi['flags'] = '';
468 $mi['prio'] = 10;
469 $mi['repo'] = '';
470 $mi['ref'] = '';
471 $mi['pkg_subrepo_id'] = 0;
472 }
473 break;
474 }
475
476 while ($rg['doit'] == 1) {
477 $mi['flags'] = trim(rg_var_str('mi::flags'));
478 $mi['prio'] = rg_var_uint('mi::prio');
479 $mi['repo'] = trim(rg_var_str('mi::repo'));
480 $mi['ref'] = trim(rg_var_str('mi::ref'));
481 $mi['pkg_subrepo_id'] = rg_var_int('mi::pkg_subrepo_id');
482
483 if (!rg_valid_referer())
484 $errmsg[] = 'invalid referer; try again';
485
486 if (!rg_token_valid($db, $rg, 'pkg_maps_edit_hl', FALSE))
487 $errmsg[] = 'invalid token; try again';
488
489 if (empty($errmsg)) {
490 $mi['uid'] = $ui_login['uid'];
491 $r = rg_pkg_maps_edit($db, $mi);
492 if ($r === FALSE) {
493 $rg['err_detail'] = rg_pkg_maps_error();
494 $errmsg[] = rg_template(
495 'user/settings/packages/map/add_edit_err.html',
496 $rg, TRUE /*xss*/);
497 }
498 }
499
500 if (empty($errmsg)) {
501 $ret .= rg_template('user/settings/packages/map/add_ok.html',
502 $rg, TRUE /*xss*/);
503 $load_form = FALSE;
504 }
505
506 break;
507 }
508
509 if ($load_form) {
510 $hints = array();
511 $hints[]['HTML:hint'] = rg_template('user/settings/packages/map/hints.html',
512 $rg, TRUE /*xss*/);
513 $rg['HTML:hints'] = rg_template_table('hints/list', $hints, $rg);
514
515 $mi['HTML:repo_subrepo_select'] = rg_pkg_map_repo_subrepo_select($db,
516 'mi::pkg_subrepo_id', $ui_login['uid'], $mi['pkg_subrepo_id']);
517 $rg['mi'] = $mi;
518 $rg['HTML:errmsg'] = rg_template_errmsg($errmsg);
519 $rg['rg_form_token'] = rg_token_get($db, $rg, 'pkg_maps_edit_hl');
520 $ret .= rg_template('user/settings/packages/map/add_edit.html',
521 $rg, TRUE /*xss*/);
522 }
523
524 rg_log_exit();
525 return $ret;
526 }
527
528 /*
529 * Main HL function for packages/repo
530 */
531 function rg_pkg_maps_high_level($db, &$rg, $paras)
532 {
533 rg_prof_start('pkg_maps_high_level');
534 rg_log_enter('pkg_maps_high_level paras:' . rg_array2string($paras));
535
536 $ret = '';
537 while (1) {
538 $op = empty($paras) ? 'list' : array_shift($paras);
539 $rg['menu3']['packages']['map'] = array($op => 1);
540
541 switch ($op) {
542 case 'add':
543 case 'edit':
544 $ret .= rg_pkg_maps_edit_high_level($db, $rg, $op, $paras);
545 break;
546
547 default:
548 $ret .= rg_pkg_maps_list_high_level($db, $rg);
549 break;
550 }
551
552 $rg['HTML:menu_level3'] =
553 rg_template('user/settings/packages/map/menu.html',
554 $rg, TRUE /*xss*/);
555
556 break;
557 }
558
559 rg_log_exit();
560 rg_prof_end('pkg_maps_high_level');
561 return $ret;
562 }
563
File inc/user/pkg_repo.inc.php added (mode: 100644) (index 0000000..3891e39)
1 <?php
2 require_once(__DIR__ . '/../prof.inc.php');
3 require_once(__DIR__ . '/../events.inc.php');
4 require_once(__DIR__ . '/../gpg.inc.php');
5 include_once(__DIR__ . '/pkg_rights.inc.php');
6
7 $rg_pkg_repo_error = '';
8
9 function rg_pkg_repo_set_error($str)
10 {
11 global $rg_pkg_repo_error;
12 $rg_pkg_repo_error = $str;
13 rg_log($str);
14 }
15
16 function rg_pkg_repo_error()
17 {
18 global $rg_pkg_repo_error;
19 return $rg_pkg_repo_error;
20 }
21
22 /*
23 * Validates pkg repo name
24 */
25 function rg_pkg_repo_ok($name)
26 {
27 if (empty($name)) {
28 rg_pkg_repo_set_error('invalid name');
29 return FALSE;
30 }
31
32 return TRUE;
33 }
34
35 /*
36 * Event functions
37 */
38 $rg_pkg_repo_functions = array(
39 'pkg_repo_add' => 'rg_pkg_repo_event_add',
40 'pkg_repo_edit' => 'rg_pkg_repo_event_edit',
41 'pkg_repo_gen_gpg_key' => 'rg_pkg_repo_event_gen_gpg_key'
42 );
43 rg_event_register_functions($rg_pkg_repo_functions);
44
45 function rg_pkg_repo_event_gen_gpg_key($db, $ev)
46 {
47 rg_prof_start('pkg_repo_event_gen_gpg_key');
48 rg_log_enter('pkg_repo_event_gen_gpg_key');
49 rg_log_ml('ev: ' . print_r($ev ,TRUE));
50
51 $ret = FALSE;
52 do {
53 $r = rg_gpg_key_gen('repo_id-' . $ev['info']['id']);
54 if ($r['ok'] != 1) {
55 rg_log('Cannot generate key: ' . $r['errmsg']);
56 break;
57 }
58
59 $params = array(
60 'id' => $ev['info']['id'],
61 'gpg_priv_key' => trim($r['priv_key']),
62 'gpg_pub_key' => trim($r['pub_key'])
63 );
64 $sql = 'UPDATE pkg_repos'
65 . ' SET gpg_priv_key = @@gpg_priv_key@@'
66 . ', gpg_pub_key = @@gpg_pub_key@@'
67 . ' WHERE id = @@id@@';
68 $res = rg_sql_query_params($db, $sql, $params);
69 if ($res === FALSE)
70 break;
71
72 rg_sql_free_result($res);
73
74 $k = 'uid::' . $ev['info']['uid'] . '::pkg_repos';
75 rg_cache_unset($k, RG_SOCKET_NO_WAIT);
76
77 $ret = array();
78 } while (0);
79
80 rg_log_exit();
81 rg_prof_end('pkg_repo_event_gen_gpg_key');
82 return $ret;
83 }
84
85 function rg_pkg_repo_event_add($db, $ev)
86 {
87 rg_prof_start('pkg_repo_event_add');
88 rg_log_enter('pkg_repo_event_add');
89 rg_log_ml('ev: ' . print_r($ev ,TRUE));
90
91 $ret = array();
92 do {
93 $a = $ev;
94 $a['category'] = 'pkg_repo_gen_gpg_key';
95 $ret[] = $a;
96 } while (0);
97
98 rg_log_exit();
99 rg_prof_end('pkg_repo_event_add');
100 return $ret;
101 }
102
103 function rg_pkg_repo_event_edit($db, $ev)
104 {
105 rg_prof_start('pkg_repo_event_edit');
106 rg_log_enter('pkg_repo_event_edit');
107 rg_log_ml('ev: ' . print_r($ev ,TRUE));
108
109 $ev['uid'] = $ev['info']['uid'];
110 $ev['pkg_repo_id'] = $ev['info']['id'];
111 unset($ev['info']);
112
113 $ret = array();
114 do {
115 $a = $ev;
116 $a['category'] = 'pkg_subrepo_pkg_repo_changed';
117 $ret[] = $a;
118 } while (0);
119
120 rg_log_exit();
121 rg_prof_end('pkg_repo_event_edit');
122 return $ret;
123 }
124
125 /*
126 * This is called from 'fixes' to add the Global repo
127 */
128 function rg_pkg_repo_add_global($db)
129 {
130 $ret = FALSE;
131 do {
132 $a = array(
133 'id' => 0,
134 'uid' => 0,
135 'name' => 'global',
136 'flags' => 'PG',
137 'disk_used_mb' => 0
138 );
139 $r = rg_pkg_repo_edit($db, $a);
140 if ($r === FALSE)
141 break;
142
143 $ret = TRUE;
144 } while (0);
145
146 return $ret;
147 }
148
149 /*
150 * Add/edit a pkg repo
151 * If uid > 0 - edit, else, add
152 */
153 function rg_pkg_repo_edit($db, $d)
154 {
155 rg_prof_start('pkg_repo_edit');
156 rg_log_enter('pkg_repo_edit: d: ' . rg_array2string($d));
157
158 $ret = FALSE;
159 $rollback = FALSE;
160 while (1) {
161 $orig_id = $d['id'];
162
163 if (rg_pkg_repo_ok($d['name']) !== TRUE)
164 break;
165
166 if (rg_sql_begin($db) !== TRUE) {
167 rg_pkg_repo_set_error('start transaction failed');
168 break;
169 }
170 $rollback = TRUE;
171
172 if ($orig_id == 0) { // add
173 $d['itime'] = time();
174 $d['version'] = 1;
175 $d['rgfs_key'] = rg_id(32);
176 $d['password'] = rg_id(16);
177 $d['gpg_priv_key'] = '';
178 $d['gpg_pub_key'] = '';
179 $d['disk_used_mb'] = 0;
180 $sql = 'INSERT INTO pkg_repos (uid, itime, name'
181 . ', flags, rgfs_key, gpg_priv_key'
182 . ', gpg_pub_key, disk_used_mb'
183 . ', version, password)'
184 . ' VALUES (@@uid@@, @@itime@@, @@name@@'
185 . ', @@flags@@, @@rgfs_key@@, @@gpg_priv_key@@'
186 . ', @@gpg_pub_key@@, @@disk_used_mb@@'
187 .', @@version@@, @@password@@)'
188 . ' RETURNING id';
189 } else { // edit
190 $sql = 'UPDATE pkg_repos'
191 . ' SET name = @@name@@'
192 . ', flags = @@flags@@'
193 . ', version = version + 1'
194 . ' WHERE uid = @@uid@@ AND id = @@id@@'
195 . ' RETURNING id';
196 }
197
198 $res = rg_sql_query_params($db, $sql, $d);
199 if ($res === FALSE) {
200 rg_pkg_repo_set_error('cannot insert/update packages repo');
201 break;
202 }
203 $row = rg_sql_fetch_array($res);
204 rg_sql_free_result($res);
205
206 $d['id'] = $row['id'];
207 $ev = array(
208 'category' => $orig_id == 0 ? 'pkg_repo_add' : 'pkg_repo_edit',
209 'prio' => 90, // should be lower than the build prio to have the key
210 'info' => $d
211 );
212 $r = rg_event_add($db, $ev);
213 if ($r !== TRUE) {
214 rg_pkg_repo_set_error('cannot add event: ' . rg_event_error());
215 break;
216 }
217
218 if (rg_sql_commit($db) !== TRUE) {
219 rg_pkg_repo_set_error('cannot commit');
220 break;
221 }
222 $rollback = FALSE;
223
224 // update cache (because of the ordering by name we need to unset)
225 $k = 'uid::' . $d['uid'] . '::pkg_repos';
226 if ($orig_id == 0) // add
227 rg_cache_set($k . '::' . $d['id'], $d, RG_SOCKET_NO_WAIT);
228 else
229 rg_cache_unset($k, RG_SOCKET_NO_WAIT);
230
231 rg_event_signal_daemon('', 0);
232
233 rg_debug_html_set('pkg_repo', $row);
234
235 $ret = $row['id'];
236 break;
237 }
238 if ($rollback)
239 rg_sql_rollback($db);
240
241 rg_log_exit();
242 rg_prof_end('pkg_repo_edit');
243 return $ret;
244 }
245
246 /*
247 * Delete pkg repos; list is array('<id>' => '<junk>, ...)
248 */
249 function rg_pkg_repo_remove($db, $uid, $list)
250 {
251 rg_prof_start('pkg_repo_remove');
252 rg_log_enter('pkg_repo_remove: list=' . rg_array2string($list));
253
254 $ret = FALSE;
255 $rollback = 0;
256 while (1) {
257 if (rg_sql_begin($db) !== TRUE) {
258 rg_pkg_repo_set_error('start transaction failed');
259 break;
260 }
261 $rollback = 1;
262
263 $my_list = array();
264 foreach ($list as $id => $junk)
265 $my_list[] = sprintf('%u', $id);
266 $sql_list = implode(', ', $my_list);
267
268 $sql = ' DELETE FROM pkg_maps'
269 . ' WHERE pkg_repo_id IN (' . $sql_list . ')';
270 $res = rg_sql_query($db, $sql);
271 if ($res === FALSE) {
272 rg_pkg_repo_set_error('cannot remove packages mapping (query error)');
273 break;
274 }
275 rg_sql_free_result($res);
276
277 $sql = ' DELETE FROM pkg_subrepos'
278 . ' WHERE pkg_repo_id IN (' . $sql_list . ')';
279 $res = rg_sql_query($db, $sql);
280 if ($res === FALSE) {
281 rg_pkg_repo_set_error('cannot remove packages subrepos (query error)');
282 break;
283 }
284 rg_sql_free_result($res);
285
286 $sql = 'DELETE FROM pkg_repos'
287 . ' WHERE id IN (' . $sql_list . ')';
288 $res = rg_sql_query($db, $sql);
289 if ($res === FALSE) {
290 rg_pkg_repo_set_error('cannot remove packages repos (query error)');
291 break;
292 }
293 rg_sql_free_result($res);
294
295 if (rg_sql_commit($db) !== TRUE) {
296 rg_pkg_repo_set_error('cannot commit (tx error)');
297 break;
298 }
299 $rollback = 0;
300
301 // invalidate cache
302 $k = 'uid::' . $uid . '::';
303 foreach ($my_list as $id)
304 rg_cache_unset($k . 'pkg_repos::' . $id, RG_SOCKET_NO_WAIT);
305 rg_cache_unset($k . 'pkg_subrepos', RG_SOCKET_NO_WAIT);
306 rg_cache_unset($k . 'pkg_maps', RG_SOCKET_NO_WAIT);
307
308 $ret = TRUE;
309 break;
310 }
311 if ($rollback)
312 rg_sql_rollback($db);
313
314 rg_log_exit();
315 rg_prof_end('pkg_repo_remove');
316 return $ret;
317 }
318
319 function rg_pkg_repo_cosmetic(&$row)
320 {
321 if (isset($row['itime']))
322 $row['itime_nice'] = gmdate('Y-m-d H:i', $row['itime']);
323
324 $row['public'] = strstr($row['flags'], 'P') ? 1 : 0;
325 $row['public_nice'] = strstr($row['flags'], 'P') ? 'Yes' : 'No';
326 $row['public_text'] = strstr($row['flags'], 'P') ? 'public' : 'private';
327
328 $row['disk_used'] = rg_1024($row['disk_used_mb'] * 1024 * 1024);
329
330 //rg_log_debug('pkg_repo_cosmetic: ' . print_r($row, TRUE));
331 }
332
333 function rg_pkg_repo_cosmetic_list(&$a)
334 {
335 foreach ($a as $id => &$row)
336 rg_pkg_repo_cosmetic($row);
337 }
338
339 /*
340 * Return the list of pkg repos for @uid (excluding global ones)
341 */
342 function rg_pkg_repo_list_one($db, $uid)
343 {
344 rg_prof_start('pkg_repo_list_one');
345 rg_log_enter('pkg_repo_list_one');
346
347 $ret = FALSE;
348 do {
349 $k = 'uid::' . $uid . '::pkg_repos';
350 $ret = rg_cache_get($k);
351 if ($ret !== FALSE)
352 break;
353
354 $params = array('uid' => $uid);
355 $sql = 'SELECT * FROM pkg_repos'
356 . ' WHERE uid = @@uid@@'
357 . ' ORDER BY name';
358 $res = rg_sql_query_params($db, $sql, $params);
359 if ($res === FALSE) {
360 rg_pkg_repo_set_error('cannot get packages repo list');
361 break;
362 }
363
364 $ret = array();
365 while (($row = rg_sql_fetch_array($res))) {
366 $id = $row['id'];
367 $ret[$id] = $row;
368 }
369 rg_sql_free_result($res);
370
371 rg_cache_set($k, $ret, RG_SOCKET_NO_WAIT);
372 } while (0);
373
374 rg_log_exit();
375 rg_prof_end('pkg_repo_list_one');
376 return $ret;
377 }
378
379 /*
380 * Return the list of pkg_subrepos (including global)
381 */
382 function rg_pkg_repo_list($db, $uid)
383 {
384 do {
385 $ret = rg_pkg_repo_list_one($db, $uid);
386 if ($ret === FALSE)
387 break;
388
389 if ($uid == 0)
390 break;
391
392 $g = rg_pkg_repo_list_one($db, 0 /*uid*/);
393 if ($g === FALSE)
394 break;
395
396 $ret = rg_array_merge($g, '', $ret);
397 } while (0);
398
399 return $ret;
400 }
401
402 /*
403 * Returns info about a pkg repo (by id)
404 */
405 function rg_pkg_repo_info($db, $uid, $id)
406 {
407 rg_prof_start('pkg_repo_info');
408 rg_log_enter('pkg_repo_info: uid=' . $uid . ' id=' . $id);
409
410 $ret = array();
411 $ret['ok'] = 0;
412 $ret['exists'] = 0;
413 while (1) {
414 $list = rg_pkg_repo_list($db, $uid);
415 if ($list === FALSE)
416 break;
417
418 $ret['ok'] = 1;
419
420 $id = sprintf('%u', $id);
421 if (!isset($list[$id]))
422 break;
423
424 $ret = array_merge($ret, $list[$id]);
425 $ret['exists'] = 1;
426 break;
427 }
428
429 rg_log_exit();
430 rg_prof_end('pkg_repo_info');
431 return $ret;
432 }
433
434 /*
435 * Returns info about a pkg repo (by name)
436 */
437 function rg_pkg_repo_info_by_name($db, $uid, $name)
438 {
439 rg_prof_start('pkg_repo_info_by_name');
440 rg_log_enter('pkg_repo_info_by_name: uid=' . $uid . ' name=' . $name);
441
442 $ret = array();
443 $ret['ok'] = 0;
444 $ret['exists'] = 0;
445 do {
446 $list = rg_pkg_repo_list($db, $uid);
447 if ($list === FALSE)
448 break;
449
450 $ret['ok'] = 1;
451
452 foreach ($list as $info) {
453 if (strcmp($name, $info['name']) != 0)
454 continue;
455
456 $ret = array_merge($ret, $info);
457 $ret['exists'] = 1;
458 break;
459 }
460 } while (0);
461
462 rg_log_exit();
463 rg_prof_end('pkg_repo_info_by_name');
464 return $ret;
465 }
466
467 /*
468 * Returns a select list
469 * @name - the variable name
470 */
471 function rg_pkg_repo_select($db, $name, $uid, $pkg_repo_id, $strict)
472 {
473 if ($strict)
474 $list = rg_pkg_repo_list_one($db, $uid);
475 else
476 $list = rg_pkg_repo_list($db, $uid);
477 if ($list === FALSE)
478 return rg_warning('Could not load packages repos.');
479
480 $ret = '<select name=\'' . $name . '\' id=\'pkg_repo_id\'>' . "\n";
481 foreach ($list as $row) {
482 $add = '';
483 if ($row['id'] == $pkg_repo_id)
484 $add = ' selected';
485 $ret .= '<option value=\'' . rg_xss_safe($row['id'])
486 . '\'' . $add . '>'
487 . rg_xss_safe($row['name']) . '</option>' . "\n";
488 }
489
490 $ret .= '</select>' . "\n";
491
492 return $ret;
493 }
494
495 /*
496 * Security validation; return TRUE if the list is valid
497 */
498 function rg_pkg_repo_list_valid($db_list, $web_list)
499 {
500 foreach ($web_list as $id => $junk) {
501 if (!isset($db_list[$id])) {
502 rg_security_violation_no_exit('user tried to delete others ids');
503 return FALSE;
504 }
505 }
506
507 return TRUE;
508 }
509
510 /*
511 * High-level function for rg_pkg_repo_list
512 */
513 function rg_pkg_repo_list_high_level($db, $rg, $paras)
514 {
515 rg_log_enter('pkg_repo_list_high_level');
516
517 $ret = '';
518 while (1) {
519 $errmsg = array();
520
521 $ui_login = rg_ui_login();
522 $strict_list = rg_pkg_repo_list_one($db, $ui_login['uid']);
523 if ($strict_list === FALSE) {
524 $rg['errmsg'] = rg_pkg_repo_error();
525 $ret .= rg_template('user/settings/packages/repo/list_err.html',
526 $rg, TRUE /*xss*/);
527 break;
528 }
529
530 $list = rg_pkg_repo_list($db, $ui_login['uid']);
531 if ($list === FALSE) {
532 $rg['errmsg'] = rg_pkg_repo_error();
533 $ret .= rg_template('user/settings/packages/repo/list_err.html',
534 $rg, TRUE /*xss*/);
535 break;
536 }
537 rg_pkg_repo_cosmetic_list($list);
538
539 $xlist = rg_var_str('delete_list');
540 while (!empty($xlist)) {
541 $del_errmsg = array();
542 if (!rg_valid_referer())
543 $del_errmsg[] = 'invalid referer; try again';
544
545 if (!rg_token_valid($db, $rg, 'pkg_repo_list', FALSE))
546 $del_errmsg[] = 'invalid token; try again.';
547
548 // Security check - a user may delete others' ids
549 if (!rg_pkg_repo_list_valid($strict_list, $xlist))
550 $del_errmsg[] = rg_template('user/settings/packages/repo/id_invalid.html',
551 $rg, TRUE /*xss*/);
552
553 if (empty($del_errmsg)) {
554 $r = rg_pkg_repo_remove($db, $ui_login['uid'], $xlist);
555 if ($r !== TRUE)
556 $del_errmsg[] = rg_pkg_repo_error();
557 }
558
559 if (empty($del_errmsg)) {
560 $ret .= rg_template('user/settings/packages/repo/delete_ok.html',
561 $rg, TRUE /*xss*/);
562 foreach ($xlist as $_id => $junk)
563 unset($strict_list[$_id]);
564 break;
565 }
566
567 $ret .= rg_template_errmsg($del_errmsg);
568 break;
569 }
570
571 $rg['rg_form_token'] = rg_token_get($db, $rg, 'pkg_repo_list');
572 $rg['HTML:errmsg'] = rg_template_errmsg($errmsg);
573 $ret .= rg_template_table('user/settings/packages/repo/list', $list, $rg);
574 break;
575 }
576
577 rg_log_exit();
578 return $ret;
579 }
580
581 /*
582 * High-level function for rg_pkg_repo_edit.
583 */
584 function rg_pkg_repo_edit_high_level($db, &$rg, $op, $paras)
585 {
586 rg_log('pkg_repo_edit_high_level op:' . $op . ' paras:' . rg_array2string($paras));
587
588 $ret = '';
589
590 $ui_login = rg_ui_login();
591
592 $rg['pi'] = array();
593 $rg['pi']['id'] = isset($paras[0]) ? sprintf('%u', $paras[0]) : 0;
594
595 $errmsg = array();
596 $load_form = TRUE;
597 while ($rg['doit'] == 0) {
598 if ($rg['pi']['id'] > 0) {
599 $rg['pi'] = rg_pkg_repo_info($db, $ui_login['uid'],
600 $rg['pi']['id']);
601 if ($rg['pi']['ok'] != 1) {
602 $ret .= rg_template_blind('internal_err.html');
603 $load_form = FALSE;
604 break;
605 }
606
607 if ($rg['pi']['exists'] != 1) {
608 $m = rg_template_blind('user/settings/packages/repo/id_invalid.html');
609 $ret .= rg_warning($m);
610 $load_form = FALSE;
611 break;
612 }
613
614 rg_pkg_repo_cosmetic($rg['pi']);
615 } else {
616 // Defaults
617 $rg['pi']['name'] = '';
618 $rg['pi']['flags'] = 'P';
619 }
620
621 $rg['pi']['public'] = strpos($rg['pi']['flags'], 'P') === FALSE ? 0 : 1;
622 break;
623 }
624
625 while ($rg['doit'] == 1) {
626 $rg['pi']['name'] = trim(rg_var_str('pi::name'));
627 $rg['pi']['public'] = trim(rg_var_str('pi::public'));
628
629 if (!rg_valid_referer())
630 $errmsg[] = 'invalid referer; try again';
631
632 if (!rg_token_valid($db, $rg, 'pkg_repo_edit_hl', FALSE))
633 $errmsg[] = 'invalid token; try again';
634
635 if (empty($rg['pi']['name']))
636 $errmsg[] = rg_template(
637 'user/settings/packages/repo/name_empty.html',
638 $rg, TRUE /*xss*/);
639
640 if (rg_chars_allow($rg['pi']['name'], '\pL\pN.', $invalid) !== 1) {
641 $rg['pi']['name_invalid'] = $invalid;
642 $errmsg[] = rg_template(
643 'user/settings/packages/repo/name_invalid.html',
644 $rg, TRUE /*xss*/);
645 }
646
647 if ($rg['pi']['id'] > 0) {
648 $i = rg_pkg_repo_info($db, $ui_login['uid'],
649 $rg['pi']['id']);
650 if ($i['exists'] != 1)
651 $errmsg[] = rg_template(
652 'user/settings/packages/repo/id_invalid.html',
653 $rg, TRUE /*xss*/);
654 } else {
655 $ri = rg_pkg_repo_info_by_name($db, $ui_login['uid'],
656 $rg['pi']['name']);
657 if ($ri === FALSE) {
658 $rg['errmsg'] = rg_pkg_repo_error();
659 $errmsg[] = rg_template('internal_err.html', $rg, TRUE /*xss*/);
660 } else if ($ri['exists'] == 1) {
661 $errmsg[] = rg_template('user/settings/packages/repo/name_duplicate.html',
662 $rg, TRUE /*xss*/);
663 }
664 }
665
666 if (empty($errmsg)) {
667 // We operate as uid 0 on pkg_repos if we are an admin.
668 $rg['pi']['uid'] = $ui_login['is_admin'] == 1 ?
669 0 : $ui_login['uid'];
670 $rg['pi']['flags'] = $rg['pi']['public'] == 1 ? 'P' : '';
671 $r = rg_pkg_repo_edit($db, $rg['pi']);
672 if ($r === FALSE) {
673 $rg['err_detail'] = rg_pkg_repo_error();
674 $errmsg[] = rg_template(
675 'user/settings/packages/repo/add_edit_err.html',
676 $rg, TRUE /*xss*/);
677 }
678 }
679
680 if (empty($errmsg)) {
681 $ret .= rg_template('user/settings/packages/repo/add_ok.html',
682 $rg, TRUE /*xss*/);
683 $load_form = FALSE;
684 }
685
686 break;
687 }
688
689 if ($load_form) {
690 $rg['HTML:errmsg'] = rg_template_errmsg($errmsg);
691 $rg['rg_form_token'] = rg_token_get($db, $rg, 'pkg_repo_edit_hl');
692 $ret .= rg_template('user/settings/packages/repo/add_edit.html',
693 $rg, TRUE /*xss*/);
694 }
695
696 return $ret;
697 }
698
699 /*
700 * Main HL function for pkg repo
701 */
702 function rg_pkg_repo_high_level($db, &$rg, $paras)
703 {
704 rg_prof_start('pkg_repo_high_level');
705 rg_log_enter('pkg_repo_high_level paras:' . rg_array2string($paras));
706
707 $ret = '';
708 while (1) {
709 $op = empty($paras) ? 'list' : array_shift($paras);
710 $rg['menu3']['packages']['repo'] = array($op => 1);
711
712 switch ($op) {
713 case 'add':
714 case 'edit':
715 $ret .= rg_pkg_repo_edit_high_level($db, $rg, $op, $paras);
716 break;
717
718 case 'rights':
719 $ret .= rg_pkg_rights_high_level($db, $rg, $paras);
720 break;
721
722 default:
723 $ret .= rg_pkg_repo_list_high_level($db, $rg, $paras);
724 break;
725 }
726
727 $rg['HTML:menu_level3'] =
728 rg_template('user/settings/packages/repo/menu.html',
729 $rg, TRUE /*xss*/);
730
731 break;
732 }
733
734 rg_log_exit();
735 rg_prof_end('pkg_repo_high_level');
736 return $ret;
737 }
738
File inc/user/pkg_rights.inc.php added (mode: 100644) (index 0000000..7947a57)
1 <?php
2 require_once(__DIR__ . '/../rights.inc.php');
3 // TODO: needed?
4 require_once(__DIR__ . '/pkg_subrepo.inc.php');
5 require_once(__DIR__ . '/pkg_repo.inc.php');
6
7 $rights = array(
8 'A' => 'Access pkg repo',
9 'G' => 'Grant rights',
10 'R' => 'Revoke rights'
11 );
12 rg_rights_register('pkgrepo', $rights, 'A',
13 FALSE, FALSE);
14
15 /*
16 * Main HL function for repo packages
17 */
18 function rg_pkg_rights_high_level($db, $rg, $paras)
19 {
20 rg_prof_start('pkg_rights_high_level');
21 rg_log_enter('pkg_rights_high_level paras:' . rg_array2string($paras));
22
23 do {
24 if (empty($paras)) {
25 $m = rg_template_blind('user/settings/packages/repo/id_invalid.html');
26 $ret = rg_warning($m);
27 break;
28 }
29
30 $pkg_repo_id = intval($paras[0]);
31 $ui_page = rg_ui_page();
32 $rg['pkg_repo_info'] = rg_pkg_repo_info($db, $ui_page['uid'], $pkg_repo_id);
33 if ($rg['pkg_repo_info']['ok'] != 1) {
34 $ret = rg_template_blind('internal_err.html');
35 break;
36 }
37
38 $ret = rg_template('user/settings/packages/repo/rights_head.html',
39 $rg, TRUE /*xss*/);
40
41 if ($rg['pkg_repo_info']['exists'] != 1) {
42 $m = rg_template_blind('user/settings/packages/repo/id_invalid.html');
43 $ret .= rg_warning($m);
44 break;
45 }
46
47 if (strstr($rg['pkg_repo_info']['flags'], 'P')) {
48 $ret .= rg_template('user/settings/packages/repo/is_public.html',
49 $rg, TRUE /*xss*/);
50 break;
51 }
52
53 rg_pkg_repo_cosmetic($rg['pkg_repo_info']);
54
55 $owner = $rg['pkg_repo_info']['uid'];
56
57 $type = 'pkgrepo';
58 $obj_id = $pkg_repo_id;
59 $ret .= rg_rights_high_level($db, $rg, $type, $type, $owner,
60 $obj_id);
61 } while (0);
62
63 rg_log_exit();
64 rg_prof_end('pkg_rights_high_level');
65 return $ret;
66 }
67
68 /*
69 * Returns true if the login user has rights over this pkg repo
70 * @pri - pkg_repo info
71 */
72 function rg_pkg_has_rights($db, $pri, $rg, $rights)
73 {
74 $x = array();
75 $x['obj_id'] = $pri['id'];
76 $x['type'] = 'pkgrepo';
77 $x['owner'] = $pri['uid'];
78 $ui_login = rg_ui_login();
79 $x['uid'] = $ui_login['uid'];
80 $x['username'] = $ui_login['username'];
81 $x['needed_rights'] = $rights;
82 $x['misc'] = '';
83 return rg_rights_allow($db, $x);
84 }
File inc/user/pkg_subrepo.inc.php added (mode: 100644) (index 0000000..1b6ec9d)
1 <?php
2 include_once(__DIR__ . '/pkg_repo.inc.php');
3 include_once(__DIR__ . '/packages_rpm.inc.php');
4
5 $rg_pkg_subrepo_error = '';
6
7 function rg_pkg_subrepo_set_error($str)
8 {
9 global $rg_pkg_subrepo_error;
10 $rg_pkg_subrepo_error = $str;
11 rg_log($str);
12 }
13
14 function rg_pkg_subrepo_error()
15 {
16 global $rg_pkg_subrepo_error;
17 return $rg_pkg_subrepo_error;
18 }
19
20 /*
21 * Event functions
22 */
23 $_f = array(
24 'pkg_subrepo_add' => 'rg_pkg_subrepo_event_add',
25 'pkg_subrepo_edit' => 'rg_pkg_subrepo_event_edit',
26 'pkg_subrepo_regenerate' => 'rg_pkg_subrepo_event_regenerate',
27 'pkg_subrepo_pkg_repo_changed' => 'rg_pkg_subrepo_event_pkg_repo_changed'
28 );
29 rg_event_register_functions($_f);
30
31 function rg_pkg_subrepo_event_add($db, $ev)
32 {
33 $ret = array();
34
35 return $ret;
36 }
37
38 function rg_pkg_subrepo_event_edit($db, $ev)
39 {
40 rg_log_enter('pkg_subrepo_event_edit');
41
42 $ret = FALSE;
43 do {
44 $sri = rg_pkg_subrepo_info($db, $ev['uid'], $ev['pkg_subrepo_id']);
45 if ($sri['ok'] != 1)
46 break;
47
48 $a = $ev;
49 $a['category'] = 'pkg_generate_dotrepo_rpm';
50 $a['force_regenerate_dotrepo'] = 1;
51
52 $ret = array();
53 $di = $sri['distro_info'];
54 foreach ($di as $env => $info) {
55 // We do not need to generate dotrepo for never generated subrepos.
56 // We wait for the first packet in the repo to trigger it.
57 if (!isset($info['dotrepo'])) {
58 rg_log_debug('env ' . $env . ' never had a dotrepo; skip it');
59 continue;
60 }
61
62 rg_log_debug('env ' . $env . ' needs rebuilding of dotrepo');
63 $a['env'] = $env;
64 $ret[] = $a;
65 }
66 } while (0);
67
68 rg_log_exit();
69 return $ret;
70 }
71
72 /*
73 * This is trigger by the addition of some user packages to
74 * a global repository.
75 * It is called from 'rgfs'.
76 */
77 function rg_pkg_subrepo_event_regenerate($db, $ev)
78 {
79 rg_log_enter('pkg_subrepo_event_regenerate');
80
81 $ret = FALSE;
82 do {
83 $ev['source'] = 'pkg_subrepo_event_regenerate';
84
85 $ev['exec'] = array();
86 $ev['exec']['move_pending'] = 1;
87
88 $ev['uid'] = 0;
89
90 $ev['pkg_maps'] = array();
91 $ev['pkg_repos'] = array();
92 $ev['pkg_subrepos'] = array();
93
94 $err = FALSE;
95 foreach ($ev['pkg_subrepo_id_list'] as $pkg_subrepo_id) {
96 $sri = rg_pkg_subrepo_info($db, $ev['uid'], $pkg_subrepo_id);
97 if ($sri['ok'] != 1) {
98 $err = TRUE;
99 break;
100 }
101 $ev['pkg_subrepos'][$pkg_subrepo_id] = $sri;
102
103 $pkg_repo_id = $sri['pkg_repo_id'];
104 $ri = rg_pkg_repo_info($db, $ev['uid'], $pkg_repo_id);
105 if ($ri['ok'] != 1) {
106 $err = TRUE;
107 break;
108 }
109 $ev['pkg_repos'][$pkg_repo_id] = $ri;
110
111 // Fake pkg_maps
112 $ev['pkg_maps'][] = array(
113 'pkg_subrepo_id' => $pkg_subrepo_id,
114 'flags' => ''
115 );
116 }
117 if ($err)
118 break;
119
120 unset($ev['pkg_subrepo_id_list']);
121
122 $r = rg_pkg_prepare_ev_for_dotrepo($db, $ev);
123 if ($r['ok'] != 1) {
124 rg_log('Cannot prepare ev: ' . $r['errmsg']);
125 break;
126 }
127
128 $r = rg_builder_add($db, $ev['repo_id'], $ev['prio'], $ev);
129 if ($r['ok'] != 1) {
130 rg_log($r['errmsg']);
131 break;
132 }
133
134 $ret = array();
135
136 //$ret[] = $ev;
137 // TODO: Then, from cron, we gather all dirty subrepos and regenerate all of them.
138 // TODO: Check all major/arch for '+pending' folder.
139 // TODO: Should we just return an array with 'category' = builder_add'?
140 // TODO: Else, why we have an event here?!
141 } while (0);
142
143 rg_log_exit();
144 return $ret;
145 }
146
147 /*
148 * This is trigger by the edit of a pkg_repo (NOT subrepo)
149 */
150 function rg_pkg_subrepo_event_pkg_repo_changed($db, $ev)
151 {
152 $ret = FALSE;
153 do {
154 $list = rg_pkg_subrepo_list_one($db, $ev['uid']);
155 if ($list === FALSE)
156 break;
157
158 foreach ($list as $id => $info) {
159 if ($info['pkg_repo_id'] != $ev['pkg_repo_id'])
160 continue;
161
162 $a = $ev;
163 $a['category'] = 'pkg_subrepo_edit';
164 $a['pkg_subrepo_id'] = $id;
165 $ret[] = $a;
166 }
167 } while (0);
168
169 return $ret;
170 }
171
172 /*
173 * This is called from 'fixes' to add the Global subrepo
174 */
175 function rg_pkg_subrepo_add_global($db)
176 {
177 $ret = FALSE;
178 do {
179 $error = FALSE;
180 $list = array('stable', 'testing');
181 foreach ($list as $name) {
182 $a = array(
183 'id' => 0,
184 'pkg_repo_id' => 1,
185 'name' => $name,
186 'disk_used_mb' => 0
187 );
188 $r = rg_pkg_subrepo_edit($db, 0 /*uid*/, $a);
189 if ($r === FALSE) {
190 $error = TRUE;
191 break;
192 }
193 }
194 if ($error)
195 break;
196
197 $ret = TRUE;
198 } while (0);
199
200 return $ret;
201 }
202
203 /*
204 * Validates pkg_subrepo name
205 */
206 function rg_pkg_subrepo_ok($name)
207 {
208 if (empty($name)) {
209 rg_pkg_subrepo_set_error('invalid name');
210 return FALSE;
211 }
212
213 return TRUE;
214 }
215
216 /*
217 * Update distro_info field
218 */
219 function rg_pkg_subrepo_update_distro_info($db, $uid, $pkg_subrepo_id, $di)
220 {
221 rg_log_enter('pkg_subrepo_update_distro_info');
222 rg_log_debug('di: ' . rg_array2string($di));
223 $ret = array('ok' => 0);
224 do {
225 $sri = rg_pkg_subrepo_info($db, $uid, $pkg_subrepo_id);
226 if ($sri['ok'] != 1) {
227 $ret['errmsg'] = $sri['errmsg'];
228 break;
229 }
230
231 $old = $sri['distro_info'];
232 rg_log_debug('old: ' . rg_array2string($old));
233 $new = $old;
234 $changed = FALSE;
235 foreach ($di as $env => $i) {
236 if (!isset($new[$env]))
237 $new[$env] = array();
238 foreach ($i as $k => $v) {
239 if (!isset($new[$env][$k])
240 || (strcmp($new[$env][$k], $v) != 0))
241 $changed = TRUE;
242 $new[$env][$k] = $v;
243 }
244 }
245 if ($changed === FALSE) {
246 rg_log_debug('no changes');
247 $ret['ok'] = 1;
248 break;
249 }
250
251 rg_log_debug('new: ' . rg_array2string($new));
252
253 $snew = rg_serialize($new);
254 if ($snew === FALSE) {
255 $ret['errmsg'] = 'cannot serialize';
256 break;
257 }
258
259 $params = array(
260 'id' => $pkg_subrepo_id,
261 'distro_info' => $snew
262 );
263 $sql = 'UPDATE pkg_subrepos'
264 . ' SET distro_info = @@distro_info@@'
265 . ' WHERE id = @@id@@';
266 $res = rg_sql_query_params($db, $sql, $params);
267 if ($res === FALSE) {
268 $ret['errmsg'] = 'cannot update pkg subrepo distro_info';
269 break;
270 }
271 rg_sql_free_result($res);
272
273 $k = 'uid::' . $uid . '::pkg_subrepos::' . $pkg_subrepo_id
274 . '::distro_info';
275 rg_cache_set($k, $new, RG_SOCKET_NO_WAIT);
276
277 $ret['ok'] = 1;
278 } while (0);
279
280 rg_log_exit();
281 return $ret;
282 }
283
284 /*
285 * Add/edit a pkg_subrepo
286 * If id > 0 - edit, else, add
287 */
288 function rg_pkg_subrepo_edit($db, $uid, $d)
289 {
290 rg_prof_start('pkg_subrepo_edit');
291 rg_log_enter('pkg_subrepo_edit: uid=' . $uid . ' d: ' . rg_array2string($d));
292
293 $ret = FALSE;
294 $rollback = false;
295 do {
296 $orig_id = $d['id'];
297
298 if (rg_pkg_subrepo_ok($d['name']) !== TRUE)
299 break;
300
301 $r = rg_sql_begin($db);
302 if ($r === FALSE) {
303 rg_pkg_subrepo_set_error('cannot start transaction: ' . rg_sql_error());
304 break;
305 }
306 $rollback = TRUE;
307
308 if ($orig_id == 0) { // add
309 $d['itime'] = time();
310 $d['disk_used_mb'] = 0;
311 $d['distro_info'] = array();
312 $d2 = $d; // we do not want distro_info to be stored as string
313 $d2['distro_info'] = rg_serialize($d['distro_info']);
314 $sql = 'INSERT INTO pkg_subrepos (pkg_repo_id, itime, name'
315 . ', disk_used_mb, distro_info)'
316 . ' VALUES (@@pkg_repo_id@@, @@itime@@, @@name@@'
317 . ', @@disk_used_mb@@, @@distro_info@@)'
318 . ' RETURNING id, version';
319 } else { // edit
320 $d2 = $d;
321 $sql = 'UPDATE pkg_subrepos'
322 . ' SET name = @@name@@'
323 . ', version = version + 1'
324 . ' WHERE id = @@id@@'
325 . ' RETURNING id, version';
326 }
327 $res = rg_sql_query_params($db, $sql, $d2);
328 if ($res === FALSE) {
329 rg_pkg_subrepo_set_error('cannot insert/update packages subrepo');
330 break;
331 }
332 $row = rg_sql_fetch_array($res);
333 rg_sql_free_result($res);
334
335 $d['version'] = $row['version'];
336 $d['id'] = $row['id'];
337 $d['uid'] = $uid;
338
339 $ev = array(
340 'category' => $orig_id == 0 ?
341 'pkg_subrepo_add' : 'pkg_subrepo_edit',
342 'prio' => 100,
343 'uid' => $uid,
344 'pkg_subrepo_id' => $d['id']
345 );
346 $r = rg_event_add($db, $ev);
347 if ($r !== TRUE) {
348 rg_internal_error('cannot add event to regenerate subrepo: '
349 . rg_event_error());
350 break;
351 }
352
353 $r = rg_sql_commit($db);
354 if ($r === FALSE) {
355 rg_pkg_subrepo_set_error('cannot commit: ' . rg_sql_error());
356 break;
357 }
358 $rollback = FALSE;
359
360 // update cache (because of the ordering by name we need to unset)
361 // TODO: better, do the reordering after we get it from the cache.
362 // TODO: same in pkg_repo.inc.php.
363 $k = 'uid::' . $uid . '::pkg_subrepos';
364 if ($orig_id == 0)
365 rg_cache_set($k . '::' . $d['id'], $d, RG_SOCKET_NO_WAIT);
366 else
367 rg_cache_unset($k, RG_SOCKET_NO_WAIT);
368
369 rg_event_signal_daemon('', 0);
370
371 rg_debug_html_set('pkg_subrepo', $row);
372
373 $ret = $d['id'];
374 } while (0);
375 if ($rollback)
376 rg_sql_rollback($db);
377
378 rg_log_exit();
379 rg_prof_end('pkg_subrepo_edit');
380 return $ret;
381 }
382
383 /*
384 * Delete pkg subrepos; list is array('<id>' => '<junk>, ...)
385 */
386 function rg_pkg_subrepo_remove($db, $uid, $list)
387 {
388 rg_prof_start('pkg_subrepo_remove');
389 rg_log_enter('pkg_subrepo_remove: list=' . rg_array2string($list));
390
391 $ret = FALSE;
392 $rollback = FALSE;
393 while (1) {
394 if (rg_sql_begin($db) !== TRUE) {
395 rg_pkg_subrepo_set_error('start transaction failed');
396 break;
397 }
398 $rollback = TRUE;
399
400 $my_list = array();
401 foreach ($list as $id => $junk)
402 $my_list[] = sprintf('%d', $id);
403
404 $sql_list = implode(', ', $my_list);
405
406 $sql = ' DELETE FROM pkg_maps'
407 . ' WHERE pkg_subrepo_id IN (' . $sql_list . ')';
408 $res = rg_sql_query($db, $sql);
409 if ($res === FALSE) {
410 rg_pkg_subrepo_set_error('cannot remove packages mapping (query error)');
411 break;
412 }
413 rg_sql_free_result($res);
414
415 $sql = 'DELETE FROM pkg_subrepos'
416 . ' WHERE id IN (' . $sql_list . ')';
417 $res = rg_sql_query($db, $sql);
418 if ($res === FALSE) {
419 rg_pkg_subrepo_set_error('cannot remove packages subrepos (query error)');
420 break;
421 }
422 rg_sql_free_result($res);
423
424 if (rg_sql_commit($db) !== TRUE) {
425 rg_pkg_subrepo_set_error('cannot commit (tx error)');
426 break;
427 }
428 $rollback = FALSE;
429
430 // invalidate cache
431 $k = 'uid::' . $uid . '::';
432 foreach ($my_list as $_id)
433 rg_cache_unset($k . 'pkg_subrepos::' . $_id, RG_SOCKET_NO_WAIT);
434 rg_cache_unset($k . 'pkg_maps', RG_SOCKET_NO_WAIT);
435
436 $ret = TRUE;
437 break;
438 }
439 if ($rollback)
440 rg_sql_rollback($db);
441
442 rg_log_exit();
443 rg_prof_end('pkg_subrepo_remove');
444 return $ret;
445 }
446
447 function rg_pkg_subrepo_cosmetic($db, &$row)
448 {
449 if (isset($row['itime']))
450 $row['itime_nice'] = gmdate('Y-m-d H:i', $row['itime']);
451
452 $row['disk_used'] = rg_1024($row['disk_used_mb'] * 1024 * 1024);
453
454 $pkg_repo_info = rg_pkg_repo_info($db, $row['uid'], $row['pkg_repo_id']);
455 if ($pkg_repo_info['exists'] != 1) {
456 $row['pkg_repo_info'] = array('name' => 'error');
457 } else {
458 rg_pkg_repo_cosmetic($pkg_repo_info);
459 $row['pkg_repo_info'] = $pkg_repo_info;
460 }
461 }
462
463 function rg_pkg_subrepo_cosmetic_list($db, &$a)
464 {
465 foreach ($a as $id => &$row)
466 rg_pkg_subrepo_cosmetic($db, $row);
467 }
468
469 /*
470 * Returns the list of pkg subrepos (only for uid $uid, excluding uid 0)
471 */
472 function rg_pkg_subrepo_list_one($db, $uid)
473 {
474 rg_prof_start('pkg_subrepo_list_one');
475 rg_log_enter('pkg_subrepo_list_one');
476
477 $ret = FALSE;
478 do {
479 $k = 'uid::' . $uid . '::pkg_subrepos';
480 $ret = rg_cache_get($k);
481 if ($ret !== FALSE)
482 break;
483
484 $params = array('uid' => $uid);
485 $sql = 'SELECT a.id AS pkg_repo_id, b.*'
486 . ' FROM pkg_repos AS a'
487 . ' INNER JOIN pkg_subrepos AS b'
488 . ' ON a.id = b.pkg_repo_id'
489 . ' WHERE a.uid = @@uid@@'
490 . ' ORDER BY a.name, b.name';
491 $res = rg_sql_query_params($db, $sql, $params);
492 if ($res === FALSE) {
493 rg_pkg_subrepo_set_error('cannot get packages subrepo list');
494 break;
495 }
496
497 $err = FALSE;
498 $list = array();
499 while (($row = rg_sql_fetch_array($res))) {
500 $id = $row['id'];
501 $row['uid'] = $uid; // we will need it if we will join with global list
502 $row['distro_info'] = rg_unserialize($row['distro_info']);
503 if ($row['distro_info'] === FALSE) {
504 rg_pkg_subrepo_set_error('cannot unserialize');
505 $err = TRUE;
506 break;
507 }
508 $list[$id] = $row;
509 }
510 rg_sql_free_result($res);
511 if ($err)
512 break;
513
514 $ret = $list;
515 rg_cache_set($k, $ret, RG_SOCKET_NO_WAIT);
516 } while (0);
517
518 rg_log_exit();
519 rg_prof_end('pkg_subrepo_list_one');
520 return $ret;
521 }
522
523 /*
524 * Return the list of pkg subrepos (including global ones)
525 */
526 function rg_pkg_subrepo_list($db, $uid)
527 {
528 do {
529 $ret = rg_pkg_subrepo_list_one($db, $uid);
530 if ($ret === FALSE)
531 break;
532
533 if ($uid == 0)
534 break;
535
536 $g = rg_pkg_subrepo_list_one($db, 0 /*uid*/);
537 if ($g === FALSE)
538 break;
539
540 $ret = rg_array_merge($g, '', $ret);
541 } while (0);
542
543 return $ret;
544 }
545
546 /*
547 * Returns info about a pkg_subrepo (by id)
548 */
549 function rg_pkg_subrepo_info($db, $uid, $id)
550 {
551 rg_prof_start('pkg_subrepo_info');
552 rg_log_enter('pkg_subrepo_info: uid=' . $uid . ' id=' . $id);
553
554 $ret = array();
555 $ret['ok'] = 0;
556 $ret['exists'] = 0;
557 while (1) {
558 $list = rg_pkg_subrepo_list($db, $uid);
559 if ($list === FALSE)
560 break;
561
562 $ret['ok'] = 1;
563
564 $id = sprintf('%d', $id);
565 if (!isset($list[$id]))
566 break;
567
568 $ret = array_merge($ret, $list[$id]);
569 $ret['exists'] = 1;
570 break;
571 }
572
573 rg_log_exit();
574 rg_prof_end('pkg_subrepo_info');
575 return $ret;
576 }
577
578 /*
579 * Returns info about a pkg_subrepo (by name)
580 */
581 function rg_pkg_subrepo_info_by_name($db, $uid, $pkg_repo_id, $name)
582 {
583 rg_prof_start('pkg_subrepo_info_by_name');
584 rg_log_enter('pkg_subrepo_info_by_name: uid=' . $uid
585 . ' pkg_repo_id=' . $pkg_repo_id
586 . ' name=' . $name);
587
588 $ret = array();
589 $ret['ok'] = 0;
590 $ret['exists'] = 0;
591 do {
592 $list = rg_pkg_subrepo_list($db, $uid);
593 if ($list === FALSE)
594 break;
595
596 $ret['ok'] = 1;
597
598 foreach ($list as $info) {
599 if ($info['pkg_repo_id'] != $pkg_repo_id)
600 continue;
601
602 if (strcmp($info['name'], $name) != 0)
603 continue;
604
605 $ret = array_merge($ret, $info);
606 $ret['exists'] = 1;
607 break;
608 }
609 } while (0);
610
611 rg_log_exit();
612 rg_prof_end('pkg_subrepo_info_by_name');
613 return $ret;
614 }
615
616 /*
617 * Returns a select list
618 * @name - the variable name
619 */
620 function rg_pkg_subrepo_select($db, $name, $uid, $id)
621 {
622 $list = rg_pkg_subrepo_list_one($db, $uid);
623 if ($list === FALSE)
624 return rg_warning('Could not load packages subrepos.');
625
626 rg_pkg_subrepo_cosmetic_list($list);
627
628 $ret = '<select name=\'' . $name . '\' id=\'pkg_subrepo_id\'>' . "\n";
629 foreach ($list as $row) {
630 $add = $row['id'] == $id ? ' selected' : '';
631 $ret .= '<option value=\'' . $row['id']
632 . '\'' . $add . '>'
633 . rg_xss_safe($row['pkg_repo_info']['name'])
634 . ' / ' . rg_xss_safe($row['name'])
635 . '</option>' . "\n";
636 }
637
638 $ret .= '</select>' . "\n";
639
640 return $ret;
641 }
642
643 /*
644 * Security validation; return TRUE if the list is valid
645 */
646 function rg_pkg_subrepo_list_valid($db_list, $web_list)
647 {
648 foreach ($web_list as $id => $junk) {
649 if (!isset($db_list[$id])) {
650 rg_security_violation_no_exit('user tried to delete others ids');
651 return FALSE;
652 }
653 }
654
655 return TRUE;
656 }
657
658 /*
659 * High-level function for rg_pkg_subrepo_list
660 */
661 function rg_pkg_subrepo_list_high_level($db, $rg)
662 {
663 rg_log_enter('pkg_subrepo_list_high_level');
664
665 $ret = '';
666 while (1) {
667 $errmsg = array();
668
669 $ui_login = rg_ui_login();
670 $use_uid = $ui_login['is_admin'] == 1 ? 0 : $ui_login['uid'];
671 $list = rg_pkg_subrepo_list_one($db, $use_uid);
672 if ($list === FALSE) {
673 $rg['errmsg'] = rg_pkg_subrepo_error();
674 $ret .= rg_template('user/settings/packages/subrepo/list_err.html',
675 $rg, TRUE /*xss*/);
676 break;
677 }
678 rg_pkg_subrepo_cosmetic_list($db, $list);
679
680 $xlist = rg_var_str('delete_list');
681 while (!empty($xlist)) {
682 $del_errmsg = array();
683 if (!rg_valid_referer())
684 $del_errmsg[] = 'invalid referer; try again';
685
686 if (!rg_token_valid($db, $rg, 'pkg_subrepo_list', FALSE))
687 $del_errmsg[] = 'invalid token; try again.';
688
689 // Security check - a user may delete others' ids
690 if (!rg_pkg_subrepo_list_valid($list, $xlist))
691 $del_errmsg[] = rg_template(
692 'user/settings/packages/subrepo/invalid_id.html',
693 $rg, TRUE /*xss*/);
694
695 if (empty($del_errmsg)) {
696 $r = rg_pkg_subrepo_remove($db, $ui_login['uid'], $xlist);
697 if ($r !== TRUE)
698 $del_errmsg[] = rg_pkg_subrepo_error();
699 }
700
701 if (empty($del_errmsg)) {
702 $ret .= rg_template('user/settings/packages/subrepo/delete_ok.html',
703 $rg, TRUE /*xss*/);
704 foreach ($xlist as $_id => $junk)
705 unset($list[$_id]);
706 break;
707 }
708
709 $ret .= rg_template_errmsg($del_errmsg);
710 break;
711 }
712
713 $rg['rg_form_token'] = rg_token_get($db, $rg, 'pkg_subrepo_list');
714 $rg['errmsg'] = '';
715 $ret .= rg_template_table('user/settings/packages/subrepo/list', $list, $rg);
716 break;
717 }
718
719 rg_log_exit();
720 return $ret;
721 }
722
723 /*
724 * High-level function for rg_pkg_subrepo_edit.
725 */
726 function rg_pkg_subrepo_edit_high_level($db, &$rg, $paras)
727 {
728 rg_log_enter('pkg_subrepo_edit_high_level paras:'
729 . rg_array2string($paras));
730
731 $ui_login = rg_ui_login();
732
733 $rg['pkg_subrepo_info'] = array();
734 $rg['pkg_subrepo_info']['id'] =
735 isset($paras[0]) ? sprintf('%d', $paras[0]) : 0;
736 $rg['pkg_subrepo_info']['name'] = '';
737 $rg['pkg_subrepo_info']['pkg_repo_id'] = 0;
738
739 $ret = '';
740 $errmsg = array();
741 $load_form = FALSE;
742 do {
743 if ($rg['doit'] == 1) {
744 $rg['pkg_subrepo_info']['name'] = trim(rg_var_str('sr::name'));
745 $rg['pkg_subrepo_info']['pkg_repo_id'] = rg_var_uint('sr::pkg_repo_id');
746
747 if (!rg_valid_referer())
748 $errmsg[] = 'invalid referer; try again';
749
750 if (!rg_token_valid($db, $rg, 'pkg_subrepo_edit_hl', FALSE))
751 $errmsg[] = 'invalid token; try again';
752
753 // TODO: this test and the next one should be in rg_pkg_subrepo_ok
754 if (empty($rg['pkg_subrepo_info']['name']))
755 $errmsg[] = rg_template(
756 'user/settings/packages/subrepo/name_empty.html',
757 $rg, TRUE /*xss*/);
758
759 if (rg_chars_allow($rg['pkg_subrepo_info']['name'], '\pL\pN.', $invalid) !== 1) {
760 $rg['pkg_subrepo_info']['name_invalid'] = $invalid;
761 $errmsg[] = rg_template(
762 'user/settings/packages/subrepo/name_invalid.html',
763 $rg, TRUE /*xss*/);
764 }
765
766 $sri = rg_pkg_subrepo_info_by_name($db,
767 $ui_login['uid'], $rg['pkg_subrepo_info']['pkg_repo_id'],
768 $rg['pkg_subrepo_info']['name']);
769 if ($sri === FALSE) {
770 $rg['errmsg'] = rg_pkg_subrepo_error();
771 $errmsg[] = rg_template('internal_err.html', $rg, TRUE /*xss*/);
772 } else if ($sri['exists'] == 1) {
773 $errmsg[] = rg_template('user/settings/packages/subrepo/name_duplicate.html',
774 $rg, TRUE /*xss*/);
775 }
776 }
777
778 if ($rg['pkg_subrepo_info']['id'] > 0) {
779 $rg['pkg_subrepo_info'] = rg_pkg_subrepo_info($db,
780 $ui_login['uid'], $rg['pkg_subrepo_info']['id']);
781 if ($rg['pkg_subrepo_info']['ok'] != 1) {
782 $ret .= rg_template_blind('internal_err.html');
783 break;
784 }
785
786 if ($rg['pkg_subrepo_info']['exists'] != 1) {
787 $m = rg_template_blind('user/settings/packages/subrepo/id_invalid.html');
788 $ret .= rg_warning($m);
789 break;
790 }
791 }
792
793 if ($rg['pkg_subrepo_info']['pkg_repo_id'] > 0) {
794 $ri = rg_pkg_repo_info($db, $ui_login['uid'],
795 $rg['pkg_subrepo_info']['pkg_repo_id']);
796 if ($ri['exists'] != 1) {
797 $m = rg_template_blind('user/settings/packages/repo/id_invalid.html');
798 $ret .= rg_warning($m);
799 break;
800 }
801 $rg['pkg_subrepo_info']['pkg_repo_info'] = $ri;
802 }
803
804 $load_form = TRUE;
805 if ($rg['doit'] != 1)
806 break;
807
808 if (!empty($errmsg))
809 break;
810
811 // We operate as uid 0 on pkg_subrepos if we are an admin.
812 $uid = $ui_login['is_admin'] == 1 ? 0 : $ui_login['uid'];
813 $r = rg_pkg_subrepo_edit($db, $uid, $rg['pkg_subrepo_info']);
814 if ($r === FALSE) {
815 $rg['err_detail'] = rg_pkg_subrepo_error();
816 rg_log_debug('rg[sr]: ' . print_r($rg['pkg_subrepo_info'], TRUE));
817 $errmsg[] = rg_template(
818 'user/settings/packages/subrepo/add_edit_err.html',
819 $rg, TRUE /*xss*/);
820 break;
821 }
822
823 $ret .= rg_template('user/settings/packages/subrepo/add_ok.html',
824 $rg, TRUE /*xss*/);
825 $load_form = FALSE;
826 } while (0);
827
828 if ($load_form) {
829 if ($rg['pkg_subrepo_info']['id'] == 0)
830 $rg['pkg_subrepo_info']['HTML:repo_select'] = rg_pkg_repo_select($db,
831 'sr::pkg_repo_id', $ui_login['uid'],
832 $rg['pkg_subrepo_info']['pkg_repo_id'], TRUE /*strict*/);
833
834 $rg['HTML:errmsg'] = rg_template_errmsg($errmsg);
835 $rg['rg_form_token'] = rg_token_get($db, $rg, 'pkg_subrepo_edit_hl');
836 $ret .= rg_template('user/settings/packages/subrepo/add_edit.html',
837 $rg, TRUE /*xss*/);
838 }
839
840 rg_log_exit();
841 return $ret;
842 }
843
844 /*
845 * Main HL function for pkg subrepo
846 */
847 function rg_pkg_subrepo_high_level($db, &$rg, $paras)
848 {
849 rg_prof_start('pkg_subrepo_high_level');
850 rg_log_enter('pkg_subrepo_high_level paras:' . rg_array2string($paras));
851
852 $ret = '';
853 while (1) {
854 $op = empty($paras) ? 'list' : array_shift($paras);
855 $rg['menu3']['packages']['subrepo'] = array($op => 1);
856
857 switch ($op) {
858 case 'add':
859 case 'edit':
860 // TODO: give error if no repo defined!
861 $ret .= rg_pkg_subrepo_edit_high_level($db, $rg, $paras);
862 break;
863
864 default:
865 $ret .= rg_pkg_subrepo_list_high_level($db, $rg);
866 break;
867 }
868
869 $rg['HTML:menu_level3'] =
870 rg_template('user/settings/packages/subrepo/menu.html',
871 $rg, TRUE /*xss*/);
872 break;
873 }
874
875 rg_log_exit();
876 rg_prof_end('pkg_subrepo_high_level');
877 return $ret;
878 }
879
File inc/util2.inc.php added (mode: 100644) (index 0000000..c2e63c3)
1 <?php
2 // Higher level helper functions
3
4 require_once(__DIR__ . '/util.inc.php');
5 require_once(__DIR__ . '/state.inc.php');
6
7 /*
8 * Returns the correct URL to the current virtual host
9 */
10 // TODO: we must move this function to hutil.inc.php
11 function rg_base_url($db, $user, $pass)
12 {
13 $hostname = rg_state_get($db, 'hostname');
14 $http_allow = rg_state_get($db, 'http_allow');
15 $https_allow = rg_state_get($db, 'https_allow');
16 //rg_log_debug('from state: ' . $hostname . ' ' . $http_allow
17 // . ' ' . $https_allow);
18 return rg_base_url_build($hostname, $http_allow, $https_allow,
19 $user, $pass);
20 }
21
22 /*
23 * Enable new distros
24 */
25 function rg_env_enable($db, $list)
26 {
27 $ret = array('ok' => 0);
28 do {
29 $en = rg_state_get_array($db, 'distros');
30 if ($en === FALSE) {
31 $ret['errmsg'] = rg_state_error();
32 break;
33 }
34
35 $do_update = FALSE;
36 foreach ($list as $env) {
37 if (isset($en[$env]) && ($en[$env] == 0)) {
38 rg_log_debug('admin disabled ' . $env);
39 continue;
40 }
41
42 if (isset($en[$env]) && ($en[$env] == 1)) {
43 //rg_log_debug('env ' . $env . ' already enabled');
44 continue;
45 }
46
47 $en[$env] = 1;
48 $do_update = TRUE;
49 }
50 if (isset($ret['errmsg']))
51 break;
52
53 if ($do_update === TRUE) {
54 $r = rg_state_set_array($db, 'distros', $en);
55 if ($r === FALSE) {
56 $ret['errmsg'] = 'cannot update state: '
57 . rg_state_error();
58 break;
59 }
60 }
61
62 $ret['ok'] = 1;
63 } while (0);
64
65 return $ret;
66 }
67
68 /*
69 * Returns some info about an 'env'
70 */
71 function rg_env_info($env)
72 {
73 $ret = array();
74
75 $p = explode('-', $env, 3);
76 $ret['distro'] = $p[0];
77 if (isset($p[1]))
78 $ret['major'] = $p[1];
79 if (isset($p[2]))
80 $ret['arch'] = $p[2];
81
82 if (strcmp($ret['distro'], 'fedora') == 0) {
83 $ret['distro_nice'] = 'Fedora Linux';
84 $ret['distro_pkg_type'] = 'rpm';
85 } else if (strcmp($ret['distro'], 'centos') == 0) {
86 $ret['distro_nice'] = 'CentOS';
87 $ret['distro_pkg_type'] = 'rpm';
88 } else if (strcmp($ret['distro'], 'debian') == 0) {
89 $ret['distro_nice'] = 'Debian';
90 $ret['distro_pkg_type'] = 'deb';
91 } else if (strcmp($ret['distro'], 'rocky') == 0) {
92 $ret['distro_nice'] = 'Rocky Linux';
93 $ret['distro_pkg_type'] = 'rpm';
94 } else if (strcmp($ret['distro'], 'archlinux') == 0) {
95 $ret['distro_nice'] = 'ArchLinux';
96 $ret['distro_pkg_type'] = 'apk?';
97 } else if (strcmp($ret['distro'], 'opensuse') == 0) {
98 $ret['distro_nice'] = 'OpenSuse';
99 $ret['distro_pkg_type'] = 'rpm';
100 } else if (strcmp($ret['distro'], 'ubuntu') == 0) {
101 $ret['distro_nice'] = 'Ubuntu';
102 $ret['distro_pkg_type'] = 'deb';
103 } else {
104 $ret['distro_nice'] = $ret['distro'];
105 $ret['distro_pkg_type'] = '?';
106 }
107
108 return $ret;
109 }
110
111 /*
112 * Transforms a distro_info coming from pkg_subrepo into a tree
113 */
114 function rg_distro_info2tree($list)
115 {
116 $ret = array();
117 foreach ($list as $env => $i) {
118 $di = rg_env_info($env);
119 $distro = $di['distro']; $major = $di['major']; $arch = $di['arch'];
120 unset($di['distro']); unset($di['major']); unset($di['arch']);
121
122 foreach ($di as $k => $v)
123 $i[$k] = $v;
124
125 if (!isset($ret[$distro]))
126 $ret[$distro] = array('versions' => array());
127
128 if (!isset($ret[$distro]['versions'][$major]))
129 $ret[$distro]['versions'][$major] = array();
130
131 if (!isset($ret[$distro]['versions'][$major]['archs'][$arch]))
132 $ret[$distro]['versions'][$major]['archs'][$arch] = $i;
133 }
134
135 return $ret;
136 }
137
138 function rg_distro_sort_func($a, $b)
139 {
140 $x = strcmp($a['distro_nice'], $b['distro_nice']);
141 if ($x != 0)
142 return $x;
143
144 // TODO: Ubuntu is using xx.yy, but we are fine for now
145 if ($a['major'] > $b['major'])
146 return 1;
147 else if ($a['major'] < $b['major'])
148 return -1;
149
150 $x = strcmp($a['arch'], $b['arch']);
151 if ($x != 0)
152 return $x;
153
154 return 0;
155 }
156
157 function rg_distro_sort($list)
158 {
159 uasort($list, 'rg_distro_sort_func');
160 return $list;
161 }
162
163 /*
164 * Returns a tree from the current list of envs
165 */
166 function rg_envs_tree($db, $only_enabled)
167 {
168 $ret = array('ok' => 0);
169 do {
170 $envs = rg_state_get_array($db, 'distros');
171 if ($envs === FALSE) {
172 $ret['errmsg'] = rg_state_error();
173 break;
174 }
175
176 $ret['tree'] = array();
177 foreach ($envs as $env => $enabled) {
178 if ($only_enabled && ($enabled != 1))
179 continue;
180
181 $ei = rg_env_info($env);
182
183 $distro = $ei['distro'];
184 if (!isset($ret['tree'][$distro]))
185 $ret['tree'][$distro] = array(
186 'pkg_type' => $ei['distro_pkg_type'],
187 'nice' => $ei['distro_nice'],
188 'versions' => array()
189 );
190
191 $major = $ei['major'];
192 if (!isset($ret['tree'][$distro]['versions'][$major]))
193 $ret['tree'][$distro]['versions'][$major] = array(
194 'archs' => array()
195 );
196
197 $arch = $ei['arch'];
198 if (!isset($ret['tree'][$distro]['versions'][$major]['archs'][$arch]))
199 $ret['tree'][$distro]['versions'][$major]['archs'][$arch] = array();
200
201 $ret['tree'][$distro]['versions'][$major]['archs'][$arch]['enabled'] = $enabled;
202 }
203
204 $ret['ok'] = 1;
205 } while (0);
206
207 return $ret;
208 }
209
210 /*
211 * Test if a env is enabled
212 * @env - environment (examples: fedora-34-x86_64)
213 * @tree - output of rg_envs_tree
214 */
215 function rg_envs_tree_is_enabled($tree, $env)
216 {
217 $p = explode('-', $env);
218
219 if (!isset($tree[$p[0]]['versions'][$p[1]]['archs'][$p[2]]['enabled']))
220 return FALSE;
221
222 return $tree[$p[0]]['versions'][$p[1]]['archs'][$p[2]]['enabled'] == 1;
223 }
224
225 /*
226 * Returns info about an environment, in a flat array
227 * @env - environment (examples: fedora-34-x86_64)
228 * @tree - output of rg_envs_tree
229 */
230 function rg_envs_tree_info($tree, $env)
231 {
232 $p = explode('-', $env);
233
234 if (!isset($tree[$p[0]]['versions'][$p[1]]['archs'][$p[2]]))
235 return FALSE;
236
237 $ret = array();
238 foreach ($tree[$p[0]] as $k => $v) {
239 if (is_array($v))
240 continue;
241
242 $ret[$k] = $v;
243 }
244
245 foreach ($tree[$p[0]]['versions'][$p[1]] as $k => $v) {
246 if (is_array($v))
247 continue;
248
249 $ret[$k] = $v;
250 }
251
252 foreach ($tree[$p[0]]['versions'][$p[1]]['archs'][$p[2]] as $k => $v) {
253 if (is_array($v))
254 continue;
255
256 $ret[$k] = $v;
257 }
258
259 return $ret;
260 }
261
File inc/webhooks.inc.php changed (mode: 100644) (index b0e2b1a..42a9ac3)
... ... rg_event_register_functions($rg_wh_functions);
16 16 function rg_wh_send($db, $ev) function rg_wh_send($db, $ev)
17 17 { {
18 18 rg_log_enter('wh_send'); rg_log_enter('wh_send');
19 //rg_log_ml('DEBUG: ev: ' . print_r($ev, TRUE));
19 rg_log_debug('ev: ' . print_r($ev, TRUE));
20 20
21 21 $ret = array(); $ret = array();
22 do {
23 $ui_login = rg_ui_login();
24 if ($ui_login['confirmed'] == 0) {
25 rg_log('User has not confirmed her e-mail; exit');
26 rg_log_debug('ui_login: ' . print_r($ui_login, TRUE));
27 break;
28 }
29
30 $x = $ev;
31 $x['category'] = 'wh_http_send';
32 $ret[] = $x;
22 33
23 $x = $ev;
24 $x['category'] = 'wh_http_send';
25 $ret[] = $x;
34 $x = $ev;
35 $x['category'] = 'wh_lambda_send';
36 $ret[] = $x;
26 37
27 $x = $ev;
28 $x['category'] = 'wh_lambda_send';
29 $ret[] = $x;
38 // we add a cloud/build event, only for pushes
39 if (strcmp($ev['wh_event'], 'P') != 0)
40 break;
30 41
31 // we add a cloud/build event, only for pushes
32 if (strcmp($ev['wh_event'], 'P') == 0) {
33 42 $x = $ev; $x = $ev;
34 43 $x['category'] = 'wh_cloud_send'; $x['category'] = 'wh_cloud_send';
35 44 $ret[] = $x; $ret[] = $x;
 
... ... function rg_wh_send($db, $ev)
37 46 $x = $ev; $x = $ev;
38 47 $x['category'] = 'wh_build_send'; $x['category'] = 'wh_build_send';
39 48 $ret[] = $x; $ret[] = $x;
40 }
49 } while (0);
41 50
42 51 rg_log_exit(); rg_log_exit();
43 52 return $ret; return $ret;
 
... ... function rg_wh_list_high_level($db, $rg, $paras)
55 64
56 65 $errmsg = array(); $errmsg = array();
57 66
67 $ui_login = rg_ui_login();
68
58 69 $delete = rg_var_uint('delete'); $delete = rg_var_uint('delete');
59 70 while ($delete == 1) { while ($delete == 1) {
60 71 if (!rg_valid_referer()) { if (!rg_valid_referer()) {
 
... ... function rg_wh_list_high_level($db, $rg, $paras)
68 79 } }
69 80
70 81 $list = rg_var_str("delete_list"); $list = rg_var_str("delete_list");
71 $r = rg_wh_remove($db, $rg['login_ui']['uid'], $list);
82 $r = rg_wh_remove($db, $ui_login['uid'], $list);
72 83 if ($r['ok'] !== 1) { if ($r['ok'] !== 1) {
73 84 $errmsg[] = 'cannot delete: ' . rg_wh_error(); $errmsg[] = 'cannot delete: ' . rg_wh_error();
74 85 break; break;
 
... ... function rg_wh_list_high_level($db, $rg, $paras)
84 95 $rg, TRUE /*xss*/); $rg, TRUE /*xss*/);
85 96 } }
86 97
87 $r = rg_wh_list($db, $rg['login_ui']['uid']);
98 $r = rg_wh_list($db, $ui_login['uid']);
88 99 if ($r['ok'] !== 1) { if ($r['ok'] !== 1) {
89 100 $rg['errmsg'] = rg_wh_error(); $rg['errmsg'] = rg_wh_error();
90 101 $ret .= rg_template('user/settings/wh/list_err.html', $ret .= rg_template('user/settings/wh/list_err.html',
91 102 $rg, TRUE /*xss*/); $rg, TRUE /*xss*/);
92 103 } else { } else {
93 104 rg_wh_cosmetic($r['list']); rg_wh_cosmetic($r['list']);
94 rg_log_ml('DEBUG: wh_list_high_level: r[list]: ' . print_r($r['list'], TRUE));
105 rg_log_debug('wh_list_high_level: r[list]: ' . print_r($r['list'], TRUE));
95 106 $rg['rg_form_token'] = rg_token_get($db, $rg, 'wh_list'); $rg['rg_form_token'] = rg_token_get($db, $rg, 'wh_list');
96 107 $ret .= rg_template_table('user/settings/wh/list', $ret .= rg_template_table('user/settings/wh/list',
97 108 $r['list'], $rg); $r['list'], $rg);
 
... ... function rg_wh_add_high_level($db, $rg, $op, $paras)
110 121 rg_prof_start('wh_add_high_level'); rg_prof_start('wh_add_high_level');
111 122 rg_log_enter('wh_add_high_level op=' . $op); rg_log_enter('wh_add_high_level op=' . $op);
112 123
113 rg_log('DEBUG: paras:' . rg_array2string($paras));
124 rg_log_debug('paras:' . rg_array2string($paras));
114 125
115 126 $ret = ''; $ret = '';
116 127 $errmsg = array(); $errmsg = array();
 
... ... function rg_wh_add_high_level($db, $rg, $op, $paras)
157 168 break; break;
158 169 } }
159 170
160 $r = rg_wh_add($db, $rg['login_ui']['uid'], $rg['wh']);
171 $ui_login = rg_ui_login();
172 $r = rg_wh_add($db, $ui_login['uid'], $rg['wh']);
161 173 if ($r['ok'] !== 1) { if ($r['ok'] !== 1) {
162 174 $errmsg[] = rg_wh_error(); $errmsg[] = rg_wh_error();
163 175 break; break;
 
... ... function rg_wh_add_high_level($db, $rg, $op, $paras)
174 186 if ($show_form) { if ($show_form) {
175 187 if ($doit == 0) { if ($doit == 0) {
176 188 if (strcmp($op, 'add') != 0) { // edit if (strcmp($op, 'add') != 0) { // edit
177 $r = rg_wh_list($db, $rg['login_ui']['uid']);
189 $ui_login = rg_ui_login();
190 $r = rg_wh_list($db, $ui_login['uid']);
178 191 if ($r['ok'] != 1) { if ($r['ok'] != 1) {
179 192 $errmsg[] = 'cannot load webhook info; try again later'; $errmsg[] = 'cannot load webhook info; try again later';
180 193 } else if (!isset($r['list'][$rg['wh']['id']])) { } else if (!isset($r['list'][$rg['wh']['id']])) {
 
... ... function rg_wh_add_high_level($db, $rg, $op, $paras)
196 209 $rg['HTML:errmsg'] = rg_template_errmsg($errmsg); $rg['HTML:errmsg'] = rg_template_errmsg($errmsg);
197 210 $rg['rg_form_token'] = rg_token_get($db, $rg, 'wh_add'); $rg['rg_form_token'] = rg_token_get($db, $rg, 'wh_add');
198 211
199 rg_log_ml('DEBUG: BEFORE FORM: wh[idata]: '
212 rg_log_debug('BEFORE FORM: wh[idata]: '
200 213 . print_r($rg['wh']['idata'], TRUE)); . print_r($rg['wh']['idata'], TRUE));
201 214 $ret .= rg_template('user/settings/wh/add_edit.html', $ret .= rg_template('user/settings/wh/add_edit.html',
202 215 $rg, TRUE /*xss*/); $rg, TRUE /*xss*/);
File inc/wh/build.inc.php changed (mode: 100644) (index 97c4dd8..08e8116)
... ... rg_event_register_functions($_f);
19 19 function rg_wh_build_job_done($db, $ev) function rg_wh_build_job_done($db, $ev)
20 20 { {
21 21 rg_prof_start('wh_build_job_done'); rg_prof_start('wh_build_job_done');
22 rg_log_ml('wh_build_job_done: ev: ' . print_r($ev, TRUE));
22 rg_log_enter('wh_build_job_done');
23 //rg_log_enter_ml('DEBUG: ev: ' . rg_array2string($ev));
23 24
24 25 $job = $ev['job']; $job = $ev['job'];
25 26 $req = isset($job['request']) ? $job['request'] : $job; $req = isset($job['request']) ? $job['request'] : $job;
26 27
27 28 $ret = FALSE; $ret = FALSE;
28 while (1) {
29 $s = $ev['status'];
30 $out = 'Worker: ' . $job['worker_name'] . "\n";
31 $out .= 'Date (UTC): '
32 . gmdate('Y-m-d H:i', $job['done']) . "\n";
33 $out .= 'Elapsed time: '
34 . ($job['done'] - $job['worker_started'])
35 . 's' . "\n\n";
36
37 $out .= 'Packages installation:' . "\n";
38 $out .= $s['packages'] . "\n\n";
39
40 foreach ($s['cmds'] as $index => $i) {
41 if (empty($req['cmds'][$index]['cmd']))
42 continue;
43
44 $out .= 'Command['
45 . $req['cmds'][$index]['cmd'] . ']:' . "\n"
46 . trim($i['log']) . "\n\n";
29 do {
30 // For example building a rpm repo
31 if (isset($req['hook_id'])) {
32 $s = $ev['status'];
33 $out = 'Worker: ' . $job['worker_name'] . "\n";
34 $out .= 'Date (UTC): '
35 . gmdate('Y-m-d H:i', $job['done']) . "\n";
36 $out .= 'Elapsed time: '
37 . ($job['done'] - $job['worker_started'])
38 . 's' . "\n\n";
39
40 $out .= 'Packages installation:' . "\n";
41 $out .= $s['packages'] . "\n\n";
42
43 foreach ($s['cmds'] as $index => $i) {
44 if (empty($req['cmds'][$index]['cmd']))
45 continue;
46
47 $out .= 'Command['
48 . $req['cmds'][$index]['cmd'] . ']:' . "\n"
49 . trim($i['log']) . "\n\n";
50 }
51
52 // TODO: should we check error code?
53 rg_wh_set_last_output($db, $ev['uid'],
54 $req['hook_id'], $out);
55
56 if (rg_debug()) {
57 $k = 'DEBUG::' . $ev['uid']
58 . '::webhooks::' . $req['hook_id'];
59 rg_log_debug('setting key [' . $k . '] to '
60 . print_r($ev, TRUE));
61 rg_cache_set($k, $ev, RG_SOCKET_NO_WAIT);
62 }
47 63 } }
48 64
49 // TODO: should we check error code?
50 rg_wh_set_last_output($db, $ev['ui']['uid'],
51 $req['hook_id'], $out);
52 65 $ret = array(); $ret = array();
53 break;
54 }
66 if (isset($req['event_callbacks'])) {
67 unset($ev['request']['event_callbacks']);
68 foreach ($req['event_callbacks'] as $cb) {
69 rg_log_debug('adding ev for callback ' . $cb);
70 $ev['category'] = $cb;
71 $ret[] = $ev;
72 }
73 }
74 } while (0);
55 75
76 //rg_log_debug('ret: ' . rg_array2string($ret));
77
78 rg_log_exit();
56 79 rg_prof_end('wh_build_job_done'); rg_prof_end('wh_build_job_done');
57 80 return $ret; return $ret;
58 81 } }
 
... ... function rg_wh_build_job_done($db, $ev)
63 86 function rg_wh_build_send_one($db, $ev) function rg_wh_build_send_one($db, $ev)
64 87 { {
65 88 rg_prof_start('wh_build_send_one'); rg_prof_start('wh_build_send_one');
66 //rg_log_ml('DEBUG: wh_build_send_one: event: ' . rg_array2string($ev));
89 //rg_log_debug('wh_build_send_one: event: ' . rg_array2string($ev));
67 90
68 91 $ret = FALSE; $ret = FALSE;
69 92 $last_output = ''; $last_output = '';
 
... ... function rg_wh_build_send_one($db, $ev)
78 101 } }
79 102
80 103 $a = $ev['wh']['idata']; $a = $ev['wh']['idata'];
104 $a['repo_id'] = $ev['ri']['repo_id'];
105 $a['repo_username'] = $ev['ri']['repo_username'];
81 106 $a['hook_id'] = $ev['wh']['id']; $a['hook_id'] = $ev['wh']['id'];
82 $a['uid'] = $ev['ui']['uid'];
107 $a['uid'] = $ev['ui_login']['uid'];
108 $a['username'] = $ev['ui_login']['username'];
83 109 $a['flags'] = $ev['wh']['flags']; $a['flags'] = $ev['wh']['flags'];
84 110 $a['url'] = $ri['clone_url_ssh']; $a['url'] = $ri['clone_url_ssh'];
85 111 $a['head'] = $ev['new_rev']; $a['head'] = $ev['new_rev'];
86 112 $a['refname'] = $ev['refname']; $a['refname'] = $ev['refname'];
87 113 $a['refname_short'] = rg_repo_ref_nice($ev['refname']); $a['refname_short'] = rg_repo_ref_nice($ev['refname']);
88 114 $a['env'] = $ev['env']; $a['env'] = $ev['env'];
115 $a['log_sid'] = $ev['log_sid'];
89 116 $a['packages'] = $ev['packages']; $a['packages'] = $ev['packages'];
90 117 // TODO: pass e-mail notification // TODO: pass e-mail notification
91 118
119 $r = rg_pkg_maps_get($db, $a['uid'], $ri['name'],
120 $a['refname_short']);
121 if ($r['ok'] != 1) {
122 rg_log('cannot get maps: ' . $r['errmsg']);
123 $last_output .= $r['errmsg'];
124 break;
125 }
126 $a['pkg_maps'] = $r['pkg_maps'];
127 $a['pkg_repos'] = $r['pkg_repos'];
128 $a['pkg_subrepos'] = $r['pkg_subrepos'];
129
130 $a['exec'] = array();
131 $a['exec']['prepare_rpms'] = 1;
132 $a['exec']['copy_to_rgfs'] = 1;
133
134 $r = rg_pkg_prepare_ev_for_dotrepo($db, $a);
135 if ($r['ok'] != 1) {
136 rg_log('Cannot prepare ev: ' . $r['errmsg']);
137 break;
138 }
139
92 140 // Call the function // Call the function
93 $r = rg_builder_add($db, $ev['ri']['repo_id'], $a);
141 $r = rg_builder_add($db, $ev['ri']['repo_id'], 10 /*prio*/, $a);
94 142 if ($r['ok'] != 1) { if ($r['ok'] != 1) {
95 143 $last_output .= $r['errmsg']; $last_output .= $r['errmsg'];
96 144 break; break;
 
... ... function rg_wh_build_send_one($db, $ev)
101 149 } }
102 150
103 151 if (!empty($last_output)) if (!empty($last_output))
104 rg_wh_set_last_output($db, $ev['ui']['uid'], $ev['wh']['id'],
152 rg_wh_set_last_output($db, $ev['ui_login']['uid'], $ev['wh']['id'],
105 153 substr($last_output, 0, 4096)); substr($last_output, 0, 4096));
106 154
107 155 rg_prof_end('wh_build_send_one'); rg_prof_end('wh_build_send_one');
 
... ... function rg_wh_build_send($db, $ev)
119 167 $ret = array(); $ret = array();
120 168
121 169 // First, get the list of hooks // First, get the list of hooks
122 $r = rg_wh_list($db, $ev['ui']['uid']);
170 $r = rg_wh_list($db, $ev['ui_login']['uid']);
123 171 if ($r['ok'] != 1) if ($r['ok'] != 1)
124 172 return FALSE; return FALSE;
125 173
 
... ... function rg_wh_build_send($db, $ev)
134 182
135 183 // If the web hook does not contain our type, skip it // If the web hook does not contain our type, skip it
136 184 if (!strchr($wh['idata']['events'], $ev['wh_event'])) { if (!strchr($wh['idata']['events'], $ev['wh_event'])) {
137 rg_log('DEBUG: ' . $ev['wh_event']
185 rg_log_debug('' . $ev['wh_event']
138 186 . ' is not present in [' . ' is not present in ['
139 187 . $wh['idata']['events'] . ']'); . $wh['idata']['events'] . ']');
140 188 continue; continue;
 
... ... function rg_wh_build_cosmetic_post(&$row)
198 246 $f = rg_template('user/settings/wh/build/env_show_one.html', $f = rg_template('user/settings/wh/build/env_show_one.html',
199 247 $rg, TRUE/*xss*/); $rg, TRUE/*xss*/);
200 248 $list = ''; $list = '';
201 //rg_log_ml('DEBUG: envs: ' . rg_array2string($row['idata']['envs']));
249 //rg_log_debug('envs: ' . rg_array2string($row['idata']['envs']));
202 250 foreach ($row['idata']['envs'] as $env => $junk) { foreach ($row['idata']['envs'] as $env => $junk) {
203 251 $list .= str_replace('##env##', $env, $f); $list .= str_replace('##env##', $env, $f);
204 252 } }
 
... ... function rg_wh_build_fill_vars(&$rg)
241 289
242 290 $a['envs'] = array(); $a['envs'] = array();
243 291 $envs = rg_var_str('wh::idata::envs'); $envs = rg_var_str('wh::idata::envs');
244 //rg_log_ml('DEBUG: envs: ' . rg_array2string($envs));
292 //rg_log_debug('envs: ' . rg_array2string($envs));
245 293 foreach ($envs as $env => $on) foreach ($envs as $env => $on)
246 294 $a['envs'][$env] = strcasecmp($on, 'on') == 0 ? 1 : 0; $a['envs'][$env] = strcasecmp($on, 'on') == 0 ? 1 : 0;
247 295
 
... ... function rg_wh_build_fill_vars(&$rg)
254 302
255 303 $rg['wh']['idata'] = $a; $rg['wh']['idata'] = $a;
256 304
257 //rg_log_ml('DEBUG: after fill_vars: ' . rg_array2string($a));
305 //rg_log_debug('after fill_vars: ' . rg_array2string($a));
258 306 } }
259 307
260 308 /* /*
 
... ... function rg_wh_build_validate_vars($rg, &$errmsg)
270 318 while (1) { while (1) {
271 319 $all_empty = TRUE; $all_empty = TRUE;
272 320
273 //rg_log_ml('DEBUG: cmds:' . rg_array2string($a['idata']['cmds']));
321 //rg_log_debug('cmds:' . rg_array2string($a['idata']['cmds']));
274 322 if (empty($a['idata']['cmds'])) { if (empty($a['idata']['cmds'])) {
275 323 $errmsg[] = rg_template('user/settings/wh/build/inv_cmd.txt', $errmsg[] = rg_template('user/settings/wh/build/inv_cmd.txt',
276 324 $rg, TRUE /*xss*/); $rg, TRUE /*xss*/);
277 325 break; break;
278 326 } }
279 327
280 //rg_log_ml('DEBUG: envs:' . rg_array2string($a['idata']['envs']));
328 //rg_log_debug('envs:' . rg_array2string($a['idata']['envs']));
281 329 if (empty($a['idata']['envs'])) { if (empty($a['idata']['envs'])) {
282 330 $errmsg[] = rg_template('user/settings/wh/build/inv_env.txt', $errmsg[] = rg_template('user/settings/wh/build/inv_env.txt',
283 331 $rg, TRUE /*xss*/); $rg, TRUE /*xss*/);
 
... ... function rg_wh_build_add_form_post($db, &$rg)
331 379 $cmds = ''; $cmds = '';
332 380 for ($i = 1; $i <= 5; $i++) for ($i = 1; $i <= 5; $i++)
333 381 $cmds .= str_replace('##i##', $i, $f); $cmds .= str_replace('##i##', $i, $f);
334 //rg_log_ml('DEBUG: cmds=' . $cmds);
382 //rg_log_debug('cmds=' . $cmds);
335 383 $rg['HTML:cmds'] = $rg['HTML:cmds'] =
336 384 rg_template_string($cmds, 0 /*off*/, $rg, TRUE /*xss*/); rg_template_string($cmds, 0 /*off*/, $rg, TRUE /*xss*/);
337 385
338 $envs = rg_worker_environments($db, $rg['login_ui']['uid']);
386 $ui_login = rg_ui_login();
387 $envs = rg_worker_environments($db, $ui_login['uid']);
339 388 $f = rg_template_blind('user/settings/wh/build/form_env.html'); $f = rg_template_blind('user/settings/wh/build/form_env.html');
340 389 $_s = ''; $_s = '';
341 390 foreach ($envs as $env) foreach ($envs as $env)
342 $_s .= str_replace('##env##', $env, $f);
343 rg_log_ml('envs: ' . $_s);
391 $_s .= str_replace('##env##', rg_xss_safe($env), $f);
392 //rg_log_debug('envs: ' . $_s);
344 393 $rg['HTML:envs'] = $rg['HTML:envs'] =
345 394 rg_template_string($_s, 0 /*off*/, $rg, TRUE /*xss*/); rg_template_string($_s, 0 /*off*/, $rg, TRUE /*xss*/);
346 395
347 //rg_log_ml('DEBUG:rg: ' . rg_array2string($rg));
396 //rg_log_debug('rg: ' . rg_array2string($rg));
348 397
349 398 $rg['HTML:custom_form'] = rg_template('user/settings/wh/build/form.html', $rg['HTML:custom_form'] = rg_template('user/settings/wh/build/form.html',
350 399 $rg, TRUE /*xss*/); $rg, TRUE /*xss*/);
File root/themes/default/admin/distros/list/footer.html added (mode: 100644) (index 0000000..71fa2b6)
1 </tbody>
2 </table>
3 </div>
4
5 <p>
6 <input type="submit" name="button" value="Update selection" />
7 </p>
8 </form>
File root/themes/default/admin/distros/list/header.html added (mode: 100644) (index 0000000..5c8e622)
1 <form method="post" action="/op/admin/distros/list" class="form_table">
2 <input type="hidden" name="update" value="1" />
3 <input type="hidden" name="token" value="@@rg_form_token@@" />
4
5 <div class="formarea_table">
6 <table>
7 <thead>
8 <tr>
9 <th>Enabled?</th>
10 <th>Name</th>
11 <th>Major</th>
12 <th>Arch</th>
13 <th>Package format</th>
14 </tr>
15 </thead>
16
17 <tbody>
File root/themes/default/admin/distros/list/line.html added (mode: 100644) (index 0000000..c054037)
1 <tr>
2 <td><input id="@@env@@" type="checkbox" name="list[@@env@@]" @@if(@@enabled@@ == 1){{checked}} /></td>
3 <td>@@distro_nice@@</td>
4 <td>@@major@@</td>
5 <td>@@arch@@</td>
6 <td>@@distro_pkg_type@@</td>
7 </tr>
8
File root/themes/default/admin/distros/list/nodata.html copied from file root/themes/default/builder/queue/nodata.html (similarity 50%) (mode: 100644) (index 8f55511..45c2b47)
1 1 <div class="mess ok"> <div class="mess ok">
2 No build jobs in queue.
2 No distributions available.
3 3 </div> </div>
File root/themes/default/admin/distros/menu.html added (mode: 100644) (index 0000000..615233b)
1 <div class="menu menu3">
2 <ul>
3 <li@@if(@@admin_distros_menu::list@@ == 1){{ class="selected"}}{{}}><a href="/op/admin/distros/list">List</a></li>
4 </ul>
5 </div>
File root/themes/default/admin/distros/update_ok.html added (mode: 100644) (index 0000000..1b9d548)
1 <div class="mess ok">
2 Distributions list has been successfully updated.
3 </div>
File root/themes/default/doc/demo/demos/packages/0/main.html added (mode: 100644) (index 0000000..dd2bc85)
1 <div class="demo_page_title">@@demo::page_name@@</div>
2
3 This tutorial will teach you how to make available to the world
4 the distribution packages built from your git repositories.<br />
5 <br />
6
7 For example, you can push your commits and, automatically, by searching
8 for a specific distribution signaling (for example. for a <b>.spec</b> file
9 on a .rpm based distribution), RocketGit will generate the source
10 package (.src.rpm etc.) and the binary package (.rpm, .deb etc.).
11 Then, it will populate the global or your personal repositories
12 with them and will expose them to others to use them.<br />
13 <br />
14
15 It will make your life easier by allowing your users to use your project:
16 you just need to push and everybody, at the next update, will have your
17 new version installed. This will bring more users onboard. Some users
18 do not know how to install from source; the rest are forced to check for
19 a new version periodically and install it, over and over again.<br />
20 Having a package repository added to your user's distribution
21 will mean faster testing cycles thanks to the automatically upgrade.<br />
22 <br />
23
24 Also, having your package repository installed, it will allow your users
25 to easily search and install other project of yours.<br />
26 <br />
27
28 Check first the <a href="/op/doc/demo/ci-1" target="_blank">
29 Continuous Integration tutorial</a>
30 to learn the how to trigger a build when you push your code.
31
File root/themes/default/doc/demo/demos/packages/0/name.html added (mode: 100644) (index 0000000..9e517a1)
1 Welcome to Packages tutorial!
File root/themes/default/doc/demo/demos/packages/create/main.html added (mode: 100644) (index 0000000..1d6060a)
1 <div class="demo_page_title">@@demo::page_name@@</div>
2
3 Next to the global package repositories, you may create some of
4 your own.<br />
5 <br />
6
7 To create a repository, you must be logged in and go to
8 <a href="/op/settings/packages/repo/add" target="_blank">Settings - Packages - Repositories - Add</a>,
9 specify a name, select the type (public or private) and press <b>Add</b>
10 button.<br />
11 To list the current repositories, go to
12 <a href="/op/settings/packages/repo" target="_blank">Settings - Packages - Repositories</a>.<br />
13 <br />
14
15 Now, go to <a href="/op/settings/packages/subrepo/add" target="_blank">Settings - Packages - Subrepositories - Add</a>,
16 select a repository and a name and press <b>Add</b> button.
17 Suggested names for a subrepositories are: <b>stable</b>, <b>testing</b>,
18 but any other names is allowed. You have a <b>List</b> submenu to see
19 all subrepositories, as well.<br />
20
21 When you push to your commits, RocketGit must figure out
22 in which package repository to put your packages.<br />
23 Is is basing this decision on the reference name (branch or tag).<br />
24 For example, you may choose to store your packages generated from the
25 <b>release</b> branch into <b>stable</b> package repository and
26 from the tags starting with letter <b>v</b> (example v0.1) inside
27 <b>testing</b> repository.<br />
28 Go to
29 <a href="/op/settings/packages/map/add" target="_blank">Settings - Packages - Mappings - Add</a>,
30 set a priority, specify a regular expression for the git repository,
31 another regular expression for the git reference and a destination
32 package repository/subrepository.<br />
33 When the build system evaluates into what repository to copy
34 a package, the list of the mappings is ordered by priority and evaluated
35 in order. In this way, you may stop the evaluation of the rules at any point
36 (by mapping to "No repo / no subrepo" destination).<br />
37 <br />
38
39 At your next push, if a package is built, it will be copied to all
40 matching repositories.<br />
41 <br />
42
43 If you go to the git repository page, there is a submenu named <b>Packages</b>
44 where you can find all repositories where the package is present,
45 grouped by repository, distribution, major version and architecture.<br />
46 You can also find the details about all past versions of a package, which
47 worker built that package and when.<br />
48 If you want to install that package on your machines, you can find there
49 instructions on how to do it.<br />
50 <br />
51
52 For private package repository, you may give rights to other users.
53 For example, you may want to have a company repository from where all
54 machines to get the updates of packages.
55
File root/themes/default/doc/demo/demos/packages/create/main.html.oldway added (mode: 100644) (index 0000000..c560ee0)
1 <div class="demo_page_title">@@demo::page_name@@</div>
2
3 You can have as many package repositories as needed.
4 You can have <b>stable</b> and <b>testing</b>, for example.
5 When you push to your repository, RocketGit must figure out
6 in which package repository to put your packages.<br />
7 We based this decision on the branch name.
8 For example, you can choose to store your packages generated from the
9 <b>releases</b> branch into <b>stable</b> package repository and
10 from the <b>main</b> branch inside <b>testing</b>.<br />
11 To achieve this, you need to have a file named <b>repo</b>
12 inside the <b>rocketgit</b> directory, in your project root directory.<br />
13 You should have this file in git but you can generate it at build time.
14 It will be consulted after the building phase.<br />
15 <br />
16
17 The format of the file is:<br />
18 <div class="term">repo map = REGEX -> REPO_NAME
19 </div>
20
21 The rules are tested in order, first match will stop the evaluation of the file.<br />
22 <b>REGEX</b> is a regular expression used to match the branch name.
23 <b>REPO_NAME</b> is the repository where the package will be stored.
24 If you use the special name <b>DISABLE</b> for the <b>REPO_NAME</b>,
25 the process of building packages will stop. For example, you can choose to
26 not trigger the process for some branches.<br />
27 <br />
28
29 An example:
30 <div class="term">repo map = master2.* -> DISABLE
31 repo map = ^(master|main)$ -> testing
32 repo map = (releases|hotfix) -> stable
33 repo map = ^bla -> bla-repo
34 </div>
35
36 The above example will stop the process if branch starts with master2 (first line).
37 It will map <b>master</b> and <b>main</b> branches to <b>testing</b> package repository (second line).
38 It will map the branches containing <b>releases</b> or <b>hotfix</b> to
39 <b>stable</b> package repository (third line).
40 It will map any branch starting with <b>bla</b> to <b>bla-repo</b> package
41 repository (last line).<br />
42
File root/themes/default/doc/demo/demos/packages/create/name.html added (mode: 100644) (index 0000000..b655261)
1 How to create a package repository
File root/themes/default/doc/demo/demos/packages/global/main.html added (mode: 100644) (index 0000000..71bd1fe)
1 <div class="demo_page_title">@@demo::page_name@@</div>
2
3 We are providing global package repositories to help anyone to easily
4 install any public software hosted on RocketGit.
5 Just go to <a href="/op/pkg_repos" target="_blank">Global Repositories Page</a>
6 and follow the instructions.<br />
7 After you have a global repository installed in your distribution,
8 you can use your favorite tool to search and install packages.
9 Thanks to the the distribution, your packages will be kept up-to-date,
10 in sync with the releases done by the authors.<br />
11 <br />
12
13 The global repository has two sub-repositories: <b>stable</b> and
14 <b>testing</b>. You may choose one of them based on your prefences.<br />
15 <br />
16
17 You too can have your packages hosted on RocketGit. Just follow the rest
18 of the tutorial to learn how.
19
File root/themes/default/doc/demo/demos/packages/global/name.html added (mode: 100644) (index 0000000..47cb428)
1 Using RocketGit global repositories
File root/themes/default/doc/demo/demos/packages/name.html added (mode: 100644) (index 0000000..53ca323)
1 Packages
File root/themes/default/doc/demo/demos/packages/see/main.html added (mode: 100644) (index 0000000..3fef399)
1 <div class="demo_page_title">@@demo::page_name@@</div>
2
3 Now, that the artifacts were defined, at the next run of the hook,
4 the repository mapping file (<b>rocketgit/repo</b>) file will be taken in
5 consideration and the packages will be built and repository will be created.<br />
6 <br />
7
8 TODO: do we will show on web the packages in a repo?
9 TODO: describe how to use the repo.
File root/themes/default/doc/demo/demos/packages/see/name.html copied from file root/themes/default/doc/demo/demos/artifacts/see/name.html (similarity 100%)
File root/themes/default/hints/repo/edit_repo_path_rights.html deleted (index 3682d72..0000000)
1 <br />
2 Examples:
3 <table>
4 <thead>
5 <tr>
6 <th>User</th>
7 <th>Path</th>
8 <th>Right</th>
9 <th>Description</th>
10 </tr>
11 </thead>
12
13 <tbody>
14 <tr>
15 <td>*</td><td>.*\.exe</td><td>no rights selected</td>
16 <td>No user is allowed to push .exe files</td>
17 </tr>
18
19 <tr>
20 <td>coworker</td><td>^doc/.*</td><td>Push</td>
21 <td>Only user <i>coworker</i> is allowed to push commits that
22 alter some files/dirs in root doc folder</td>
23 </tr>
24
25 <tr>
26 <td>*</td><td>^users/@USER@/</td><td>Push</td>
27 <td>Any user can push to his folder inside '/users/' (@USER@ will be
28 replaced with the username of the connecting user at the 'push' time).</td>
29 </tr>
30
31 <tr>
32 <td>*</td><td>empty</td><td>no rights selected</td>
33 <td>This is a drop all rule. Can be used, for example, to block
34 all the rules that might follow.</td>
35 </tr>
36 </tbody>
37 </table>
File root/themes/default/hints/repo/edit_repo_refs_rights.html deleted (index 3378a38..0000000)
1 <br />
2 Bad whitespace: if checked, commits with mixed tabs and spaces, trailing
3 spaces/tabs etc. will be allowed.<br />
4 <br />
5
6 Anonymous push: any random person can anonymously push changes that will be
7 automatically transformed in a merge request. This allows users who does not
8 have an account here to be able to easy contribute to your project.
9 See <a href="/op/features/anonpush" target="_blank">here</a> for more info.<br />
10 <br />
11
12 If your 'Reference' field does not start with '/', '/refs/heads/' will be
13 automatically prepended.<br />
14 <br />
15
16 Examples:<br />
17 <table>
18 <thead>
19 <tr>
20 <th>User</th>
21 <th>Reference</th>
22 <th>Rights</th>
23 <th>Description</th>
24 </tr>
25 </thead>
26
27 <tbody>
28 <tr>
29 <td>fred</td><td>users/secret</td><td>no rights selected</td>
30 <td>User fred cannot push into /refs/heads/users/secret reference</td>
31 </tr>
32 <tr>
33 <td>coworker</td><td>/refs/heads/x</td><td>Fetch,Push</td>
34 <td>User <b>coworker</b> is allowed to fetch and push into branch x.</td>
35 </tr>
36
37 <tr>
38 <td>user1</td><td>devel-.*</td><td>Non fast-forward</td>
39 <td>user1 is allowed to force push (non fast-forward) in any branch
40 that starts with 'devel-', for example 'devel-1.0'.</td>
41 </tr>
42
43 <tr>
44 <td>*</td><td>users/@USER@/</td><td>Push</td>
45 <td>Any user can push to his private ref
46 '/refs/heads/users/username_of_the_pushing_user' (@USER@ is replaced
47 with the username of the connecting user at the push time).</td>
48 </tr>
49
50 <tr>
51 <td>*</td><td>empty</td><td>no rights selected</td>
52 <td>This is a drop all rule. Can be used, for example, to block
53 all the rules that might follow.</td>
54 </tr>
55 </tbody>
56 </table>
File root/themes/default/hints/repo/edit_repo_rights.html deleted (index a254abe..0000000)
1 <br />
2 Here you can add generic rights for your co-workers / friends.<br />
File root/themes/default/hints/repo/edit_rights.html deleted (index f710ae3..0000000)
1 <br />
2 You do not have to grant yourself rights.
3 You can observe the autogenerated rule that grants you maximum rights.<br />
4 <br />
5
6 IP can be empty, meaning any IP will match.
7 You can use both IPv4 and IPv6. Some examples: 4.4.4.4, 1.2.3.0/24,
8 2001:6:3456::/64.<br />
9 <br />
10
11 Priorities are used to order the rights. They are evaluated top to bottom.
12 and must be greater than 10 and lower than 30000.<br />
13 <br />
14
15 To add a deny rule, just do not select any right; if matched, the evaluation
16 of the next rules will stop.<br />
File root/themes/default/pkg_repos/welcome_begin.html added (mode: 100644) (index 0000000..c1f0285)
1 <div class="main_title">Package repositories</div>
2
3 <div class="repo_body">
4
File root/themes/default/pkg_repos/welcome_end.html copied from file root/themes/default/errmsg/footer.html (similarity 100%)
File root/themes/default/rights/form_pkgrepo.html renamed from root/themes/default/user/repo/rights/form_repo.html (similarity 73%) (mode: 100644) (index ff3afb8..9786fec)
1 @@grant_note@@
2
1 3 <div class="formarea formarea_small"> <div class="formarea formarea_small">
2 4
3 <div class="formarea_title">@@if(@@right_id@@ == 0){{Grant repo rights}}{{Edit repo rights}}</div>
5 <div class="formarea_title">@@if(@@right_id@@ == 0){{Grant pkg repo rights}}{{Edit pkg repo rights}}</div>
4 6
5 @@errmsg@@
7 @@grant_errmsg@@
6 8
7 <form method="post" action="@@url_repo@@/admin/repo_rights">
9 <form method="post" action="/op/settings/packages/repo/rights/@@pkg_repo_info::id@@">
8 10 <input type="hidden" name="right_id" value="@@right_id@@" /> <input type="hidden" name="right_id" value="@@right_id@@" />
9 11 <input type="hidden" name="grant" value="1" /> <input type="hidden" name="grant" value="1" />
10 12 <input type="hidden" name="token" value="@@rg_form_token@@" /> <input type="hidden" name="token" value="@@rg_form_token@@" />
 
25 27 </p> </p>
26 28
27 29 <p> <p>
28 <label for="ip">IP addresses/prefix (comma/space separated)</label><br />
30 <label for="ip">IP addresses/prefix (comma/space/enter separated)</label><br />
29 31 <textarea name="ip" id="ip" rows="3">@@ip@@</textarea> <textarea name="ip" id="ip" rows="3">@@ip@@</textarea>
30 32 </p> </p>
31 33
File root/themes/default/rights/list_pkgrepo/footer.html renamed from root/themes/default/user/repo/rights/list_repo/footer.html (similarity 100%)
File root/themes/default/rights/list_pkgrepo/header.html renamed from root/themes/default/user/repo/rights/list_repo/header.html (similarity 100%)
File root/themes/default/rights/list_pkgrepo/line.html renamed from root/themes/default/user/repo/rights/list_repo/line.html (similarity 64%) (mode: 100644) (index 390cab0..a1da39f)
7 7 <td>@@ip_nice@@</td> <td>@@ip_nice@@</td>
8 8 <td>@@rights_text@@</td> <td>@@rights_text@@</td>
9 9 <td><small>@@description_nlbr@@</small></td> <td><small>@@description_nlbr@@</small></td>
10 <td>@@if(@@can_be_deleted@@ == 1){{<a href="@@url_repo@@/admin/repo_rights?edit_id=@@right_id@@">Edit</a>}}{{N/A}}</td>
10 <td>@@if(@@can_be_deleted@@ == 1){{<a href="/op/settings/packages/repo/rights/@@pkg_repo_info::id@@/?edit_id=@@right_id@@"><span class="but">Edit</span></a>}}{{N/A}}</td>
11 11 </tr> </tr>
File root/themes/default/rights/list_pkgrepo/nodata.html renamed from root/themes/default/user/repo/rights/list_repo/nodata.html (similarity 100%)
File root/themes/default/user/pkg/list/footer.html copied from file root/themes/default/builder/cmds/footer.html (similarity 100%)
File root/themes/default/user/pkg/list/header.html added (mode: 100644) (index 0000000..a291765)
1 <table>
2 <thead>
3 <tr>
4 <th>Type</th>
5 <th>Public?</th>
6 <th>Repo name</th>
7 <th>Subrepo name</th>
8 <th>Distribution</th>
9 <th>Version</th>
10 <th>Architecture</th>
11 <th>How to install the package</th>
12 </tr>
13 </thead>
14
15 <tbody>
File root/themes/default/user/pkg/list/line.html added (mode: 100644) (index 0000000..43d476c)
1 <tr>
2 <td>@@if(@@pkg_repo_info::is_global@@ == 1){{Global}}{{User}}</td>
3 <td>@@if(@@pkg_repo_info::public@@ == 1){{Public}}{{Private}}</td>
4 <td>@@pkg_repo_info::name@@</td>
5 <td>@@pkg_subrepo_info::name@@</td>
6 <td>@@distro_nice@@</td>
7 <td>@@major@@</td>
8 <td>@@arch@@</td>
9 <td>
10 <div class="term">@@howto@@</div>
11 </td>
12 </tr>
13
File root/themes/default/user/pkg/list/nodata.html added (mode: 100644) (index 0000000..4760fa1)
1 <div class="mess ok">
2 No packages repositories avilable.
3 </div>
File root/themes/default/user/pkg/no_packages.html copied from file root/themes/default/repo/bug/list/nodata.html (similarity 54%) (mode: 100644) (index 5a9a182..bc0a56d)
1 1 <div class="mess ok"> <div class="mess ok">
2 No bugs found.
2 No packages available.
3 3 </div> </div>
File root/themes/default/user/pkg/redhat/priv_download.html added (mode: 100644) (index 0000000..79815a1)
1 <a href="@@pkg::dotrepo_pkg_url@@/@@pkg::dotrepo_pkg_name@@">
2 <span class="but">Download</span>
3 </a>
4
5 <div class="term"># Press the <b>Download</b> button above, copy the rpm to any machine you want, and then:
6 @@pkg::cmd@@ install @@ESCAPE_SHELL_ARG:pkg::dotrepo_pkg_name@@
7 @@if("@@pkg::user@@" != ""){{
8 @@pkg::cmd@@ install @@ESCAPE_SHELL_ARG:pkg::user_repo_name@@
9 }}
10 </div>
11
12 @@if("@@pkg::user@@" != ""){{
13 @@pkg::other@@
14 }}
File root/themes/default/user/pkg/redhat/pub_download.html added (mode: 100644) (index 0000000..9cadafc)
1 <div class="term">@@pkg::cmd@@ install <a href="@@pkg::dotrepo_pkg_url@@/@@pkg::dotrepo_pkg_name@@">@@pkg::dotrepo_pkg_url@@/@@pkg::dotrepo_pkg_name@@</a>
2 @@if("@@pkg::user@@" != ""){{
3 @@pkg::cmd@@ install @@ESCAPE_SHELL_ARG:pkg::user_repo_name@@
4 }}
5 </div>
6
7 @@if("@@pkg::user@@" != ""){{
8 @@pkg::other@@
9 }}
File root/themes/default/user/repo/rights/delete_ok.html deleted (index 8891bc7..0000000)
1 <div class="mess ok">
2 The rights have been successfully deleted.
3 </div>
File root/themes/default/user/repo/rights/deny.html deleted (index b905a4c..0000000)
1 <div class="mess error">
2 You are not allowed to grant rights.
3 </div>
File root/themes/default/user/repo/rights/form_repo_path.html deleted (index ecbbb16..0000000)
1 <div class="formarea formarea_small">
2
3 <div class="formarea_title">@@if(@@right_id@@ == 0){{Grant path rights}}{{Edit path rights}}</div>
4
5 @@errmsg@@
6
7 <form method="post" action="@@url_repo@@/admin/path_rights">
8 <input type="hidden" name="right_id" value="@@right_id@@" />
9 <input type="hidden" name="grant" value="1" />
10 <input type="hidden" name="token" value="@@rg_form_token@@" />
11
12 <p>
13 <label for="username">User (use '*' for any user)</label><br />
14 <input type="text" name="username" id="username" value="@@username@@" size="50" />
15 </p>
16
17 <p>
18 <label for="ref">Path (regexp)</label><br />
19 <input type="text" name="misc" id="ref" value="@@misc@@" />
20 </p>
21
22 <fieldset>
23 <legend>Rights</legend>
24 @@rights_checkboxes@@
25 </fieldset>
26
27 <p>
28 <label for="description">Description</label><br />
29 <textarea name="description" id="description" rows="3">@@description@@</textarea>
30 </p>
31
32 <p>
33 <label for="ip">IP addresses/prefix (comma/space separated)</label><br />
34 <textarea name="ip" id="ip" rows="3">@@ip@@</textarea>
35 </p>
36
37 <p>
38 <label for="prio">Priority (10 - 30000)</label><br />
39 <input type="text" name="prio" id="prio" value="@@prio@@" />
40 </p>
41
42 <p>
43 <input type="submit" name="button" value="Grant" />
44 </p>
45 </form>
46 </div>
File root/themes/default/user/repo/rights/form_repo_refs.html deleted (index ee3d279..0000000)
1 <div class="formarea formarea_small">
2
3 <div class="formarea_title">@@if(@@right_id@@ == 0){{Grant refs rights}}{{Edit refs rights}}</div>
4
5 @@errmsg@@
6
7 <form method="post" action="@@url_repo@@/admin/refs_rights">
8 <input type="hidden" name="right_id" value="@@right_id@@" />
9 <input type="hidden" name="grant" value="1" />
10 <input type="hidden" name="token" value="@@rg_form_token@@" />
11
12 <p>
13 <label for="username">User (use '*' for any user)</label><br />
14 <input type="text" name="username" id="username" value="@@username@@" size="50" />
15 </p>
16
17 <p>
18 <label for="ref">Reference (regexp, leave empty for any)</label><br />
19 <input type="text" name="misc" id="ref" value="@@misc@@" />
20 </p>
21
22 <fieldset>
23 <legend>Rights</legend>
24 @@rights_checkboxes@@
25 </fieldset>
26
27 <p>
28 <label for="description">Description</label><br />
29 <textarea name="description" id="description" rows="3">@@description@@</textarea>
30 </p>
31
32 <p>
33 <label for="ip">IP addresses/prefix (comma/space separated)</label><br />
34 <textarea name="ip" id="ip" rows="3">@@ip@@</textarea>
35 </p>
36
37 <p>
38 <label for="prio">Priority (10 - 30000)</label><br />
39 <input type="text" name="prio" id="prio" value="@@prio@@" />
40 </p>
41
42 <p>
43 <input type="submit" name="button" value="Grant" />
44 </p>
45 </form>
46 </div>
File root/themes/default/user/repo/rights/grant_ok.html deleted (index 8170801..0000000)
1 <div class="mess ok">
2 The rights have been successfully granted.
3 </div>
File root/themes/default/user/repo/rights/list_repo_path/header.html deleted (index 2b17f40..0000000)
1 @@list_errmsg@@
2
3 <form method="post" action="@@url_repo@@/admin/path_rights" class="form_table">
4 <input type="hidden" name="delete" value="1" />
5 <input type="hidden" name="token" value="@@rg_form_token@@" />
6
7 <div class="formarea_table">
8 <table>
9 <thead>
10 <tr>
11 <th>Select</th>
12 <th>Priority</th>
13 <th>Who</th>
14 <th>Date (UTC)</th>
15 <th>User</th>
16 <th>IP</th>
17 <th>Path</th>
18 <th>Path rights</th>
19 <th>Description</th>
20 <th>Operations</th>
21 </tr>
22 </thead>
23
24 <tbody>
File root/themes/default/user/repo/rights/list_repo_path/line.html deleted (index 4dfbd0f..0000000)
1 <tr>
2 <td>@@if(@@can_be_deleted@@ == 1){{<input type="checkbox" name="rights_delete_ids[@@right_id@@]" />}}{{N/A}}</td>
3 <td>@@prio@@</td>
4 <td>@@who_name@@</td>
5 <td>@@itime_text@@</td>
6 <td>@@username@@</td>
7 <td>@@ip_nice@@</td>
8 <td>@@misc@@</td>
9 <td>@@rights_text@@</td>
10 <td><small>@@description_nlbr@@</small></td>
11 <td>@@if(@@can_be_deleted@@ == 1){{<a href="@@url_repo@@/admin/path_rights?edit_id=@@right_id@@">Edit</a>}}{{N/A}}</td>
12 </tr>
File root/themes/default/user/repo/rights/list_repo_path/nodata.html deleted (index e69de29..0000000)
File root/themes/default/user/repo/rights/list_repo_refs/header.html deleted (index afc810c..0000000)
1 @@list_errmsg@@
2
3 <form method="post" action="@@url_repo@@/admin/refs_rights" class="form_table">
4 <input type="hidden" name="delete" value="1" />
5 <input type="hidden" name="token" value="@@rg_form_token@@" />
6
7 <div class="formarea_table">
8 <table>
9 <thead>
10 <tr>
11 <th>Select</th>
12 <th>Priority</th>
13 <th>Who</th>
14 <th>Date (UTC)</th>
15 <th>User</th>
16 <th>IP</th>
17 <th>Ref</th>
18 <th>Refs rights</th>
19 <th>Description</th>
20 <th>Operations</th>
21 </tr>
22 </thead>
23
24 <tbody>
File root/themes/default/user/repo/rights/list_repo_refs/line.html deleted (index 61d1c58..0000000)
1 <tr>
2 <td>@@if(@@can_be_deleted@@ == 1){{<input type="checkbox" name="rights_delete_ids[@@right_id@@]" />}}{{N/A}}</td>
3 <td>@@prio@@</td>
4 <td>@@who_name@@</td>
5 <td>@@itime_text@@</td>
6 <td>@@username@@</td>
7 <td>@@ip_nice@@</td>
8 <td>@@misc@@</td>
9 <td>@@rights_text@@</td>
10 <td><small>@@description_nlbr@@</small></td>
11 <td>@@if(@@can_be_deleted@@ == 1){{<a href="@@url_repo@@/admin/refs_rights?edit_id=@@right_id@@">Edit</a>}}{{N/A}}</td>
12 </tr>
File root/themes/default/user/repo/rights/list_repo_refs/nodata.html deleted (index e69de29..0000000)
File root/themes/default/user/settings/packages/map/add_edit.html added (mode: 100644) (index 0000000..9241859)
1 <div class="formarea formarea_small">
2
3 <div class="formarea_title">@@if(@@mi::id@@ == 0){{Add a new}}{{Update}} packages mapping</div>
4
5 @@errmsg@@
6
7 <form method="post" action="/op/settings/packages/map/@@if(@@mi::id@@ == 0){{add}}{{edit/@@mi::id@@}}">
8 <input type="hidden" name="doit" value="1" />
9 <input type="hidden" name="token" value="@@rg_form_token@@" />
10
11 <p>
12 <label for="prio">Priority (lower = early; between 0 and 255)</label><br />
13 <input class="form_short" type="text" name="mi::prio" id="prio" value="@@mi::prio@@" size="3" />
14 </p>
15
16 <p>
17 <label for="repo">Git repository specification (regex, empty = all)</label><br />
18 <input type="text" name="mi::repo" id="repo" value="@@mi::repo@@" />
19 </p>
20
21 <p>
22 <label for="ref">Reference (regex, empty = all, example: <i>release(-.*)</i>)</label><br />
23 <input type="text" name="mi::ref" id="ref" value="@@mi::ref@@" />
24 </p>
25
26 <p>
27 <label for="pkg_subrepo_id">Package repository / subrepository</label><br />
28 @@mi::repo_subrepo_select@@
29 </p>
30
31 <p>
32 <input type="submit" name="button" value="@@if(@@mi::id@@ == 0){{Add}}{{Update}}" />
33 </p>
34 </form>
35 </div>
36
37 @@hints@@
File root/themes/default/user/settings/packages/map/add_edit_err.html added (mode: 100644) (index 0000000..9cd62c0)
1 cannot add/edit packages mapping: @@err_detail@@
File root/themes/default/user/settings/packages/map/add_ok.html added (mode: 100644) (index 0000000..d4e7bb4)
1 <div class="mess ok">
2 The packages mapping has been successfully added/edited.
3 </div>
File root/themes/default/user/settings/packages/map/delete_err.html added (mode: 100644) (index 0000000..f1b3320)
1 could not delete the selected packages mappings (@@err_detail@@)
File root/themes/default/user/settings/packages/map/delete_ok.html added (mode: 100644) (index 0000000..80f387b)
1 <div class="mess ok">
2 The packages mappings have been successfully deleted.
3 </div>
File root/themes/default/user/settings/packages/map/hints.html added (mode: 100644) (index 0000000..6d8b16d)
1 <br />
2 The mapping allows you to copy the built packages to multiple subrepositories.
File root/themes/default/user/settings/packages/map/id_invalid.html added (mode: 100644) (index 0000000..53a4192)
1 invalid packages map id
File root/themes/default/user/settings/packages/map/list/footer.html renamed from root/themes/default/user/repo/rights/list_repo_path/footer.html (similarity 100%)
File root/themes/default/user/settings/packages/map/list/header.html added (mode: 100644) (index 0000000..a669403)
1 @@errmsg@@
2
3 <form method="post" action="/op/settings/packages/map/list" class="form_table">
4 <input type="hidden" name="doit" value="1" />
5 <input type="hidden" name="token" value="@@rg_form_token@@" />
6
7 <div class="formarea_table">
8 <table>
9 <thead>
10 <tr>
11 <th>Select</th>
12 <th>Insert date (UTC)</th>
13 <th>Priority</th>
14 <th>Repository specification</th>
15 <th>References (regex)</th>
16 <th>Target repository type</th>
17 <th>Target repository name</th>
18 <th>Operations</th>
19 </tr>
20 </thead>
21
22 <tbody>
File root/themes/default/user/settings/packages/map/list/line.html added (mode: 100644) (index 0000000..2775c04)
1 <tr>
2 <td><input type="checkbox" name="delete_list[@@id@@]" /></td>
3 <td>@@itime_nice@@</td>
4 <td>@@prio@@</td>
5 <td>@@repo@@</td>
6 <td>@@ref@@</td>
7 <td>@@pkg_subrepo_info::pkg_repo_info::public_text@@</td>
8 <td>@@pkg_subrepo_info::pkg_repo_info::name@@ / @@pkg_subrepo_info::name@@</td>
9 <td><a href="/op/settings/packages/map/edit/@@id@@"><span class="but">Edit</span></a></td>
10 </tr>
11
File root/themes/default/user/settings/packages/map/list/nodata.html added (mode: 100644) (index 0000000..e042d7a)
1 <div class="mess ok">
2 No packages mappings added yet.
3 </div>
File root/themes/default/user/settings/packages/map/list_err.html added (mode: 100644) (index 0000000..6bfa2ff)
1 could not list packages mappings (@@errmsg@@)
File root/themes/default/user/settings/packages/map/menu.html added (mode: 100644) (index 0000000..5619f8f)
1 <div class="menu menu3">
2 <ul>
3 <li@@if(@@menu3::packages::map::list@@ == 1){{ class="selected"}}><a href="/op/settings/packages/map/list">List</a></li>
4 <li@@if(@@menu3::packages::map::add@@ == 1){{ class="selected"}}><a href="/op/settings/packages/map/add">Add</a></li>
5 </ul>
6 </div>
File root/themes/default/user/settings/packages/menu.html added (mode: 100644) (index 0000000..07d8fda)
1 <div class="menu menu3">
2 <ul>
3 <li@@if(@@menu2::packages::repo@@ == 1){{ class="selected"}}><a href="/op/settings/packages/repo">Repositories</a></li>
4 <li@@if(@@menu2::packages::subrepo@@ == 1){{ class="selected"}}><a href="/op/settings/packages/subrepo">Subrepositories</a></li>
5 <li@@if(@@menu2::packages::map@@ == 1){{ class="selected"}}><a href="/op/settings/packages/map">Mappings</a></li>
6 </ul>
7 </div>
8 @@menu_level3@@
File root/themes/default/user/settings/packages/repo/add_edit.html added (mode: 100644) (index 0000000..409ba37)
1 <div class="formarea formarea_small">
2
3 <div class="formarea_title">@@if(@@pi::id@@ == 0){{Add a new}}{{Update}} packages repo</div>
4
5 @@errmsg@@
6
7 <form method="post" action="/op/settings/packages/repo/@@if(@@pi::id@@ == 0){{add}}{{edit/@@pi::id@@}}">
8 <input type="hidden" name="doit" value="1" />
9 <input type="hidden" name="token" value="@@rg_form_token@@" />
10
11 <p>
12 <label for="name">Name</label><br />
13 <input type="text" name="pi::name" id="name" value="@@pi::name@@" />
14 </p>
15
16 <p>
17 <label for="public">Visibility</label><br />
18 <select name="pi::public">
19 <option value="1"@@if(@@pi::public@@ == 1){{ selected="selected"}}{{}}>Public</option>
20 <option value="0"@@if(@@pi::public@@ == 0){{ selected="selected"}}{{}}>Private</option>
21 </select>
22 </p>
23
24 <p>
25 <input type="submit" name="button" value="@@if(@@pi::id@@ == 0){{Add}}{{Update}}" />
26 </p>
27 </form>
28 </div>
File root/themes/default/user/settings/packages/repo/add_edit_err.html added (mode: 100644) (index 0000000..f3a40e5)
1 cannot add/edit packages repo: @@err_detail@@
File root/themes/default/user/settings/packages/repo/add_ok.html added (mode: 100644) (index 0000000..f172188)
1 <div class="mess ok">
2 The packages repo has been successfully added/edited.
3 </div>
File root/themes/default/user/settings/packages/repo/delete_ok.html added (mode: 100644) (index 0000000..206cb19)
1 <div class="mess ok">
2 The packages repo(s) has been successfully deleted.
3 </div>
File root/themes/default/user/settings/packages/repo/hints.html copied from file root/themes/default/user/settings/apikeys/hints.html (similarity 58%) (mode: 100644) (index a7d50e2..e68a468)
... ... API keys are used to access RocketGit's API by HTTP(S).<br />
3 3 Check <a href="/op/doc/api">API documentation</a> for more info.<br /> Check <a href="/op/doc/api">API documentation</a> for more info.<br />
4 4 <b>Count</b> shows how many times the API key has been used.<br /> <b>Count</b> shows how many times the API key has been used.<br />
5 5 Example: Example:
6 <div class="term">$ curl --header 'Authorization: @@login_ui::username@@ put_here_the_apikey' \
7 --data '{"cmd": "user_info", "user": "@@login_ui::username@@"}' \
6 <div class="term">$ curl --header 'Authorization: @@FUNC:UI_LOGIN:username@@ put_here_the_apikey' \
7 --data '{"cmd": "user_info", "user": "@@FUNC:UI_LOGIN:username@@"}' \
8 8 @@base_url@@/op/api @@base_url@@/op/api
9 9 </div> </div>
File root/themes/default/user/settings/packages/repo/id_invalid.html added (mode: 100644) (index 0000000..2abb8b7)
1 invalid packages repo id
File root/themes/default/user/settings/packages/repo/is_public.html added (mode: 100644) (index 0000000..3638331)
1 <div class="mess error">
2 package repository is public, no need to give rights
3 </div>
File root/themes/default/user/settings/packages/repo/list/footer.html renamed from root/themes/default/user/repo/rights/list_repo_refs/footer.html (similarity 100%)
File root/themes/default/user/settings/packages/repo/list/header.html copied from file root/themes/default/user/settings/apikeys/list/header.html (similarity 50%) (mode: 100644) (index b60ac9e..f6812b2)
1 1 @@errmsg@@ @@errmsg@@
2 @@status@@
3 2
4 <form method="post" action="/op/settings/apikeys/list" class="form_table">
3 <form method="post" action="/op/settings/packages/repo/list" class="form_table">
5 4 <input type="hidden" name="doit" value="1" /> <input type="hidden" name="doit" value="1" />
6 5 <input type="hidden" name="token" value="@@rg_form_token@@" /> <input type="hidden" name="token" value="@@rg_form_token@@" />
7 6
 
10 9 <thead> <thead>
11 10 <tr> <tr>
12 11 <th>Select</th> <th>Select</th>
13 <th>Upload date (UTC)</th>
14 12 <th>Name</th> <th>Name</th>
15 <th>First use (UTC)</th>
16 <th>Last use (UTC)</th>
17 <th>Last IP</th>
18 <th>Last command</th>
19 <th>Count</th>
13 <th>Public?</th>
14 <th>Version</th>
15 <th>Insert date (UTC)</th>
16 <th>Disk used</th>
17 <th>Operations</th>
20 18 </tr> </tr>
21 19 </thead> </thead>
22 20
File root/themes/default/user/settings/packages/repo/list/line.html added (mode: 100644) (index 0000000..00913fa)
1 <tr>
2 <td><input type="checkbox" name="delete_list[@@id@@]" /></td>
3 <td>@@name@@</td>
4 <td>@@public_nice@@</td>
5 <td>@@version@@</td>
6 <td>@@itime_nice@@</td>
7 <td>@@disk_used@@</td>
8 <td>
9 <a href="/op/settings/packages/repo/edit/@@id@@"><span class="but">Edit</span></a>
10 @@if(@@public@@ == 0){{
11 <a href="/op/settings/packages/repo/rights/@@id@@"><span class="but">Rights</span></a>
12 }}
13 </td>
14 </tr>
15
File root/themes/default/user/settings/packages/repo/list/nodata.html added (mode: 100644) (index 0000000..d6a6948)
1 <div class="mess ok">
2 No packages repositories added yet.
3 </div>
File root/themes/default/user/settings/packages/repo/list_err.html added (mode: 100644) (index 0000000..15d931c)
1 <div class="mess error">
2 Could not list packages repositories (@@errmsg@@).
3 </div>
File root/themes/default/user/settings/packages/repo/menu.html added (mode: 100644) (index 0000000..75066a3)
1 <div class="menu menu3">
2 <ul>
3 <li@@if(@@menu3::packages::repo::list@@ == 1){{ class="selected"}}><a href="/op/settings/packages/repo/list">List</a></li>
4 <li@@if(@@menu3::packages::repo::add@@ == 1){{ class="selected"}}><a href="/op/settings/packages/repo/add">Add</a></li>
5 </ul>
6 </div>
File root/themes/default/user/settings/packages/repo/name_duplicate.html added (mode: 100644) (index 0000000..2f80ee4)
1 name already exists
File root/themes/default/user/settings/packages/repo/name_empty.html added (mode: 100644) (index 0000000..034349c)
1 name is empty
File root/themes/default/user/settings/packages/repo/name_invalid.html added (mode: 100644) (index 0000000..106c748)
1 name is invalid (invalid char(s): '@@pi::name_invalid@@')
File root/themes/default/user/settings/packages/repo/rights_head.html added (mode: 100644) (index 0000000..b68886c)
1 <div class="pkg_repo_title">
2 Package repo @@pkg_repo_info::name@@
3 </div>
File root/themes/default/user/settings/packages/subrepo/add_edit.html added (mode: 100644) (index 0000000..365b3a4)
1 <div class="formarea formarea_small">
2
3 <div class="formarea_title">@@if(@@pkg_subrepo_info::id@@ == 0){{Add a new}}{{Update}} packages subrepo</div>
4
5 @@errmsg@@
6
7 <form method="post" action="/op/settings/packages/subrepo/@@if(@@pkg_subrepo_info::id@@ == 0){{add}}{{edit/@@pkg_subrepo_info::id@@}}">
8 <input type="hidden" name="doit" value="1" />
9 <input type="hidden" name="token" value="@@rg_form_token@@" />
10
11 <p>
12 @@if(@@pkg_subrepo_info::id@@ == 0){{
13 <label for="pkg_repo_id">Repository</label><br />
14 @@pkg_subrepo_info::repo_select@@
15 }}{{
16 Repository: <b>@@pkg_subrepo_info::pkg_repo_info::name@@</b>
17 }}
18 </p>
19
20 <p>
21 <label for="name">Subrepository name (example: <i>stable</i>, <i>unstable</i> etc.)</label><br />
22 <input type="text" name="sr::name" id="name" value="@@pkg_subrepo_info::name@@" />
23 </p>
24
25 <p>
26 <input type="submit" name="button" value="@@if(@@pkg_subrepo_info::id@@ == 0){{Add}}{{Update}}" />
27 </p>
28 </form>
29 </div>
File root/themes/default/user/settings/packages/subrepo/add_edit_err.html added (mode: 100644) (index 0000000..a2f6043)
1 cannot add/edit packages subrepo: @@err_detail@@
File root/themes/default/user/settings/packages/subrepo/add_ok.html added (mode: 100644) (index 0000000..34c065d)
1 <div class="mess ok">
2 The packages subrepo has been successfully added/edited.
3 </div>
File root/themes/default/user/settings/packages/subrepo/delete_ok.html added (mode: 100644) (index 0000000..a06b8fc)
1 <div class="mess ok">
2 The packages subrepo(s) has been successfully deleted.
3 </div>
File root/themes/default/user/settings/packages/subrepo/hints.html copied from file root/themes/default/user/settings/apikeys/hints.html (similarity 58%) (mode: 100644) (index a7d50e2..e68a468)
... ... API keys are used to access RocketGit's API by HTTP(S).<br />
3 3 Check <a href="/op/doc/api">API documentation</a> for more info.<br /> Check <a href="/op/doc/api">API documentation</a> for more info.<br />
4 4 <b>Count</b> shows how many times the API key has been used.<br /> <b>Count</b> shows how many times the API key has been used.<br />
5 5 Example: Example:
6 <div class="term">$ curl --header 'Authorization: @@login_ui::username@@ put_here_the_apikey' \
7 --data '{"cmd": "user_info", "user": "@@login_ui::username@@"}' \
6 <div class="term">$ curl --header 'Authorization: @@FUNC:UI_LOGIN:username@@ put_here_the_apikey' \
7 --data '{"cmd": "user_info", "user": "@@FUNC:UI_LOGIN:username@@"}' \
8 8 @@base_url@@/op/api @@base_url@@/op/api
9 9 </div> </div>
File root/themes/default/user/settings/packages/subrepo/id_invalid.html added (mode: 100644) (index 0000000..1e09dda)
1 invalid packages subrepo id
File root/themes/default/user/settings/packages/subrepo/list/footer.html copied from file root/themes/default/admin/ldap/list/footer.html (similarity 100%)
File root/themes/default/user/settings/packages/subrepo/list/header.html added (mode: 100644) (index 0000000..b2a08ad)
1 @@errmsg@@
2
3 <form method="post" action="/op/settings/packages/subrepo/list" class="form_table">
4 <input type="hidden" name="doit" value="1" />
5 <input type="hidden" name="token" value="@@rg_form_token@@" />
6
7 <div class="formarea_table">
8 <table>
9 <thead>
10 <tr>
11 <th>Select</th>
12 <th>Repo name</th>
13 <th>Subrepo name</th>
14 <th>Version</th>
15 <th>Insert date (UTC)</th>
16 <th>Disk used</th>
17 <th>Operations</th>
18 </tr>
19 </thead>
20
21 <tbody>
File root/themes/default/user/settings/packages/subrepo/list/line.html added (mode: 100644) (index 0000000..dddef6c)
1 <tr>
2 <td><input type="checkbox" name="delete_list[@@id@@]" /></td>
3 <td>@@pkg_repo_info::name@@</td>
4 <td>@@name@@</td>
5 <td>@@version@@</td>
6 <td>@@itime_nice@@</td>
7 <td>@@disk_used@@</td>
8 <td><a href="/op/settings/packages/subrepo/edit/@@id@@"><span class="but">Edit</span></a></td>
9 </tr>
10
File root/themes/default/user/settings/packages/subrepo/list/nodata.html added (mode: 100644) (index 0000000..be59639)
1 <div class="mess ok">
2 No packages subrepositories added yet.
3 </div>
File root/themes/default/user/settings/packages/subrepo/list_err.html added (mode: 100644) (index 0000000..ac2cc7d)
1 <div class="mess error">
2 Could not list packages subrepositories (@@errmsg@@).
3 </div>
File root/themes/default/user/settings/packages/subrepo/menu.html added (mode: 100644) (index 0000000..c002788)
1 <div class="menu menu3">
2 <ul>
3 <li@@if(@@menu3::packages::subrepo::list@@ == 1){{ class="selected"}}><a href="/op/settings/packages/subrepo/list">List</a></li>
4 <li@@if(@@menu3::packages::subrepo::add@@ == 1){{ class="selected"}}><a href="/op/settings/packages/subrepo/add">Add</a></li>
5 </ul>
6 </div>
File root/themes/default/user/settings/packages/subrepo/name_duplicate.html added (mode: 100644) (index 0000000..2f80ee4)
1 name already exists
File root/themes/default/user/settings/packages/subrepo/name_empty.html added (mode: 100644) (index 0000000..034349c)
1 name is empty
File root/themes/default/user/settings/packages/subrepo/name_invalid.html added (mode: 100644) (index 0000000..de2a879)
1 name is invalid (invalid char(s): '@@pkg_subrepo_info::name_invalid@@')
File tests/pkg_rpm.php added (mode: 100644) (index 0000000..8bcabc7)
1 <?php
2 error_reporting(E_ALL | E_STRICT);
3 ini_set('track_errors', 'On');
4
5 $rg_cache_debug = TRUE;
6 $rg_util_debug = TRUE;
7 $rg_sql_debug = 100;
8 $test_normal = TRUE;
9
10 $INC = dirname(__FILE__) . '/../inc';
11 require_once(dirname(__FILE__) . '/config.php');
12 require_once($INC . '/init.inc.php');
13 require_once($INC . '/util.inc.php');
14 require_once($INC . '/user/packages.inc.php');
15 require_once('helpers.inc.php');
16 require_once('http.inc.php');
17
18 rg_log_set_file('pkg_rpm.log');
19
20 require_once('common.php');
21
22 $_testns = 'pkg_rpm';
23
24 rg_log_enter('rg_packages_rpm_dotrepo_files1');
25 $uid = 0;
26 $pkg_subrepo_id = 1;
27 $distro = 'fedora';
28 $r = rg_packages_rpm_dotrepo_files($db, $uid, $pkg_subrepo_id, $distro);
29 if ($r['ok'] != 1) {
30 rg_log('cannot generate archive: ' . $r['errmsg']);
31 exit(1);
32 }
33 if (!isset($r['rocketgit-global-stable.spec'])) {
34 rg_log_ml('r: ' . print_r($r, TRUE));
35 rg_log('could not find spec file!');
36 exit(1);
37 }
38 rg_log_exit();
39
40
41 rg_log('OK!');
42
File tests/pkg_subrepo.php added (mode: 100644) (index 0000000..ce2861b)
1 <?php
2 error_reporting(E_ALL | E_STRICT);
3 ini_set('track_errors', 'On');
4
5 $test_normal = TRUE;
6 $rg_cache_debug = TRUE;
7
8 require_once(__DIR__ . '/config.php');
9 require_once(__DIR__ . '/../inc/init.inc.php');
10 require_once(__DIR__ . '/../inc/bug.inc.php');
11 require_once(__DIR__ . '/../inc/sql.inc.php');
12 require_once(__DIR__ . '/../inc/struct.inc.php');
13 require_once(__DIR__ . '/../inc/fixes.inc.php');
14 require_once('helpers.inc.php');
15 require_once('http.inc.php');
16
17 rg_log_set_file('pkg_subrepo.log');
18
19 require_once('common.php');
20
21 $_testns = 'pkg_subrepo';
22
23 rg_test_create_user($db, $u1);
24 $info1 = array('id' => $u1['username']);
25 prepare_http($info1);
26 test_login($test_url, $u1);
27
28
29 $pkg_subrepos_list = array(1 => 'stable', 2 => 'testing');
30 foreach ($pkg_subrepos_list as $pkg_subrepo_id => $pkg_subrepo_name) {
31 rg_log('');
32 rg_log_enter('Loading Admin -> Settings -> Packages -> Subrepositories'
33 . ' -> global/edit pkg_subrepo_id ' . $pkg_subrepo_id . '...');
34 $data = array();
35 $headers = array();
36 $r = do_req($info1, $test_url . '/op/settings/packages/subrepo/edit/'
37 . $pkg_subrepo_id, $data, $headers);
38 if ($r === FALSE) {
39 rg_log('Cannot load page!');
40 exit(1);
41 }
42 if (!isset($r['tokens']['pkg_subrepo_edit_hl'])) {
43 rg_log_ml('r:' . print_r($r, TRUE));
44 rg_log('No pkg_subrepo_edit_hl token?!');
45 exit(1);
46 }
47 $token = $r['tokens']['pkg_subrepo_edit_hl'];
48
49 rg_log('Posting the form...');
50 $data = array(
51 'doit' => 1,
52 'token' => $token,
53 'sr::name' => $pkg_subrepo_name
54 );
55 $r = do_req($info1, $test_url . '/op/settings/packages/subrepo/edit/'
56 . $pkg_subrepo_id, $data, $headers);
57 if (!strstr($r['body'], 'The packages subrepo has been successfully added')) {
58 rg_log_ml('r: ' . print_r($r, TRUE));
59 rg_log('Cannot post form (expected answer missing)!');
60 exit(1);
61 }
62 }
63 rg_log_exit();
64
65
66 rg_log('OK!');
File tests/wh_build.c added (mode: 100644) (index 0000000..31dbf45)
1 int main(void)
2 {
3 return 0;
4 }
File tests/wh_build.conf added (mode: 100644) (index 0000000..338d8ca)
1 #!/bin/bash
2
3 echo "configure: it is doing nothing"
File tests/wh_build.git.sh added (mode: 100755) (index 0000000..3341da5)
1 #!/bin/bash
2
3 set -e
4 set -u
5
6 echo "Cloning repo..."
7 rm -rf temp_repos/wh_build
8 git clone "${1}" temp_repos/wh_build
9
10 cp wh_build.spec temp_repos/wh_build/
11 cp wh_build.make temp_repos/wh_build/Makefile
12 cp wh_build.conf temp_repos/wh_build/configure
13 chmod a+x temp_repos/wh_build/configure
14 cp wh_build.c temp_repos/wh_build/x.c
15
16 cd temp_repos/wh_build
17 git checkout -b main || :
18
19 mkdir -p rocketgit
20 (
21 echo "./"
22 echo " map = envs/@@env@@/"
23 echo " regex = .*\.out"
24 echo " content_type = text/plain"
25 ) > rocketgit/artifacts
26
27 git add .
28 git commit -a -m "c1"
29
30 echo "Pushing..."
31 git push --set-upstream origin main
File tests/wh_build.make added (mode: 100644) (index 0000000..bd08503)
1 all: x
2
3 x: x.c
4 $(CC) $(CFLAGS) -g -o x x.c
5 @# generate an artifact
6 env > env.out
7 echo "blaș" > blaș.out
8
9 install: x
10 mkdir -p "$(DESTDIR)/usr/bin"
11 cp x "$(DESTDIR)/usr/bin/"
File tests/wh_build.php added (mode: 100644) (index 0000000..766c6ae)
1 <?php
2 error_reporting(E_ALL | E_STRICT);
3 ini_set('track_errors', 'On');
4
5 // TODO: add a mock worker?
6
7 $rg_cache_debug = TRUE;
8 $test_normal = TRUE;
9
10 $INC = dirname(__FILE__) . '/../inc';
11 require_once(dirname(__FILE__) . '/config.php');
12 require_once($INC . '/init.inc.php');
13 require_once($INC . '/user.inc.php');
14 require_once('helpers.inc.php');
15 require_once('http.inc.php');
16
17 rg_log_set_file('wh_build.log');
18
19 require_once('common.php');
20
21 $_testns = 'wh_build';
22
23
24 // This test makes sense only on my devel machine
25 if (php_uname('n') != 'r1.embedromix.ro') {
26 rg_log('OK!');
27 exit(0);
28 }
29
30
31 rg_log('');
32 rg_log('Creating a user...');
33 $rg_ui = array(
34 'username' => 'wh_build-user-' . rg_id(8),
35 'confirmed' => 20
36 );
37 rg_test_create_user($db, $rg_ui);
38 $info = array('id' => $rg_ui['username']);
39 prepare_http($info);
40
41 rg_log('Creating a bad user...');
42 $rg_bad = array(
43 'username' => 'wh_build-mal-' . rg_id(8),
44 'confirmed' => 20
45 );
46 rg_test_create_user($db, $rg_bad);
47 $info_bad = array('id' => $rg_ui['username']);
48 prepare_http($info_bad);
49
50
51 rg_log('');
52 rg_log_enter('Login good user...');
53 $r = test_login($test_url, $rg_ui);
54 if ($r === FALSE) {
55 rg_log('Cannot login good user!');
56 exit(1);
57 }
58 rg_log_exit();
59
60
61 rg_log('');
62 rg_log_enter('Login bad user...');
63 $r = test_login($test_url, $rg_bad);
64 if ($r === FALSE) {
65 rg_log('Cannot login bad user!');
66 exit(1);
67 }
68 rg_log_exit();
69
70
71 rg_log('');
72 rg_log_enter('Registering build webhook...');
73 $extra = array(
74 'wh::description' => 'description1 <xss> build hook',
75 'wh::repo' => '',
76 'wh::refname' => '',
77 'wh::idata::secrets::0::name' => 'secret1', // we cannot use <xss> here - it will be rejected by bash
78 'wh::idata::secrets::0::value' => 'value1<xss>',
79 'wh::idata::events' => 'P',
80 'wh::idata::envs[fedora-34-x86_64]' => 'on',
81 'wh::idata::packages' => 'nano',
82 'wh::idata::cmds::1::cmd' => 'make',
83 'wh::idata::cmds::1::label_ok' => 'success <xss>',
84 'wh::idata::cmds::1::label_nok' => 'fail <xss>'
85 );
86 rg_test_wh_add_edit($db, $rg_ui, 'build', 'generic', $extra);
87 $wh_id = $extra['id'];
88 rg_log('wh_id=' . $wh_id);
89 rg_log_exit();
90
91
92 rg_test_upload_ssh_key($db, $rg_ui, 'wh_build', $kn);
93
94
95 $pkg_repo_pub_name = 'whbuildpublic' . rg_id(8);
96 $pkg_repo_pub = array(
97 'pi::name' => $pkg_repo_pub_name,
98 'pi::public' => 1
99 );
100 rg_test_pkg_repo_add_edit($db, $rg_ui, $pkg_repo_pub);
101
102
103 $pkg_subrepo_pub = array('sr::name' => 'stable');
104 rg_test_pkg_subrepo_add_edit($db, $rg_ui, $pkg_repo_pub, $pkg_subrepo_pub);
105
106
107 $pkg_repo_priv_name = 'whbuildpriv' . rg_id(8);
108 $pkg_repo_priv = array(
109 'pi::name' => $pkg_repo_priv_name,
110 'pi::public' => 0
111 );
112 rg_test_pkg_repo_add_edit($db, $rg_ui, $pkg_repo_priv);
113
114 $pkg_subrepo_priv = array('sr::name' => 'stable');
115 rg_test_pkg_subrepo_add_edit($db, $rg_ui, $pkg_repo_priv, $pkg_subrepo_priv);
116
117
118 $pkg_map_pub = array(
119 'mi::repo' => '',
120 'mi::ref' => '',
121 'mi::pkg_subrepo_id' => $pkg_subrepo_pub['id']
122 );
123 rg_test_pkg_map_add_edit($db, $rg_ui, $pkg_map_pub);
124
125 $pkg_map_priv = array(
126 'mi::repo' => '',
127 'mi::ref' => '',
128 'mi::pkg_subrepo_id' => $pkg_subrepo_priv['id']
129 );
130 rg_test_pkg_map_add_edit($db, $rg_ui, $pkg_map_priv);
131
132 // Add a global mapping (global package repository)
133 $pkg_map_priv = array(
134 'mi::repo' => '',
135 'mi::ref' => '',
136 'mi::pkg_subrepo_id' => 2
137 );
138 rg_test_pkg_map_add_edit($db, $rg_ui, $pkg_map_priv);
139
140
141 rg_log('');
142 rg_log_enter('Creating a repo and pushing it');
143 $repo = array('name' => 'wh_build');
144 rg_test_create_repo($db, $rg_ui, $repo);
145 $repo_url = 'ssh://rocketgit@' . $rg_ssh_host . ':' . $rg_ssh_port
146 . '/user/' . $rg_ui['username'] . '/' . $repo['name'];
147 rg_log('repo_url=' . escapeshellarg($repo_url));
148 $r = rg_exec('./wh_build.git.sh ' . escapeshellarg($repo_url),
149 '', FALSE, FALSE, FALSE);
150 if ($r['ok'] != 1) {
151 rg_log('Could not create and push local git repo: ' . $r['errmsg'] . '!');
152 exit(1);
153 }
154 rg_log_exit();
155
156
157 rg_log('');
158 rg_log_enter('Testing if hook executed with success');
159 $key = 'DEBUG::' . $rg_ui['uid'] . '::webhooks::' . $wh_id;
160 $r = test_wait_cache($key, 600);
161 $p = @$r['status']['cmds'][1];
162 if (strcmp($p['status'], '0') != 0) {
163 rg_log_ml('r: ' . print_r($r, TRUE));
164 rg_log('Sseems the build did not work well'
165 . ' [' . $p['status'] . ']! See above.');
166 exit(1);
167 }
168 rg_log_exit();
169
170
171 // TODO: check user private repo stuff
172 // TODO: global public repo
173
174
175 rg_log('');
176 rg_log_enter('Checking packages');
177 $r = rg_test_packages($rg_ui, $repo);
178 $e = '>os/+pending/' . $rg_ui['username']
179 . '/' . $rg_ui['username'] . '+' . $repo['name'] . '-0.1-1.x86_64.rpm<';
180 if (!strstr($r['body'], $e)) {
181 rg_log_ml('packages page: ' . $r['body']);
182 rg_log('Link to os package not found [' . $e . ']!');
183 exit(1);
184 }
185 // TODO: check meta?
186 // TODO: check if another user does not have access
187 rg_log_exit();
188
189
190 rg_log('');
191 rg_log_enter('Checking public dotrepo download');
192 $r = rg_test_packages_file($rg_ui, $rg_ui, 'user',
193 $pkg_repo_pub_name, 'stable',
194 'os/rocketgit-' . $rg_ui['username'] . '-'
195 . $pkg_repo_pub_name . '-stable-1.1-1.noarch.rpm');
196 // TODO: try to unpack the rpm?
197 $e = 'content-type: application/x-rpm';
198 if (!stristr($r['header'], $e)) {
199 rg_log_ml('headers: ' . $r['header']);
200 rg_log('Content-Type is not ok [' . $e . ']!');
201 exit(1);
202 }
203 rg_log_exit();
204
205
206 // TODO: test private repo (pay attention to password)
207 rg_log('');
208 rg_log_enter('Checking private dotrepo download');
209 $r = rg_test_packages_file($rg_ui, $rg_ui, 'user',
210 $pkg_repo_priv_name, 'stable',
211 'os/rocketgit-' . $rg_ui['username'] . '-'
212 . $pkg_repo_priv_name . '-stable-1.1-1.noarch.rpm');
213 // TODO: try to unpack the rpm?
214 $e = 'content-type: application/x-rpm';
215 if (!stristr($r['header'], $e)) {
216 rg_log_ml('headers: ' . $r['header']);
217 rg_log('Content-Type is not ok [' . $e . ']!');
218 exit(1);
219 }
220 rg_log_exit();
221
222
223 rg_log('');
224 rg_log_enter('Checking private dotrepo download (by bad user)');
225 $r = rg_test_packages_file($rg_bad, $rg_ui, 'user',
226 $pkg_repo_priv_name, 'stable',
227 'os/rocketgit-' . $rg_ui['username'] . '-'
228 . $pkg_repo_priv_name . '-stable-1.1-1.noarch.rpm');
229 // TODO: try to unpack the rpm?
230 if ($r['ci']['http_code'] != 404) {
231 rg_log('We must get 404 instead of ' . $r['ci']['http_code']
232 . ' if we do not have access!');
233 exit(1);
234 }
235 rg_log_exit();
236
237
238 rg_log('');
239 rg_log_enter('Checking packages repomd download');
240 $r = rg_test_packages_file($rg_ui, $rg_ui, 'user',
241 $pkg_repo_pub_name, 'stable',
242 'os/repodata/repomd.xml');
243 $e = '<?xml ';
244 if (!strstr($r['body'], $e)) {
245 rg_log_ml('packages repomd page: ' . $r['body']);
246 rg_log('XML seems invalid [' . $e . ']!');
247 exit(1);
248 }
249 $e = 'content-type: text/xml';
250 if (!stristr($r['header'], $e)) {
251 rg_log_ml('headers: ' . $r['header']);
252 rg_log('Content-Type is not ok [' . $e . ']!');
253 exit(1);
254 }
255 rg_log_exit();
256
257
258 rg_log('');
259 rg_log_enter('Checking packages rpm download');
260 $r = rg_test_packages_file($rg_ui, $rg_ui, 'user',
261 $pkg_repo_pub_name, 'stable',
262 'os/' . $rg_ui['username'] . '+' . $repo['name'] . '-0.1-1.x86_64.rpm');
263 $e = 'content-type: application/x-rpm';
264 if (!stristr($r['header'], $e)) {
265 rg_log_ml('headers: ' . $r['header']);
266 rg_log('Content-Type is not ok [' . $e . ']!');
267 exit(1);
268 }
269 rg_log_exit();
270
271
272 rg_log('');
273 rg_log_enter('Checking artifacts 1');
274 $r = rg_test_artifacts_page($rg_ui, $repo, '/envs/fedora-34-x86_64');
275 $e = '<a href="/user/' . $rg_ui['username'] . '/' . $repo['name'] . '/artifacts/download/envs/fedora-34-x86_64/bla%C8%99.out">Download</a>';
276 if (!strstr($r['body'], $e)) {
277 rg_log_ml('artifacts: ' . $r['body']);
278 rg_log('Link to artifact not found [' . $e . ']!');
279 exit(1);
280 }
281 $r = rg_test_artifacts_file($rg_ui, $repo, '/envs/fedora-34-x86_64/blaș.out');
282 rg_log_ml('blaș.out: ' . print_r($r, TRUE));
283 $e = 'blaș' . "\n";
284 if (strcmp($r['body'], $e) != 0) {
285 rg_log('Content of artifact not ok [' . $r['body'] . '] != [' . $e . ']!');
286 exit(1);
287 }
288 $e = 'content-length: 6' . "\r\n";
289 if (!stristr($r['header'], $e)) {
290 rg_log_ml('headers: ' . $r['header']);
291 rg_log('Content-Length of artifact not ok [' . $e . ']!');
292 exit(1);
293 }
294 $e = 'content-type: text/plain';
295 if (!stristr($r['header'], $e)) {
296 rg_log_ml('headers: ' . $r['header']);
297 rg_log('Content-type of artifact not ok [' . $e . ']!');
298 exit(1);
299 }
300 // TODO: check artifacts fs/meta?
301 rg_log_exit();
302
303
304 rg_log('');
305 rg_log_enter('Make a change and push again (for delta packages)');
306 rg_cache_unset($key, 0); // to not get the same cache info
307 $r = rg_exec('cd temp_repos/wh_build'
308 . ' && sed -i -e "s/^Version:.*0.1/Version: 0.2/" wh_build.spec'
309 . ' && git commit -a -m "new version"'
310 . ' && git push',
311 '', FALSE, FALSE, FALSE);
312 if ($r['ok'] != 1) {
313 rg_log('Could not push again: ' . $r['errmsg'] . '!');
314 exit(1);
315 }
316 rg_log_exit();
317
318
319 rg_log('');
320 rg_log_enter('Testing if hook executed with success (part 2)');
321 $key = 'DEBUG::' . $rg_ui['uid'] . '::webhooks::' . $wh_id;
322 $r = test_wait_cache($key, 600);
323 $p = @$r['status']['cmds'][1];
324 if (strcmp($p['status'], '0') != 0) {
325 rg_log_ml('r: ' . print_r($r, TRUE));
326 rg_log('Sseems the build did not work well'
327 . ' [' . $p['status'] . ']! See above.');
328 exit(1);
329 }
330 rg_log_exit();
331
332
333 // TODO: test artifacts 2 (overwrite)
334 // TODO: test rfs/rpm packages (by http)
335
336
337 // TODO: add a test for 'map_into_source'
338
339
340 // TODO: test that packages are in +pending (time race?)
341 rg_log('OK!');
File tests/wh_cloud.git.sh changed (mode: 100755) (index c4b90a3..5a16ad1)
... ... set -u
6 6 export GIT_SSH_COMMAND="ssh -o ControlMaster=no -o IdentityFile=${PWD}/keys/${RG_SSH_KEY} -o IdentitiesOnly=yes" export GIT_SSH_COMMAND="ssh -o ControlMaster=no -o IdentityFile=${PWD}/keys/${RG_SSH_KEY} -o IdentitiesOnly=yes"
7 7
8 8 echo "Cloning repo..." echo "Cloning repo..."
9 rm -rf wh_cloud.git
10 git clone "${1}" wh_cloud.git
11 cd wh_cloud.git
9 rm -rf temp_repos/wh_cloud.git
10 git clone "${1}" temp_repos/wh_cloud.git
11 cd temp_repos/wh_cloud.git
12 12 cat >appspec.yml <<EOF cat >appspec.yml <<EOF
13 13 version: 0.0 version: 0.0
14 14 os: linux os: linux
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/catalinux/rocketgit

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/catalinux/rocketgit

Clone this repository using git:
git clone git://git.rocketgit.com/user/catalinux/rocketgit

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main