Is there a safe way to modify another package's entry in the RPM database? - installation

I've run into the problem described in this question, where an old package was Obsoleted, and its %preun script is run with $1 = 0, resulting in undesirable behavior. I know this could be worked around by using -e + -i, as suggested in that answer, or the --nopreun flag, but it's difficult to get that information out to users who are accustomed to simply using -U.
I can't modify the existing %preun scripts in the wild. I don't see any way to run additional code from the new package after the old one's preun. I can't find any way to have my new package programmatically prevent the old %preun script from executing.
Is there any safe way to reach into the RPM database and remove a scriptlet for an existing package?

Jeff Johnson is absolutely correct that it should not be done. However it certainly can be done.
I have done this in an RPM at work, for distribution, but note, this was a contained semi-structured environment with no remote hands to all systems.
If you have remote hands access, take the "remove, install" path, and script that.
If you really feel you should be doing this, then these are the pointers. I'm not going to show you exactly how I did it because it was "work" and not mine to share. The concepts are mine :-)
First, back up the /var/lib/rpm/Packages file (cp /var/lib/rpm/Packages /var/tmp/Packages.bkp). Put it somehwere safe. Update your backup if any one else changes the system whilst you are working on your solution. MAke regular checks on the count of RPMs and test every which way from Sunday, after each change or step.
You will need to use the db_unload and db_load commands. For speed, you will need to use "s2p" to convert any shell sed patterns to perl. Then build a pipe which looks like this:
db_unload /var/tmp/Packages.bkp |perl -i -e "s2p converted string" |db_load /var/tmp/Packages.new
You can then attempt to test the Packages.new by copying ot over the original. Always run rpm --rebuilddb after manual changes. If you see any errors, restore the back up and rebuild the db again.
If you need to put it in an RPM, then convert it to Lua, and put it in the pretrans or posttrans scriptlet (%pretrans -p <lua>). The selection depends on the ordering you are trying to achieve. The Lua interpreter is built in to rpm, and so it will run OK during a new system install even if your RPM gets called somehow. I wrapped my "pipe" in a lua long string, and made it only execute if the system already exists. It does nothing otherwise. If you are thinking "that will never happen" then check out "Never say Never".
BTW you can completely stiff your RPM base and thus future administration of the system if you mess this up. If you do that, and have no backup or way out, it would be a hard way to learn that you are responsible for your own actions. Just saying that you have been warned!

No you cannot edit an rpmdb: the headers are protected
from change by a SHA1 or a digital signature.
Instead upgrade to a fixed version of the package using --nopreun
to prevent running the buggy script let.

Related

Is there a way to prevent a bash script from running certain commands if the script has to be run again?

I have a bash script that works at the moment. It gets an image and JDK 8 from a link and then runs a installer for the JDK 8 to move on to setting up another piece of software.
As I was debugging the script, I kept finding myself having to delete directories and even the java installation because when I introduce a fix and rerun the script, I have to wait for everything to download again and I have to worry about duplicate files messing up my current logic -which can probably be improved, but I'll go to the StackExchange Code Review site later.
At the moment, I would like to know what approaches there are to prevent commands -like downloading the JDK and running the JDK installer script all over again and others- from running again.
What kind of general approaches are out there for cases such as these?
For the JDK download and running the installer, I did think of simply checking for the existing of java on the system and if there is then bash would not not to run those commands.
However, there are other commands I do not want run and I do want to simply check, for example, the existence of certain files to prevent wget-ing them all over again and moving them -causing duplicates. (Should I maybe suck it up and do that anyway as that might be best practice?)
I did also think of perhaps, at each successful command, outputting like a 1 to a text file and mapping each line in that text file to the commands run in the script (like using an if statement to see if that command had a 1 or not in the text file) and if it was a 0, then the script would know only to run that command and never the 1s.
That sounded clunky to me and I am pretty sure that is not a good approach.

Validation test failure for build of jq-1.5 on FreeBSD 9.x... Now what?

A note in the README file said to ask questions here, so I am doing so.
The RIPEstat service has just shut off their own port 43 plain text service and now is forcing everyone to access their data using jq. I have zero experience with or knowledge of jq, but I am forced to give it a try. I have just built the thing successfully from sources (jq-1.5) on my crusty old FreeBSD 9.x system and the build completed OK, but one of the post-build verification tests (tests/onigtest) failed. I am looking at the test-suite.log file but none of what's in there means anything to me. (Unfortunately, I am new to stackoverflow also, and thus, I have no idea how to even upload a copy of that here so that the maintainer can peruse it.)
So, my questions:
1) Should I even worry about the failure of tests/onigtest?
2) If I should, then what should I do about this failure?
3) What is the best and/or most proper way for me to get a copy of the test-suite.log file to the maintainer(s)?
Should I even worry about the failure of tests/onigtest?
If the only failures are related to onigtest, then most likely only the regex filters will be affected.
what should I do about this failure?
According to the jq download page, there is a pre-built binary for FreeBSD, so you might try that.
From your brief description, it's not clear to me what exactly you did, but if you haven't already done so, you might also consider building an executable from a git clone of "master" as per the guidelines on the download page; see also https://github.com/stedolan/jq/wiki/Installation#or-build-from-source
What is the best and/or most proper way for me to get a copy of the test-suite.log file to the maintainer(s)?
You could create a ticket at https://github.com/stedolan/jq/issues

