File Makefile.in changed (mode: 100644) (index 2a3b938..3bb352d) |
... |
... |
tests: |
23 |
23 |
install: all |
install: all |
24 |
24 |
@mkdir -pv $(I_USR_SHARE)/$(PRJ) |
@mkdir -pv $(I_USR_SHARE)/$(PRJ) |
25 |
25 |
cp -vdr inc hooks root scripts $(I_USR_SHARE)/$(PRJ) |
cp -vdr inc hooks root scripts $(I_USR_SHARE)/$(PRJ) |
|
26 |
|
@ |
|
27 |
|
@echo "Installing configs..." |
26 |
28 |
@mkdir -pv $(I_ETC)/xinetd.d |
@mkdir -pv $(I_ETC)/xinetd.d |
27 |
29 |
cp -vd --no-clobber samples/rg $(I_ETC)/xinetd.d/$(PRJ) |
cp -vd --no-clobber samples/rg $(I_ETC)/xinetd.d/$(PRJ) |
28 |
30 |
@mkdir -pv $(I_ETC)/cron.d |
@mkdir -pv $(I_ETC)/cron.d |
|
... |
... |
install: all |
32 |
34 |
@mkdir -pv $(I_ETC)/$(PRJ) |
@mkdir -pv $(I_ETC)/$(PRJ) |
33 |
35 |
cp -vd --no-clobber samples/config.php $(I_ETC)/$(PRJ)/ |
cp -vd --no-clobber samples/config.php $(I_ETC)/$(PRJ)/ |
34 |
36 |
cp -vd samples/config.php $(I_ETC)/$(PRJ)/config.php.sample |
cp -vd samples/config.php $(I_ETC)/$(PRJ)/config.php.sample |
|
37 |
|
cp -vd --no-clobber samples/php-fpm.conf $(I_ETC)/$(PRJ)/ |
|
38 |
|
cp -vd --no-clobber samples/pool.conf $(I_ETC)/$(PRJ)/ |
35 |
39 |
@mkdir -pv $(I_ETC)/logrotate.d |
@mkdir -pv $(I_ETC)/logrotate.d |
36 |
40 |
cp -vd samples/logrotate $(I_ETC)/logrotate.d/$(PRJ) |
cp -vd samples/logrotate $(I_ETC)/logrotate.d/$(PRJ) |
|
41 |
|
@mkdir -pv $(I_USR)/lib/systemd/system/ |
|
42 |
|
cp -vd samples/systemd.service $(I_USR)/lib/systemd/system/rocketgit-fpm.service |
37 |
43 |
@ |
@ |
38 |
44 |
@echo "Installing tools..." |
@echo "Installing tools..." |
39 |
45 |
@mkdir -pv $(I_USR_SBIN) |
@mkdir -pv $(I_USR_SBIN) |
|
... |
... |
install: all |
43 |
49 |
@echo "Installing log stuff..." |
@echo "Installing log stuff..." |
44 |
50 |
@mkdir -pv $(I_VAR_LOG)/$(PRJ) |
@mkdir -pv $(I_VAR_LOG)/$(PRJ) |
45 |
51 |
@-chown -R rocketgit:rocketgit $(I_VAR_LOG)/$(PRJ) |
@-chown -R rocketgit:rocketgit $(I_VAR_LOG)/$(PRJ) |
46 |
|
@-find $(I_VAR_LOG)/$(PRJ) -type d -exec chmod -R 0755 {} \; |
|
|
52 |
|
@-find $(I_VAR_LOG)/$(PRJ) -type d -exec chmod -R 0700 {} \; |
47 |
53 |
@-find $(I_VAR_LOG)/$(PRJ) -type f -exec chmod -R 0600 {} \; |
@-find $(I_VAR_LOG)/$(PRJ) -type f -exec chmod -R 0600 {} \; |
48 |
54 |
@ |
@ |
49 |
|
@mkdir -pv $(I_VAR_LOG)/$(PRJ)-web |
|
50 |
|
@-chown -R apache:apache $(I_VAR_LOG)/$(PRJ)-web |
|
51 |
|
@-find $(I_VAR_LOG)/$(PRJ)-web -type d -exec chmod -R 0755 {} \; |
|
52 |
|
@-find $(I_VAR_LOG)/$(PRJ)-web -type f -exec chmod -R 0600 {} \; |
|
53 |
|
@ |
|
54 |
55 |
@echo "Installing varlib stuff..." |
@echo "Installing varlib stuff..." |
55 |
56 |
@mkdir -pv $(I_VAR_LIB)/$(PRJ) |
@mkdir -pv $(I_VAR_LIB)/$(PRJ) |
56 |
57 |
@mkdir -pv $(I_VAR_LIB)/$(PRJ)/locks |
@mkdir -pv $(I_VAR_LIB)/$(PRJ)/locks |
|
... |
... |
install: all |
59 |
60 |
@mkdir -pv $(I_VAR_LIB)/$(PRJ)/qstats |
@mkdir -pv $(I_VAR_LIB)/$(PRJ)/qstats |
60 |
61 |
@mkdir -pv $(I_VAR_LIB)/$(PRJ)/sockets |
@mkdir -pv $(I_VAR_LIB)/$(PRJ)/sockets |
61 |
62 |
@mkdir -pv $(I_VAR_LIB)/$(PRJ)/worker |
@mkdir -pv $(I_VAR_LIB)/$(PRJ)/worker |
|
63 |
|
@ |
62 |
64 |
@echo "Fixing rights..." |
@echo "Fixing rights..." |
63 |
|
@-find $(I_VAR_LIB)/$(PRJ) -type d -exec chmod 0755 {} \; |
|
64 |
|
@-find $(I_VAR_LIB)/$(PRJ) -type f -exec chmod 0600 {} \; |
|
|
65 |
|
@echo "Fixing rights: /var/lib dirs..." |
|
66 |
|
@-find $(I_VAR_LIB)/$(PRJ) -mindepth 1 -type d | xargs chmod -c 0700 |
|
67 |
|
@echo "Fixing rights: /var/lib files..." |
|
68 |
|
@-find $(I_VAR_LIB)/$(PRJ) -type f | xargs chmod -c 0600 |
65 |
69 |
@mkdir -pv --mode=0700 $(I_VAR_LIB)/$(PRJ)/tmp |
@mkdir -pv --mode=0700 $(I_VAR_LIB)/$(PRJ)/tmp |
66 |
70 |
@-chown -R rocketgit:rocketgit $(I_VAR_LIB)/$(PRJ) |
@-chown -R rocketgit:rocketgit $(I_VAR_LIB)/$(PRJ) |
67 |
|
@-chown root:root $(I_VAR_LIB)/$(PRJ) |
|
68 |
71 |
@-chown root:root $(I_VAR_LIB)/$(PRJ)/worker |
@-chown root:root $(I_VAR_LIB)/$(PRJ)/worker |
|
72 |
|
@-chown root:root $(I_VAR_LIB)/$(PRJ) |
|
73 |
|
@-chmod -c 0755 $(I_VAR_LIB)/$(PRJ) |
69 |
74 |
@ |
@ |
70 |
75 |
@echo "Installing SELinux stuff..." |
@echo "Installing SELinux stuff..." |
71 |
76 |
@mkdir -pv --mode=0755 $(I_USR_SHARE)/selinux/targeted |
@mkdir -pv --mode=0755 $(I_USR_SHARE)/selinux/targeted |
File TODO changed (mode: 100644) (index a8bfdcf..efb1295) |
1 |
1 |
== Where I stopped last time == |
== Where I stopped last time == |
|
2 |
|
[ ] I am investigating the switch to php-fpm: |
|
3 |
|
- a systemd start file must be provided (also a classic one) |
|
4 |
|
- Add the new files to spec |
|
5 |
|
- Adapt SELinux file. |
|
6 |
|
- Adjust docker/vm build scripts |
|
7 |
|
[ ] Better explain why world needs another git hosting repo. |
|
8 |
|
[ ] How do we get rid of post-update hook? rpm will auto clean it? |
|
9 |
|
Let's see on rocketgit.com. |
|
10 |
|
[ ] |
2 |
11 |
|
|
3 |
12 |
== BEFORE NEXT RELEASE == |
== BEFORE NEXT RELEASE == |
|
13 |
|
[ ] use shutdown function for async cache stuff? Maybe other things? |
|
14 |
|
I do not think so... Should we have a write ahead log: |
|
15 |
|
something like we inform the cache that we need to clean an entry |
|
16 |
|
it the connection is broken. |
|
17 |
|
[ ] UTF8 with the databse, please check. |
|
18 |
|
[ ] main page: add a new way to ear money: add sponsort, directly in the source |
|
19 |
|
to be shown on every deployed rocketgit instalation. |
|
20 |
|
We can use bidding for the order. |
|
21 |
|
[ ] Investigate socket activation for fpm? Cache? Events? |
|
22 |
|
[ ] Why do I show info about correct host name in hooks?! |
|
23 |
|
Maybe because only in the hook can we output stuff? |
|
24 |
|
Also, give correct command to change the url, not only inform the user. |
|
25 |
|
[ ] http: do we allow a fetch for a anon user from a private repo? test! |
|
26 |
|
Not only http. |
|
27 |
|
[ ] If user has push access, why do we create a namespace?! |
|
28 |
|
Maybe because I do not know the pushed refs? |
|
29 |
|
[ ] 2fa: http is not supported yet! |
|
30 |
|
[ ] Now, also the web part can do the db update. |
|
31 |
|
[ ] Get rid of rwe? |
|
32 |
|
[ ] rg_repo_fetch_push_helper: if git repo is not created, delay the fetch/push? |
|
33 |
|
[ ] target_ui => owner_ui? |
|
34 |
|
[ ] Consolidate "welcome to rocketgit" messages! |
|
35 |
|
[ ] when creating a vm, pass 'rng' device |
|
36 |
|
[ ] Allow user to upload GPG keys ids and use them as an authentication |
|
37 |
|
witness when pushing signed stuff. |
|
38 |
|
[ ] Provide the URL to the pull request |
|
39 |
|
[ ] Add custom hooks (example: hooks.d/post-update.d/*) |
|
40 |
|
[ ] Disable auto gc and run it one per day, more or less? |
|
41 |
|
[ ] Log client version when fetching/pushing? |
|
42 |
|
[ ] man git-http-backend: |
|
43 |
|
The backend process sets GIT_COMMITTER_NAME to $REMOTE_USER and |
|
44 |
|
GIT_COMMITTER_EMAIL to ${REMOTE_USER}@http.${REMOTE_ADDR}, ensuring |
|
45 |
|
that any reflogs created by git-receive-pack contain some identifying |
|
46 |
|
information of the remote user who performed the push. |
|
47 |
|
[ ] Clone/push by HTTP: cannot send the welcome message. |
|
48 |
|
Probably, we have to add a patch to git-receive/send-pack. |
|
49 |
|
[ ] Add support for nginx and lighttpd. |
|
50 |
|
php-fpm comes with files in /etc/nginx! So can we! |
|
51 |
|
[ ] At least for http we do not check if host does not matches and warn user |
|
52 |
|
to change it. |
|
53 |
|
[ ] Get rid of xinetd and run remote.php as a service. With a .service file. |
|
54 |
|
The same for all other cron scripts (except cron.php)! |
|
55 |
|
[ ] unit test for apikeys |
|
56 |
|
[ ] advertise on git mailing list. |
|
57 |
|
[ ] git-receive-pack: check certificate stuff! |
|
58 |
|
[ ] We may want to use fastcgi_finish_request to continue doing stuff in |
|
59 |
|
background. |
|
60 |
|
[ ] demo: list pages (and titles) in a text file to not have it hardcoded! |
|
61 |
|
[ ] demo: small tutorial on how to contribute to a project on rocketgit |
|
62 |
|
[ ] demo: ci1: I did not explain how it works regarding workers/libvirt/etc. |
|
63 |
|
[ ] https://libreboot.org/git/#githosting; also why you should not use |
|
64 |
|
github/gitlab. We should link to this in a section: "Why we need |
|
65 |
|
another git hosting solution?" |
|
66 |
|
[ ] build: Instruct user to add qemu-guest-agent package? |
|
67 |
|
[ ] demo: contributing to a project - how easy it is. |
|
68 |
|
[ ] We have no event for tag push! |
|
69 |
|
[ ] Notify user if a repo is created and nothing is pushed. |
|
70 |
|
Maybe SSH is a barrier? |
|
71 |
|
[ ] wh: add a rsync plugin, with user and pass. |
4 |
72 |
[ ] build: Document how to start builder.sh (from cron or let it read the conf |
[ ] build: Document how to start builder.sh (from cron or let it read the conf |
5 |
73 |
file). Or, never install worker.conf and let an admin to rename |
file). Or, never install worker.conf and let an admin to rename |
6 |
74 |
worker.conf.sample into worker.conf |
worker.conf.sample into worker.conf |
|
45 |
113 |
firewall-cmd --permanent --add-port=19999/tcp |
firewall-cmd --permanent --add-port=19999/tcp |
46 |
114 |
firewall-cmd --reload |
firewall-cmd --reload |
47 |
115 |
[ ] Register with freecode.club |
[ ] Register with freecode.club |
48 |
|
[ ] build: give error if we cannot install one of the packages. |
|
49 |
|
[ ] build: allow user to install some dependencies. |
|
|
116 |
|
[ ] build: allow user to install some dependencies (done). |
50 |
117 |
Or maybe try to detect from the spec file? |
Or maybe try to detect from the spec file? |
51 |
|
We also must specify how to install packages. |
|
52 |
|
[ ] wh: we do not have the time of last run! |
|
|
118 |
|
[ ] wh: we do not have the time of last run! Where? |
53 |
119 |
[ ] build: allow adding environment variables for a job. |
[ ] build: allow adding environment variables for a job. |
54 |
120 |
[ ] Somehow, warn the user that no environments are available and instruct |
[ ] Somehow, warn the user that no environments are available and instruct |
55 |
121 |
she/him to add workers. |
she/him to add workers. |
56 |
122 |
[ ] css: 'mess' class has a 5px top margin. it is not ok (check edit webhook). |
[ ] css: 'mess' class has a 5px top margin. it is not ok (check edit webhook). |
57 |
|
[ ] Filter environment (allow only a-zA-Z0-9_.) |
|
|
123 |
|
[ ] Filter environment (allow only a-zA-Z0-9_.). Why? |
58 |
124 |
[ ] Join builders.inc.php and workers.inc.php? |
[ ] Join builders.inc.php and workers.inc.php? |
59 |
125 |
[ ] build: builder.php: we should wait for a notification instead to poll |
[ ] build: builder.php: we should wait for a notification instead to poll |
60 |
126 |
the database. |
the database. |
61 |
|
[ ] build: enforce a max build time; use cost; use max_workers. |
|
62 |
|
[ ] build: If a user has own workers, do not use global ones (of course, |
|
63 |
|
arch is taken in consideration). |
|
|
127 |
|
[ ] build: enforce a max build time. |
64 |
128 |
[ ] build: show user the status of the workers. Also, how much time they |
[ ] build: show user the status of the workers. Also, how much time they |
65 |
129 |
were used and what builds they did. |
were used and what builds they did. |
66 |
130 |
[ ] build: find a way to reuse machines, so we avoid the startup cost. |
[ ] build: find a way to reuse machines, so we avoid the startup cost. |
67 |
|
Take care also about package instalation. |
|
68 |
131 |
[ ] build: avoid starting a lot of services. We do not need them! |
[ ] build: avoid starting a lot of services. We do not need them! |
69 |
132 |
[ ] Some daemon to synchronize two instances (master standby or just |
[ ] Some daemon to synchronize two instances (master standby or just |
70 |
133 |
load balancing)? |
load balancing)? |
|
112 |
175 |
[ ] build: allow user to specify some packages to be installed first? |
[ ] build: allow user to specify some packages to be installed first? |
113 |
176 |
[ ] Get rid of php-mbstring! It is not in main repo on Oracle Linux! |
[ ] Get rid of php-mbstring! It is not in main repo on Oracle Linux! |
114 |
177 |
[ ] Destroy storage for 'build' machines |
[ ] Destroy storage for 'build' machines |
115 |
|
[ ] If a user types a wrong e-mail at registration phase, and without |
|
116 |
|
confirmation we do not allow access, we have a problem. |
|
117 |
|
Add a hint in "Create a new account" page to warn about this. |
|
118 |
|
Also, to explain why we need the e-mail address. |
|
119 |
|
Maybe, add a permanent warning on the login page |
|
120 |
|
that the e-mail is not confirmed and add hide or edit account links. |
|
121 |
178 |
[ ] Add a new right: "allow pushes only if they are signed". |
[ ] Add a new right: "allow pushes only if they are signed". |
122 |
179 |
As with ss keys, a user may want to add public gpg keys to a list |
As with ss keys, a user may want to add public gpg keys to a list |
123 |
180 |
that is allowed to push. Take care: you can sign tags but also |
that is allowed to push. Take care: you can sign tags but also |
|
321 |
378 |
execute the hook? The problem is that I have no link between the repo |
execute the hook? The problem is that I have no link between the repo |
322 |
379 |
and hooks. Maybe go to the repo and link the hooks? what about |
and hooks. Maybe go to the repo and link the hooks? what about |
323 |
380 |
'repo create' hook trigger? |
'repo create' hook trigger? |
324 |
|
[ ] docker: document somewhere that is available and how to use it. |
|
325 |
381 |
[ ] wh: Add a link to a "movie" explaining how with one hook you can cover both |
[ ] wh: Add a link to a "movie" explaining how with one hook you can cover both |
326 |
382 |
production and evaluation deployments. |
production and evaluation deployments. |
327 |
383 |
[ ] wh: notify user when a hook fails. |
[ ] wh: notify user when a hook fails. |
|
834 |
890 |
[ ] ssh: Show user the entry that must be added for known_hosts |
[ ] ssh: Show user the entry that must be added for known_hosts |
835 |
891 |
[ ] LDAP: http://mageconfig.blogspot.ro/2014/06/configure-gitgerrit-with-open-ldap-for.html |
[ ] LDAP: http://mageconfig.blogspot.ro/2014/06/configure-gitgerrit-with-open-ldap-for.html |
836 |
892 |
[ ] Pass only uid to events, we already have it in cache! |
[ ] Pass only uid to events, we already have it in cache! |
837 |
|
[ ] 'confirmed' should be built in the event handlers not in callers. |
|
838 |
|
It is already checked in rg_mail_template! |
|
839 |
893 |
[ ] When we push by ssh, we have the user, so we can give more info about |
[ ] When we push by ssh, we have the user, so we can give more info about |
840 |
894 |
why the push failed. Carefull, not too much info. For example: |
why the push failed. Carefull, not too much info. For example: |
841 |
895 |
"You have no key uploaded, go to ..." |
"You have no key uploaded, go to ..." |
|
... |
... |
But, we have a problem with the expiration time! |
1407 |
1461 |
[ ] If the confirmation code is truncated, an internal error is generated |
[ ] If the confirmation code is truncated, an internal error is generated |
1408 |
1462 |
instead of a user error! |
instead of a user error! |
1409 |
1463 |
[ ] Third option: anybody can create an account but must be validated by admin. |
[ ] Third option: anybody can create an account but must be validated by admin. |
1410 |
|
[ ] After creating the account, keep the user logged in and allow login |
|
1411 |
|
even if is not confirmed (option in config). |
|
1412 |
1464 |
[ ] When I close a bug, seems I add myself to the watch table again! |
[ ] When I close a bug, seems I add myself to the watch table again! |
1413 |
1465 |
[ ] Should we load the lables in rg_bug_info? |
[ ] Should we load the lables in rg_bug_info? |
1414 |
1466 |
[ ] Do we need a rg_bug_cosmetic for notes/users/repos/etc? |
[ ] Do we need a rg_bug_cosmetic for notes/users/repos/etc? |
File inc/git.inc.php changed (mode: 100644) (index 45f72f6..c4a9bb0) |
... |
... |
function rg_git_short($ref) |
48 |
48 |
return $ref; |
return $ref; |
49 |
49 |
} |
} |
50 |
50 |
|
|
51 |
|
function rg_git_info($msg) |
|
|
51 |
|
function rg_git_info($band, $msg) |
52 |
52 |
{ |
{ |
|
53 |
|
echo $band; |
53 |
54 |
$x = explode("\n", trim($msg)); |
$x = explode("\n", trim($msg)); |
54 |
55 |
foreach ($x as $line) { |
foreach ($x as $line) { |
55 |
56 |
rg_log("INFO: $line"); |
rg_log("INFO: $line"); |
56 |
|
echo "RocketGit: Info: $line\n"; |
|
|
57 |
|
echo 'RocketGit: Info: ' . $line . "\n"; |
57 |
58 |
} |
} |
58 |
59 |
} |
} |
59 |
60 |
|
|
|
61 |
|
function rg_git_info_pack($band, $msg) |
|
62 |
|
{ |
|
63 |
|
$s = $band; |
|
64 |
|
$x = explode("\n", trim($msg)); |
|
65 |
|
foreach ($x as $line) { |
|
66 |
|
rg_log("INFO: $line"); |
|
67 |
|
$s .= 'RocketGit: Info: ' . $line . "\n"; |
|
68 |
|
} |
|
69 |
|
|
|
70 |
|
echo rg_git_pack($s); |
|
71 |
|
} |
|
72 |
|
|
60 |
73 |
/* |
/* |
61 |
74 |
* Installs rg hooks instead of original ones, by making a link |
* Installs rg hooks instead of original ones, by making a link |
62 |
75 |
*/ |
*/ |
|
... |
... |
function rg_git_init($dst) |
123 |
136 |
while (1) { |
while (1) { |
124 |
137 |
$dir = dirname($dst); |
$dir = dirname($dst); |
125 |
138 |
if (!file_exists($dir)) { |
if (!file_exists($dir)) { |
126 |
|
$r = @mkdir($dir, 0755, TRUE); |
|
|
139 |
|
$r = @mkdir($dir, 0700, TRUE); |
127 |
140 |
if ($r === FALSE) { |
if ($r === FALSE) { |
128 |
141 |
rg_git_set_error("cannot create dir [$dir] ($php_errormsg)"); |
rg_git_set_error("cannot create dir [$dir] ($php_errormsg)"); |
129 |
142 |
break; |
break; |
|
... |
... |
function rg_git_clone($src, $dst) |
175 |
188 |
while (1) { |
while (1) { |
176 |
189 |
$dir = dirname($dst); |
$dir = dirname($dst); |
177 |
190 |
if (!file_exists($dir)) { |
if (!file_exists($dir)) { |
178 |
|
$r = @mkdir($dir, 0755, TRUE); |
|
|
191 |
|
$r = @mkdir($dir, 0700, TRUE); |
179 |
192 |
if ($r === FALSE) { |
if ($r === FALSE) { |
180 |
193 |
rg_git_set_error("cannot create dir [$dir] ($php_errormsg)"); |
rg_git_set_error("cannot create dir [$dir] ($php_errormsg)"); |
181 |
194 |
break; |
break; |
|
... |
... |
function rg_git_update_branch($db, $a) |
1452 |
1465 |
|
|
1453 |
1466 |
$_x = array(); |
$_x = array(); |
1454 |
1467 |
$msg = rg_template("msg/push_merge_request.txt", $_x, FALSE /*xss*/); |
$msg = rg_template("msg/push_merge_request.txt", $_x, FALSE /*xss*/); |
1455 |
|
rg_git_info($a['refname'] . ':' . "\n" . $msg); |
|
|
1468 |
|
rg_git_info('', $a['refname'] . ':' . "\n" . $msg); |
1456 |
1469 |
|
|
1457 |
1470 |
$history['history_category'] = REPO_CAT_GIT_BRANCH_ANON_PUSH; |
$history['history_category'] = REPO_CAT_GIT_BRANCH_ANON_PUSH; |
1458 |
1471 |
$history['history_message'] = 'Anonymous push to ref ' |
$history['history_message'] = 'Anonymous push to ref ' |
|
... |
... |
function rg_git_update_branch($db, $a) |
1482 |
1495 |
'name' => $a['repo_name'], |
'name' => $a['repo_name'], |
1483 |
1496 |
'url' => rg_base_url() . $a['login_url'] |
'url' => rg_base_url() . $a['login_url'] |
1484 |
1497 |
. '/' . $a['repo_name'], |
. '/' . $a['repo_name'], |
1485 |
|
'clone_url' => $a['repo_clone_url'] |
|
|
1498 |
|
'clone_url' => $a['repo_clone_url_http'] |
1486 |
1499 |
); |
); |
1487 |
1500 |
unset($ev['repo_id']); unset($ev['repo_name']); |
unset($ev['repo_id']); unset($ev['repo_name']); |
1488 |
1501 |
$r = rg_event_add($db, $ev); |
$r = rg_event_add($db, $ev); |
|
... |
... |
function rg_git_request_pull($repo_path, $start, $url, $end, $patch) |
2038 |
2051 |
return $ret; |
return $ret; |
2039 |
2052 |
} |
} |
2040 |
2053 |
|
|
|
2054 |
|
/* |
|
2055 |
|
* Prepares a git packet from a string |
|
2056 |
|
*/ |
|
2057 |
|
function rg_git_pack($str) |
|
2058 |
|
{ |
|
2059 |
|
return sprintf("%04x", 4 + strlen($str)) . $str; |
|
2060 |
|
} |
|
2061 |
|
|
|
2062 |
|
/* |
|
2063 |
|
* Prepares a 'flush' packet |
|
2064 |
|
*/ |
|
2065 |
|
function rg_git_flush() |
|
2066 |
|
{ |
|
2067 |
|
return '0000'; |
|
2068 |
|
} |
|
2069 |
|
|
|
2070 |
|
/* |
|
2071 |
|
* Callback used by rg_exec to output in band 1 |
|
2072 |
|
*/ |
|
2073 |
|
function rg_git_band_1($s) |
|
2074 |
|
{ |
|
2075 |
|
echo rg_git_pack("\x01" . $s); |
|
2076 |
|
} |
|
2077 |
|
|
|
2078 |
|
/* |
|
2079 |
|
* Callback used by rg_exec to output in band 2 |
|
2080 |
|
*/ |
|
2081 |
|
function rg_git_band_2($s) |
|
2082 |
|
{ |
|
2083 |
|
echo rg_git_pack("\x02" . $s); |
|
2084 |
|
} |
|
2085 |
|
|
|
2086 |
|
/* |
|
2087 |
|
* Callback used by rg_exec to output in band 3 |
|
2088 |
|
*/ |
|
2089 |
|
function rg_git_band_3($s) |
|
2090 |
|
{ |
|
2091 |
|
echo rg_git_pack("\x03" . $s); |
|
2092 |
|
} |
|
2093 |
|
|
2041 |
2094 |
?> |
?> |
File inc/repo.inc.php changed (mode: 100644) (index 68f6e8b..1355166) |
... |
... |
function rg_repo_cosmetic($db, &$row) |
106 |
106 |
{ |
{ |
107 |
107 |
global $rg_ssh_port, $rg_git_port; |
global $rg_ssh_port, $rg_git_port; |
108 |
108 |
|
|
109 |
|
$row['clone_url'] = ''; |
|
110 |
|
|
|
111 |
109 |
// Because this field was added later and the cache may not have it |
// Because this field was added later and the cache may not have it |
112 |
110 |
if (!isset($row['template'])) |
if (!isset($row['template'])) |
113 |
111 |
$row['template'] = ''; |
$row['template'] = ''; |
|
... |
... |
function rg_repo_cosmetic($db, &$row) |
132 |
130 |
$_ui['username'], $row['name']); |
$_ui['username'], $row['name']); |
133 |
131 |
$row['clone_url_git'] = rg_re_repo_git($_ui['organization'], |
$row['clone_url_git'] = rg_re_repo_git($_ui['organization'], |
134 |
132 |
$_ui['username'], $row['name']); |
$_ui['username'], $row['name']); |
135 |
|
if ($rg_ssh_port != 0) |
|
136 |
|
$row['clone_url'] = $row['clone_url_ssh']; |
|
137 |
|
else |
|
138 |
|
$row['clone_url'] = $row['clone_url_git']; |
|
|
133 |
|
$row['clone_url_http'] = rg_re_repo_http($_ui['organization'], |
|
134 |
|
$_ui['username'], $row['name']); |
139 |
135 |
} |
} |
140 |
136 |
|
|
141 |
137 |
$row['master_name'] = '-'; |
$row['master_name'] = '-'; |
|
... |
... |
function rg_repo_event_symlink_by_name($db, $e) |
573 |
569 |
// Create links' parent |
// Create links' parent |
574 |
570 |
$new_path_parent = dirname($new_path); |
$new_path_parent = dirname($new_path); |
575 |
571 |
if (!is_dir($new_path_parent)) { |
if (!is_dir($new_path_parent)) { |
576 |
|
$r = mkdir($new_path_parent, 0755, TRUE); |
|
|
572 |
|
$r = mkdir($new_path_parent, 0700, TRUE); |
577 |
573 |
if ($r === FALSE) { |
if ($r === FALSE) { |
578 |
574 |
rg_repo_set_error("cannot create links' parent"); |
rg_repo_set_error("cannot create links' parent"); |
579 |
575 |
break; |
break; |
|
... |
... |
function rg_repo_event_storage_create($db, $e) |
607 |
603 |
while (1) { |
while (1) { |
608 |
604 |
$by_id_path = rg_repo_path_by_id($e['ui']['uid'], $e['ri']['repo_id']); |
$by_id_path = rg_repo_path_by_id($e['ui']['uid'], $e['ri']['repo_id']); |
609 |
605 |
if (!is_dir($by_id_path)) { |
if (!is_dir($by_id_path)) { |
610 |
|
if (mkdir($by_id_path, 0755, TRUE) === FALSE) { |
|
|
606 |
|
if (mkdir($by_id_path, 0700, TRUE) === FALSE) { |
611 |
607 |
rg_repo_set_error("could not create folder $dst"); |
rg_repo_set_error("could not create folder $dst"); |
612 |
608 |
break; |
break; |
613 |
609 |
} |
} |
|
... |
... |
function rg_repo_api($db, $a) |
2402 |
2398 |
return $ret; |
return $ret; |
2403 |
2399 |
} |
} |
2404 |
2400 |
|
|
|
2401 |
|
/* |
|
2402 |
|
* Helper for SSH/GIT/HTTP(S) fetch/push |
|
2403 |
|
* @host - the host name accessed - may be different than the good one |
|
2404 |
|
* @ip - from where the connections come |
|
2405 |
|
* @cmd: 'git-upload-pack' or 'git-receive-pack' |
|
2406 |
|
* @need_namespace_copy - true if we need to clone refs |
|
2407 |
|
* TODO: move it to user.inc.php?! |
|
2408 |
|
*/ |
|
2409 |
|
function rg_repo_fetch_push_helper($db, $host, $ip, $login_ui, $prefix, $user, |
|
2410 |
|
$repo, $cmd, $need_namespace_copy) |
|
2411 |
|
{ |
|
2412 |
|
rg_prof_start('repo_fetch_push_helper'); |
|
2413 |
|
rg_log_enter('repo_fetch_push_helper: host=' . $host |
|
2414 |
|
. ' prefix=' . $prefix . ' user=' . $user |
|
2415 |
|
. ' repo=' . $repo . ' cmd=' . $cmd |
|
2416 |
|
. ' need_namespace_copy=' . ($need_namespace_copy ? 'yes' : 'no')); |
|
2417 |
|
|
|
2418 |
|
$ret = array('ok' => 0, 'allow' => 1, 'push_allowed' => 1); |
|
2419 |
|
while (1) { |
|
2420 |
|
// Extracts command and computes permissions |
|
2421 |
|
if (strncasecmp($cmd, 'git-upload-pack', 15) == 0) { |
|
2422 |
|
$cmd = 'git-upload-pack'; |
|
2423 |
|
$needed_rights = 'F'; |
|
2424 |
|
$push = 0; |
|
2425 |
|
} else if (strncasecmp($cmd, 'git-receive-pack', 16) == 0) { |
|
2426 |
|
$cmd = 'git-receive-pack'; |
|
2427 |
|
// We need push or anonymous push |
|
2428 |
|
$needed_rights = 'P|H'; |
|
2429 |
|
$push = 1; |
|
2430 |
|
} else { |
|
2431 |
|
$ret['error'] = 'Unknown command'; |
|
2432 |
|
break; |
|
2433 |
|
} |
|
2434 |
|
|
|
2435 |
|
// Validity/security checks |
|
2436 |
|
// Load info about the owner |
|
2437 |
|
if (rg_user_ok($user) !== TRUE) { |
|
2438 |
|
$ret['error'] = 'User is invalid (' . rg_user_error() . ')'; |
|
2439 |
|
break; |
|
2440 |
|
} |
|
2441 |
|
$ret['owner_ui'] = rg_user_info($db, 0, $user, ''); |
|
2442 |
|
if ($ret['owner_ui']['ok'] != 1) { |
|
2443 |
|
$ret['error'] = 'Internal problems; try again later, please'; |
|
2444 |
|
break; |
|
2445 |
|
} |
|
2446 |
|
if ($ret['owner_ui']['exists'] != 1) { |
|
2447 |
|
$ret['error'] = 'User does not exists'; |
|
2448 |
|
break; |
|
2449 |
|
} |
|
2450 |
|
|
|
2451 |
|
// Loading info about the repository |
|
2452 |
|
if (rg_repo_ok($repo) !== TRUE) { |
|
2453 |
|
$ret['error'] = 'Repository is invalid (' |
|
2454 |
|
. rg_repo_error() . ')'; |
|
2455 |
|
break; |
|
2456 |
|
} |
|
2457 |
|
$ret['ri'] = rg_repo_info($db, 0, $ret['owner_ui']['uid'], $repo); |
|
2458 |
|
if ($ret['ri']['ok'] != 1) { |
|
2459 |
|
$ret['error'] = 'Internal problems; try again later, please'; |
|
2460 |
|
break; |
|
2461 |
|
} |
|
2462 |
|
if ($ret['ri']['exists'] != 1) { |
|
2463 |
|
$ret['error'] = 'Repository does not exists'; |
|
2464 |
|
break; |
|
2465 |
|
} |
|
2466 |
|
if ($ret['ri']['deleted'] == 1) { |
|
2467 |
|
$ret['error'] = 'Repository has been deleted'; |
|
2468 |
|
break; |
|
2469 |
|
} |
|
2470 |
|
|
|
2471 |
|
$ls = rg_repo_lock_status($db, $ret['ri']['repo_id']); |
|
2472 |
|
if ($ls['ok'] != 1) { |
|
2473 |
|
$ret['error'] = 'Could not get lock status: ' . rg_repo_error(); |
|
2474 |
|
break; |
|
2475 |
|
} |
|
2476 |
|
if (($ls['status'] == 1) && ($login_ui['uid'] != $ls['uid'])) { |
|
2477 |
|
$_u = rg_user_info($db, $ls['uid'], '', ''); |
|
2478 |
|
if ($_u['exists'] == 1) |
|
2479 |
|
$_user = $_u['username']; |
|
2480 |
|
else |
|
2481 |
|
$_user = '?'; |
|
2482 |
|
$ret['error'] = 'Repository has been locked user ' . $_user |
|
2483 |
|
. ' at ' . gmdate('Y-m-d H:i', $ls['itime']) . ' UTC.' |
|
2484 |
|
. ' Reason: ' . $ls['reason']; |
|
2485 |
|
break; |
|
2486 |
|
} |
|
2487 |
|
|
|
2488 |
|
$repo_path = rg_repo_path_by_id($ret['owner_ui']['uid'], |
|
2489 |
|
$ret['ri']['repo_id']); |
|
2490 |
|
$ret['repo_path'] = $repo_path; |
|
2491 |
|
rg_log('DEBUG: repo_path=' . $repo_path); |
|
2492 |
|
|
|
2493 |
|
// TODO: signal user that the repo moved and provide a hint how to follow |
|
2494 |
|
|
|
2495 |
|
$x = array(); |
|
2496 |
|
$x['obj_id'] = $ret['ri']['repo_id']; |
|
2497 |
|
$x['type'] = 'repo_refs'; |
|
2498 |
|
$x['owner'] = $ret['ri']['uid']; |
|
2499 |
|
$x['uid'] = $login_ui['uid']; |
|
2500 |
|
$x['username'] = $login_ui['uid'] == 0 ? '' : $login_ui['username']; |
|
2501 |
|
$x['needed_rights'] = $needed_rights; |
|
2502 |
|
$x['ip'] = $ip; |
|
2503 |
|
$x['misc'] = ''; |
|
2504 |
|
$r = rg_rights_allow($db, $x); |
|
2505 |
|
if ($r !== TRUE) { |
|
2506 |
|
$ret['error'] = 'You have no rights to access this repo'; |
|
2507 |
|
$ret['allow'] = 0; |
|
2508 |
|
break; |
|
2509 |
|
} |
|
2510 |
|
|
|
2511 |
|
// We need to know if Push (and not anon) is allowed, so we can |
|
2512 |
|
// give the user a chance to authenticate. |
|
2513 |
|
// TODO: change rg_rights_allow to return what rights are |
|
2514 |
|
// allowed and use it. |
|
2515 |
|
$x['needed_rights'] = 'P'; |
|
2516 |
|
$r = rg_rights_allow($db, $x); |
|
2517 |
|
if ($r !== TRUE) |
|
2518 |
|
$ret['push_allowed'] = 0; |
|
2519 |
|
|
|
2520 |
|
// If we are enrolled, ask for login token |
|
2521 |
|
// For push we always ask for it, for fetch only if repo is |
|
2522 |
|
// NOT public. And we can ask only if we have a ssh connection. |
|
2523 |
|
// For git protocol we cannot because we do not have the |
|
2524 |
|
// username/uid of the connecting user. |
|
2525 |
|
if (isset($_SERVER['SSH_CONNECTION'])) { |
|
2526 |
|
if (($ret['ri']['public'] == 0) || ($push == 1)) { |
|
2527 |
|
$r = rg_totp_verify_ip($db, $login_ui['uid'], |
|
2528 |
|
$ip); |
|
2529 |
|
if (($r['ok'] == 0) && (empty($r['list']))) { |
|
2530 |
|
$ret['error'] = rg_totp_error(); |
|
2531 |
|
break; |
|
2532 |
|
} |
|
2533 |
|
} |
|
2534 |
|
} |
|
2535 |
|
|
|
2536 |
|
// TODO: limit per connection |
|
2537 |
|
// TODO: limit time and/or cpu |
|
2538 |
|
// TODO: limit cpuset |
|
2539 |
|
// TODO: limit io |
|
2540 |
|
// TODO: put process in a cgroup? |
|
2541 |
|
|
|
2542 |
|
if (($push == 1) |
|
2543 |
|
&& rg_user_over_limit($db, $ret['owner_ui'], $max)) { |
|
2544 |
|
// TODO: be aware that a push may mean a delete => |
|
2545 |
|
// free space?! |
|
2546 |
|
// We should mark the repo over limit when we compute |
|
2547 |
|
// the disk space - same problem |
|
2548 |
|
$ret['error'] = 'Cannot push: user is over limit' |
|
2549 |
|
. ' (' . $ret['owner_ui']['disk_used_mb'] . 'MiB >= ' |
|
2550 |
|
. $max . 'MiB)'; |
|
2551 |
|
break; |
|
2552 |
|
} |
|
2553 |
|
|
|
2554 |
|
// Put in environment all we need |
|
2555 |
|
putenv('ROCKETGIT_LOGIN_UID=' . $login_ui['uid']); |
|
2556 |
|
putenv('ROCKETGIT_LOGIN_URL=' . rg_re_userpage($login_ui)); |
|
2557 |
|
putenv('ROCKETGIT_REPO_ID=' . $ret['ri']['repo_id']); |
|
2558 |
|
putenv('ROCKETGIT_REPO_PATH=' . $repo_path); |
|
2559 |
|
putenv('ROCKETGIT_REPO_NAME=' . $ret['ri']['name']); |
|
2560 |
|
putenv('ROCKETGIT_REPO_UID=' . $ret['ri']['uid']); |
|
2561 |
|
putenv('ROCKETGIT_REPO_CLONE_URL=' . $ret['ri']['clone_url_http']); |
|
2562 |
|
putenv('ROCKETGIT_IP=' . $ip); |
|
2563 |
|
putenv('ROCKETGIT_ITIME=' . microtime(TRUE)); |
|
2564 |
|
putenv('ROCKETGIT_HOST=' . $host); |
|
2565 |
|
if (($push == 1) && $need_namespace_copy) { |
|
2566 |
|
$namespace = 'rg_' . rg_id(8); |
|
2567 |
|
rg_log('namespace is ' . $namespace); |
|
2568 |
|
putenv('GIT_NAMESPACE=' . $namespace); |
|
2569 |
|
|
|
2570 |
|
// Prepare refs to avoid the following message: |
|
2571 |
|
// 'No refs in common and none specified; doing nothing. |
|
2572 |
|
// Perhaps you should specify a branch such as 'master'.' |
|
2573 |
|
// TODO: cannot we copy only the pushed branch?! |
|
2574 |
|
$dst = $repo_path . '/refs/namespaces/' . $namespace . '/refs'; |
|
2575 |
|
$r = rg_copy_tree($repo_path . '/refs/heads', $dst . '/heads/', 0700); |
|
2576 |
|
if ($r !== TRUE) { |
|
2577 |
|
$ret['error'] = 'Internal error (cannot copy heads)'; |
|
2578 |
|
break; |
|
2579 |
|
} |
|
2580 |
|
$r = rg_copy_tree($repo_path . '/refs/tags', |
|
2581 |
|
$dst . '/tags/', 0700); |
|
2582 |
|
if ($r !== TRUE) { |
|
2583 |
|
$ret['error'] = |
|
2584 |
|
'Internal error (cannot copy tags)'; |
|
2585 |
|
break; |
|
2586 |
|
} |
|
2587 |
|
} |
|
2588 |
|
|
|
2589 |
|
// TODO: we may want to call here the git-shell cmd and remove |
|
2590 |
|
// it from remote.php? |
|
2591 |
|
|
|
2592 |
|
$ret['ok'] = 1; |
|
2593 |
|
break; |
|
2594 |
|
} |
|
2595 |
|
|
|
2596 |
|
rg_log_exit(); |
|
2597 |
|
rg_prof_end('repo_fetch_push_helper'); |
|
2598 |
|
return $ret; |
|
2599 |
|
} |
|
2600 |
|
|
2405 |
2601 |
?> |
?> |
File inc/user.inc.php changed (mode: 100644) (index a47e1c6..083d64a) |
... |
... |
function rg_user_event_rename($db, $event) |
142 |
142 |
return $ret; |
return $ret; |
143 |
143 |
} |
} |
144 |
144 |
|
|
|
145 |
|
/* |
|
146 |
|
* Empty user data |
|
147 |
|
*/ |
|
148 |
|
function rg_user_empty() |
|
149 |
|
{ |
|
150 |
|
return array( |
|
151 |
|
'ok' => 0, |
|
152 |
|
'uid' => 0, |
|
153 |
|
'is_admin' => 0, |
|
154 |
|
'rights' => '', |
|
155 |
|
'homepage' => '', |
|
156 |
|
'username' => '', |
|
157 |
|
'exists' => 0, |
|
158 |
|
'organization' => 0, |
|
159 |
|
'confirmed' => 0 |
|
160 |
|
); |
|
161 |
|
} |
|
162 |
|
|
145 |
163 |
/* |
/* |
146 |
164 |
* Cosmetic function for 'user' info |
* Cosmetic function for 'user' info |
147 |
165 |
*/ |
*/ |
|
... |
... |
function rg_user_link_by_name($db, $event) |
169 |
187 |
rg_log("user_link_by_name: event=" . rg_array2string($event)); |
rg_log("user_link_by_name: event=" . rg_array2string($event)); |
170 |
188 |
|
|
171 |
189 |
$by_id = rg_user_path_by_id($event['ui']['uid']); |
$by_id = rg_user_path_by_id($event['ui']['uid']); |
172 |
|
if (!is_dir($by_id) && (mkdir($by_id, 0755, TRUE) === FALSE)) { |
|
|
190 |
|
if (!is_dir($by_id) && (mkdir($by_id, 0700, TRUE) === FALSE)) { |
173 |
191 |
rg_user_set_error("cannot mkdir by_id=$by_id ($php_errormsg)"); |
rg_user_set_error("cannot mkdir by_id=$by_id ($php_errormsg)"); |
174 |
192 |
return FALSE; |
return FALSE; |
175 |
193 |
} |
} |
176 |
194 |
|
|
177 |
195 |
$by_name = rg_user_path_by_name($event['ui']['username']); |
$by_name = rg_user_path_by_name($event['ui']['username']); |
178 |
196 |
$by_name_parent = dirname($by_name); |
$by_name_parent = dirname($by_name); |
179 |
|
if (!is_dir($by_name_parent) && (mkdir($by_name_parent, 0755, TRUE) === FALSE)) { |
|
|
197 |
|
if (!is_dir($by_name_parent) |
|
198 |
|
&& (mkdir($by_name_parent, 0700, TRUE) === FALSE)) { |
180 |
199 |
rg_user_set_error("cannot mkdir by_name_parent=$by_name_parent ($php_errmsg)"); |
rg_user_set_error("cannot mkdir by_name_parent=$by_name_parent ($php_errmsg)"); |
181 |
200 |
return FALSE; |
return FALSE; |
182 |
201 |
} |
} |
|
... |
... |
function rg_user_info($db, $uid, $user, $email) |
655 |
674 |
rg_prof_start("user_info"); |
rg_prof_start("user_info"); |
656 |
675 |
rg_log_enter("user_info: uid=$uid user=$user email=$email"); |
rg_log_enter("user_info: uid=$uid user=$user email=$email"); |
657 |
676 |
|
|
658 |
|
$ret = array(); |
|
659 |
|
$ret['ok'] = 0; |
|
660 |
|
$ret['exists'] = 0; |
|
661 |
|
$ret['uid'] = 0; |
|
662 |
|
$ret['is_admin'] = 0; |
|
663 |
|
$ret['rights'] = ''; |
|
664 |
|
$ret['homepage'] = ''; |
|
|
677 |
|
$ret = rg_user_empty(); |
665 |
678 |
while (1) { |
while (1) { |
666 |
679 |
$params = array("uid" => $uid, |
$params = array("uid" => $uid, |
667 |
680 |
"user" => $user, |
"user" => $user, |
|
... |
... |
function rg_user_info($db, $uid, $user, $email) |
682 |
695 |
|
|
683 |
696 |
$sql = "SELECT * FROM users WHERE uid = @@uid@@"; |
$sql = "SELECT * FROM users WHERE uid = @@uid@@"; |
684 |
697 |
} else if (!empty($user)) { |
} else if (!empty($user)) { |
685 |
|
if (rg_user_ok($user) !== TRUE) |
|
|
698 |
|
if (rg_user_ok($user) !== TRUE) { |
|
699 |
|
// cannot exists |
|
700 |
|
$ret['ok'] = 1; |
686 |
701 |
break; |
break; |
|
702 |
|
} |
687 |
703 |
|
|
688 |
704 |
$c = rg_cache_get("username_to_uid::" . $user); |
$c = rg_cache_get("username_to_uid::" . $user); |
689 |
705 |
if ($c !== FALSE) { |
if ($c !== FALSE) { |
|
... |
... |
function rg_user_info($db, $uid, $user, $email) |
701 |
717 |
|
|
702 |
718 |
$sql = "SELECT * FROM users WHERE email = @@email@@"; |
$sql = "SELECT * FROM users WHERE email = @@email@@"; |
703 |
719 |
} else { |
} else { |
704 |
|
rg_user_set_error("invalid user"); |
|
|
720 |
|
$ret['ok'] = 1; |
705 |
721 |
break; |
break; |
706 |
722 |
} |
} |
707 |
723 |
|
|
|
... |
... |
function rg_user_login_by_sid($db, &$rg) |
784 |
800 |
rg_log_enter("user_login_by_sid: sid=" . $rg['sid']); |
rg_log_enter("user_login_by_sid: sid=" . $rg['sid']); |
785 |
801 |
|
|
786 |
802 |
// Make sure it is not passed by client |
// Make sure it is not passed by client |
787 |
|
$rg['login_ui'] = array(); |
|
788 |
|
$rg['login_ui']['uid'] = 0; |
|
789 |
|
$rg['login_ui']['is_admin'] = 0; |
|
790 |
|
$rg['login_ui']['rights'] = ""; |
|
791 |
|
$rg['login_ui']['username'] = ""; |
|
792 |
|
$rg['login_ui']['organization'] = 0; |
|
793 |
|
$rg['login_ui']['confirmed'] = 0; |
|
|
803 |
|
$rg['login_ui'] = rg_user_empty(); |
794 |
804 |
|
|
795 |
805 |
$ret = FALSE; |
$ret = FALSE; |
796 |
806 |
while (1) { |
while (1) { |
|
... |
... |
function rg_user_login_by_user_pass($db, $user, $pass, $login_token, $lock_ip, |
925 |
935 |
rg_log_enter("user_login_by_user_pass: user=$user" |
rg_log_enter("user_login_by_user_pass: user=$user" |
926 |
936 |
. " login_token=$login_token lock_ip=$lock_ip"); |
. " login_token=$login_token lock_ip=$lock_ip"); |
927 |
937 |
|
|
928 |
|
$ui = array(); |
|
929 |
|
$ui['uid'] = 0; |
|
930 |
|
$ui['is_admin'] = 0; |
|
931 |
|
$ui['rights'] = ""; |
|
|
938 |
|
$ui = rg_user_empty(); |
932 |
939 |
|
|
933 |
940 |
$ret = FALSE; |
$ret = FALSE; |
934 |
941 |
while (1) { |
while (1) { |
|
... |
... |
function rg_user_list_to_full_info($db, $list) |
1820 |
1827 |
return $ret; |
return $ret; |
1821 |
1828 |
} |
} |
1822 |
1829 |
|
|
|
1830 |
|
/* |
|
1831 |
|
* Deals with push/fetch by HTTP(S) |
|
1832 |
|
*/ |
|
1833 |
|
function rg_user_http_git($db, $rg, $paras) |
|
1834 |
|
{ |
|
1835 |
|
rg_prof_start('user_http_git'); |
|
1836 |
|
rg_log_enter('user_http_git'); |
|
1837 |
|
|
|
1838 |
|
rg_log('DEBUG: ct=' . $rg['ct']); |
|
1839 |
|
if (strcasecmp($rg['ct'], 'application/x-git-upload-pack-request') == 0) |
|
1840 |
|
$service = 'git-upload-pack'; |
|
1841 |
|
else if (strcasecmp($rg['ct'], 'application/x-git-receive-pack-request') == 0) |
|
1842 |
|
$service = 'git-receive-pack'; |
|
1843 |
|
else |
|
1844 |
|
$service = isset($_REQUEST['service']) ? $_REQUEST['service'] : ''; |
|
1845 |
|
rg_log('DEBUG: service=' . $service); |
|
1846 |
|
|
|
1847 |
|
$protocol = isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0'; |
|
1848 |
|
|
|
1849 |
|
$ret = FALSE; |
|
1850 |
|
while (1) { |
|
1851 |
|
if (empty($service)) |
|
1852 |
|
break; |
|
1853 |
|
|
|
1854 |
|
$ret = TRUE; |
|
1855 |
|
|
|
1856 |
|
set_time_limit(3600); |
|
1857 |
|
|
|
1858 |
|
rg_log_ml('paras: ' . print_r($paras, TRUE)); |
|
1859 |
|
|
|
1860 |
|
if (count($paras) < 2) { |
|
1861 |
|
//TODO |
|
1862 |
|
} |
|
1863 |
|
|
|
1864 |
|
$prefix = array_shift($paras); |
|
1865 |
|
if (strcmp($prefix, 'user') != 0) { |
|
1866 |
|
$user = $prefix; |
|
1867 |
|
$prefix = ''; |
|
1868 |
|
} else { |
|
1869 |
|
$user = array_shift($paras); |
|
1870 |
|
} |
|
1871 |
|
$repo = array_shift($paras); |
|
1872 |
|
$file = implode('/', $paras); |
|
1873 |
|
rg_log('DEBUG: file=' . $file); |
|
1874 |
|
|
|
1875 |
|
header('Expires: Fri, 01 Jan 1980 00:00:00 GMT'); |
|
1876 |
|
header('Pragma: no-cache'); |
|
1877 |
|
header('Cache-Control: no-cache, max-age=0, must-revalidate'); |
|
1878 |
|
|
|
1879 |
|
// if user is valid, retry auth |
|
1880 |
|
// if user is not valid, consider anonymous |
|
1881 |
|
$authd = FALSE; |
|
1882 |
|
$u = ''; |
|
1883 |
|
$empty_user = TRUE; |
|
1884 |
|
$auth_ui = rg_user_empty(); |
|
1885 |
|
while (isset($_SERVER['PHP_AUTH_USER']) |
|
1886 |
|
&& isset($_SERVER['PHP_AUTH_PW'])) { |
|
1887 |
|
$u = $_SERVER['PHP_AUTH_USER']; |
|
1888 |
|
$p = $_SERVER['PHP_AUTH_PW']; |
|
1889 |
|
$empty_user = FALSE; |
|
1890 |
|
rg_log('DEBUG: HTTP auth: u=' . $u); |
|
1891 |
|
|
|
1892 |
|
if (empty($u)) |
|
1893 |
|
break; |
|
1894 |
|
|
|
1895 |
|
$auth_ui = rg_user_info($db, 0, $u, ''); |
|
1896 |
|
if ($auth_ui['ok'] !== 1) { |
|
1897 |
|
rg_log('DEBUG: set errror (500): ' . rg_user_error()); |
|
1898 |
|
header('X-Rocketgit-Error: ' . rg_user_error()); |
|
1899 |
|
header($protocol . ' 500 Internal server error'); |
|
1900 |
|
break; |
|
1901 |
|
} |
|
1902 |
|
$authd = rg_user_login_by_user_pass($db, $u, $p, |
|
1903 |
|
'' /*login_token*/, TRUE /*lock IP*/, |
|
1904 |
|
$rg['login_ui']); |
|
1905 |
|
break; |
|
1906 |
|
} |
|
1907 |
|
|
|
1908 |
|
$host = isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : ''; |
|
1909 |
|
$need_namespace_copy = strcmp($file, 'info/refs'); |
|
1910 |
|
$r = rg_repo_fetch_push_helper($db, $host, $rg['ip'], |
|
1911 |
|
$rg['login_ui'], $prefix, $user, $repo, $service, |
|
1912 |
|
$need_namespace_copy); |
|
1913 |
|
//rg_log_ml('DEBUG: repo_fetch_push_helper: ' . print_r($r, TRUE)); |
|
1914 |
|
if ($r['ok'] !== 1) { |
|
1915 |
|
rg_log('DEBUG: set errror: ' . $r['error']); |
|
1916 |
|
header('X-Rocketgit-Error: ' . $r['error']); |
|
1917 |
|
|
|
1918 |
|
if (isset($r['owner_ui'])) { |
|
1919 |
|
if ($r['owner_ui']['ok'] != 1) { |
|
1920 |
|
header($protocol . ' 500 Internal server error'); |
|
1921 |
|
break; |
|
1922 |
|
} |
|
1923 |
|
|
|
1924 |
|
if ($r['owner_ui']['exists'] != 1) { |
|
1925 |
|
header($protocol . ' 404 Not found'); |
|
1926 |
|
break; |
|
1927 |
|
} |
|
1928 |
|
} |
|
1929 |
|
|
|
1930 |
|
if (isset($r['ri'])) { |
|
1931 |
|
if ($r['ri']['ok'] != 1) { |
|
1932 |
|
header($protocol . ' 500 Internal server error'); |
|
1933 |
|
break; |
|
1934 |
|
} |
|
1935 |
|
|
|
1936 |
|
if ($r['ri']['exists'] != 1) { |
|
1937 |
|
header($protocol . ' 404 Not found'); |
|
1938 |
|
break; |
|
1939 |
|
} |
|
1940 |
|
} |
|
1941 |
|
|
|
1942 |
|
header($protocol . ' 500 Internal server error'); |
|
1943 |
|
break; |
|
1944 |
|
} |
|
1945 |
|
$repo_path = $r['repo_path']; |
|
1946 |
|
|
|
1947 |
|
if ($r['allow'] !== 1) { |
|
1948 |
|
rg_log('DEBUG: allow != 1 => 401'); |
|
1949 |
|
// Connecting user has no rights to push, not even anon. |
|
1950 |
|
// The user be authed at this point, but may try another |
|
1951 |
|
// user/pass combination. |
|
1952 |
|
header($protocol . ' 401 Unauthorized status'); |
|
1953 |
|
header('WWW-Authenticate: Basic' |
|
1954 |
|
. ' realm="Use empty user if you have no account"'); |
|
1955 |
|
break; |
|
1956 |
|
} |
|
1957 |
|
|
|
1958 |
|
rg_log('DEBUG: push_allowed=' . $r['push_allowed'] |
|
1959 |
|
. ' empty_user=' . ($empty_user ? 'yes' : 'no') |
|
1960 |
|
. ' authd=' . ($authd === TRUE ? 'yes' : 'no') |
|
1961 |
|
. ' exists=' . $auth_ui['exists']); |
|
1962 |
|
if ($r['push_allowed'] !== 1) { |
|
1963 |
|
// We have only anon push rights at this point. |
|
1964 |
|
// If user is correct, but password not, we will ask |
|
1965 |
|
// the user to try again. If user is not correct, |
|
1966 |
|
// we will go on with anon push access. |
|
1967 |
|
if ($empty_user |
|
1968 |
|
|| (($authd === FALSE) && ($auth_ui['exists'] == 1))) { |
|
1969 |
|
rg_log('DEBUG: send 401'); |
|
1970 |
|
header($protocol . ' 401 Unauthorized status'); |
|
1971 |
|
header('WWW-Authenticate: Basic' |
|
1972 |
|
. ' realm="Use empty user if you have no account"'); |
|
1973 |
|
break; |
|
1974 |
|
} |
|
1975 |
|
} else { |
|
1976 |
|
rg_log('DEBUG: user has full push rights'); |
|
1977 |
|
} |
|
1978 |
|
|
|
1979 |
|
if (strcmp($file, 'info/refs') == 0) { |
|
1980 |
|
rg_log('DEBUG: info/refs'); |
|
1981 |
|
// TODO: we should allow this only if the connecting user has |
|
1982 |
|
// fetch rights! |
|
1983 |
|
header('Content-Type: application/x-' |
|
1984 |
|
. $service . '-advertisement'); |
|
1985 |
|
|
|
1986 |
|
echo rg_git_pack('# service=' . $service . "\n"); |
|
1987 |
|
echo rg_git_flush(); |
|
1988 |
|
|
|
1989 |
|
$run = '/usr/libexec/git-core/' . $service |
|
1990 |
|
. ' --stateless-rpc --advertise-refs' |
|
1991 |
|
. ' ' . escapeshellarg($repo_path); |
|
1992 |
|
$e = rg_exec($run, '', 'rg_echo', 'rg_git_band_2'); |
|
1993 |
|
if ($e['code'] != 0) |
|
1994 |
|
rg_log('Error executing command: ' . $e['errmsg']); |
|
1995 |
|
} else if (strcasecmp($rg['ct'], 'application/x-git-upload-pack-request') == 0) { |
|
1996 |
|
rg_log('DEBUG: git-upload-pack...'); |
|
1997 |
|
|
|
1998 |
|
header('Content-Type: application/x-git-upload-pack-result'); |
|
1999 |
|
|
|
2000 |
|
// TODO: seems I cannot do this here - |
|
2001 |
|
// seems remote receive-pack expects ACK/NAK first: |
|
2002 |
|
// fatal: git fetch_pack: expected ACK/NAK, got '... |
|
2003 |
|
/* |
|
2004 |
|
rg_git_info_pack("\x02", '== Welcome to RocketGit! =='); |
|
2005 |
|
rg_git_info_pack("\x02", 'you are connecting from IP ' |
|
2006 |
|
. $rg['ip'] . '.'); |
|
2007 |
|
// If user does not correct to the correct URL, correct them |
|
2008 |
|
if (!empty($host) && (strcasecmp($host, $rg['rg_http_host_no_port']) != 0)) |
|
2009 |
|
rg_git_info_pack("\x02", 'Please use ' . $rg['rg_http_host_no_port'] |
|
2010 |
|
. ' instead of ' . $host . '.'); |
|
2011 |
|
putenv('ROCKETGIT_SHOW_INFO=0'); |
|
2012 |
|
*/ |
|
2013 |
|
|
|
2014 |
|
$run = '/usr/libexec/git-core/git-upload-pack' |
|
2015 |
|
. ' --stateless-rpc' |
|
2016 |
|
. ' ' . escapeshellarg($repo_path); |
|
2017 |
|
|
|
2018 |
|
$data_in = @file_get_contents('php://input'); |
|
2019 |
|
$e = rg_exec($run, $data_in, 'rg_echo', 'rg_git_band_2'); |
|
2020 |
|
if ($e['code'] != 0) |
|
2021 |
|
rg_log('Error executing command: ' . $e['errmsg']); |
|
2022 |
|
} else if (strcasecmp($rg['ct'], 'application/x-git-receive-pack-request') == 0) { |
|
2023 |
|
rg_log('DEBUG: git-receive-pack...'); |
|
2024 |
|
|
|
2025 |
|
header('Content-Type: application/x-git-receive-pack-result'); |
|
2026 |
|
|
|
2027 |
|
rg_git_info_pack("\x02", '== Welcome to RocketGit! =='); |
|
2028 |
|
rg_git_info_pack("\x02", 'you are connecting from IP ' |
|
2029 |
|
. $rg['ip'] . '.'); |
|
2030 |
|
// If user does not correct to the correct URL, correct them |
|
2031 |
|
if (!empty($host) && (strcasecmp($host, $rg['rg_http_host_no_port']) != 0)) |
|
2032 |
|
rg_git_info_pack("\x02", 'Please use ' . $rg['rg_http_host_no_port'] |
|
2033 |
|
. ' instead of ' . $host . '.'); |
|
2034 |
|
putenv('ROCKETGIT_SHOW_INFO=0'); |
|
2035 |
|
|
|
2036 |
|
$run = '/usr/libexec/git-core/git-receive-pack' |
|
2037 |
|
. ' --stateless-rpc' |
|
2038 |
|
. ' ' . escapeshellarg($repo_path); |
|
2039 |
|
|
|
2040 |
|
$data_in = @file_get_contents('php://input'); |
|
2041 |
|
//rg_log('DEBUG: data_in=' . $data_in); |
|
2042 |
|
file_put_contents('/tmp/data_in', $data_in); |
|
2043 |
|
$e = rg_exec($run, $data_in, 'rg_echo', 'rg_echo'); |
|
2044 |
|
if ($e['code'] != 0) |
|
2045 |
|
rg_log('Error executing command: ' . $e['errmsg']); |
|
2046 |
|
} else { |
|
2047 |
|
rg_log('Unknown service!'); |
|
2048 |
|
} |
|
2049 |
|
|
|
2050 |
|
break; |
|
2051 |
|
} |
|
2052 |
|
|
|
2053 |
|
rg_log_exit(); |
|
2054 |
|
rg_prof_end('user_http_git'); |
|
2055 |
|
return $ret; |
|
2056 |
|
} |
|
2057 |
|
|
1823 |
2058 |
?> |
?> |
File inc/util.inc.php changed (mode: 100644) (index 4689c32..dc9b8cf) |
... |
... |
function rg_lock($file) |
127 |
127 |
|
|
128 |
128 |
$f = @fopen($rg_lock_dir . "/" . $file, "w"); |
$f = @fopen($rg_lock_dir . "/" . $file, "w"); |
129 |
129 |
if ($f === FALSE) { |
if ($f === FALSE) { |
130 |
|
rg_internal_error("Cannot open lock $file ($php_errormsg)."); |
|
|
130 |
|
rg_internal_error('Cannot open lock [' . $rg_lock_dir |
|
131 |
|
. '/' . $file . '] (' . $php_errormsg . ').'); |
131 |
132 |
return FALSE; |
return FALSE; |
132 |
133 |
} |
} |
133 |
134 |
|
|
|
... |
... |
function rg_re_url($area) |
189 |
190 |
|
|
190 |
191 |
function rg_re_userpage($ui) |
function rg_re_userpage($ui) |
191 |
192 |
{ |
{ |
|
193 |
|
if (isset($ui['uid']) && ($ui['uid'] == 0)) |
|
194 |
|
return ''; |
|
195 |
|
|
192 |
196 |
if (!isset($ui['organization'])) { |
if (!isset($ui['organization'])) { |
193 |
197 |
rg_internal_error("rg_re_userpage called with wrong ui (no org)!"); |
rg_internal_error("rg_re_userpage called with wrong ui (no org)!"); |
194 |
198 |
rg_log("ui: " . print_r($ui, TRUE)); |
rg_log("ui: " . print_r($ui, TRUE)); |
|
... |
... |
function rg_re_repo_git($organization, $user, $repo) |
276 |
280 |
. $prefix . "/" . rawurlencode($user) . "/" . rawurlencode($repo); |
. $prefix . "/" . rawurlencode($user) . "/" . rawurlencode($repo); |
277 |
281 |
} |
} |
278 |
282 |
|
|
|
283 |
|
function rg_re_repo_http($organization, $user, $repo) |
|
284 |
|
{ |
|
285 |
|
$prefix = ''; |
|
286 |
|
if ($organization == 0) |
|
287 |
|
$prefix = '/user'; |
|
288 |
|
|
|
289 |
|
return rg_base_url() . $prefix . "/" |
|
290 |
|
. rawurlencode($user) . "/" . rawurlencode($repo); |
|
291 |
|
} |
|
292 |
|
|
279 |
293 |
function rg_var_get($name) |
function rg_var_get($name) |
280 |
294 |
{ |
{ |
281 |
295 |
if (isset($_SERVER[$name])) |
if (isset($_SERVER[$name])) |
|
... |
... |
function rg_var_a2s($var) |
386 |
400 |
*/ |
*/ |
387 |
401 |
function rg_chars_allow($name, $allowed_regexp, &$invalid) |
function rg_chars_allow($name, $allowed_regexp, &$invalid) |
388 |
402 |
{ |
{ |
389 |
|
if (preg_match('/^[' . $allowed_regexp . ']*$/uUD', $name) !== 1) { |
|
|
403 |
|
// Modifiers: u = UTF8, D = PCRE_DOLLAR_ENDONLY |
|
404 |
|
// http://php.net/manual/en/reference.pcre.pattern.modifiers.php |
|
405 |
|
if (preg_match('/^[' . $allowed_regexp . ']*$/uD', $name) !== 1) { |
390 |
406 |
$invalid = preg_replace('/[' . $allowed_regexp . ']/', '', $name); |
$invalid = preg_replace('/[' . $allowed_regexp . ']/', '', $name); |
391 |
407 |
rg_log("chars_allow: [$name] does not match [$allowed_regexp]"); |
rg_log("chars_allow: [$name] does not match [$allowed_regexp]"); |
392 |
408 |
return FALSE; |
return FALSE; |
|
... |
... |
function rg_ok($msg) |
966 |
982 |
*/ |
*/ |
967 |
983 |
function rg_exec($cmd, $input, $cb_stdout, $cb_stderr) |
function rg_exec($cmd, $input, $cb_stdout, $cb_stderr) |
968 |
984 |
{ |
{ |
969 |
|
rg_prof_start("exec"); |
|
970 |
|
rg_log_enter("Executing [$cmd]..."); |
|
|
985 |
|
rg_prof_start('exec'); |
|
986 |
|
rg_log_enter('Executing [' . $cmd . ']'); |
971 |
987 |
|
|
972 |
988 |
$ret = array(); |
$ret = array(); |
973 |
989 |
$ret['ok'] = 0; |
$ret['ok'] = 0; |
974 |
|
$ret['errmsg'] = ""; |
|
|
990 |
|
$ret['errmsg'] = ''; |
975 |
991 |
$ret['code'] = 65000; // fake code |
$ret['code'] = 65000; // fake code |
|
992 |
|
$ret['data'] = ''; |
|
993 |
|
$ret['stderr'] = ''; |
976 |
994 |
while (1) { |
while (1) { |
977 |
995 |
$desc = array( |
$desc = array( |
978 |
996 |
0 => array("pipe", "r"), |
0 => array("pipe", "r"), |
|
... |
... |
function rg_exec($cmd, $input, $cb_stdout, $cb_stderr) |
989 |
1007 |
|
|
990 |
1008 |
//rg_log_ml('DEBUG: proc_open pipes: ' . print_r($pipes, TRUE)); |
//rg_log_ml('DEBUG: proc_open pipes: ' . print_r($pipes, TRUE)); |
991 |
1009 |
|
|
992 |
|
$stderr = ""; |
|
993 |
|
$ret['data'] = ""; |
|
994 |
1010 |
$rx = array($pipes[1], $pipes[2]); |
$rx = array($pipes[1], $pipes[2]); |
995 |
1011 |
$wx = array(); |
$wx = array(); |
996 |
1012 |
if (!empty($input)) |
if (!empty($input)) |
|
... |
... |
function rg_exec($cmd, $input, $cb_stdout, $cb_stderr) |
1014 |
1030 |
|
|
1015 |
1031 |
//rg_log('DEBUG: write event on fd ' . $fd . '!'); |
//rg_log('DEBUG: write event on fd ' . $fd . '!'); |
1016 |
1032 |
|
|
1017 |
|
//rg_log('DEBUG: Writing [' . $input . ']...'); |
|
|
1033 |
|
//rg_log('DEBUG: Writing to fd ' . $fd |
|
1034 |
|
// . ' [' . $input . ']...'); |
1018 |
1035 |
$r = @fwrite($fd, $input); |
$r = @fwrite($fd, $input); |
1019 |
1036 |
if ($r === FALSE) { |
if ($r === FALSE) { |
1020 |
1037 |
$ret['ermsg'] = 'cannot write'; |
$ret['ermsg'] = 'cannot write'; |
|
... |
... |
function rg_exec($cmd, $input, $cb_stdout, $cb_stderr) |
1048 |
1065 |
continue; |
continue; |
1049 |
1066 |
} |
} |
1050 |
1067 |
|
|
1051 |
|
rg_log('DEBUG: got data from fd ' . $fd |
|
1052 |
|
. ': ' . $_d); |
|
1053 |
1068 |
if ($fd === $pipes[2]) { |
if ($fd === $pipes[2]) { |
1054 |
1069 |
if ($cb_stderr === FALSE) { |
if ($cb_stderr === FALSE) { |
1055 |
|
rg_log('DEBUG: fd is pipes[2], append to stderr var'); |
|
1056 |
|
$stderr .= $_d; |
|
|
1070 |
|
//rg_log('DEBUG: fd is pipes[2], append to stderr var: ' . $_d); |
|
1071 |
|
$ret['stderr'] .= $_d; |
1057 |
1072 |
} else { |
} else { |
1058 |
|
rg_log('DEBUG: fd is pipes[2], call stdout cb'); |
|
1059 |
|
cb_stderr($_d); |
|
|
1073 |
|
//rg_log('DEBUG: fd is pipes[2], call stdout cb:' . $_d); |
|
1074 |
|
$cb_stderr($_d); |
1060 |
1075 |
} |
} |
1061 |
1076 |
} else if ($fd === $pipes[1]) { |
} else if ($fd === $pipes[1]) { |
1062 |
1077 |
if ($cb_stdout === FALSE) { |
if ($cb_stdout === FALSE) { |
1063 |
|
rg_log('Stream data to stdout using echo.'); |
|
|
1078 |
|
//rg_log('DEBUG: fd is pipes[1], append to stdout var: ' . $_d); |
1064 |
1079 |
$ret['data'] .= $_d; |
$ret['data'] .= $_d; |
1065 |
1080 |
} else { |
} else { |
1066 |
|
rg_log('DEBUG: fd is pipes[1], call stdout cb'); |
|
1067 |
|
cb_stdout($_d); |
|
|
1081 |
|
//rg_log('DEBUG: fd is pipes[1], call stdout cb: ' . $_d); |
|
1082 |
|
$cb_stdout($_d); |
1068 |
1083 |
} |
} |
|
1084 |
|
} else { |
|
1085 |
|
rg_internal_error('invalid fd'); |
1069 |
1086 |
} |
} |
1070 |
1087 |
} |
} |
1071 |
1088 |
|
|
1072 |
1089 |
if (!empty($ret['errmsg'])) |
if (!empty($ret['errmsg'])) |
1073 |
1090 |
break; |
break; |
1074 |
1091 |
} |
} |
1075 |
|
$stderr = trim($stderr); |
|
|
1092 |
|
$ret['stderr'] = trim($ret['stderr']); |
1076 |
1093 |
$ret['data'] = trim($ret['data']); |
$ret['data'] = trim($ret['data']); |
1077 |
1094 |
|
|
1078 |
1095 |
for ($i = 0; $i < 3; $i++) |
for ($i = 0; $i < 3; $i++) |
|
... |
... |
function rg_exec($cmd, $input, $cb_stdout, $cb_stderr) |
1081 |
1098 |
|
|
1082 |
1099 |
$err = proc_close($a); |
$err = proc_close($a); |
1083 |
1100 |
if ($err != 0) { |
if ($err != 0) { |
|
1101 |
|
rg_log('DEBUG: exec returned ' . $err); |
1084 |
1102 |
$ret['code'] = $err; |
$ret['code'] = $err; |
1085 |
|
$ret['errmsg'] = "code " . $err . ": " . $stderr; |
|
1086 |
|
} |
|
1087 |
|
|
|
1088 |
|
if (empty($ret['errmsg'])) { |
|
1089 |
|
$ret['code'] = 0; |
|
1090 |
|
$ret['ok'] = 1; |
|
|
1103 |
|
$ret['errmsg'] = 'task returned code ' . $err |
|
1104 |
|
. ' (' . $ret['stderr'] . ')'; |
|
1105 |
|
break; |
1091 |
1106 |
} |
} |
1092 |
1107 |
|
|
|
1108 |
|
//rg_log('DEBUG: exec returned ok'); |
|
1109 |
|
$ret['code'] = 0; |
|
1110 |
|
$ret['ok'] = 1; |
1093 |
1111 |
break; |
break; |
1094 |
1112 |
} |
} |
1095 |
1113 |
|
|
|
... |
... |
function rg_copy_tree($src, $dst, $mask) |
1230 |
1248 |
global $php_errormsg; |
global $php_errormsg; |
1231 |
1249 |
|
|
1232 |
1250 |
rg_prof_start("copy_tree"); |
rg_prof_start("copy_tree"); |
1233 |
|
rg_log_enter("copy_tree($src, $dst, $mask)"); |
|
|
1251 |
|
rg_log_enter("copy_tree($src, $dst, mask=$mask)"); |
1234 |
1252 |
|
|
1235 |
1253 |
$ret = FALSE; |
$ret = FALSE; |
1236 |
1254 |
while (1) { |
while (1) { |
|
... |
... |
function rg_socket($path, $buf, $timeout, $tries, $flags) |
1555 |
1573 |
break; |
break; |
1556 |
1574 |
} |
} |
1557 |
1575 |
if ($r === FALSE) { |
if ($r === FALSE) { |
1558 |
|
rg_log("Could not connect the socket (" . socket_strerror(socket_last_error()) . ")!"); |
|
|
1576 |
|
rg_log('Could not connect the socket [' . $path . ']' |
|
1577 |
|
. '(' . socket_strerror(socket_last_error()) . ')!'); |
1559 |
1578 |
break; |
break; |
1560 |
1579 |
} |
} |
1561 |
1580 |
rg_prof_end('socket-connect'); |
rg_prof_end('socket-connect'); |
|
... |
... |
function rg_force_alphanum($s) |
1736 |
1755 |
return preg_replace('/[^A-Za-z0-9_]/', '', $s); |
return preg_replace('/[^A-Za-z0-9_]/', '', $s); |
1737 |
1756 |
} |
} |
1738 |
1757 |
|
|
|
1758 |
|
/* |
|
1759 |
|
* Dummy function to be used in rg_exec callback |
|
1760 |
|
*/ |
|
1761 |
|
function rg_echo($s) |
|
1762 |
|
{ |
|
1763 |
|
echo $s; |
|
1764 |
|
} |
|
1765 |
|
|
1739 |
1766 |
?> |
?> |
File rocketgit.spec.in changed (mode: 100644) (index 8486d6d..e60363b) |
... |
... |
Source: http://kernel.embedromix.ro/us/rocketgit/%{name}-%{version}.tar.gz |
13 |
13 |
URL: https://rocketgit.com/ |
URL: https://rocketgit.com/ |
14 |
14 |
BuildRoot: %{_tmppath}/%{name}-%{version}-buildroot |
BuildRoot: %{_tmppath}/%{name}-%{version}-buildroot |
15 |
15 |
BuildArch: noarch |
BuildArch: noarch |
16 |
|
Requires: httpd, mod_ssl, php, php-cli, php-pgsql, xinetd |
|
|
16 |
|
Requires: httpd, mod_ssl, php-fpm, php-cli, php-pgsql, xinetd |
17 |
17 |
Requires: git, cronie, postgresql-server |
Requires: git, cronie, postgresql-server |
18 |
18 |
Requires: util-linux |
Requires: util-linux |
19 |
19 |
# SELinux stuff |
# SELinux stuff |
|
... |
... |
rm -rf ${RPM_BUILD_ROOT} |
81 |
81 |
%defattr (-,root,root,0755) |
%defattr (-,root,root,0755) |
82 |
82 |
%dir @USR_SHARE@/@PRJ@ |
%dir @USR_SHARE@/@PRJ@ |
83 |
83 |
%doc README LICENSE Changelog TODO selinux/@PRJ@.* |
%doc README LICENSE Changelog TODO selinux/@PRJ@.* |
84 |
|
%dir @ETC@/@PRJ@ |
|
|
84 |
|
%attr(0700,rocketgit,rocketgit) %dir @ETC@/@PRJ@ |
85 |
85 |
@ETC@/@PRJ@/config.php.sample |
@ETC@/@PRJ@/config.php.sample |
86 |
86 |
@ETC@/logrotate.d/rocketgit |
@ETC@/logrotate.d/rocketgit |
87 |
87 |
%config(noreplace) @ETC@/@PRJ@/config.php |
%config(noreplace) @ETC@/@PRJ@/config.php |
|
88 |
|
%config(noreplace) @ETC@/@PRJ@/php-fpm.conf |
|
89 |
|
%config(noreplace) @ETC@/@PRJ@/pool.conf |
88 |
90 |
%config(noreplace) @ETC@/cron.d/rocketgit |
%config(noreplace) @ETC@/cron.d/rocketgit |
89 |
91 |
%config(noreplace) @ETC@/xinetd.d/rocketgit |
%config(noreplace) @ETC@/xinetd.d/rocketgit |
90 |
92 |
%config(noreplace) @ETC@/httpd/conf.d/rocketgit.conf |
%config(noreplace) @ETC@/httpd/conf.d/rocketgit.conf |
91 |
|
%attr(0755,rocketgit,rocketgit) %dir @VAR_LOG@/@PRJ@ |
|
92 |
|
%attr(0755,apache,apache) %dir @VAR_LOG@/@PRJ@-web |
|
|
93 |
|
%attr(0700,rocketgit,rocketgit) %dir @VAR_LOG@/@PRJ@ |
93 |
94 |
%attr(0755,root,root) %dir @VAR_LIB@/@PRJ@ |
%attr(0755,root,root) %dir @VAR_LIB@/@PRJ@ |
94 |
|
%attr(0755,rocketgit,rocketgit) %dir @VAR_LIB@/@PRJ@/locks |
|
95 |
|
%attr(0755,rocketgit,rocketgit) %dir @VAR_LIB@/@PRJ@/repos |
|
96 |
|
%attr(0755,rocketgit,rocketgit) %dir @VAR_LIB@/@PRJ@/q_merge_requests |
|
97 |
|
%attr(0755,rocketgit,rocketgit) %dir @VAR_LIB@/@PRJ@/sockets |
|
|
95 |
|
%attr(0700,rocketgit,rocketgit) %dir @VAR_LIB@/@PRJ@/locks |
|
96 |
|
%attr(0700,rocketgit,rocketgit) %dir @VAR_LIB@/@PRJ@/repos |
|
97 |
|
%attr(0700,rocketgit,rocketgit) %dir @VAR_LIB@/@PRJ@/q_merge_requests |
|
98 |
|
%attr(0700,rocketgit,rocketgit) %dir @VAR_LIB@/@PRJ@/sockets |
98 |
99 |
%attr(0700,rocketgit,rocketgit) %dir @VAR_LIB@/@PRJ@/tmp |
%attr(0700,rocketgit,rocketgit) %dir @VAR_LIB@/@PRJ@/tmp |
99 |
100 |
%attr(0700,root,root) %dir @VAR_LIB@/@PRJ@/worker |
%attr(0700,root,root) %dir @VAR_LIB@/@PRJ@/worker |
100 |
101 |
%attr(0700,root,root) @USR_SBIN@/* |
%attr(0700,root,root) @USR_SBIN@/* |
101 |
102 |
@USR_SHARE@/@PRJ@/* |
@USR_SHARE@/@PRJ@/* |
102 |
103 |
@USR_SHARE@/selinux/*/@PRJ@.pp |
@USR_SHARE@/selinux/*/@PRJ@.pp |
|
104 |
|
@USR@/lib/systemd/system/* |
103 |
105 |
|
|
104 |
106 |
%changelog |
%changelog |
105 |
107 |
* Wed Oct 17 2012 Catalin(ux) M. BOIE <catab at embedromix dot ro> 0.10 |
* Wed Oct 17 2012 Catalin(ux) M. BOIE <catab at embedromix dot ro> 0.10 |
File samples/php-fpm.conf added (mode: 100644) (index 0000000..9b95e2e) |
|
1 |
|
;;;;;;;;;;;;;;;;;;;;; |
|
2 |
|
; FPM Configuration ; |
|
3 |
|
;;;;;;;;;;;;;;;;;;;;; |
|
4 |
|
|
|
5 |
|
; All relative paths in this configuration file are relative to PHP's install |
|
6 |
|
; prefix. |
|
7 |
|
|
|
8 |
|
; Include one or more files. If glob(3) exists, it is used to include a bunch of |
|
9 |
|
; files from a glob(3) pattern. This directive can be used everywhere in the |
|
10 |
|
; file. |
|
11 |
|
include=/etc/rocketgit/pool.conf |
|
12 |
|
|
|
13 |
|
;;;;;;;;;;;;;;;;;; |
|
14 |
|
; Global Options ; |
|
15 |
|
;;;;;;;;;;;;;;;;;; |
|
16 |
|
|
|
17 |
|
[global] |
|
18 |
|
; Pid file |
|
19 |
|
; Default Value: none |
|
20 |
|
pid = /run/php-fpm/rocketgit.pid |
|
21 |
|
|
|
22 |
|
; Error log file |
|
23 |
|
; If it's set to "syslog", log is sent to syslogd instead of being written |
|
24 |
|
; in a local file. |
|
25 |
|
; Default Value: /var/log/php-fpm.log |
|
26 |
|
error_log = /var/log/php-fpm/rocketgit.log |
|
27 |
|
|
|
28 |
|
; syslog_facility is used to specify what type of program is logging the |
|
29 |
|
; message. This lets syslogd specify that messages from different facilities |
|
30 |
|
; will be handled differently. |
|
31 |
|
; See syslog(3) for possible values (ex daemon equiv LOG_DAEMON) |
|
32 |
|
; Default Value: daemon |
|
33 |
|
;syslog.facility = daemon |
|
34 |
|
|
|
35 |
|
; syslog_ident is prepended to every message. If you have multiple FPM |
|
36 |
|
; instances running on the same server, you can change the default value |
|
37 |
|
; which must suit common needs. |
|
38 |
|
; Default Value: php-fpm |
|
39 |
|
;syslog.ident = php-fpm |
|
40 |
|
|
|
41 |
|
; Log level |
|
42 |
|
; Possible Values: alert, error, warning, notice, debug |
|
43 |
|
; Default Value: notice |
|
44 |
|
;log_level = notice |
|
45 |
|
|
|
46 |
|
; If this number of child processes exit with SIGSEGV or SIGBUS within the time |
|
47 |
|
; interval set by emergency_restart_interval then FPM will restart. A value |
|
48 |
|
; of '0' means 'Off'. |
|
49 |
|
; Default Value: 0 |
|
50 |
|
;emergency_restart_threshold = 0 |
|
51 |
|
|
|
52 |
|
; Interval of time used by emergency_restart_interval to determine when |
|
53 |
|
; a graceful restart will be initiated. This can be useful to work around |
|
54 |
|
; accidental corruptions in an accelerator's shared memory. |
|
55 |
|
; Available Units: s(econds), m(inutes), h(ours), or d(ays) |
|
56 |
|
; Default Unit: seconds |
|
57 |
|
; Default Value: 0 |
|
58 |
|
;emergency_restart_interval = 0 |
|
59 |
|
|
|
60 |
|
; Time limit for child processes to wait for a reaction on signals from master. |
|
61 |
|
; Available units: s(econds), m(inutes), h(ours), or d(ays) |
|
62 |
|
; Default Unit: seconds |
|
63 |
|
; Default Value: 0 |
|
64 |
|
;process_control_timeout = 0 |
|
65 |
|
|
|
66 |
|
; The maximum number of processes FPM will fork. This has been design to control |
|
67 |
|
; the global number of processes when using dynamic PM within a lot of pools. |
|
68 |
|
; Use it with caution. |
|
69 |
|
; Note: A value of 0 indicates no limit |
|
70 |
|
; Default Value: 0 |
|
71 |
|
;process.max = 128 |
|
72 |
|
|
|
73 |
|
; Specify the nice(2) priority to apply to the master process (only if set) |
|
74 |
|
; The value can vary from -19 (highest priority) to 20 (lower priority) |
|
75 |
|
; Note: - It will only work if the FPM master process is launched as root |
|
76 |
|
; - The pool process will inherit the master process priority |
|
77 |
|
; unless it specified otherwise |
|
78 |
|
; Default Value: no set |
|
79 |
|
;process.priority = -19 |
|
80 |
|
|
|
81 |
|
; Send FPM to background. Set to 'no' to keep FPM in foreground for debugging. |
|
82 |
|
; Default Value: yes |
|
83 |
|
daemonize = no |
|
84 |
|
|
|
85 |
|
; Set open file descriptor rlimit for the master process. |
|
86 |
|
; Default Value: system defined value |
|
87 |
|
;rlimit_files = 1024 |
|
88 |
|
|
|
89 |
|
; Set max core size rlimit for the master process. |
|
90 |
|
; Possible Values: 'unlimited' or an integer greater or equal to 0 |
|
91 |
|
; Default Value: system defined value |
|
92 |
|
;rlimit_core = 0 |
|
93 |
|
|
|
94 |
|
; Specify the event mechanism FPM will use. The following is available: |
|
95 |
|
; - select (any POSIX os) |
|
96 |
|
; - poll (any POSIX os) |
|
97 |
|
; - epoll (linux >= 2.5.44) |
|
98 |
|
; Default Value: not set (auto detection) |
|
99 |
|
;events.mechanism = epoll |
|
100 |
|
|
|
101 |
|
; When FPM is build with systemd integration, specify the interval, |
|
102 |
|
; in second, between health report notification to systemd. |
|
103 |
|
; Set to 0 to disable. |
|
104 |
|
; Available Units: s(econds), m(inutes), h(ours) |
|
105 |
|
; Default Unit: seconds |
|
106 |
|
; Default value: 10 |
|
107 |
|
;systemd_interval = 10 |
File samples/pool.conf added (mode: 100644) (index 0000000..b3bb360) |
|
1 |
|
; Start a new pool named 'rocketgit'. |
|
2 |
|
; the variable $pool can we used in any directive and will be replaced by the |
|
3 |
|
; pool name ('rocketgit' here) |
|
4 |
|
[rocketgit] |
|
5 |
|
|
|
6 |
|
; Per pool prefix |
|
7 |
|
; It only applies on the following directives: |
|
8 |
|
; - 'slowlog' |
|
9 |
|
; - 'listen' (unixsocket) |
|
10 |
|
; - 'chroot' |
|
11 |
|
; - 'chdir' |
|
12 |
|
; - 'php_values' |
|
13 |
|
; - 'php_admin_values' |
|
14 |
|
; When not set, the global prefix (or @php_fpm_prefix@) applies instead. |
|
15 |
|
; Note: This directive can also be relative to the global prefix. |
|
16 |
|
; Default Value: none |
|
17 |
|
;prefix = /path/to/pools/$pool |
|
18 |
|
|
|
19 |
|
; Unix user/group of processes |
|
20 |
|
; Note: The user is mandatory. If the group is not set, the default user's group |
|
21 |
|
; will be used. |
|
22 |
|
; RPM: apache Choosed to be able to access some dir as httpd |
|
23 |
|
user = rocketgit |
|
24 |
|
; RPM: Keep a group allowed to write in log dir. |
|
25 |
|
group = rocketgit |
|
26 |
|
|
|
27 |
|
; The address on which to accept FastCGI requests. |
|
28 |
|
; Valid syntaxes are: |
|
29 |
|
; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific IPv4 address on |
|
30 |
|
; a specific port; |
|
31 |
|
; '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on |
|
32 |
|
; a specific port; |
|
33 |
|
; 'port' - to listen on a TCP socket to all IPv4 addresses on a |
|
34 |
|
; specific port; |
|
35 |
|
; '[::]:port' - to listen on a TCP socket to all addresses |
|
36 |
|
; (IPv6 and IPv4-mapped) on a specific port; |
|
37 |
|
; '/path/to/unix/socket' - to listen on a unix socket. |
|
38 |
|
; Note: This value is mandatory. |
|
39 |
|
listen = /run/php-fpm/rocketgit.sock |
|
40 |
|
|
|
41 |
|
; Set listen(2) backlog. |
|
42 |
|
; Default Value: 65535 |
|
43 |
|
;listen.backlog = 65535 |
|
44 |
|
|
|
45 |
|
; Set permissions for unix socket, if one is used. In Linux, read/write |
|
46 |
|
; permissions must be set in order to allow connections from a web server. |
|
47 |
|
; Default Values: user and group are set as the running user |
|
48 |
|
; mode is set to 0660 |
|
49 |
|
;listen.owner = nobody |
|
50 |
|
;listen.group = nobody |
|
51 |
|
;listen.mode = 0660 |
|
52 |
|
|
|
53 |
|
; When POSIX Access Control Lists are supported you can set them using |
|
54 |
|
; these options, value is a comma separated list of user/group names. |
|
55 |
|
; When set, listen.owner and listen.group are ignored |
|
56 |
|
listen.acl_users = apache,nginx |
|
57 |
|
;listen.acl_groups = |
|
58 |
|
|
|
59 |
|
; List of addresses (IPv4/IPv6) of FastCGI clients which are allowed to connect. |
|
60 |
|
; Equivalent to the FCGI_WEB_SERVER_ADDRS environment variable in the original |
|
61 |
|
; PHP FCGI (5.2.2+). Makes sense only with a tcp listening socket. Each address |
|
62 |
|
; must be separated by a comma. If this value is left blank, connections will be |
|
63 |
|
; accepted from any ip address. |
|
64 |
|
; Default Value: any |
|
65 |
|
listen.allowed_clients = 127.0.0.1 |
|
66 |
|
|
|
67 |
|
; Specify the nice(2) priority to apply to the pool processes (only if set) |
|
68 |
|
; The value can vary from -19 (highest priority) to 20 (lower priority) |
|
69 |
|
; Note: - It will only work if the FPM master process is launched as root |
|
70 |
|
; - The pool processes will inherit the master process priority |
|
71 |
|
; unless it specified otherwise |
|
72 |
|
; Default Value: no set |
|
73 |
|
; process.priority = -19 |
|
74 |
|
|
|
75 |
|
; Choose how the process manager will control the number of child processes. |
|
76 |
|
; Possible Values: |
|
77 |
|
; static - a fixed number (pm.max_children) of child processes; |
|
78 |
|
; dynamic - the number of child processes are set dynamically based on the |
|
79 |
|
; following directives. With this process management, there will be |
|
80 |
|
; always at least 1 children. |
|
81 |
|
; pm.max_children - the maximum number of children that can |
|
82 |
|
; be alive at the same time. |
|
83 |
|
; pm.start_servers - the number of children created on startup. |
|
84 |
|
; pm.min_spare_servers - the minimum number of children in 'idle' |
|
85 |
|
; state (waiting to process). If the number |
|
86 |
|
; of 'idle' processes is less than this |
|
87 |
|
; number then some children will be created. |
|
88 |
|
; pm.max_spare_servers - the maximum number of children in 'idle' |
|
89 |
|
; state (waiting to process). If the number |
|
90 |
|
; of 'idle' processes is greater than this |
|
91 |
|
; number then some children will be killed. |
|
92 |
|
; ondemand - no children are created at startup. Children will be forked when |
|
93 |
|
; new requests will connect. The following parameter are used: |
|
94 |
|
; pm.max_children - the maximum number of children that |
|
95 |
|
; can be alive at the same time. |
|
96 |
|
; pm.process_idle_timeout - The number of seconds after which |
|
97 |
|
; an idle process will be killed. |
|
98 |
|
; Note: This value is mandatory. |
|
99 |
|
pm = dynamic |
|
100 |
|
|
|
101 |
|
; The number of child processes to be created when pm is set to 'static' and the |
|
102 |
|
; maximum number of child processes when pm is set to 'dynamic' or 'ondemand'. |
|
103 |
|
; This value sets the limit on the number of simultaneous requests that will be |
|
104 |
|
; served. Equivalent to the ApacheMaxClients directive with mpm_prefork. |
|
105 |
|
; Equivalent to the PHP_FCGI_CHILDREN environment variable in the original PHP |
|
106 |
|
; CGI. The below defaults are based on a server without much resources. Don't |
|
107 |
|
; forget to tweak pm.* to fit your needs. |
|
108 |
|
; Note: Used when pm is set to 'static', 'dynamic' or 'ondemand' |
|
109 |
|
; Note: This value is mandatory. |
|
110 |
|
pm.max_children = 50 |
|
111 |
|
|
|
112 |
|
; The number of child processes created on startup. |
|
113 |
|
; Note: Used only when pm is set to 'dynamic' |
|
114 |
|
; Default Value: min_spare_servers + (max_spare_servers - min_spare_servers) / 2 |
|
115 |
|
pm.start_servers = 5 |
|
116 |
|
|
|
117 |
|
; The desired minimum number of idle server processes. |
|
118 |
|
; Note: Used only when pm is set to 'dynamic' |
|
119 |
|
; Note: Mandatory when pm is set to 'dynamic' |
|
120 |
|
pm.min_spare_servers = 5 |
|
121 |
|
|
|
122 |
|
; The desired maximum number of idle server processes. |
|
123 |
|
; Note: Used only when pm is set to 'dynamic' |
|
124 |
|
; Note: Mandatory when pm is set to 'dynamic' |
|
125 |
|
pm.max_spare_servers = 10 |
|
126 |
|
|
|
127 |
|
; The number of seconds after which an idle process will be killed. |
|
128 |
|
; Note: Used only when pm is set to 'ondemand' |
|
129 |
|
; Default Value: 10s |
|
130 |
|
;pm.process_idle_timeout = 10s; |
|
131 |
|
pm.process_idle_timeout = 30s; |
|
132 |
|
|
|
133 |
|
; The number of requests each child process should execute before respawning. |
|
134 |
|
; This can be useful to work around memory leaks in 3rd party libraries. For |
|
135 |
|
; endless request processing specify '0'. Equivalent to PHP_FCGI_MAX_REQUESTS. |
|
136 |
|
; Default Value: 0 |
|
137 |
|
;pm.max_requests = 500 |
|
138 |
|
|
|
139 |
|
; The URI to view the FPM status page. If this value is not set, no URI will be |
|
140 |
|
; recognized as a status page. It shows the following informations: |
|
141 |
|
; pool - the name of the pool; |
|
142 |
|
; process manager - static, dynamic or ondemand; |
|
143 |
|
; start time - the date and time FPM has started; |
|
144 |
|
; start since - number of seconds since FPM has started; |
|
145 |
|
; accepted conn - the number of request accepted by the pool; |
|
146 |
|
; listen queue - the number of request in the queue of pending |
|
147 |
|
; connections (see backlog in listen(2)); |
|
148 |
|
; max listen queue - the maximum number of requests in the queue |
|
149 |
|
; of pending connections since FPM has started; |
|
150 |
|
; listen queue len - the size of the socket queue of pending connections; |
|
151 |
|
; idle processes - the number of idle processes; |
|
152 |
|
; active processes - the number of active processes; |
|
153 |
|
; total processes - the number of idle + active processes; |
|
154 |
|
; max active processes - the maximum number of active processes since FPM |
|
155 |
|
; has started; |
|
156 |
|
; max children reached - number of times, the process limit has been reached, |
|
157 |
|
; when pm tries to start more children (works only for |
|
158 |
|
; pm 'dynamic' and 'ondemand'); |
|
159 |
|
; Value are updated in real time. |
|
160 |
|
; Example output: |
|
161 |
|
; pool: www |
|
162 |
|
; process manager: static |
|
163 |
|
; start time: 01/Jul/2011:17:53:49 +0200 |
|
164 |
|
; start since: 62636 |
|
165 |
|
; accepted conn: 190460 |
|
166 |
|
; listen queue: 0 |
|
167 |
|
; max listen queue: 1 |
|
168 |
|
; listen queue len: 42 |
|
169 |
|
; idle processes: 4 |
|
170 |
|
; active processes: 11 |
|
171 |
|
; total processes: 15 |
|
172 |
|
; max active processes: 12 |
|
173 |
|
; max children reached: 0 |
|
174 |
|
; |
|
175 |
|
; By default the status page output is formatted as text/plain. Passing either |
|
176 |
|
; 'html', 'xml' or 'json' in the query string will return the corresponding |
|
177 |
|
; output syntax. Example: |
|
178 |
|
; http://www.foo.bar/status |
|
179 |
|
; http://www.foo.bar/status?json |
|
180 |
|
; http://www.foo.bar/status?html |
|
181 |
|
; http://www.foo.bar/status?xml |
|
182 |
|
; |
|
183 |
|
; By default the status page only outputs short status. Passing 'full' in the |
|
184 |
|
; query string will also return status for each pool process. |
|
185 |
|
; Example: |
|
186 |
|
; http://www.foo.bar/status?full |
|
187 |
|
; http://www.foo.bar/status?json&full |
|
188 |
|
; http://www.foo.bar/status?html&full |
|
189 |
|
; http://www.foo.bar/status?xml&full |
|
190 |
|
; The Full status returns for each process: |
|
191 |
|
; pid - the PID of the process; |
|
192 |
|
; state - the state of the process (Idle, Running, ...); |
|
193 |
|
; start time - the date and time the process has started; |
|
194 |
|
; start since - the number of seconds since the process has started; |
|
195 |
|
; requests - the number of requests the process has served; |
|
196 |
|
; request duration - the duration in µs of the requests; |
|
197 |
|
; request method - the request method (GET, POST, ...); |
|
198 |
|
; request URI - the request URI with the query string; |
|
199 |
|
; content length - the content length of the request (only with POST); |
|
200 |
|
; user - the user (PHP_AUTH_USER) (or '-' if not set); |
|
201 |
|
; script - the main script called (or '-' if not set); |
|
202 |
|
; last request cpu - the %cpu the last request consumed |
|
203 |
|
; it's always 0 if the process is not in Idle state |
|
204 |
|
; because CPU calculation is done when the request |
|
205 |
|
; processing has terminated; |
|
206 |
|
; last request memory - the max amount of memory the last request consumed |
|
207 |
|
; it's always 0 if the process is not in Idle state |
|
208 |
|
; because memory calculation is done when the request |
|
209 |
|
; processing has terminated; |
|
210 |
|
; If the process is in Idle state, then informations are related to the |
|
211 |
|
; last request the process has served. Otherwise informations are related to |
|
212 |
|
; the current request being served. |
|
213 |
|
; Example output: |
|
214 |
|
; ************************ |
|
215 |
|
; pid: 31330 |
|
216 |
|
; state: Running |
|
217 |
|
; start time: 01/Jul/2011:17:53:49 +0200 |
|
218 |
|
; start since: 63087 |
|
219 |
|
; requests: 12808 |
|
220 |
|
; request duration: 1250261 |
|
221 |
|
; request method: GET |
|
222 |
|
; request URI: /test_mem.php?N=10000 |
|
223 |
|
; content length: 0 |
|
224 |
|
; user: - |
|
225 |
|
; script: /home/fat/web/docs/php/test_mem.php |
|
226 |
|
; last request cpu: 0.00 |
|
227 |
|
; last request memory: 0 |
|
228 |
|
; |
|
229 |
|
; Note: There is a real-time FPM status monitoring sample web page available |
|
230 |
|
; It's available in: @EXPANDED_DATADIR@/fpm/status.html |
|
231 |
|
; |
|
232 |
|
; Note: The value must start with a leading slash (/). The value can be |
|
233 |
|
; anything, but it may not be a good idea to use the .php extension or it |
|
234 |
|
; may conflict with a real PHP file. |
|
235 |
|
; Default Value: not set |
|
236 |
|
;pm.status_path = /status |
|
237 |
|
|
|
238 |
|
; The ping URI to call the monitoring page of FPM. If this value is not set, no |
|
239 |
|
; URI will be recognized as a ping page. This could be used to test from outside |
|
240 |
|
; that FPM is alive and responding, or to |
|
241 |
|
; - create a graph of FPM availability (rrd or such); |
|
242 |
|
; - remove a server from a group if it is not responding (load balancing); |
|
243 |
|
; - trigger alerts for the operating team (24/7). |
|
244 |
|
; Note: The value must start with a leading slash (/). The value can be |
|
245 |
|
; anything, but it may not be a good idea to use the .php extension or it |
|
246 |
|
; may conflict with a real PHP file. |
|
247 |
|
; Default Value: not set |
|
248 |
|
;ping.path = /ping |
|
249 |
|
|
|
250 |
|
; This directive may be used to customize the response of a ping request. The |
|
251 |
|
; response is formatted as text/plain with a 200 response code. |
|
252 |
|
; Default Value: pong |
|
253 |
|
;ping.response = pong |
|
254 |
|
|
|
255 |
|
; The access log file |
|
256 |
|
; Default: not set |
|
257 |
|
;access.log = log/$pool.access.log |
|
258 |
|
|
|
259 |
|
; The access log format. |
|
260 |
|
; The following syntax is allowed |
|
261 |
|
; %%: the '%' character |
|
262 |
|
; %C: %CPU used by the request |
|
263 |
|
; it can accept the following format: |
|
264 |
|
; - %{user}C for user CPU only |
|
265 |
|
; - %{system}C for system CPU only |
|
266 |
|
; - %{total}C for user + system CPU (default) |
|
267 |
|
; %d: time taken to serve the request |
|
268 |
|
; it can accept the following format: |
|
269 |
|
; - %{seconds}d (default) |
|
270 |
|
; - %{miliseconds}d |
|
271 |
|
; - %{mili}d |
|
272 |
|
; - %{microseconds}d |
|
273 |
|
; - %{micro}d |
|
274 |
|
; %e: an environment variable (same as $_ENV or $_SERVER) |
|
275 |
|
; it must be associated with embraces to specify the name of the env |
|
276 |
|
; variable. Some exemples: |
|
277 |
|
; - server specifics like: %{REQUEST_METHOD}e or %{SERVER_PROTOCOL}e |
|
278 |
|
; - HTTP headers like: %{HTTP_HOST}e or %{HTTP_USER_AGENT}e |
|
279 |
|
; %f: script filename |
|
280 |
|
; %l: content-length of the request (for POST request only) |
|
281 |
|
; %m: request method |
|
282 |
|
; %M: peak of memory allocated by PHP |
|
283 |
|
; it can accept the following format: |
|
284 |
|
; - %{bytes}M (default) |
|
285 |
|
; - %{kilobytes}M |
|
286 |
|
; - %{kilo}M |
|
287 |
|
; - %{megabytes}M |
|
288 |
|
; - %{mega}M |
|
289 |
|
; %n: pool name |
|
290 |
|
; %o: output header |
|
291 |
|
; it must be associated with embraces to specify the name of the header: |
|
292 |
|
; - %{Content-Type}o |
|
293 |
|
; - %{X-Powered-By}o |
|
294 |
|
; - %{Transfert-Encoding}o |
|
295 |
|
; - .... |
|
296 |
|
; %p: PID of the child that serviced the request |
|
297 |
|
; %P: PID of the parent of the child that serviced the request |
|
298 |
|
; %q: the query string |
|
299 |
|
; %Q: the '?' character if query string exists |
|
300 |
|
; %r: the request URI (without the query string, see %q and %Q) |
|
301 |
|
; %R: remote IP address |
|
302 |
|
; %s: status (response code) |
|
303 |
|
; %t: server time the request was received |
|
304 |
|
; it can accept a strftime(3) format: |
|
305 |
|
; %d/%b/%Y:%H:%M:%S %z (default) |
|
306 |
|
; %T: time the log has been written (the request has finished) |
|
307 |
|
; it can accept a strftime(3) format: |
|
308 |
|
; %d/%b/%Y:%H:%M:%S %z (default) |
|
309 |
|
; %u: remote user |
|
310 |
|
; |
|
311 |
|
; Default: "%R - %u %t \"%m %r\" %s" |
|
312 |
|
;access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%" |
|
313 |
|
|
|
314 |
|
; The log file for slow requests |
|
315 |
|
; Default Value: not set |
|
316 |
|
; Note: slowlog is mandatory if request_slowlog_timeout is set |
|
317 |
|
slowlog = /var/log/php-fpm/rocketgit-slow.log |
|
318 |
|
|
|
319 |
|
; The timeout for serving a single request after which a PHP backtrace will be |
|
320 |
|
; dumped to the 'slowlog' file. A value of '0s' means 'off'. |
|
321 |
|
; Available units: s(econds)(default), m(inutes), h(ours), or d(ays) |
|
322 |
|
; Default Value: 0 |
|
323 |
|
;request_slowlog_timeout = 0 |
|
324 |
|
request_slowlog_timeout = 2s |
|
325 |
|
|
|
326 |
|
; The timeout for serving a single request after which the worker process will |
|
327 |
|
; be killed. This option should be used when the 'max_execution_time' ini option |
|
328 |
|
; does not stop script execution for some reason. A value of '0' means 'off'. |
|
329 |
|
; Available units: s(econds)(default), m(inutes), h(ours), or d(ays) |
|
330 |
|
; Default Value: 0 |
|
331 |
|
;request_terminate_timeout = 0 |
|
332 |
|
|
|
333 |
|
; Set open file descriptor rlimit. |
|
334 |
|
; Default Value: system defined value |
|
335 |
|
;rlimit_files = 1024 |
|
336 |
|
|
|
337 |
|
; Set max core size rlimit. |
|
338 |
|
; Possible Values: 'unlimited' or an integer greater or equal to 0 |
|
339 |
|
; Default Value: system defined value |
|
340 |
|
;rlimit_core = 0 |
|
341 |
|
|
|
342 |
|
; Chroot to this directory at the start. This value must be defined as an |
|
343 |
|
; absolute path. When this value is not set, chroot is not used. |
|
344 |
|
; Note: you can prefix with '$prefix' to chroot to the pool prefix or one |
|
345 |
|
; of its subdirectories. If the pool prefix is not set, the global prefix |
|
346 |
|
; will be used instead. |
|
347 |
|
; Note: chrooting is a great security feature and should be used whenever |
|
348 |
|
; possible. However, all PHP paths will be relative to the chroot |
|
349 |
|
; (error_log, sessions.save_path, ...). |
|
350 |
|
; Default Value: not set |
|
351 |
|
;chroot = |
|
352 |
|
|
|
353 |
|
; Chdir to this directory at the start. |
|
354 |
|
; Note: relative path can be used. |
|
355 |
|
; Default Value: current directory or / when chroot |
|
356 |
|
;chdir = /var/www |
|
357 |
|
|
|
358 |
|
; Redirect worker stdout and stderr into main error log. If not set, stdout and |
|
359 |
|
; stderr will be redirected to /dev/null according to FastCGI specs. |
|
360 |
|
; Note: on highloaded environement, this can cause some delay in the page |
|
361 |
|
; process time (several ms). |
|
362 |
|
; Default Value: no |
|
363 |
|
;catch_workers_output = yes |
|
364 |
|
|
|
365 |
|
; Clear environment in FPM workers |
|
366 |
|
; Prevents arbitrary environment variables from reaching FPM worker processes |
|
367 |
|
; by clearing the environment in workers before env vars specified in this |
|
368 |
|
; pool configuration are added. |
|
369 |
|
; Setting to "no" will make all environment variables available to PHP code |
|
370 |
|
; via getenv(), $_ENV and $_SERVER. |
|
371 |
|
; Default Value: yes |
|
372 |
|
;clear_env = no |
|
373 |
|
|
|
374 |
|
; Limits the extensions of the main script FPM will allow to parse. This can |
|
375 |
|
; prevent configuration mistakes on the web server side. You should only limit |
|
376 |
|
; FPM to .php extensions to prevent malicious users to use other extensions to |
|
377 |
|
; exectute php code. |
|
378 |
|
; Note: set an empty value to allow all extensions. |
|
379 |
|
; Default Value: .php |
|
380 |
|
;security.limit_extensions = .php .php3 .php4 .php5 |
|
381 |
|
|
|
382 |
|
; Pass environment variables like LD_LIBRARY_PATH. All $VARIABLEs are taken from |
|
383 |
|
; the current environment. |
|
384 |
|
; Default Value: clean env |
|
385 |
|
;env[HOSTNAME] = $HOSTNAME |
|
386 |
|
;env[PATH] = /usr/local/bin:/usr/bin:/bin |
|
387 |
|
;env[TMP] = /tmp |
|
388 |
|
;env[TMPDIR] = /tmp |
|
389 |
|
;env[TEMP] = /tmp |
|
390 |
|
|
|
391 |
|
; Additional php.ini defines, specific to this pool of workers. These settings |
|
392 |
|
; overwrite the values previously defined in the php.ini. The directives are the |
|
393 |
|
; same as the PHP SAPI: |
|
394 |
|
; php_value/php_flag - you can set classic ini defines which can |
|
395 |
|
; be overwritten from PHP call 'ini_set'. |
|
396 |
|
; php_admin_value/php_admin_flag - these directives won't be overwritten by |
|
397 |
|
; PHP call 'ini_set' |
|
398 |
|
; For php_*flag, valid values are on, off, 1, 0, true, false, yes or no. |
|
399 |
|
|
|
400 |
|
; Defining 'extension' will load the corresponding shared extension from |
|
401 |
|
; extension_dir. Defining 'disable_functions' or 'disable_classes' will not |
|
402 |
|
; overwrite previously defined php.ini values, but will append the new value |
|
403 |
|
; instead. |
|
404 |
|
|
|
405 |
|
; Note: path INI options can be relative and will be expanded with the prefix |
|
406 |
|
; (pool, global or @prefix@) |
|
407 |
|
|
|
408 |
|
; Default Value: nothing is defined by default except the values in php.ini and |
|
409 |
|
; specified at startup with the -d argument |
|
410 |
|
;php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f www@my.domain.com |
|
411 |
|
;php_flag[display_errors] = off |
|
412 |
|
php_admin_value[error_log] = /var/log/rocketgit/pool-error.log |
|
413 |
|
php_admin_flag[log_errors] = on |
|
414 |
|
php_admin_value[memory_limit] = 32M |
File scripts/remote.php changed (mode: 100644) (index b03344f..3b8d13c) |
... |
... |
rg_prof_start("remote.php"); |
23 |
23 |
|
|
24 |
24 |
rg_log_set_file($rg_log_dir . "/remote.log"); |
rg_log_set_file($rg_log_dir . "/remote.log"); |
25 |
25 |
|
|
26 |
|
function git_output($str) |
|
27 |
|
{ |
|
28 |
|
echo sprintf("%04x", 4 + 4 + strlen($str)) . 'ERR ' . $str; |
|
29 |
|
} |
|
30 |
|
|
|
31 |
26 |
function info($str) |
function info($str) |
32 |
27 |
{ |
{ |
33 |
28 |
rg_log("Sending: " . $str); |
rg_log("Sending: " . $str); |
|
... |
... |
function fatal($str) |
53 |
48 |
// But, keep in mind that at least git archive --remote |
// But, keep in mind that at least git archive --remote |
54 |
49 |
// expects a 4 byte len! |
// expects a 4 byte len! |
55 |
50 |
//echo "\n" . $str2; |
//echo "\n" . $str2; |
56 |
|
git_output($str2); |
|
|
51 |
|
echo rg_git_pack('ERR ' . $str2); |
57 |
52 |
} |
} |
58 |
53 |
exit(1); |
exit(1); |
59 |
54 |
} |
} |
|
... |
... |
if (isset($_SERVER['SSH_CONNECTION'])) { |
110 |
105 |
info('== Welcome to RocketGit! =='); |
info('== Welcome to RocketGit! =='); |
111 |
106 |
info('you are connecting from IP ' . $ip . '.'); |
info('you are connecting from IP ' . $ip . '.'); |
112 |
107 |
|
|
113 |
|
$conn_ui = rg_user_info($db, $login_uid, '', ''); |
|
114 |
|
if ($conn_ui['exists'] != 1) |
|
|
108 |
|
$login_ui = rg_user_info($db, $login_uid, '', ''); |
|
109 |
|
if ($login_ui['exists'] != 1) |
115 |
110 |
fatal("User does not exists (conn)."); |
fatal("User does not exists (conn)."); |
116 |
|
info('you are connecting as user \'' . $conn_ui['username'] . '\'.'); |
|
|
111 |
|
info('you are connecting as user \'' . $login_ui['username'] . '\'.'); |
117 |
112 |
|
|
118 |
|
putenv('ROCKETGIT_INFO_SHOW=1'); |
|
|
113 |
|
putenv('ROCKETGIT_SHOW_INFO=0'); |
119 |
114 |
|
|
120 |
115 |
// Only normal keys can execute some commands |
// Only normal keys can execute some commands |
121 |
116 |
if (strstr($flags, 'N')) |
if (strstr($flags, 'N')) |
|
... |
... |
if (isset($_SERVER['SSH_CONNECTION'])) { |
128 |
123 |
// We do this operation after dispatch to not impact the latency. |
// We do this operation after dispatch to not impact the latency. |
129 |
124 |
// TODO: This should be put in a queue for performance reasons |
// TODO: This should be put in a queue for performance reasons |
130 |
125 |
// At the same time, update stats? events? |
// At the same time, update stats? events? |
131 |
|
$_r = rg_keys_update_use($db, $conn_ui['uid'], $key_id, $ip, |
|
|
126 |
|
$_r = rg_keys_update_use($db, $login_ui['uid'], $key_id, $ip, |
132 |
127 |
$cmd_repo); |
$cmd_repo); |
133 |
128 |
if ($_r !== TRUE) |
if ($_r !== TRUE) |
134 |
129 |
rg_internal_error("Cannot update key last_use!"); |
rg_internal_error("Cannot update key last_use!"); |
|
... |
... |
if (isset($_SERVER['SSH_CONNECTION'])) { |
146 |
141 |
$login_uid = 0; |
$login_uid = 0; |
147 |
142 |
$key_id = 0; |
$key_id = 0; |
148 |
143 |
$flags = ''; |
$flags = ''; |
149 |
|
$conn_ui = array('uid' => 0, |
|
|
144 |
|
$login_ui = array('uid' => 0, |
150 |
145 |
'username' => 'anonymous user', |
'username' => 'anonymous user', |
151 |
146 |
'organization' => 0); |
'organization' => 0); |
152 |
147 |
|
|
|
... |
... |
if (isset($_SERVER['SSH_CONNECTION'])) { |
170 |
165 |
$ip = rg_fix_ip(getenv("REMOTE_HOST")); |
$ip = rg_fix_ip(getenv("REMOTE_HOST")); |
171 |
166 |
} |
} |
172 |
167 |
|
|
173 |
|
// Extracts command and computes permissions |
|
174 |
168 |
if (strncasecmp($cmd_repo, "git-upload-pack", 15) == 0) { |
if (strncasecmp($cmd_repo, "git-upload-pack", 15) == 0) { |
175 |
|
$cmd = "git-upload-pack"; |
|
176 |
|
$needed_rights = "F"; |
|
177 |
|
$push = 0; |
|
178 |
|
} else if (strncasecmp($cmd_repo, "git-receive-pack", 16) == 0) { |
|
179 |
|
$cmd = "git-receive-pack"; |
|
180 |
|
// We need push or anonymous push |
|
181 |
|
$needed_rights = "P|H"; |
|
182 |
|
$push = 1; |
|
|
169 |
|
$cmd = 'git-upload-pack'; |
|
170 |
|
} else if (strncasecmp($cmd_repo ', "git-receive-pack', 16) == 0) { |
|
171 |
|
$cmd = 'git-receive-pack'; |
183 |
172 |
} else { |
} else { |
184 |
|
rg_log("Unknown command [$cmd_repo]"); |
|
185 |
|
fatal("Unknown command!"); |
|
|
173 |
|
$cmd = $cmd_repo; |
186 |
174 |
} |
} |
187 |
175 |
|
|
188 |
176 |
// extract repository name |
// extract repository name |
|
... |
... |
if (strstr($flags, 'W')) { |
209 |
197 |
fatal('A worker can only clone!'); |
fatal('A worker can only clone!'); |
210 |
198 |
} |
} |
211 |
199 |
|
|
212 |
|
// validity/security checks |
|
213 |
|
// Load info about the owner |
|
214 |
|
if (rg_user_ok($user) !== TRUE) |
|
215 |
|
fatal("User [$user] is invalid (" . rg_user_error() . ")!"); |
|
216 |
|
$owner_ui = rg_user_info($db, 0, $user, ""); |
|
217 |
|
if ($owner_ui['ok'] != 1) |
|
218 |
|
fatal("Internal problems. Try again later, please."); |
|
219 |
|
if ($owner_ui['exists'] != 1) |
|
220 |
|
fatal("User does not exists."); |
|
221 |
|
|
|
222 |
|
// Loading info about the repository |
|
223 |
|
if (rg_repo_ok($repo) !== TRUE) |
|
224 |
|
fatal("Repo is invalid (" . rg_repo_error() . ")"); |
|
225 |
|
$ri = rg_repo_info($db, 0, $owner_ui['uid'], $repo); |
|
226 |
|
if ($ri['ok'] != 1) |
|
227 |
|
fatal("Internal problems. Try again later, please."); |
|
228 |
|
if ($ri['exists'] != 1) |
|
229 |
|
fatal("Repo does not exists."); |
|
230 |
|
if ($ri['deleted'] == 1) |
|
231 |
|
fatal("Repo has been deleted!"); |
|
232 |
|
|
|
233 |
|
$ls = rg_repo_lock_status($db, $ri['repo_id']); |
|
234 |
|
if ($ls['ok'] != 1) |
|
235 |
|
fatal('Could not get lock status: ' . rg_repo_error()); |
|
236 |
|
if (($ls['status'] == 1) && ($conn_ui['uid'] != $ls['uid'])) { |
|
237 |
|
$_u = rg_user_info($db, $ls['uid'], '', ''); |
|
238 |
|
if ($_u['exists'] == 1) |
|
239 |
|
$_user = $_u['username']; |
|
240 |
|
else |
|
241 |
|
$_user = '?'; |
|
242 |
|
fatal('Repository has been locked user ' . $_user |
|
243 |
|
. ' at ' . gmdate('Y-m-d H:i', $ls['itime']) . ' UTC.' |
|
244 |
|
. ' Reason: ' . $ls['reason']); |
|
245 |
|
} |
|
246 |
|
|
|
247 |
|
$repo_path = rg_repo_path_by_id($owner_ui['uid'], $ri['repo_id']); |
|
248 |
|
rg_log("repo_path=$repo_path."); |
|
249 |
|
|
|
250 |
|
// TODO: signal user that the repo moved and provide a hint how to follow |
|
251 |
|
|
|
252 |
|
$x = array(); |
|
253 |
|
$x['obj_id'] = $ri['repo_id']; |
|
254 |
|
$x['type'] = 'repo_refs'; |
|
255 |
|
$x['owner'] = $ri['uid']; |
|
256 |
|
$x['uid'] = $conn_ui['uid']; |
|
257 |
|
$x['username'] = $conn_ui['username']; |
|
258 |
|
$x['needed_rights'] = $needed_rights; |
|
259 |
|
$x['ip'] = $ip; |
|
260 |
|
$x['misc'] = ''; |
|
261 |
|
$ret = rg_rights_allow($db, $x); |
|
262 |
|
if ($ret !== TRUE) |
|
263 |
|
fatal("You have no rights to access this repo!"); |
|
264 |
|
|
|
265 |
|
// If we are enrolled, ask for login token |
|
266 |
|
// For push we always ask for it, for fetch only if repo is NOT public |
|
267 |
|
// And we can ask only if we have a ssh connection. For git protocol we cannot |
|
268 |
|
// because we do not have the username/uid of the connecting user. |
|
269 |
|
if (isset($_SERVER['SSH_CONNECTION'])) { |
|
270 |
|
if (($ri['public'] == 0) || ($push == 1)) { |
|
271 |
|
$r = rg_totp_verify_ip($db, $conn_ui['uid'], $ip); |
|
272 |
|
if (($r['ok'] == 0) && (empty($r['list']))) |
|
273 |
|
fatal(rg_totp_error() . '.'); |
|
274 |
|
} |
|
275 |
|
} |
|
276 |
|
|
|
277 |
|
// TODO: limit per connection |
|
278 |
|
// TODO: limit time and/or cpu |
|
279 |
|
// TODO: limit cpuset |
|
280 |
|
// TODO: limit io |
|
281 |
|
// TODO: put process in a cgroup? |
|
282 |
|
|
|
283 |
|
|
|
284 |
|
if (($push == 1) && rg_user_over_limit($db, $owner_ui, $max)) |
|
285 |
|
fatal("Cannot push: user is over limit" |
|
286 |
|
. " (" . $owner_ui['disk_used_mb']. "MiB >= " . $max . "MiB)"); |
|
287 |
|
|
|
288 |
|
// Put in environment all we need |
|
289 |
|
putenv("ROCKETGIT_LOGIN_UID=" . $login_uid); |
|
290 |
|
putenv("ROCKETGIT_LOGIN_URL=" . rg_re_userpage($conn_ui)); |
|
291 |
|
putenv("ROCKETGIT_KEY_ID=" . $key_id); |
|
292 |
|
putenv("ROCKETGIT_REPO_ID=" . $ri['repo_id']); |
|
293 |
|
putenv("ROCKETGIT_REPO_PATH=" . $repo_path); |
|
294 |
|
putenv("ROCKETGIT_REPO_NAME=" . $ri['name']); |
|
295 |
|
putenv("ROCKETGIT_REPO_UID=" . $ri['uid']); |
|
296 |
|
putenv("ROCKETGIT_REPO_CLONE_URL=" . $ri['clone_url']); |
|
297 |
|
putenv("ROCKETGIT_IP=$ip"); |
|
298 |
|
putenv("ROCKETGIT_ITIME=" . microtime(TRUE)); |
|
299 |
|
putenv("ROCKETGIT_HOST=" . $host); |
|
300 |
|
if ($push == 1) { |
|
301 |
|
$namespace = "rg_" . rg_id(8); |
|
302 |
|
rg_log("namespace is $namespace."); |
|
303 |
|
putenv("GIT_NAMESPACE=" . $namespace); |
|
304 |
|
|
|
305 |
|
// Prepare refs to avoid the following message: |
|
306 |
|
// "No refs in common and none specified; doing nothing. |
|
307 |
|
// Perhaps you should specify a branch such as 'master'." |
|
308 |
|
$dst = $repo_path . '/refs/namespaces/' . $namespace . '/refs'; |
|
309 |
|
$r = rg_copy_tree($repo_path . '/refs/heads', $dst . '/heads/', 0755); |
|
310 |
|
if ($r !== TRUE) |
|
311 |
|
fatal("Internal error (cannot copy heads)"); |
|
312 |
|
$r = rg_copy_tree($repo_path . '/refs/tags', $dst . '/tags/', 0755); |
|
313 |
|
if ($r !== TRUE) |
|
314 |
|
fatal("Internal error (cannot copy tags)"); |
|
315 |
|
} |
|
|
200 |
|
$r = rg_repo_fetch_push_helper($db, $host, $ip, $login_ui, $prefix, $user, |
|
201 |
|
$repo, $cmd, TRUE /*need_namespace_copy*/); |
|
202 |
|
if ($r['ok'] != 1) |
|
203 |
|
fatal($r['error']); |
316 |
204 |
|
|
317 |
205 |
$run = "git-shell -c \"" . $cmd . " " . escapeshellarg($repo_path) . "\""; |
$run = "git-shell -c \"" . $cmd . " " . escapeshellarg($repo_path) . "\""; |
318 |
206 |
$run = $cmd . ' ' . escapeshellarg($repo_path); |
$run = $cmd . ' ' . escapeshellarg($repo_path); |
319 |
207 |
rg_log("Running [$run]..."); |
rg_log("Running [$run]..."); |
320 |
208 |
rg_prof_start($cmd); |
rg_prof_start($cmd); |
|
209 |
|
// TODO: shouldn't we use rg_exec to capture stderr? |
321 |
210 |
passthru($run, $ret); |
passthru($run, $ret); |
322 |
211 |
rg_prof_end($cmd); |
rg_prof_end($cmd); |
323 |
212 |
rg_log("[$run] returned $ret."); |
rg_log("[$run] returned $ret."); |