Hosting Mercurial with IIS 6 - python

I'm trying to set up Mercurial repositories to be hosted by IIS under Windows Server 2003. Following this post I installed Python 2.5.4.4 and Mercurial 1.3, set up virtual dir, extracted library.zip and created hgwebdir.config.
However, when I trying to open the http://hostname/hg/hgwebdir.cgi I got an error “The specified CGI application misbehaved by not returning a complete set of HTTP headers.” I did all by best:
Checked IIS mappings to both .py and .cgi extensions. I even tried to use FastCGI with no success.
Created “Hello World” in the same dir and checked that it works fine.
Checked read/exec permissions to Python, IIS and repos directories for IUSR, IWAM and NETWORK SERVICE.
Tried to apply two different patches from Mercurial mailing list. Since they both are old I haven't success with it.
INstalled Sysinternals' procmon and checked for filesystem errors during request. I found nothing except lots of Buffer Overflow results in Python process while it loads it's libraries.
Tried to add 'Content-type: text/html' to the script.
One more thing is when I'm requesting inexistent script file (e.g /hg/inexist.cgi) I have the same error. Nothing helped!

Some more things that I needed to fix:
Where the various HOWTOs say to use c:\whatever\Python26\python.exe -u "%s" "%s" instead use c:\whatever\Python26\python.exe -u -O -B "%s" "%s" -O causes it to also look for .pyo files (not just .py or .pyc, which at least in my version weren't present). -B causes it to not attempt to compile .py files that it finds into .pyo files (which fails due to lacking write permissions)
I'd installed Python 2.7. Mercurial 1.6.2's .pyo files were compiled with Python 2.6. This resulted in a magic number error. Uninstalling 2.7 and installing 2.6.5 fixed this. (If you're reading this at some point in the future, this point may no longer be relevant - check the name of the DLL in Mercurial's directory, or TortoiseHg's directory, depending on where you took library.zip from)
hgwebdir.cgi is now just hgweb.cgi - webdir was integrated into it

In my situation, this error caused by line application = hgwebdir('c:\somewhere\hgweb.config') in hgweb.cgi, it should be application = hgweb('c:\somewhere\hgweb.config').
Besides, uncomment line import cgitb; cgitb.enable() in hgweb.cgi will give you more info about the error( and other errors).
P.S. I use Python 2.6.6 and Mercurial 1.7.3 on Windows Server 2003 with IIS 6.0.

In my case, the critical step that fixed it was using:
c:\whatever\Python26\python.exe -u -O -B "%s" "%s
Before that it was not working with the error:
A problem occurred in a Python script. Here is the sequence of function calls leading up to the error, in the order they occurred.
c:\hg\hgweb.cgi in ()
13 import cgitb; cgitb.enable()
14
15 from mercurial import demandimport; demandimport.enable()
16 from mercurial.hgweb import hgweb, wsgicgi
17 application = hgweb(config)
mercurial undefined, demandimport undefined
<type 'exceptions.ImportError'>: No module named mercurial
args = ('No module named mercurial',)

Finally I got that "no headers" error returned on any python script error, so I checked script with console interpreter and fixed errors in my config file. And of course I should ask this question at ServerFault instead of StackOverflow - the lack of sleep did the job :)

There's a pretty good post at http://vampirebasic.blogspot.com/2009/06/running-mercurial-on-windows.html that'll get you started, but if you need more detail or to go further than the writer did, I've got a 4 part blog post that covers everything you need to know about getting up and running on IIS, including Active Directory integration, pull/push privileges, customization of the UI:
http://www.endswithsaurus.com/2010/05/setting-up-and-configuring-mercurial-in.html
It's worth a read...

Related

Pycharm Django Console No module named 'django_manage_shell' on WSL

I recently started to working on WSL Ubuntu-20.04. There is no problem on running the server. But when I tried to connect the Django Console of Pycharm, I get the error below:
Traceback (most recent call last):
File "<input>", line 7, in <module>
ModuleNotFoundError: No module named 'django_manage_shell'
I checked the consoles interpreter and starting script, tried to add project path, my virtualenv path but nothing worked.
My Django Console Options
This is starting script:
import sys; print('Python %s on %s' % (sys.version, sys.platform))
import django; print('Django %s' % django.get_version())
sys.path.extend([WORKING_DIR_AND_PYTHON_PATHS])
if 'setup' in dir(django): django.setup()
import django_manage_shell; django_manage_shell.run(PROJECT_ROOT)
I had no issues like this when I working on Ubuntu nor Windows. This issue happened with WSL.
So I'm waiting for your helps and thanks a lot for your time.
I'm not on WSL but this question came up when I was searching for a solution and Hassaan AlAnsary's answer helped me.
On Linux, running PyCharm 2022.2.1, with Python in Docker, I got this error and solved it by modifying the starting script in Settings -> Build, Execution, Deployment -> Console -> Django Console.
I took the line:
sys.path.extend([WORKING_DIR_AND_PYTHON_PATHS])
and I added the location of the helper in the Docker container:
sys.path.extend([WORKING_DIR_AND_PYTHON_PATHS, "/opt/.pycharm_helpers/pycharm"])
and this fixed the problem.
So, I have a terrible workaround for this, and I will leave it here for fellow travelers passing through this lonely part of StackOverflow. But I hope someone else can do better.
The django_manage_shell module is coming from PyCharm's helpers, and isn't part of the normal Django distribution. When running under WSL, these helpers are not accessible to the python interpreter, and you get the above error.
The best solution I was able to arrive at was to make the code in that helper module accessible in the startup script. Fortunately, you can get at this module (and the fix_getpass module it relies on) with only mild difficulty. The code for each can be found in these spots (depending on your PyCharm installation):
C:\Program Files\JetBrains\PyCharm 2021.2\plugins\python\helpers\pycharm\django_manage_shell.py
C:\Program Files\JetBrains\PyCharm 2021.2\plugins\python\helpers\pycharm\fix_getpass.py
I took the code I found in those modules, and pasted it into the Django Console startup script in PyCharm. I had to reorganize things a bit, and change the call django_manage_shell.run() to invoke the copied-over code instead.
I cannot stress how brittle and gross this approach is, but I haven't found an alternative. If I figure out a better approach, or if JetBrains fixes this on their own, I'll come back and update this answer.
EDIT: Slight improvement to my original solution, which involved a rogue python module on the WSL side. This avoids polluting your project, and constrains the hack to just the PyCharm side of things.
as #Nacho said, it is because PyCharm can't reach the helpers folder on Windows Host machine from within WSL.
You can add the path to the PyCharm helpers folder to your path mapping.
consequently, all the helper files will be reachable by pycharm
One way to do that is to:
Open Setting -> Build, Execution, Deployment -> Django Console
add new Path Mapping
local path
C:/Program Files/JetBrains/PyCharm 2021.3.3/plugins/python/helpers/pycharm
remote path
/mnt/c/Program Files/JetBrains/PyCharm 2021.3.3/plugins/python/helpers/pycharm
Close the console and open it again
modify the path above according to your PyCharm version and WSL setup
now PyCharm will be able to locate django_manage_shell and any other

Python script installation fails on windows

I'm trying to deploy a larger python project which includes a script on
windows. Installation works fine on UNIX, but on windows it seems
impossible to get the script running. I've created a minimal example on
GitHub to demonstrate
the problem.
When running pip install ., the script is installed to C:\Program Files\Python39\Scripts\hello-world. The directory is contained in the
PATH. My user has read & execute permissions. The hashbang of
hello-world is replaced with #!c:\program files\python39\python.exe,
which also seems correct. However, running hello-world in the console
yields the following error:
C:\Users\malte>hello-world
'hello-world' is not recognized as an internal or external command,
operable program or batch file.
I expected this to work. Why doesn't it? How can I fix this?
I've tried some things, and noticed another strange behavior in this
context. Running shutil.which('hello-world') returns None. If I
rename hello-world to hello-world.exe, then calling hello-world
results in a strange error, most likely because windows
now thinks the script is a binary. That's fine. Except that now
shutil.which('hello-world')
returns 'C:\\Program Files\\Python39\\Scripts\\hello-world.EXE'. Why?
Update
The master branch of the respository now contains a solution that works cross-platform, which I learned from here: https://matthew-brett.github.io/pydagogue/installing_scripts.html.
It's not exactly clear to me, but the following paragraph from the Python documentation seems to state that a script with a hashbang line must have an extension associated with the python launcher in order for windows to recognize it: https://docs.python.org/3/using/windows.html#from-a-script
In other words, it appears that my assumption that using the scripts parameter of setuptools.setup works cross-platform is subject to some conditions which are hidden somewhere in the python documentation.

Use Python on MAMP

I'm slowly migrating from PHP to Python. In particular, as I work in webdev/webdesign I would like to display a basic HTML page using Python, using the following code:
#!/usr/bin/python
print('<html><head></head><body>This is a test</body></html>')
Sending the file online on my host as index.cgi, I've had no problem displaying the content of the file.
The problems start when I try to install the WSGI module on MAMP, or just to make Python work in general with it.
When it go to localhost/index.cgi the content of the file is displayed instead of its results.
I've followed half a dozen tutorials and none seems to work, I always encounter a problem at one point or another. It seems to come from the fact that Apache that comes with MAMP isn't built in a way that lets you add modules to it (such as wsgi).
This is also comes from the fact that I can't find any recent article on how to install Python on MAMP, they all either date from 2008 or 2009, with old versions of MAMP, Python and Macports.
Can somebody points me to the current procedure to make this work ?
EDIT : Ok after finding this article I gathered that MAMP by default don't process CGI scripts outside of the cgi-bin/ folder in MAMP/. So I modified the Apache conf file as explained, it now apparently reads the .cgi file but throws an error 500 with the content shown above. Is the code the culprit or is it MAMP's ?
Got it to work, the problem were the missing CGI interpretation of MAMP outside of the cgi-bin/ folder (see original post) and the missing headers :
print 'Content-type: text/html\n\n'
I've just gone through this process on OSX Catalina with Mamp V5.5
For me I had to follow the following steps:
Make sure your file has the first line:
#!/usr/bin/python
or a path to any valid Python installation or environment. Make sure your python is working correctly.
The file must have the extension cgi e.g.
blah.cgi (not .py)
Then it will work from any folder.
The file must have execute permissions. In terminal:
chmod 755 blah.cgi
The file must send a content type near the beginning ( no brackets for Python versions < 3 ):
print('Content-type: text/html \n\n')
An additional step I would recommend is adding this at the beginning of your page:
import sys
sys.stderr = open("err.log",'w')
Which will route all your error messages to the file err.log in the same directory which is insanely useful for debugging. If your page comes back with 500 Internal Server Error, you should see some errors in err.log file (unless the problem was in initial imports before this statement).
There are other config changes you can make to keep the .py extension but I won't go into that here.
This is just standard CGI, nothing special here, no need for WSGI. You do need to install Python. You can install it wherever you like, as long as your script can find it. You see the line:
#! /usr/bin/python
that is where the script will try to find Python, so change it to your Python installation, or fix your Python installation to be there.

Launching python subprocess has different behavior depending on launcher

I'm attempting to launch Python 2.5 from Python 2.6. The reason for this is a compiled library I'm trying to use (GDAL) isn't supported for the version of Python distributed with another program (ArcGIS).
Here's what I'm attempting to do. The main.py file in Python 2.6:
import subprocess
p = subprocess.Popen(['C:\OSGeo4W\gdal_python_exec.bat', 'X:\\local\\import_tests.py'])
gdal_python_exec.bat is a windows batch script that fires up the 2.5 version of Python I want while also setting up some environment variables:
#echo off
set OSGEO4W_ROOT=C:\OSGeo4W
PATH=%OSGEO4W_ROOT%\bin;%PATH%
for %%f in (%OSGEO4W_ROOT%\etc\ini\*.bat) do call %%f
#echo on
#C:\OSGeo4W\bin\python.exe %1
import_tests.py tries to import gdal:
try:
from osgeo import gdal
raw_input('Imported! (Press enter)')
except Exception, e:
print(e)
raw_input('Failed! (Press enter)')
When I run main.py at a DOS command line as python.exe main.py (that's Arc's 2.6 version of python), things work fine. However, if I take the same script and add it as a 'toolbox' inside the main application and launch it from there, I get a "DLL not found" for the GDAL lib inside the import_tests.py file!
How can this happen when subprocess is the module that's launching a different Python interpreter? Any ideas on what could be happening?
Edit: I can verify that the os.environ['PATH'] variables are the same in both calls.
Edit2: The C:\Program Files\ArcGIS...\Bin directory contained a dll that wasn't compatible with my python bindings. Windows searched the cwd first and attempted to load that dll, failed, then reported a "dll not found" error.
Regardless of whether PATH is correct, a simple test would be to change to a different arbitrary directory and do python.exe C:\full\path\to\main.py. If that reproduces the problem then you know it's some sort of path problem.
Check sys.path, I'll bet that's where the difference is. If that's the case, you probably need to alter the way you make your Python code and libraries are accessible from python.exe, either using the site module or using something else like zc.buildout/zc.recipe.egg's support for generating console_scripts with the correct sys.path baked in.
It appears from comments posted elsewhere that
"The working one is C:\Windows and the broken one is C:\Program Files\ArcGIS...\Bin."
Do a os.chdir to make it work.
[No idea what this really means, the comment was hard to parse.]

Trouble resetting /tmp value to push mercurial changes

I have been using mercurial for about a year and haven't had any issues.
Today I ran into an issue for the first time.
When I try to push to the remote server with
$ hg push
I get the following response
searching for changes
remote: abort: No space left on device
abort: unexpected response: empty string
I googled this issue and found that it is a documented issue, and I found the following excerpt from Mercurial FAQ:
4.28. I get a "no space left" or "disk quota exceeded" on push
I get a "no space left" or "disk quota exceeded" on push, but there is plenty of space or/and I have no quota limit on the device where the remote hg repository is.
The problem comes probably from the fact that mercurial uses /tmp (or one of the directory define by environment variables $TMPDIR, $TEMP or $TMP) to uncompress the bundle received on the wire. The decompression may then reach device limits.
You can of course set $TMPDIR to another location on remote in the default shell configuration file, but it will be potentially used by other processes than mercurial. Another solution is to set a hook in a global .hgrc on remote. See the description of how to set a hook for changing tmp directory on remote when pushing.
I have created the hook in my /etc/mercurial/hgrc file that looks like this
[hooks]
pre-serve.tmpdir = python:hgenviron.settmpdir
and then I am supposed to create hgenviron.py
import os
#see http://docs.python.org/lib/module-tempfile.html
def settmpdir(ui, repo, hooktype, node=None, source=None, **kwargs):
os.environ["TMPDIR"] = "/home/tmp"
The problem I am having is that I don't know how to add this file to $PYTHONPATH in fedora
My operating system is Fedora 12 x86_64
I have python 2.6
I have mercurial 1.6.4
UPDATE:
I just added hgenviron.py to /usr/lib/python2.6/site-packages/hg/hgenviron.py and
PYTHONPATH=$PYTHONPATH:/usr/lib/python2.6/site-packages/hg/hgenviron.py
export PYTHONPATH
to a .sh file in /etc/profile.d, along with the hook in /etc/mercurial/.
However I still get the error:
remote: abort: pre-serve.tmpdir hook is invalid (import of "hgenviron" failed) abort:
no suitable response from remote hg!
The problem is using the wrong import statement. It should be from hg import hgenviron
For setting PYTHONPATH Depends on how/where you want to add it.
In /etc/profile.d you can find a set of scripts that are ran when bash is loaded. /etc/profile is the global file, which calls the scripts and has this comment:
# System wide environment and startup programs, for login setup
# Functions and aliases go in /etc/bashrc
# It's NOT good idea to change this file unless you know what you
# are doing. Much better way is to create custom.sh shell script in
# /etc/profile.d/ to make custom changes to environment. This will
# prevent need for merging in future updates.
/etc/profile is ran when the bash environment is loaded. Locally to the user, you edit ~/.bash_profile or ~/.bashrc (if they doesn't exist, you can create them). These scripts are ran when the specific user logs in. You should examine these files in detail to understand how the environment is created and setup.
You would add something like this:
PYTHONPATH=/home/tmp:$PYTHONPATH
export PYTHONPATH
If you're struggling to get to the bottom of the PYTHONPATH issue, you can specifically state the location of the hgenviron.py file.
pre-serve.tmpdir = python:/var/hg/hgenviron.py:settmpdir
Note that settmpdir is then called with a : rather than . in the original example.

Categories