Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GS and symblinks #582

Open
tablatronix opened this issue May 31, 2013 · 34 comments
Open

GS and symblinks #582

tablatronix opened this issue May 31, 2013 · 34 comments
Labels
Milestone

Comments

@tablatronix
Copy link
Member

reposting from #580

but due to the way GS "calculates" its position in the filesystem (basename of FILE), it does not work when
a/ the site directory is symlinked,
b/ the admin/ directory is symlinked.

@aoloe
Copy link

aoloe commented May 31, 2013

the easiest way to solve the problem might be to allow the definition of GSADMIN (already there) and GSROOTPATH in gsconfig.php.
i don't really like the way the path is currently guessed, but for the standard cases it seems to be working good enough...

@tablatronix
Copy link
Member Author

That is why this issue is still open.
#384

@tablatronix tablatronix added this to the Eventually milestone Jun 26, 2014
@df8oe
Copy link

df8oe commented Aug 28, 2016

I have investigated the following:

You can symlink to every file in admin folder - except the following two:

/admin/inc/common.php
/admin/inc/template_functions.php

I have running a complete getsimple without problems and symlinked every file from external /admin to webdir - except the above two. If I replace one or both of the files with symlinks to external positions site stops working.

@tablatronix
Copy link
Member Author

tablatronix commented Aug 28, 2016

so when you symblink the entire admin folder what happens?
have you tried 3.4 master branch ?

@df8oe
Copy link

df8oe commented Aug 28, 2016

If I symlink complete folder message "This page is temporarily unavailable" appears.

I have looked at the logs and there are many lines where access to data and cache with
"../../data/cache/"
and
"chmod(): No such file or directory"
appeared.

So I think there are relative paths and these fail when starting at symlinked directory..

@tablatronix
Copy link
Member Author

yeah i forgot everything will be relative to the admin folder even gsconfig

@df8oe
Copy link

df8oe commented Aug 28, 2016

Further investigations:

Function get_root_path() declared in template_functions.php returns path of original file and not of symlink (what is mandatory for function if symlink is in web directory).

@tablatronix
Copy link
Member Author

tablatronix commented Aug 28, 2016

it looks like GSROOTPATH is the key here

ohh lol, yes you see that too

So i can either make this a undefined check and you can declare in php ini or htaccess setini.
Or we can try to detect symblinked and original which is probably impossible.

@df8oe
Copy link

df8oe commented Aug 28, 2016

Yes. I think this can be solved if path is calculated in gsconfig.php hich NEVER CAN BE A SYMLINK... If path is calculated inside this file it must always be correct...

@tablatronix
Copy link
Member Author

tablatronix commented Aug 28, 2016

ok so this might be possible, we can always do a link check before loading common, and then we know we are symblinked and modify accordingly.

Or we could just allow overrides of gsrootpath and also allow an auto detect capability by using something other than _FILE_ like scriptname or PHP_SELF although these can cause other problems sometimes.

@df8oe
Copy link

df8oe commented Aug 28, 2016

I think there is more than one possibility to get correct path. The way which is used in template_functions.php returns path of original file instead of symlinked one. I amnot 100% sure that's all but thats one of possibly two issues that prevents symlinking installation... If there is another one I can investigate when first problem is fixed :)

@tablatronix
Copy link
Member Author

tablatronix commented Aug 28, 2016

