jeb6kids has asked for the wisdom of the Perl Monks concerning the following question:

*standard first time poster's apologies here*

Would someone please help me find PM's documentation on "how to support a network production environment while doing code changes to multiple custom packages used in common across several scripts"?

I'm not talking about the library (CVS) issues, but the roll-out of a change to a custom package while dependent scripts and packages are in use.

Is there a technique somewhere that will help me make my changes in one directory (and break things without breaking production), then move the changed code to a pre-production directory so beta testers can see it before it goes into production?

I am selfishing trying to avoid the error-prone alteration of "use lib proddir;" lines for each script that has dependencies on packages that could exist at prod, pre-prod or dev...

THANKS!

Readmore

I support a few perl apps for a large network production environment. My apps employ the use of standard packages and some custom packages of my own.

The perl scripts are kept in a commom tool location that all network users have access to. My custom packages are kept in a visible location that isn't in the standard @INC. I could perhaps change @INC, but it is already wastefully full and I'm not a sysadmin and sadly it wouldn't help me meet all requirements either.

To reach my packages, each script has a "use lib prodlib;" line to help them resolve "use CustomPackage;" statements.

I thought I had a solution when I just added after the "use lib prodlib;" line another "use lib protectedlib;" line placing a search through my own protected directory first (unreadable to anyone but me). This helped me do development on a single package that I can see, but users can't see. But woe, this doesn't help me promote changes to a "beta" level so that a few others can test a soon-to-be-production level.

My next thought was to add "YAUL" statment between my protected development library directory and the production library directory that searched a path through each user's $ENV{HOME}/preprod directory. This way, any user wanting to try out pre-production code could place a symlink to the pre-prod dir in their own home. When the prod scripts executed, suddenly the pre-prod packages would be found before the prod packages.

I trust the monks who have passed this way before know a better solution-- please accept my gratitude in advance for your patient instruction.

Replies are listed 'Best First'.
Re: Supporting a production environment
by Abigail-II (Bishop) on May 03, 2004 at 23:16 UTC
    Would someone please help me find PM's documentation on "how to support a network production environment while doing code changes to multiple custom packages used in common across several scripts"?
    Your question isn't a Perl specific one. It's a general one. The typical production environment is separated from the production environment. And usually, there is a testing environment, completely separate from both development and production as well. The testing environment should be identical to the production environment.

    The situation you describe sounds like a big mess to me. Phrases like I'm not a sysadmin suggest that people don't really cooperate in your company (either your sysadmin department isn't working to fullfil the developers needs, or you are working against policy).

    Your post gives me too little detail to give a useful direct answer. My suggestion is to reorganize the environment, or abandon all hope.

    Abigail

      Thanks for taking the time to reply to my misguided questions!

      Sadly, I feel my poor communication skills have wasted your efforts to help me improve... so if you don't mind, would you please take a look at my question again in the light of the possibility that

      • I may not have such an unsalvageable mess as you imagine,
      • I do have cooperation from my sysadmin department,
      • the people in my company do cooperate, and
      • my Perl tool development efforts are fully supported by policy?

      How would your answer change? In a more perfect world than I communicated, what technique in Perl would you use to help administer a live production environment where changes may have to be quickly developed, tested and brought on-line while other parts of the whole may be in use. What in your wisom is the perfect organized environment for doing what you suggest?

      Nearly everyone who sacrificed to give me help also worshipped your opinion... I would feel horrible if I had to live knowing I had missed the mark so far in your eyes.

      The fact that no one pointed me to an already existing node which duplicates this querry gives me hope that perhaps this question is worthy of discussion. Most likely your attention to this lack will help many future initiates like myself cross the span over a safer bridge.

      Forgive me for not again providing the details you require to give a useful answer- just say so and I'll provide you more.

      (If this thread is still too general don't bother yourself over my inquiry).

      Thanks again in advance

Re: Supporting a production environment
by tilly (Archbishop) on May 04, 2004 at 00:16 UTC
    As Abigail-II says, the right way to do this is to have independent environments for development, QA and production. Sometimes the realities of life place developers in a position where they can't get that, no matter how clearly they know why they need to, and the desire for a paycheck keeps you there.

    If that is your situation, then one solution is that you can create some form of Local::Config module whose purpose is to look at some combination of user, environment variables, configuration files, command line arguments or whatever else you choose to decide what version of the code to run. Then it should adjust @INC to fit that, and can also set key variables. For instance you likely will want development code to connect to a different database instance than production code - that can be set up here. This module should be kept as small and simple as possible because updating it is a real PITA. (I'd suggest having the configuration module figure out what version you are running, and then load the real configuration module of that version. That module now can set all environment variables that you need, special configuration information etc. This makes developing and rolling out a new configuration variable much easier - the global module never gets touched. Only the one that it loads.)

    If your needs are simple, you can just specify some environment variables that make the switch, and create some shell aliases to make it easy for you to switch between them. However once you have 3-4 variables to keep on flipping together, having the configuration module is a lifesaver.

      Thanks!

      You're Good! How to implement independent environments for development, QA and production using Perl is exactly what I was asking... (although I horribly failed to make this clear to Abigail-II (forgive me)).

      I think your solution has great merit and will begin now to understand better this idea of dynamic changes to @INC... for some reason I was believing that @INC must be fairly static except for some simple compile-time tweaks as I was already using. I always thought that Packages were loaded by searching the @INC path and that little or no "execution" took place until all the "use Package;" statments had been seen. You are very enlightened.

      Thanks again!

        It's hard to give any specifics, as they require much more knowledge of your product(s) and environments, so I keep it very general. But what I am going to say is not Perl specific, and if you are looking for specific Perl answers, you are approaching this the wrong way. Separating production and testing, and upgrading production are general engineering problems - and have nothing to do with the language(s) being used.

        What you need is hardware, and most of all, procedures. To keep your production running smoothly, you need procedures, and you need everyone to follow the procedures. Sanctions for breaking the procedures should be severe - like firing the offender.

        You need at least three different environments: development, testing and production, and perhaps more (staging, several levels of testing, release). Out of development should come easy (as in, automatically) to install packages (SUN packages, HP depot files, RPMs, your own deployment tool). Your testing environment should be as much a copy of your production environment as possible (identical hardware, same OS, same version of libraries/tools, recent copy of data, etc). Install the package that comes out of development in your testing environment - if the install fails, throw it back to development, and restore your testing environment. If the installation succeeds, run your tests. Test all new functionality. Run your regression tests making sure nothing that shouldn't have changed did. Run more tests. Let everyone bring in their kids and let them bang on the keyboards for a day. Run your tests and regressions tests again. If satisfied, scedule a maintainance window for your production environment. In the maintainance window, do a full backup of your production environment. Check whether you can actually restore from the backup you made. Upgrade your production environment. Close your maintainance window and go home. Be back in before the first user starts work.

        Abigail

Re: Supporting a production environment
by McMahon (Chaplain) on May 04, 2004 at 00:13 UTC
    In general, I agree with Abigail's response. I think your political problem is bigger than your code problem.

    That said, however, I've been where you are, kinda.

    You'll probably have to adjust the politics, but have you considered a run-time or logon interface that looks something like:

    Enter 1 to run production code.
    Enter 2 to run some stuff I hacked up this morning.
    Enter 3 to send an email to Management demanding a test environment.

    ...and control your users' behavior/access/environment from the moment they enter the environment?
Re: Supporting a production environment
by sgifford (Prior) on May 04, 2004 at 03:12 UTC
    I've sometimes solved problems like this using environment variables. I'll use variables for the "root" of the project, and set PERL5LIB to the directories for the current environment. I set the production values in Apache's httpd.conf, and when I'm testing I set them from a script.

      Thank you!

      I did a little experimenting-- this also might be just what I need to alter the location where Packages are found depending on the environment...

      My brief look at this technique seems to indicate that internal "use lib PackageDir;" statements take precedent over values set into PERL5LIB 8--(, but I could alter my current practice to make this suggestion work for me too!

        One caveat of using PERL5LIB is that it's ignored if you're running under taint mode (and if this is a Web application, you should be). You can work around this by doing your own PERL5LIB handling. This is only safe if the environment is under your control, and the script isn't setUID or grant other special powers when run from the command-line.
        BEGIN { if ($ENV{PERL5LIB} and $ENV{PERL5LIB} =~ /^(.*)$/) { # Blindly untaint. Taintchecking is to protect from Web data; # the environment is under our control. eval "use lib '$_';" foreach (reverse split(/:/,$1)); } }
Re: Supporting a production environment
by rupesh (Hermit) on May 04, 2004 at 07:19 UTC
    I can't agree more with Abigail-II. Moreover, Production Environment being the most sensitive as well as the most critical.
    I have been in the same situation before, and have realised that it is better to device your own plans other than postponing things because of insufficient privileges (like adminsterating, access levels etc.)
    I'll let you know my thoughts ... and feel free to reply with any questions.
    Here's my opinion:
    1. Leave the development area alone. Let the developers do whatever they want to. That region is of least importance with respect to your external customers/clients
    2. Have two test-bed environments (at least a minimum of one). One say 'User Acceptance' and the other 'Demo' (Pre-Production). The Demo should be exactly similiar (in terms of OS, Scripts, security levels etc.) to PROD.
    3. Make sure your code goes to Prod ONLY if UA and Demo are fine. Otherwise, start all over again
    4. Take a copy of your scripts in production to a location where only you (and whoever concerned) have access to - say 'prodbackup'. Update this directory every time there is a production move.
    5. You might also want to consider comparing files in 'prodbackup' with the ones in prod, so as to maintain consistency in the files.

    That's just the beginning. Once you have some kind of process in place, there are wonders you can do by enforcing procedures (in terms of automation) and reports.
    All the best.

      Thanks for your many suggestions!

      You're idea to maintain a prodbackup directory to preserve past working versions for recovery from human error is excellent.