Find files created or modified by an installer

To track changes in OSX filesystem while an installer runs I'm trying to use the fs_usage.
Can somebody guide me with a simple example on how to interpret the result. There a lot of terms I don't understand when I examine it.
fs_usage's output tends to be full of irrelevant chatter, and hard to interpret. I'd recommend using fseventer, which just shows changed files without all the nonsense. If you're an Apple developer, you can also use PackageMaker's snapshot package feature (which records everything that happens, and offers to make an installer package that does the same things).

Using SVN for the first time

Not sure if I should be asking here or Server Fault.
Anyhow, I recently started a project at a new job that has SVN installed. I didn't use it even though I was given SSH access with some keygen thing. But now I've done some reading online for beginner's and I'm having a tough time getting past "which svn" after I input a command through SSH. I guess that tells me the path to the repository (which is /usr/bin/svn) but I don't even know how to get to that directory (I'm using Terminal on Mac OS X).
All this makes me feel pretty stupid, since I've never really had to use the terminal to do web projects before and this is my first experience with SVN via SSH (Hell, first time using SSH even).
I have been googling and reading for a weekend now, but I figured someone on here probably has a good idea of where to find the files or to check which are under SVN etc. I think my main problem is finding out how to use the terminal to "get" to the folder I want to be working on.
I did read up on the commands to check if a file is under SVN, check out, update, commit, etc. I would just like to know how to get to these files to do that. Sorry for the noob question and thanks in advance
Bonus points if someone explains the benefits of SSH (I totally understand the benefits of SVN and would love to learn it properly)
You're likely better off using a subversion client. Two of the most popular ones for OS X are http://versionsapp.com and http://zennaware.com/cornerstone/index.php (lately my dev friends seem to like cornerstone more.)
These should let you do all (or nearly all) SVN functions, but by using a GUI. You'll still want to learn the terminology. Take a look at http://svnbook.red-bean.com/en/1.6/svn.basic.html
You want SVN+SSH as it's more secure, but that shouldn't mean you have to use the command line.
Well there is no need to go to the /usr/bin even though svn resides there. /usr/bin is a standard location which is automatically included when the system tries to resolve the location of a file. You should be able to just start using SVN commands like:
svn checkout ...
The benefits of using SVN and SSH are separate questions all together.
svn list --verbose http://host_name/svn_dir will give you a list of the current versioned projects (including revision number and modified date)
svn checkout http://host_name/svn_dir/repository_name projectx will checkout the repo (creating a working copy on your local machine)
I'd recommend the manual here, even if you don't read it to start with and just use it as your first reference point when needed.

Appropriate/best practice way to execute some PHP unrelated to database when a module is first installed?

I'm creating a module that requires a few things to be done (once only) when the module is installed. There may be a number of things that need to be done, but the most basic thing that I need to do is make an API call to a server to let the external server know that the module was installed, and to get a few updated configuration items.
I read this this question on stackoverflow however in my situation I truly am interested in executing code that has nothing to do with the database, fixtures, updating tables, etc. Also, just to be clear this module has no affect (effect?) on the front end. FYI, I've also read this spectacular article by Alan Storm, but this really only drives home the point in my mind that the install/upgrade scripts are not for executing random PHP.
In my mind, I have several possible ways to accomplish this:
I do what I fear is not a best practice and add some PHP to my setup/install script to execute this php
I create some sort of cronjob that will execute the task I need once only (not sure how this would work, but it seems like it might be a "creative" solution - of course if cron is not setup properly then this will fail, which is not good
I create a core_config_data flag ('mynamespace/mymodule/initialized') that I set once my script has run, and I check on every area of the adminhtml that my module touches (CMS/Pages and my own custom adminhtml controller). This seems like a good solution except for all of the extra overhead every time CMS/Pages is hit or my controller is hit, checking this core_config_data setting. The GOOD thing about this solution would be that if something were to fail with my API call, I can set this flag to false and it will run again, display the appropriate message, and continue to run until it succeeds (or have additional logic that will stop the initialization code after XX number of attempts)
Are any of these options the "best" way, and is there any sort of precedent for this somewhere, such as a respected extension or from Magento themselves?
Thanks in advance for your time!
You raise an interesting question.
At the moment, I am not aware of a means to go about executing any arbitrary PHP on module installation, the obvious method (rightly/wrongly) would be to use the installer setup/upgrade script as per 1 of your Q.
2 and 3 seem like a more resource intensive approach, ie. needlessly checking on every page load (cache or not).
There is also the approach of using ./pear to install your module (assuming you packaged it using Magento). I had a very quick look through ./downloader/pearlib/php/pearmage.php but didn't see any lines which execute (vs copying files). I would have imagined this is the best place to execute something on install (other than 1 mentioned above).
But, I've never looked into this, so I'm fairly interested in other possible answers.

Resources