problem number 2
get_admin_path uses gsroot path, this needs to be handled as well.
fixing this I am having luck using an auto prepend to set GSROOTPATH to dirname(dirname(server[PHP_SELF] ... one could also set in gsconfig

I am unware of what you mean by template_functions, care to elaborate ?

@df8oe
Copy link

df8oe commented Aug 28, 2016

I have hard-coded webdirectory path in template_functions.php get_root_path() return and now I can symlink template_functions.php. Failure again when I symlink common.php, too --> I'll check that now ;)

@df8oe
Copy link

df8oe commented Aug 28, 2016

OK.

Actual state:

  • return of get_root_path is hard coded in template_functions.php. This php now also is a symlink in my test installation.

When I symlink common.php too I got the error:

Fatal error: Cannot redeclare getPageContent() (previously declared in /var/further_path_stuff_of_webdir/admin/inc/caching_functions.php:29) in /var/further_path_stuff_of_place_of_installation/admin/inc/caching_functions.php on line 29

It seems so that the function is identified in the original file and the symlinked file, too. So it is a redeclaration...

@tablatronix
Copy link
Member Author

tablatronix commented Aug 28, 2016

Well I think you might be doing this differently than i am, i am symblinking the entire admin folder not files.
Ill probably have a solution to tonight but it will be on 3.4 we might have to backport it to 3.3 since there is no longer any dev on 3.3 aside from bug fixes

@df8oe
Copy link

df8oe commented Aug 29, 2016

I have found a solution that works for me.

get_root_path now looks like this:

function get_root_path() {
$name = dirname($_SERVER['SCRIPT_FILENAME']);
$pos = strrpos($name,'admin');
return substr($name,0,$pos);
}

Now I can symlink every folder inside admin and every file inside admin.

I do not understand: If I symlink complete folder admin, it is NOT working ???!!!

A folder admin within only symlinks --> works
A symlinked folder admin -->does not work....

@tablatronix
Copy link
Member Author

Interesting. Well there will need to 2 be seprate processes for getting paths when accesing from frontend vs backend but it should be easy to do. Basically the paths change by one level.

Are you using soft links?

@df8oe
Copy link

df8oe commented Aug 30, 2016

Yes I am using softlinks. I have now intensively worked with this GS installationand it works without problems.

The reason why I do not have symlinked complete admin folder from start on was that customers should be able to add their own language files to admin/lang. So I symlinked each file in admin and each folder in admin excluded lang. lang is a real folder and contains symlinks to the preinstalled language files andcustomers canadd their own files to their installation.

@tablatronix
Copy link
Member Author

you could always modify GSLANGPATH i think.

I am having problems where it wont include files, but throws no warnings, very odd. I get function does not exist errors which makes no sense, a require should fatally fail before that.

@tablatronix
Copy link
Member Author

and now it works, no idea what that was about

@tablatronix
Copy link
Member Author

tablatronix commented Aug 30, 2016

ok so this works fairly well in 3.4, i will just have to fix the relative url stuff to be compatible I think.

All i did was define GSROOTPATH and it just works.
In windows

 Directory of C:\bin\web\dev\getsimple\symblink
08/30/2016  11:04 AM    <SYMLINKD>     admin [c:\bin\web\dev\getsimple\symblinksrc\admin]`

I will test linux later.

I think you are gonna have problems with plugins that do their own pathing and do not use definitions for pathing. A quick way to find these might be to change GSADMIN and see what breaks

@df8oe
Copy link

df8oe commented Aug 30, 2016

That sounds good... Will you fix it in 3.3.x, too? I want to stay at the stable version as long as 3.4 is not offered as stable.

@tablatronix
Copy link
Member Author

yeah ill take a look at it, the problem with 3.3 is it uses the gsroot path to get the admin path, so that will have to be rewriten.

@df8oe
Copy link

df8oe commented Aug 30, 2016

Yeahut I think we can relyon adminpath is always admin/ so it can be hard coded.

Many thanks for your work - I love GS.

@df8oe
Copy link

df8oe commented Aug 30, 2016

My keyboard sometimes is eating characters - so there are typos -sorry :/

@tablatronix
Copy link
Member Author

admin path is not always admin

@tablatronix
Copy link
Member Author

The main problem here is that it is almost impossible to get the working directory of a script, you have to use $_SERVER variable which can be wrong or empty, and they are relative paths, not absolute paths, you need to do a lot of substringing which means we need to do all this logic before even including stuff. Alot of the pathing logic was removed because it can be problematic for symlinks ( normal use ).

I think it is better to just allow the user to pass i the paths manually, but this has to be done before gsconfig, so that is another problem.

So i just haev to find out how to do this automatically , or allow users to , without having to set some php env.

@tablatronix
Copy link
Member Author

tablatronix commented Aug 30, 2016

So I have come up with a crazy method of doing this automatically.

Since the following is true

  • GSADMIN is unknown
  • Path depth is unknown ( for example style.php, upload.php are all in subfolders in admin )

We cannot use either of those to calculate the paths.

So I came up with this.

  • Get script DIR and file __DIR__
  • add extra checking here to make sure script dir is correct
  • explode into arrays
  • reverse arrays
  • array diff, we are looking for the first path difference ( this works around not knowing admin name )
  • get first index of diff ( this is our path difference offset )
  • array slice path from index to end
  • change first index to the indexoffset of the script path (replaces the subpath)
  • reverse array back
  • implode with DIRECTORY_SEPERATOR

It should work

@df8oe
Copy link

df8oe commented Aug 30, 2016

=8-|

I am impressed. I agree: that should wok in every circumstance. OK - my solution (simple against this) works for me, too but: there are scenarios where it will not work. Your solution should work... I do not see any possible unclear step.

@tablatronix
Copy link
Member Author

I also have to make exceptions for front end with this also, so it gets complicated fast.

@df8oe
Copy link

df8oe commented Aug 31, 2016

OK. Its very easy for me to change the above function with every update where template_functions.php was changed. So only one problem exists:

After an update it is neccessary to login as admin first. If you do not website is not working. After simply logging in (I think database is updated) everything is ok.

Question: is it possible to automate this process locally on webserver - e.g. by calling a script from command line to do these changes?

@tablatronix
Copy link
Member Author

Yeah that is another thing I encountered, ill have to test out the install and upgrade redirecting.

hmm, yeah I have been meaning to bypass that login thing by making it optional or allowing it if a cookie exists and not necessarily logged in.
I actually will have to look and see how that is implemented, i forget.

@tablatronix
Copy link
Member Author

tablatronix commented Aug 31, 2016

This is 3.4 but it should be the same

common.php

/**
 * service is unavailable
 * performs a service unavailable if front end
 */
function serviceUnavailable(){
    return; // <--  bypass
    if(is_frontend()){
        header('HTTP/1.1 503 Service Temporarily Unavailable');
        header('Status: 503 Service Temporarily Unavailable');
        header('Retry-After: 7200'); // in seconds
        i18n('SERVICE_UNAVAILABLE');
        die();
    }
}

you can just add a return to that and bypass that function.

@tablatronix
Copy link
Member Author

tablatronix commented Aug 31, 2016

more notes

$_SERVER['SCRIPT_FILENAME'] provides the full path, but since it is provided by the server, it can vary and not be reliable, for example it might resolve symlinks on one server and not on another, or just not contain the full path.

I am using getcwd() but it can also return different paths or be blocked on different systems.

#1107

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants