WebApp configuration in mod_perl 2 environment - perl

I have a web app I'm writing in mod_perl 2. (It's a custom handler module, not registry or perlrun scripts.) There are several configuration options I'd like to have set at server initialization, preferably from a configuration file. The problem I'm having is that I haven't found a good place to pass a filename for my app's config file.
I first tried loading "./app.conf" but the current directory isn't the location of the modules, so it's unpredictable and error-prone. Or, I have to assume some path -- relative or absolute. This is inflexible and could be problematic if the host OS distribution is changed. I don't want to hard-code a path (though, something in /etc may be acceptable if there's just no better way).
I also tried PerlSetVar, but the value isn't available until request time. While this is workable, it means I'm potentially reading a config file from disk at least once per child (thread) init. I would rather load at server init and have an immutable static hash that is part of the spawned environment when a child is created.
I considered using a config.pl, but this means I either have a config.pl with one option to configure where to find the app.conf file, or I move the options themselves into config.pl and require end-users to respect Perl syntax when setting options. Future users will be internal admins, so that's not unreasonable, but it's more complicated than I'd like.
So what am I missing? Any good alternatives?

Usually a top priority is to avoid having configuration files amongst your executables. Otherwise a server misconfiguration could accidentally show your private configuration info to the world. I put everything the app needs under /srv/app0, with subdir cfg which is a sibling to the dirs containing executables. (More detail.)
If you're pre-loading modules via PerlPostConfigRequire startup.pl to access mod/startup.pl then that's the best place to put the configuration file location ../cfg/app.cnf and you have complete flexibility re how to store the configuration in memory. An alternative is to PerlModule your modules and load the configuration (with a relative path as above) in a BEGIN block within one of them.
Usually processing a configuration file doesn't take appreciable time, so a popular option is to lazy-load: if the code detects the configuration is missing it loads it before continuing. That's no use if the code needed to know the configuration earlier than that, but it avoids lots of problems, especially when migrating code to a non-modperl env.

Related

How to set WinDbg cache* local symbol path

This is my WinDbg target launch link.
From
"E:\software\Windows Kits\10\Debuggers\x86\windbg.exe" -y SRV*
E:\symbol*http://msdl.microsoft.com/download/symbols -b -k com:port=//./pipe/com_1,baud=115200,pipe
to
"E:\software\Windows Kits\10\Debuggers\x86\windbg.exe" -y SRV*[cache*]E:\symbol;D:\projects*http://msdl.microsoft.com/download/symbols -b -k com:port=//./pipe/com_1,baud=115200,pipe
My local symbolic address is D:\projects, The local pdb file is always locked.
You are mixing the HTTP server SRV* with the cache cache*. And all in all I wonder why you actually need a cache. It doesn't look like you want one. You may have a larger misunderstanding of how a symbol path works. This answer will not go into all details as well.
Microsoft symbols
Let's begin with the Microsoft symbol server:
SRV*E:\symbol*http://msdl.microsoft.com/download/symbols
srv says that this is a HTTP server.
E:\symbol says where those symbols shall be stored
http://... says where to get the symbols from
the individual parts of that definition are separated by *
Your own symbols
What you probably want is to have your local symbols (PDB files on your disk) available. You do that with just
D:\projects
and nothing else, where D:\projects is a directory which directly contains the PDB files, which is often the case when you build the project locally on your machine.
If your company has a network share, you simply add the network share:
srv to say it's a online resource
C:\netsymbols as your local directory
\\ourserver\symbols for the network share
the individual parts of that definition are separated by * (like before)
If you have a company symbol server via HTTP (like TFS offers), you would use
srv to be a HTTP server.
E:\oursymbols says where those symbols shall be stored (don't put that directory near your source code, e.g. don't use D:\projects, because that likely contains your projects, not symbols)
http://tfs.example.com/myproject for your company's server.
the individual parts of that definition are separated by * (like before)
Combination of different symbol paths
You can combine different symbol paths using ;. You typically want to do that in the order of latency and throughput, i.e.
Your local hard disk (like D:\projects)
Your local network (like srv*C:\netsymbols*\\ourserver\symbols or local HTTP servers)
Internet (like Microsoft HTTP server)
D:\projects;srv*C:\netsymbols*\\ourserver\symbols;srv*E:\oursymbols*http://tfs.example.com/myproject;SRV*E:\symbol*http://msdl.microsoft.com/download/symbols
The cache
Now, the symbol cache is a harder to grasp concept. It is defined by
cache*E:\symbolcache
cache is the indicator that you want a cache
E:\symbolcache is where you want the cache to be on hard disk
the individual parts of that definition are separated by * (like before)
The cache will store everything which is right of it. So typically you put that first, giving
cache*E:\symbolcache;D:\projects;srv*C:\netsymbols*\\ourserver\symbols;srv*E:\oursymbols*http://tfs.example.com/myproject;SRV*E:\symbol*http://msdl.microsoft.com/download/symbols
I never used a cache, because I prefer to have individual locations for the different symbols. The cache may be useful if you don't specify HDD locations for each individual part.
Commands
If you're not sure how to construct a symbol path, take a look at .symfix and .sympath+. These will help you get a correct Microsoft symbol server as well as combine other paths correctly. See this answer for more examples on symbol paths and how they work.

customize the location of save files (apkovl)

Trying to be concise, I would like alpine to save backups made with lbu ci within a subdir of the bootable disk while the behavior is to put the saves in its root.
Insight
I have searched the internet and tried various things but they all failed.
Here it talks about the boot parameter of syslinux.conf:
A relative path, interpreted relative to the root of the alpine_dev.
This is my append inside syslinux.conf
This boot parameter should be used to specify where the backups are at startup, while where they should be saved with lbu ci should be written in /etc;/lbu/lbu.conf.
however, I don't understand how to use these variables here either,
although it should be clear.

Systemic overhead of shims

I'm considering using shims to get around a game demanding Admin privileges (I tried editing the embedded "requestedExecutionLevel" tag with Resource Hacker and using .manifest files, but discovered the launcher software always downloads a new version of itself before running, thereby overwriting "asInvoker" with "requireAdministrator"). If I write protect the exe it exits with an error.
I understand that the shim required to spoof Admin privileges will probably add no appreciable overhead in itself; but MicroSoft's Application Compatibility Toolkit (ACT) that you need to install to enable shims uses a database to keep track of which application requires which shim. I'm sure this could be done with little overhead; but having seen MS' (and other corporates') past bloatware, I'm concerned my entire system will be slowed down if I install it.
Does anyone have DIRECT experience of installing ACT and KNOWS whether it slows the system down generally?
I've discovered you can add RUNASINVOKER as the value of a STRING key given the name of the application's full path here:
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers
and it will do the job without you having to install Microsoft's ACT package.
Example: if you had an application called Smeagol.exe in the directory c:\LordOfTheRings, then create a STRING key called:
c:\LordOfTheRings\Smeagol.exe
in
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers
and give it the value of
^ RUNASINVOKER
and it will run without requesting Admin privileges.

Using shared memory in mod_perl environment

I have a requirement wherein
I have to place a data structure (Perl hash) in memory, so that each HTTP process (running a Perl script) will use that hash.
The hash structure is around 300 MB.
The environment is mod_perl
I thought of creating a module to load at Apache start that creates a hash in a shared region and returns a reference to it.
Can you please comment on the behaviour, or suggest alternative solutions. Also please point to some good resources to check the examples.
If you place huge hash data on mod_perl memory,
then mod_perl parent process reads it at server startup phase.
In first, you create Your/HugeData.pm on #INC directory.
package Your::HugeData;
our %dictionary = (
....
);
Next, apache process reads this on startup.
# In apache.conf (or anywhere apache config file)
PerlModule Your::HugeData
Then your script can use %Your::HugeData::dictionary as package variable.
# In mod_perl handler script or ModPerl::Registry (CGI emulate) script.
use Your::HugeData;
...
my $tokyo = $Your::HugeData::dictionary{tokyo};
When you use prefork MPM on Linux Apache, OS prefers "Copy on Write" mechanism.
So forked child processes see parent proces'es data if you only read the data.
In other words, there may be not waste memory using.
I would be thinking in terms of handing it around via Storable store it to a file, retrieve it at start.
If it needs to change, you'd need to use flock to arbitrate IO, and potentially some sort of mechanism for checking when it changed last (e.g. check mtime).

pylons/paste config files in fastcgi (deployment)

I'm running a pylons app using fastcgi and apache2. There are two versions (different revisions from my svn repo), one for staging and one for production. I'd like them to use different paste config files.
Right now, my dispatch.fcgi inside htdocs in the pylons app just uses one config file (so both stage and live use the same configuration). I'd like to be able to have debugging enabled on the stage server but not on the live server, for example. Any suggestions?
One approach would be to have more than one dispatch.fcgi prepared (referencing different INI files), then run a script on deployment to copy the correct one into the active position.
Another approach would be to have two .fcgi files, then use an IfDefine directive to select the proper rules in your main httpd.conf.
In other words, on the staging server, you start httpd with httpd -D staging, then put the staging config inside <IfDefine staging></IfDefine> and the other config inside <IfDefine !staging></IfDefine>
The limitation of this approach is that since IfDefine is binary, going past two options while still having a "default" option requires a bunch of extra lines. It's not the end of the world, and if you require a parameter to be given on all deployments it stays clean.
Still, I would use option #1.