Links to know aboutMusic The Chiara String Quartet Chiara Quartet (MySpace) Greenwood Music Camp UNL School of Music PHP PEAR Installer Manifesto phpDocumentor PEAR phar docblock PHP_Parser PHP_Parser_DocblockParser PHP_ParserGenerator PHP_LexerGenerator PEAR_PackageFileManager PHP_Archive Games_Chess Blogs Joshua Eichorn Paul M. Jones Davey Shafik Popular EntriesSetting up your own PEAR channel with Chiara_PEAR_Server - the official way
(28) Do you develop a website? It is infinitely better to synchronize live and development sites using the PEAR Installer(25) Using PEAR 1.4.0 to install PEAR packages on a remote host(19) doing the PEAR thing(19) PEAR now fits in a bottle: meet go-pear.phar(17) CategoriesPowered by |
Sunday, February 11. 2007Do you develop a website? It is infinitely better to synchronize live and development sites using the PEAR InstallerTrackbacks
Trackback specific URI for this entry
No Trackbacks
Comments
Display comments as
(Linear | Threaded)
What's the difference between PEAR's:
pear upgrade --force pearweb-1.1.1 ...and: svn switch http://localhost/svnroot/pearweb/tags/1.1.1 SVN makes it very easy to create lots of tags that are very much like version numbers. If you need to downgrade, just svn switch to an earlier tag and things work out. For external libraries, you can simply include them as part of the repository, and update them when the package is updated, or you can use svn:externals to pin the library to an external SVN repository, possibly a specific revision, that is versioned along with the files. SVN, of course, can't help you with database upgrades, but that's a knotty issue as you mentioned. This is all in the spirit of friendly inquiry, because if it turns out that PEAR can serve as a PHP version of SVN/CVS, it will still be immensely helpful for the masses of us who are on webhosts who don't support version control systems.
the difference between svn switch and using pear is: it depends.
If you have no external dependencies, it is the same. However, in this situation: you are using an external XML-RPC package that has a security vulnerability in version 1.0.2. Your website version 1.1.1 uses XML-RPC 1.0.2, and 1.1.2 uses XML-RPC 1.0.3. You need to temporarily revert to 1.1.1 The difference is huge. When you use svn switch, you are also reverting to the insecure XML-RPC. With pear upgrade pearweb-1.1.1, you are only reverting the code section that needs to be reverted. Of course, you can also fix this problem by having separate repositories for each dependency, but then on upgrade, you have to remember which repository has been upgraded, and run a series of svn switch commands. Ultimately, this makes absolutely no sense, as svn was not designed to handle remote dependencies, and PEAR was. So, it could be a huge difference, or none at all, it just depends on the project. Great question, let's have some more like this!
That's a very powerful feature!
SVN, actually, can automatically update external dependencies from external repositories using svn:externals (http://svnbook.red-bean.com/en/1.0/ch07s03.html), but you'd have to change the svn property, and then switch to that new revision, to keep the XML-RPC version up to date. It would look like: 1. On a developmental version or using the repobrowser, edit your 1.1.1 tag's svn:external definition to point from the 1.0.2 version to the 1.0.3 version using: svn propset svn:externals libs/xml-rpc http://localhost/svnroot/pear/xml-rpc/tags/1.0.3 ...making a new tag if you want your tags to be immutable. 2. svn switch'ing to that tag, SVN will handle the externals definition and load the new version of XML-RPC due to the changed svn:externals definition. I must emphasize, however, this workflow makes no sense in the context of PEAR because PEAR doesn't run off SVN! You'd have to set up your own SVN repository to mooch packages off of. Conversely, though, in order to use PEAR's infrastructure, the package you want to use must be served off a PEAR server (I've considered setting one of those up for my own library, HTML Purifier, is it difficult to do?). But I believe PEAR can also piggy-back off of external tools like svn/cvs using post-install scripts, which makes it all the more powerful.
Setting up a PEAR channel server is not difficult, check out the free PDF of chapter 5 at the packt website http://www.packtpub.com/book/PEAR-installer
It should get you up and running in no time. It is interesting to note that you can run a channel server out of a subdirectory, so you do not need a unique hostname, only a unique url. In other words "pear.example.com/subdirectory" is a valid channel name, and would run out of http://pear.example.com/subdirectory
We've been using this for a while with Midgard layout templates since they can be easily packaged with PEAR.
Now the plan is to move also site structure and configs to a similar, PEAR-packaged format with its own custom role to sync it to a database...
One of the example packages demonstrating custom file tasks and custom file roles is the PEAR_Installer_Role_Chiaramdb2schema role and PEAR_Task_Chiara_Managedb task for auto-updating a database. These are explained in detail in Chapter 2, but of course (as always) the code is free.
This role is being used in production at the University of Nebraska-Lincoln internally, and works well, but it is an experimental concept, so I would be wary of auto-updating role/tasks. It's safest to do this in a post-install script like the PEAR website's script in cvs at pearweb/pearweb.php However, using a custom task to automatically insert the contents of a file into a database is an interesting idea. It would be good to think about the security implications of doing this, and to make sure that the task only runs on packages from the official midgard channel. This could help to prevent any potential malicious use of the task by unrelated packages. The likelihood of a malicious attack is low, since it can by its nature be easily traced to its source and must be publicly released, but it is still a good idea to cover ones bases.
Midgard's DB-updating role (Role_Midgardelement) does not allow direct DB updates, but only creation/updating of style elements using the Midgard API. This means quite a bunch of safeties are built into the process.
Two weak points in your explanation are that 1) you didn't finish discussing why this method helps if you have different host names on your development and production servers, and 2) you still have configuration local in your PEAR config that is getting lost in case of an accident, not much different from excluding config files from rsync. Admittedly, you don't forget to update local config files with custom PEAR config items though.
Hi Jan,
I'll address those two good points 1) I forgot The code itself contained references to the URLs like so: [a href="@ROOT_URL@/index.php"]Home[/a] Then, in package.xml: [file name="whatever.php"] [tasks:replace from="@ROOT_URL@" to="root_url" type="pear-config" /] [/file] (replace [] with angle brackets < and >) 2) The significant and redeeming difference between the configuration file that is used in some setups and a PEAR configuration file is that the custom configuration file must be parsed every single time the server executes, otherwise there is no way to determine hostnames. Thus, if the file disappears, the entire site goes down, and all the links break. If the pear configuration file disappears, the site will continue to work normally, and the PEAR configuration file can be reconstructed quite easily using the pear config-create command, and then individually pear config-set each variable. In other words, because the PEAR configuration file is never actually used by the website code, but only by the PEAR installer, it is far less mission-critical, and can be reconstructed. Although this is annoying, it doesn't result in heart-pounding sweaty-palmed scramble to fix it in the same way as a corrupted custom configuration file.
I think the configuration file argument is a bit moot, since you usually have some configuration files anyway, at least if you use any third party software or libraries. But that's nitpicking now.
Another issue with the replace tasks is, regardless of the strength of this functionality, that you always have to install the website package, even to test only little changes on your development server. You can't run your dev server directly off the actual development code. This is of course true for all PEAR packages and has nothing to do with your article
Actually, take a look at phpDocumentor for an example of code that both runs right out of the install directory and also out of a PEAR install with the same codebase. For extreme cases like this, one can always use an if(){} with a replacement. using the @ROOT_URL@ example:
However, the requirement to install in order to test is not onerous. I just maintain a terminal window that is open (or an Alt-F2 windows if in linux but not in X) where I have pear up -f package.xml and use this to update the local install. This is a good design practice, as it also verifies you have a valid configuration for the website's package.xml so that when you install on the live site, it actually works.
How does your solution compare to using PHING in combination with SVN (or CVS)?
I'd be inclined to have PHING: - do an SVN export - apply configuration settings - synchronise with the live server So far I spotted no downsides compared to your solution and the bonus of not having a packaging step. Am I missing anything?
Phing is of course a fantastic tool, but I don't think its design principles are as geared towards managing remote dependencies and version management as PEAR. Instead, it is designed to automate common build processes of files on the same host. Phing is based on the principles behind systems like GNU make and Java's Ant, which are used to construct complex packages and transform files into other things using scripting files (either text or xml).
Phing, of course, also relies upon .xml files to do what it does, similar to PEAR, so there really is no difference in terms of packaging. Let me illustrate: Phing: - make xml file - do the phing thing PEAR: - make xml file - do the pear thing In fact, the channel server is unnecessary, and is only useful for automatic upgrade cron jobs like at pear.php.net. What I did in order to upgrade the chiaraquartet.net site was I had a CVS repository outside the public_html directory, and when the time was ripe for a release, I did these steps: $ cvs upd -P -d $ pear package $ pear upgrade package.xml Why pear package? Then I have a .tgz sitting around, which makes these steps unnecessary when reverting to version 1.2.3: $ cvs upd -R RELEASE_1_2_3 $ pear up -f package.xml Instead, I could just: $ pear up -f website-1.2.3.tgz Also, Phing is not designed to handle these contingencies easily: - revert to a previous version - update only dependencies - revert just a broken depedency From the documentation, and what you've described, it sounds like you would need a separate phing .xml (or at least a separate section) for each of these tasks, all of which are just 1-liners when using PEAR. So, Phing is a great tool but I wouldn't try to bend it to do what PEAR specializes in. You could, however, use the PEAR Package task to make your package.xml file to get started if you already have a phing build: http://phing.info/docs/guide/2.2.0/chapters/appendixes/AppendixC-OptionalTasks.html#PearPackageTask Let me put it another way: Phing can be installed/upgraded using the PEAR Installer. PEAR can be installed/upgraded using the PEAR Installer. Which tool is designed and trusted specifically to handle deployment of remote packages?
So basically you're saying that it's a good idea to use the PEAR package manager to manage upgrades to your live website.
I'd like to expand on that and say that it's a good idea to use any package manager to manage your live website. The PEAR package manager is just one choice, and thanks to your efforts a really good choice. We tend to use distribution native package managers so creating new servers is a snap, clone a fresh OS filesystem image in the SAN, assign it to a blade, boot up, set some machine specific configuration settings, use the distributions native package manager to fetch in the latest package for your server package with all the associated dependencies and we're good to go. Makes setting up new development and test systems a snap. We're mainly a Python house currently, so we're using Pythons native package manager distutils to create OS packages. In the todo list is to figure out a good way to automate this kind of thing for PHP. Are you by any chance aware of good tools to create rpm's and deb's from PEAR packages? BTW. database versioning is also an interesting topic. It has two facets that make it a bit more difficult. One is the distributed versioning aspect where you have to synchronize versiondependencies across machine boundaries. Basically the same issue you get with any kind of RPC service (including webservices). The other problem is that you can't use the regular remove old version, install new version idiom due to the need to migrate data. I'm currently looking at using the database refactoring idiom to version the database. Basically you create scripts that take you from database version a to version b. When upgrading/downgrading your database you find a path through the refactoring scripts to the new version. This can facilitate some good tooling to automate the creation of the refactoring scripts.
Hi Ants,
The PEAR_Command_Packaging package (http://pear.php.net/PEAR_Command_Packaging) is designed specifically to support creation of .rpm packages based on PEAR packages. The package is designed to allow extension for other packaging formats, but nobody has stepped forward to implement them, implying demand for .rpm is much stronger than demand for .deb. If it would be useful to you to have .deb, I don't think it would be difficult to implement, I happen to be unfamiliar with the format (even though I use Kubuntu), and obviously have devoted my time to other things like maintaining PEAR, PhpDocumentor, etc.
What do you think about Capistrano? Can PEAR Installer be used instead of it?
Capistrano is a neat tool.. It is focused on complete applications, and as such excels at management of Apache. The use of symbolic links to different versions is an interesting idea, which of course does require a restart to the server.
Capistrano is designed mainly to handle single-chunk applications, whereas PEAR is designed to handle applications with many remote dependencies. As such, some tasks are difficult with Capistrano (often requiring new code to be written) such as upgrade/revert just a single dependency (this requires multiple capistrano scripts with internal symlinks for each dependency. I would say Capistrano would be an interesting way to begin development, but I am curious how it would scale as the application becomes more complex. With PEAR, it is easy to split up an existing application into sub-packages, to add dependencies, and so on. Capistrano may require more tweaking, but time will tell. Of course, one could always use the PEAR Installer locally to manage dependencies, and then deploy to a live site a complete application using Capistrano, but it should be noted that using a PHP-based tool and a ruby-based tool to do similar and possibly overlapping things is asking for trouble. Lastly, PEAR runs identically on windows and unix, whereas capistrano is designed explicitly for a unix-based system, so if that matters to you (God help you if you're running a production website on windows!) then PEAR is clearly a better choice.
Well, as for external dependencies we tend to copy them into project's repository or use svn:externals pinned to the specific revision. IMHO, that's the only 100% guarantee that nothing will break on the next update.
That's why i find PEAR installer only good for managing packages dependencies and initial project's repository setup when i need to put all external dependencies to some local folder of my working directory and commit them. But seriously i do really think Capistrano is a better tool for projects deployment. How would one install the same copies of application to several web serves in a cluster with PEAR installer? And let's not forget Capistrano allows one to script each step of deployment very easily and customize it. Correct me if i'm wrong please and PEAR installer can do all that for me too! Anyway something similar to Capistrano written with PHP would be super useful.
Hi Greg,
I just __enjoyed__ your book (two times), and I am really exited about learning to utilize everything the PEAR installer offers. I have an application which can provide information as XML RPC to the end user. However I want to make it easier for the end user to display the information, and therefore I have written some helper files, which I want to distribute as a PEAR package. Some of the files are library files, some are template files and then some are webfiles. On page 154 you shortly mention something about web files, but I don't think I follow you completely. When I run the post-install script, I am asked where to put the webfiles. But there is not one place to put the webfiles. I have several development applications, and I cannot put them all in the same library
I should probably elaborate a bit on the question.
I want to make some code available to my users. It is partly backend, templates and standard webfiles. The purpose is to make it really easy to install a standard implementation of the application, but I still want to make it easy to customize the installation and still be able to do safe updates. Often one would like to customize something. For instance if you have a shopping cart, you might want to add an extra field and some rules, say: cart.php - the standard implementation is edited to reflect the changes // customized stuff in the standard implementation $form->addElement('text', 'new_field', 'New field'); $form->addRule('new_field', 'required'); And you would probably want to change the css-file entirely to reflect the other aspects of your site. But having customized stuff I cannot just update my package anymore without breaking the customization made by the user. How can one come around this problem? Another thing - having the postinstall script write a configuration file is probably often something you want to do. Is there anyway to pull out the information from one's old configuration file and use it when running the postinstall script (so one can just push enter and not have to remember the values on updates?) By the way, thank you for the really great work and the great book. Both are brilliant.
You describe the usage of PackageFileManger brilliantly, and it is a nice tool to maintain package.xml. However, it seems as if you edit the file tags (eg. adds a task), it is overwritten if you use the PacakageFileManger again. Is there any way to avoid this behaviour?
Well it seems as if I found the solution myself - some of the keys being the following:
$pfm = new PEAR_PackageFileManager2(); $pfm->setOptions( // ... 'exceptions' => array(), // ... ); // ... $pfm->addReplacement('setup.php', 'pear-config', '@php_dir@', 'php_dir'); $pfm->addGlobalReplacement('package-info', '@package-version@', 'version'); $postInstall = $pfm->initPostinstallScript('setup.php'); $postInstall->addParamGroup( 'setup', array( $postInstall->getParam('webroot', 'Webroot'), $postInstall->getParam('intraface', 'Private Key'), ), 'Settings' ); $pfm->addPostInstallTask($postInstall, 'setup.php'); // ...
It seems as if the installer just gives a "no valid package found" if the package depends on a non-discovered channel. Perhaps the error message could be a bit more helpful. It took me quite some time to figure out what the problem was
I use phpontrax to develop my web applications. There are environments in the config file for Trax. I basically set in the Vhost on the dev server SetEnv TRAX_ENV development and on the production server Vhost SetEnv TRAX_ENV production. Doing that in your code you can access $_SERVER['TRAX_ENV'] and then load the db stuff or whatever for the specific environment.
|
Links in this articlePEAR Installer ManifestoCalendar
QuicksearchMy Latest ReleasesTop Exitspear.php.net (537)
pecl.php.net (156) www.php.net (149) news.php.net (112) php.net (103) Blog Administration |
|||||||||||||||||||||||||||||||||||||||||||||||||