Centos, Amazon Linux, NFS and the dreaded "nobody" problem Tue, Jan 31. 2012
I have been fighting a problem with mounting volumes from an NFS Server in AWS for a few days. With more pressing issues at hand, I had to try and google for solutions for an hour or so before bed, and nothing I was doing was having any effect. Curiously, an Ubuntu based machine that was mounting the drive using NFS3 was not having the same problem. Only the Amazon Linux servers that were using NFS4 were having the issue, and were showing all files and directories as being owned by nobody:nobody.
drwxr-xr-x 2 nobody nobody 22 Jan 9 19:58 installervc
drwxr-xr-x 2 nobody nobody 4.0K Jan 9 19:56 avatar
drwxr-xr-x 2 nobody nobody 4.0K Jan 9 19:56 accessories
I had previously insured that the user UID and group GID for the user that would be writing files (in my case "apache" was the same (with the same UID and GID) on the NFS server and the servers mounting the nfs volume.
As it turned out the problem was with the configuration (or lack thereof) of the rpcidmapd service. NFS4 relies on this service to map users between machines. The "idmapd" requires that the domain of both the client and server should match for the UID/GID mapping to work, and in my case it wasn't. Probably many people with proper DNS configuration don't hit this problem, but we did not have a proper DNS setup, as these machines are part of a growing cluster. Compounding the problem I had set the configuration files to have meaningless host names rather than a domain.
You can tweak this setup by editing the: /etc/idmapd.conf file, and find the "Domain" variable:
Domain = yourdomain.com
Set these to be the same for the server and all the clients.
The last problem was that I had to restart the idmapd process, which has an /etc/init.d control script named /etc/rpcidmapd
[root@web1 init.d]# ls -lath | grep rpcid
-rwxr-xr-x 1 root root 2.7K Jul 28 2011 rpcidmapd
Restart the process on both the nfs server and any nfs clients. If the source of your problem is the same as mine, your user & group mapping problems should be solved:
sudo /etc/inti.d/rpcidmapd restart
Finally!!!!
drwxr-xr-x 2 apache apache 22 Jan 9 19:58 installervc
drwxr-xr-x 2 apache apache 4.0K Jan 9 19:56 avatar
drwxr-xr-x 2 apache apache 4.0K Jan 9 19:56 accessories
drwxr-xr-x 2 nobody nobody 22 Jan 9 19:58 installervc
drwxr-xr-x 2 nobody nobody 4.0K Jan 9 19:56 avatar
drwxr-xr-x 2 nobody nobody 4.0K Jan 9 19:56 accessories
I had previously insured that the user UID and group GID for the user that would be writing files (in my case "apache" was the same (with the same UID and GID) on the NFS server and the servers mounting the nfs volume.
As it turned out the problem was with the configuration (or lack thereof) of the rpcidmapd service. NFS4 relies on this service to map users between machines. The "idmapd" requires that the domain of both the client and server should match for the UID/GID mapping to work, and in my case it wasn't. Probably many people with proper DNS configuration don't hit this problem, but we did not have a proper DNS setup, as these machines are part of a growing cluster. Compounding the problem I had set the configuration files to have meaningless host names rather than a domain.
You can tweak this setup by editing the: /etc/idmapd.conf file, and find the "Domain" variable:
Domain = yourdomain.com
Set these to be the same for the server and all the clients.
The last problem was that I had to restart the idmapd process, which has an /etc/init.d control script named /etc/rpcidmapd
[root@web1 init.d]# ls -lath | grep rpcid
-rwxr-xr-x 1 root root 2.7K Jul 28 2011 rpcidmapd
Restart the process on both the nfs server and any nfs clients. If the source of your problem is the same as mine, your user & group mapping problems should be solved:
sudo /etc/inti.d/rpcidmapd restart
Finally!!!!
drwxr-xr-x 2 apache apache 22 Jan 9 19:58 installervc
drwxr-xr-x 2 apache apache 4.0K Jan 9 19:56 avatar
drwxr-xr-x 2 apache apache 4.0K Jan 9 19:56 accessories
Defined tags for this entry: Amazon Linux, Centos, IDMAPD, Linux, NFS, NFS Nobody, NFS4, Redhat, RPCIDMAPD
Calculate a person's age in a MySQL query -- continued Fri, Aug 19. 2011
The serendipity cache blew up on me for this article so I had to split it into 2 parts.
MySQL knows how to work with the Gregorian calender, and I believe it is easier to let MySQL do the work, rather than trying to figure out how to implement the different cases. I chose to implement the "last day of the month" technique. In this case, we'll do this by creating a mysql date based on March 1st of the current year, and subtract one day from it to get to the last day of February.
If you read my article on "Finding next monday" using mysql date functions, you would have seen how DATE_ADD() can be used to help solve a lot of problems, even though the name can be misleading when you are actually using it to subtract. Using it with the following test dates proves that mysql has fully implemented the leap year logic accurately:
DATE_ADD to the rescue
MySQL knows how to work with the Gregorian calender, and I believe it is easier to let MySQL do the work, rather than trying to figure out how to implement the different cases. I chose to implement the "last day of the month" technique. In this case, we'll do this by creating a mysql date based on March 1st of the current year, and subtract one day from it to get to the last day of February.
If you read my article on "Finding next monday" using mysql date functions, you would have seen how DATE_ADD() can be used to help solve a lot of problems, even though the name can be misleading when you are actually using it to subtract. Using it with the following test dates proves that mysql has fully implemented the leap year logic accurately:
Continue reading "Calculate a person's age in a MySQL query -- continued" »
Calculate a person's age in a MySQL query Fri, Aug 12. 2011
Recently a question was posed on the Phpfreaks.com forums, as to the best way for someone to store a user's birth date using the MySQL database. One person suggested using a varchar as they were most familiar with string functions. My answer was to use the MySQL date type.
I provided a quick "advantages of using date" comparison list:
Storing as a DATE
•A MySQL Date requires 3 Bytes of storage
•You can do Date arithmetic inside mysql (search for dates within ranges) and use mysql functions to calculate values directly in a query
•It intrinsically will only store valid dates
•You can format it in numerous ways
Storing as a Varchar
•A string will require minimum 8 bytes, or 10 with separators
•can't do any form of efficient native range queries
•can't reformat it easily in SQL
•will allow completely invalid dates
I thought a great proof of the benefit of this approach was to show that you could have MySQL calculate the person's current age in a query, using their birthday. Certainly with a string, using PHP for example, you would typically query the database to pull out the string and for each row, turn it into a PHP date and do some calculations in your code, and you'd arrive at the same place, but I wanted to show just how capable SQL -- and in this case MySQL can be especially when you use the native data types and some functions.
I provided a quick "advantages of using date" comparison list:
Storing as a DATE
•A MySQL Date requires 3 Bytes of storage
•You can do Date arithmetic inside mysql (search for dates within ranges) and use mysql functions to calculate values directly in a query
•It intrinsically will only store valid dates
•You can format it in numerous ways
Storing as a Varchar
•A string will require minimum 8 bytes, or 10 with separators
•can't do any form of efficient native range queries
•can't reformat it easily in SQL
•will allow completely invalid dates
I thought a great proof of the benefit of this approach was to show that you could have MySQL calculate the person's current age in a query, using their birthday. Certainly with a string, using PHP for example, you would typically query the database to pull out the string and for each row, turn it into a PHP date and do some calculations in your code, and you'd arrive at the same place, but I wanted to show just how capable SQL -- and in this case MySQL can be especially when you use the native data types and some functions.
Continue reading "Calculate a person's age in a MySQL query" »
SQL UPDATE for strings in MongoDB Fri, May 20. 2011
MongoDB currently does not offer the equivalent of a SQL Update statement when you want to change the value of a string to something that is based on the current value. In my case I needed to find spaces and change them to underscores -- something done easily in php with str_replace(), and in MySQL with REPLACE.
If you had a table named foo with a column named "mystr" you could do this sort of update like this:
UPDATE foo SET mystr = REPLACE(mystr, ' ', '_');
MongoDB does have collection.update() that works with a series of "modifier" operations, but none of them are useful for doing modifications to the current value of a document field when that field is a string.
MongoDB does however support javascript, and the javascript replace() function implements a regular expression search and replace. I was able to accomplish the update using the forEach() method to process the resulting documents one at a time. While not as efficient as having mongo do this internally with a specially built update modifier, at least this method only needs to operate on documents that are known to require modifications, and could be run in the mongo interactive client easily.
Again, assuming the collection is named "foo" and the document field is named "mystr"
db.foo.find({ mystr: /[ ]+/ }).forEach( function(u) { u.mystr = u.mystr.replace(/[ ]/g, "_"); db.foo.save(u); } );
An existing patch promises to add a new update() modifier but until such a time as it exists, this approach can be used when you need to update strings in a collection, referencing the existing values in the transformation.
If you had a table named foo with a column named "mystr" you could do this sort of update like this:
UPDATE foo SET mystr = REPLACE(mystr, ' ', '_');
MongoDB does have collection.update() that works with a series of "modifier" operations, but none of them are useful for doing modifications to the current value of a document field when that field is a string.
MongoDB does however support javascript, and the javascript replace() function implements a regular expression search and replace. I was able to accomplish the update using the forEach() method to process the resulting documents one at a time. While not as efficient as having mongo do this internally with a specially built update modifier, at least this method only needs to operate on documents that are known to require modifications, and could be run in the mongo interactive client easily.
Again, assuming the collection is named "foo" and the document field is named "mystr"
db.foo.find({ mystr: /[ ]+/ }).forEach( function(u) { u.mystr = u.mystr.replace(/[ ]/g, "_"); db.foo.save(u); } );
An existing patch promises to add a new update() modifier but until such a time as it exists, this approach can be used when you need to update strings in a collection, referencing the existing values in the transformation.
Load the Url symfony helper in a model or form class Tue, Jan 18. 2011
I'm doing some symfony work and needed to use the Url helper in a form class to return an error message that included a link. I would consider this one of those exceptions where you really need to be able to have markup in a class rather than in a template.
I should probably mention that this is the way that works in version 1.4.3, and that the method that works in actions will not work in a form class. That method is:
sfContext::getInstance()->getConfiguration()->loadHelpers(...);
That method was deprecated and there is also this article to consider.
In this case, the solution was to access the sfApplicationConfiguration object. In order to use the Url helper so you can call link_to() you need to also include the 'Tag' helper.
sfApplicationConfiguration::getActive()->loadHelpers(array('Url', 'Tag'));
// now you can use link_to(...)
Obviously this would allow you to load other helpers in the same way ... i18n for example.
I should probably mention that this is the way that works in version 1.4.3, and that the method that works in actions will not work in a form class. That method is:
sfContext::getInstance()->getConfiguration()->loadHelpers(...);
That method was deprecated and there is also this article to consider.
In this case, the solution was to access the sfApplicationConfiguration object. In order to use the Url helper so you can call link_to() you need to also include the 'Tag' helper.
sfApplicationConfiguration::getActive()->loadHelpers(array('Url', 'Tag'));
// now you can use link_to(...)
Obviously this would allow you to load other helpers in the same way ... i18n for example.
How to configure AVReloaded to work with Longtail's JW Player Google Analytics Pro plugin Tue, Sep 14. 2010
Allvideos Reloaded (AVReloaded) is a really nice piece of software engineering from Fritz Elfert. Rather than hardcode for all the individual players out there, Fritz created a macro system that allows you describe the parameters for any player, so it can be configured and updated.
Like the Allvideos plugin, AVReloaded comes bundled with the ubiquitous JW Player for Flash. If you are streaming flash movies from your website, one worthwhile plugin is longtail's Google Analytics Pro. The current license price for the plugin is $19 from longtail's site. If you're already using Google Analytics, the plugin feeds "Content" events from the player to Google Analytics which will show up under the "Event Tracking" menu. Ever have questions like: "I wonder what videos people are actually watching on my site" or "for this new video, how many seconds do they watch before they get bored and close it?" If so, then this plugin is for you. The player will generate events that GA groups into 3 categories: "Video Plays", "Percentage Played" and "Seconds Played". Drilling down you get a nice list of the Videos on your site. For example, finding out that people only watch on average 10% of that promotional video for your product is probably a sign that you may need some better material.
Like the Allvideos plugin, AVReloaded comes bundled with the ubiquitous JW Player for Flash. If you are streaming flash movies from your website, one worthwhile plugin is longtail's Google Analytics Pro. The current license price for the plugin is $19 from longtail's site. If you're already using Google Analytics, the plugin feeds "Content" events from the player to Google Analytics which will show up under the "Event Tracking" menu. Ever have questions like: "I wonder what videos people are actually watching on my site" or "for this new video, how many seconds do they watch before they get bored and close it?" If so, then this plugin is for you. The player will generate events that GA groups into 3 categories: "Video Plays", "Percentage Played" and "Seconds Played". Drilling down you get a nice list of the Videos on your site. For example, finding out that people only watch on average 10% of that promotional video for your product is probably a sign that you may need some better material.
« previous page
(Page 1 of 17, totaling 98 entries)
next page »


