High-Availability Storage Cluster With GlusterFS On Ubuntu 12.04

This tutorial shows how to combine four single storage servers (running Ubuntu 12.04) to a distributed replicated storage with GlusterFS. Nodes 1 and 2 (replication1) as well as 3 and 4 (replication2) will mirror each other, and replication1 and replication2 will be combined to one larger storage server (distribution). Basically, this is RAID10 over network. If you lose one server from replication1 and one from replication2, the distributed volume continues to work. The client system (Ubuntu 12.04 as well) will be able to access the storage as if it was a local filesystem. GlusterFS is a clustered file-system capable of scaling to several peta-bytes. It aggregates various storage bricks over Infiniband RDMA or TCP/IP interconnect into one large parallel network file system. Storage bricks can be made of any commodity hardware such as x86_64 servers with SATA-II RAID and Infiniband HBA.

I do not issue any guarantee that this will work for you!

 

1 Preliminary Note

In this tutorial I use five systems, four servers and a client:

  • server1.example.com: IP address 192.168.0.100 (server)
  • server2.example.com: IP address 192.168.0.101 (server)
  • server3.example.com: IP address 192.168.0.102 (server)
  • server4.example.com: IP address 192.168.0.103 (server)
  • client1.example.com: IP address 192.168.0.104 (client)

Because we will run all the steps from this tutorial with root privileges, we can either prepend all commands in this tutorial with the string sudo, or we become root right now by typing

sudo su

All five systems should be able to resolve the other systems’ hostnames. If this cannot be done through DNS, you should edit the /etc/hosts file so that it looks as follows on all five systems:

vi /etc/hosts

127.0.0.1       localhost.localdomain   localhost
192.168.0.100   server1.example.com     server1
192.168.0.101   server2.example.com     server2
192.168.0.102   server3.example.com     server3
192.168.0.103   server4.example.com     server4
192.168.0.104   client1.example.com     client1

# The following lines are desirable for IPv6 capable hosts
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts

(It is also possible to use IP addresses instead of hostnames in the following setup. If you prefer to use IP addresses, you don’t have to care about whether the hostnames can be resolved or not.)

 

2 Setting Up The GlusterFS Servers

server1.example.com/server2.example.com/server3.example.com/server4.example.com:

GlusterFS is available as a package for Ubuntu 12.04, therefore we can install it as follows:

apt-get install glusterfs-server

The command

glusterfsd –version

should now show the GlusterFS version that you’ve just installed (3.2.5 in this case):

root@server1:~# glusterfsd –version
glusterfs 3.2.5 built on Jan 31 2012 07:39:58
Repository revision: git://git.gluster.com/glusterfs.git
Copyright (c) 2006-2011 Gluster Inc. <http://www.gluster.com>
GlusterFS comes with ABSOLUTELY NO WARRANTY.
You may redistribute copies of GlusterFS under the terms of the GNU General Public License.
root@server1:~#

If you use a firewall, ensure that TCP ports 111, 24007, 24008, 24009-(24009 + number of bricks across all volumes) are open on server1.example.com, server2.example.com, server3.example.com, and server4.example.com.

Next we must add server2.example.com, server3.example.com, and server4.example.com to the trusted storage pool (please note that I’m running all GlusterFS configuration commands from server1.example.com, but you can as well run them from server2.example.com or server3.example.com or server4.example.com because the configuration is repliacted between the GlusterFS nodes – just make sure you use the correct hostnames or IP addresses):

server1.example.com:

On server1.example.com, run

gluster peer probe server2.example.com
gluster peer probe server3.example.com
gluster peer probe server4.example.com

Output should be as follows:

root@server1:~# gluster peer probe server2.example.com
Probe successful
root@server1:~#

The status of the trusted storage pool should now be similar to this:

gluster peer status

root@server1:~# gluster peer status
Number of Peers: 3

Hostname: server2.example.com
Uuid: 600ff607-f7fd-43f6-af8d-419df703376d
State: Peer in Cluster (Connected)

Hostname: server3.example.com
Uuid: 1d6a5f3f-c2dd-4727-a050-0431772cc381
State: Peer in Cluster (Connected)

Hostname: server4.example.com
Uuid: 0bd9d445-0b5b-4a91-be6f-02b13c41d5d6
State: Peer in Cluster (Connected)
root@server1:~#

Next we create the distributed replicated share named testvol with two replicas (please note that the number of replicas is half the number of servers in this case because we want to set up distributed replication) on server1.example.com, server2.example.com, server3.example.com, and server4.example.com in the /data directory (this will be created if it doesn’t exist):

gluster volume create testvol replica 2 transport tcp server1.example.com:/data server2.example.com:/data server3.example.com:/data server4.example.com:/data

root@server1:~# gluster volume create testvol replica 2 transport tcp server1.example.com:/data server2.example.com:/data server3.example.com:/data server4.example.com:/data
Creation of volume testvol has been successful. Please start the volume to access data.
root@server1:~#

Start the volume:

gluster volume start testvol

It is possible that the above command tells you that the action was not successful:

root@server1:~# gluster volume start testvol
Starting volume testvol has been unsuccessful
root@server1:~#

In this case you should check the output of…

server1.example.com/server2.example.com/server3.example.com/server4.example.com:

netstat -tap | grep glusterfsd

on both servers.

If you get output like this…

root@server1:~# netstat -tap | grep glusterfsd
tcp        0      0 *:24009                 *:*                     LISTEN      1110/glusterfsd
tcp        0      0 localhost.localdom:1019 localhost.localdo:24007 ESTABLISHED 1110/glusterfsd
root@server1:~#

… everything is fine, but if you don’t get any output…

root@server2:~# netstat -tap | grep glusterfsd
root@server2:~#

root@server3:~# netstat -tap | grep glusterfsd
root@server3:~#

root@server4:~# netstat -tap | grep glusterfsd
root@server4:~#

… restart the GlusterFS daemon on the corresponding server (server2.example.com, server3.example.com, and server4.example.com in this case):

server2.example.com/server3.example.com/server4.example.com:

/etc/init.d/glusterfs-server restart

Then check the output of…

netstat -tap | grep glusterfsd

… again on these servers – it should now look like this:

root@server2:~# netstat -tap | grep glusterfsd
tcp        0      0 *:24009                 *:*                     LISTEN      1152/glusterfsd
tcp        0      0 localhost.localdom:1018 localhost.localdo:24007 ESTABLISHED 1152/glusterfsd
root@server2:~#

root@server3:~# netstat -tap | grep glusterfsd
tcp        0      0 *:24009                 *:*                     LISTEN      1311/glusterfsd
tcp        0      0 localhost.localdom:1018 localhost.localdo:24007 ESTABLISHED 1311/glusterfsd
root@server3:~#

root@server4:~# netstat -tap | grep glusterfsd
tcp        0      0 *:24009                 *:*                     LISTEN      1297/glusterfsd
tcp        0      0 localhost.localdom:1019 localhost.localdo:24007 ESTABLISHED 1297/glusterfsd
root@server4:~#

Now back to server1.example.com:

server1.example.com:

You can check the status of the volume with the command

gluster volume info

root@server1:~# gluster volume info

Volume Name: testvol
Type: Distributed-Replicate
Status: Started
Number of Bricks: 2 x 2 = 4
Transport-type: tcp
Bricks:
Brick1: server1.example.com:/data
Brick2: server2.example.com:/data
Brick3: server3.example.com:/data
Brick4: server4.example.com:/data
root@server1:~#

By default, all clients can connect to the volume. If you want to grant access to client1.example.com (= 192.168.0.104) only, run:

gluster volume set testvol auth.allow 192.168.0.104

Please note that it is possible to use wildcards for the IP addresses (like 192.168.*) and that you can specify multiple IP addresses separated by comma (e.g. 192.168.0.104,192.168.0.105).

The volume info should now show the updated status:

gluster volume info

root@server1:~# gluster volume info

Volume Name: testvol
Type: Distributed-Replicate
Status: Started
Number of Bricks: 2 x 2 = 4
Transport-type: tcp
Bricks:
Brick1: server1.example.com:/data
Brick2: server2.example.com:/data
Brick3: server3.example.com:/data
Brick4: server4.example.com:/data
Options Reconfigured:
auth.allow: 192.168.0.104

3 Setting Up The GlusterFS Client

client1.example.com:

On the client, we can install the GlusterFS client as follows:

apt-get install glusterfs-client

Then we create the following directory:

mkdir /mnt/glusterfs

That’s it! Now we can mount the GlusterFS filesystem to /mnt/glusterfs with the following command:

mount.glusterfs server1.example.com:/testvol /mnt/glusterfs

(Instead of server1.example.com you can as well use server2.example.com or server3.example.com or server4.example.com in the above command!)

You should now see the new share in the outputs of…

mount

root@client1:~# mount
/dev/mapper/server5-root on / type ext4 (rw,errors=remount-ro)
proc on /proc type proc (rw,noexec,nosuid,nodev)
sysfs on /sys type sysfs (rw,noexec,nosuid,nodev)
fusectl on /sys/fs/fuse/connections type fusectl (rw)
none on /sys/kernel/debug type debugfs (rw)
none on /sys/kernel/security type securityfs (rw)
udev on /dev type devtmpfs (rw,mode=0755)
devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=0620)
tmpfs on /run type tmpfs (rw,noexec,nosuid,size=10%,mode=0755)
none on /run/lock type tmpfs (rw,noexec,nosuid,nodev,size=5242880)
none on /run/shm type tmpfs (rw,nosuid,nodev)
/dev/sda1 on /boot type ext2 (rw)
server1.example.com:/testvol on /mnt/glusterfs type fuse.glusterfs (rw,allow_other,default_permissions,max_read=131072)
root@client1:~#

… and…

df -h

root@client1:~# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/server5-root
29G  1.1G   27G   4% /
udev                  238M  4.0K  238M   1% /dev
tmpfs                  99M  212K   99M   1% /run
none                  5.0M     0  5.0M   0% /run/lock
none                  247M     0  247M   0% /run/shm
/dev/sda1             228M   24M  193M  11% /boot
server1.example.com:/testvol
58G  2.1G   53G   4% /mnt/glusterfs
root@client1:~#

Instead of mounting the GlusterFS share manually on the client, you could modify /etc/fstab so that the share gets mounted automatically when the client boots.

Open /etc/fstab and append the following line:

vi /etc/fstab

[...]
server1.example.com:/testvol /mnt/glusterfs glusterfs defaults,_netdev 0 0

(Again, instead of server1.example.com you can as well use server2.example.com or server3.example.com or server4.example.com!)

To test if your modified /etc/fstab is working, reboot the client:

reboot

After the reboot, you should find the share in the outputs of…

df -h

… and…

mount

 

4 Testing

Now let’s create some test files on the GlusterFS share:

client1.example.com:

touch /mnt/glusterfs/test1
touch /mnt/glusterfs/test2
touch /mnt/glusterfs/test3
touch /mnt/glusterfs/test4
touch /mnt/glusterfs/test5
touch /mnt/glusterfs/test6

Now let’s check the /data directory on server1.example.com, server2.example.com, server3.example.com, and server4.example.com. You will notice that replication1 as well as replication2 hold only a part of the files/directories that make up the GlusterFS share on the client, but the nodes that make up replication1 (server1 and server2) or replication2 (server3 and server4) contain the same files (mirroring):

server1.example.com:

ls -l /data

root@server1:~# ls -l /data
total 0
-rw-r–r– 1 root root 0 2012-05-29 15:49 test1
-rw-r–r– 1 root root 0 2012-05-29 15:49 test2
-rw-r–r– 1 root root 0 2012-05-29 15:49 test4
-rw-r–r– 1 root root 0 2012-05-29 15:49 test5
root@server1:~#

server2.example.com:

ls -l /data

root@server2:~# ls -l /data
total 0
-rw-r–r– 1 root root 0 2012-05-29 15:49 test1
-rw-r–r– 1 root root 0 2012-05-29 15:49 test2
-rw-r–r– 1 root root 0 2012-05-29 15:49 test4
-rw-r–r– 1 root root 0 2012-05-29 15:49 test5
root@server2:~#

server3.example.com:

ls -l /data

root@server3:~# ls -l /data
total 0
-rw-r–r– 1 root root 0 2012-05-29 15:49 test3
-rw-r–r– 1 root root 0 2012-05-29 15:49 test6
root@server3:~#

server4.example.com:

ls -l /data

root@server4:~# ls -l /data
total 0
-rw-r–r– 1 root root 0 2012-05-29 15:49 test3
-rw-r–r– 1 root root 0 2012-05-29 15:49 test6
root@server4:~#

Now we shut down server1.example.com and server4.example.com and add/delete some files on the GlusterFS share on client1.example.com.

server1.example.com/server4.example.com:

shutdown -h now

client1.example.com:

rm -f /mnt/glusterfs/test5
rm -f /mnt/glusterfs/test6

The changes should be visible in the /data directory on server2.example.com and server3.example.com:

server2.example.com:

ls -l /data

root@server2:~# ls -l /data
total 0
-rw-r–r– 1 root root 0 2012-05-29 15:49 test1
-rw-r–r– 1 root root 0 2012-05-29 15:49 test2
-rw-r–r– 1 root root 0 2012-05-29 15:49 test4
root@server2:~#

server3.example.com:

ls -l /data

root@server3:~# ls -l /data
total 0
-rw-r–r– 1 root root 0 2012-05-29 15:49 test3
root@server3:~#

Let’s boot server1.example.com and server4.example.com again and take a look at the /data directory:

server1.example.com:

ls -l /data

root@server1:~# ls -l /data
total 0
-rw-r–r– 1 root root 0 2012-05-29 15:49 test1
-rw-r–r– 1 root root 0 2012-05-29 15:49 test2
-rw-r–r– 1 root root 0 2012-05-29 15:49 test4
-rw-r–r– 1 root root 0 2012-05-29 15:49 test5
root@server1:~#

server4.example.com:

ls -l /data

root@server4:~# ls -l /data
total 0
-rw-r–r– 1 root root 0 2012-05-29 15:49 test3
-rw-r–r– 1 root root 0 2012-05-29 15:49 test6
root@server4:~#

As you see, server1.example.com and server4.example.com haven’t noticed the changes that happened while they were down. This is easy to fix, all we need to do is invoke a read command on the GlusterFS share on client1.example.com, e.g.:

client1.example.com:

ls -l /mnt/glusterfs/

root@client1:~# ls -l /mnt/glusterfs/
total 0
-rw-r–r– 1 root root 0 2012-05-29 15:49 test1
-rw-r–r– 1 root root 0 2012-05-29 15:49 test2
-rw-r–r– 1 root root 0 2012-05-29 15:49 test3
-rw-r–r– 1 root root 0 2012-05-29 15:49 test4
root@client1:~#

Now take a look at the /data directory on server1.example.com and server4.example.com again, and you should see that the changes have been replicated to these nodes:

server1.example.com:

ls -l /data

root@server1:~# ls -l /data
total 0
-rw-r–r– 1 root root 0 2012-05-29 15:49 test1
-rw-r–r– 1 root root 0 2012-05-29 15:49 test2
-rw-r–r– 1 root root 0 2012-05-29 15:49 test4
root@server1:~#

server4.example.com:

ls -l /data

root@server4:~# ls -l /data
total 0
-rw-r–r– 1 root root 0 2012-05-29 15:49 test3

Is it possible to get the iOS 6.1 SDK for Xcode 4.2 on Snow Leopard?

Still possible. In fact, you can do all the development and submit applications to Appstore using XCode 4.2 on Snow Leopard with SDK 6.1. However, you can’t run simulator 6.1 (so use a real device).

Here is how (a few steps abbreviated):

  1. You will need to find a system with Lion/Mountain Lion and XCode 4.5, which you will use as a source of data (I have one in VMWare). IMPORTANT: You will need to connect an iOS device running ios 6.1 to that system and open it in XCode 4.5 organizer, so that XCode can download appropriate symbols.
  2. From system with XCode 4.5 copy the following source directories:

    Device Support: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/6.1 (10B141)

    SDK: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.1.sdk

    It may be most convenient to archive each directory using tar, like so: tar cvf /tmp/archive.tar << name of your directory >>

    NOTE: specific version of Device Support directory may differ, (i.e. “6.1.2 (10B146)” or higher), use the one matching your ios device in all following instructions.

  3. You will need to copy these directories to the Snow Leopard system with XCode 4.2 into the following directories (assuming your XCode installation is in /Developer. If, like mine, it’s somewhere else, replace first component of the path as needed):

    Device Support: /Developer/Platforms/iPhoneOS.platform/DeviceSupport/

    SDK: /Developer/Platforms/iPhoneOS.platform/Developer/SDKs

    If using tar, change into each directory and extract its respective tar archive like so: tar xvf /tmp/archive.tar . Using tar has an advantage of preserving timestamps, symbolink links etc, if there are any.

    After copying, remove link “Latest” in Device Support directory and re-link to “6.1 (10B141)” like so: ln -s “6.1 (10B141)” Latest

==============================================

At this point you can restart XCode 4.2 and you should be able to:

  • Add your 6.1 device in organizer, and run and debug code on it
  • Select 6.1 SDK as “latest” for your projects and build against it.

==============================================

However, if you are trying to support a 4″ iPhone 5 screen (by adding Default-568h@2x.png startup image) you still can’t quite submit an application built that way to the Appstore. XCode 4.2 embeds SDK 5.0 into some of the metadata in the application archive, so it looks like the application is built against 5.0 sdk. Appstore actively refuses binaries that include 4″ screen support and are not built against 6.0 or higher SDK.

So, you must resort to some manual work to tell Appstore what is already true :)

Here is how:

  1. Archive your application. Open archive directory in finder (right click on the line, “reveal in finder”), open Terminal, type “cd “, drag and drop the directory to Terminal and press “Enter”. Now you are in that directory and can work with files there.
  2. cd Products/Applications/yourapp.app
  3. There will be a file called Info.plist – it’s in a binary form. Convert it to XML like so: plutil -convert xml1 Info.plist
  4. Open Info.plist in your favorite editor. Find references to sdk 5.0 (or binary value of SDK) in the following entries and replace with references to 6.1: DTPlatformVersion: 6.1 DTPlatformBuild: 10B141 DTSDKBuild: 10B141 DTSDKName: iphoneos6.1

If you feel adventurous, replace XCode version and build values too. I did not.

  1. plutil -convert binary1 Info.plist
  2. Now you need to re-sign the application. Application binary is in the same folder, should be named “yourapp”

To do so, you will first need a copy of embedded entitlements file that is to be used during signing.

  • You can either copy that file from an application archive made under XCode 4.5: look for file name: archived-expanded-entitlements.xcent , copy to the application directory (just in case, not sure if needed)
  • extract it from current application like so: codesign -d –entitlements /tmp/entitlements.xml “yourapp”

Open file /tmp/entitlements.txt in text editor and clean up any weird stuff that goes before < ?xml version tag, save.

  1. Now find the exact name of your distribution certificate. You can copy it from a number of places, but the best is to open Keychain Access app, select the distribution certificate, doube-click to open properties and copy “common name”. It should be something like “iPhone Distribution: your company”
  2. Still in the archive directory, run codesign as follows: First remove current signature file just in case:

    rm -rf _CodeSignature

    Then run:

    codesign -f -s “iPhone Distribution: your company” –entitlements /tmp/entitlements.xml yourapp

This is it. Your application is now built against 6.1 SDK and shows as such. You should be able to validate and submit it to appstore from Organizer.

============================

Disclaimer: my app submitted this way is still “Waiting for Review”. Will post here if it is accepted/rejected because of this.

Note: so why jump through these hoops? Well, a few reasons:

  1. Because I should be able to develop in whatever environment I want, dammit.
  2. XCode 4.2 on OSX 10.6 is the last version of XCode that supports PowerPC and OSX 10.4 SDK. If, like me, you have to support an old desktop product that must run on that platform – you have no choice, but to stick with it until last PowerPC user drops his device. These guys are old and tenacious. Using two machines for development is not an attractive option for me.

Django and Multiple Methods Per url Pattern

HTTP verbs are not used to determine the route to a view method by deliberate design in Django. Sometimes I find it useful to be able to specify different methods for the same url pattern – one per HTTP verb. The Django book contains an interesting example of how this can be done using the django.conf.urls.defaults.url method to separate POST from GET processing. I’ve extended the example to provide handling to cover the standard HTTP verbs.

 
Listing: router.py

from django.http import Http404, HttpResponseNotAllowed
from django.conf.urls.defaults import url

GET = 'GET'
PUT = 'PUT'
POST = 'POST'
HEAD = 'HEAD'
TRACE = 'TRACE'
DELETE = 'DELETE'
OPTIONS = 'OPTIONS'

HTTP_METHODS = (GET, POST, PUT, HEAD, DELETE, OPTIONS, TRACE)

def dispatch(request, *args, **kwargs):
view = kwargs.pop(request.method, None)
if view:
for method in HTTP_METHODS:
kwargs.pop(method, None)
return view(request, *args, **kwargs)
else:
allowed_methods = []
for method in HTTP_METHODS:
if kwargs.pop(method, None):
allowed_methods.append(method)
if allowed_methods:
return HttpResponseNotAllowed(allowed_methods)
else:
raise Http404

def mapping(regex, viewname, get = None, post = None, put = None, delete = None,
head = None, options = None, trace = None):
views = { GET: get, POST: post, PUT: put, DELETE: delete, HEAD: head,
OPTIONS: options, TRACE: trace }
return url(regex, dispatch, views, viewname)


Listing: urls.py

from django.conf.urls.defaults import *
from router import mapping
import views

urlpatterns = patterns('',
(r'^$', views.index),
mapping(r'^document/(?P[A-Za-z0-9]+)/$', 'single_document',
views.single_document_get, views.single_document_post),
)

*This article was extracted from another source : http://watchitlater.com/blog/2009/06/django-and-multiple-methods-per-url-pattern/

iOS 5.1 SDK for Xcode 4.2 on Snow Leopard

To get Xcode 4.2 on Snow Leopard to run code on a device running iOS 5.1 you can do this:

  1. If you have another Mac running Lion and Xcode 4.3.1 you can copy the files from:

    /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/5.1 (9B176)

  2. Place the copied files in the equivalent place on your Snow Leopard Mac: probably

    /Developer/Platforms/iPhoneOS.platform/DeviceSupport

  3. Similarly copy the iOS 5.1 SDK files found in this directory:

    /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk

  4. Also copy ‘version.plist’ from the Lion machine in the iPhoneOS.platform folder to the Snow Leopard machine.
  5. Re-start Xcode on the Snow Leopard machine and re-connect the devices and it seems happy enough.

If you don’t have access to a machine with Lion and Xcode 4.3.1:

  1. You can get the files out of the 4.3.1 DMG which can be downloaded from Apple here: Downloads for Apple Developers.
  2. Mount the DMG, Show Package Contents on the Xcode icon and drill down to

    /Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport

  3. Follow the steps above.

You might find it more convenient to use Apple’s proprietary ditto method (sudo ditto src dest) in the terminal window to copy the folders.

Note, this hack will also work for latest iOS 6 and 6.1 SDK.

And that is the second way:

echo copying iPhoneOS6.0.sdk
cp -R /Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk               /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/

echo copying iphonesim6.0.sdk
cp -R /Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator6.0.sdk /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/

echo copying devicesupport for 6.0
cp -R /Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/6.0 (10A403)                 /Developer/Platforms/iPhoneOS.platform/DeviceSupport/

#remove old -latest- link
rm -f /Developer/Platforms/iPhoneOS.platform/DeviceSupport/Latest

echo setting up Latest link
cd /Developer/Platforms/iPhoneOS.platform/DeviceSupport/
ln -s ./6.0 (10A403) ./Latest

Multi-language support in Django

The Django documentation on internationalization describes how to add multi-language support to your application. As it took me a few tries to get it right, here’s a rundown of what I did to add it to an existing project.

Step 1 — update settings.py
In settings.py, make sure that USE_I18N is set to True, which is the default. The LANGUAGE_CODE setting controls the default language for the site, so if you only need to support one language you set it here.

Then add the LocaleMiddleware class to your MIDDLEWARE_CLASSES, which for a clean project might look like this:

1 MIDDLEWARE_CLASSES = (
2     'django.middleware.common.CommonMiddleware',
3     'django.contrib.sessions.middleware.SessionMiddleware',
4     'django.contrib.auth.middleware.AuthenticationMiddleware',
5     'django.middleware.locale.LocaleMiddleware',
6 )

Note that the order of the middleware classes makes a difference. LocaleMiddleware is needed for Django to select the user-preferred language from data in the request (i.e. cookies or the Accept-Language http header).

Step 2 — add translation keys to templates
Every template that should have translation support must load the i18n tag library using the {% load %} template tag. Once loaded, you can use the {% trans %} tag to mark a string for translation. A minimalistic hello-world template could look like this:

1 {% load i18n %}
2 {% trans "Hello" %}

Step 3 — create language files
Once your templates are set up, it’s time to create the language files. This step depends a bit on which operating system you’re running. I use Ubuntu Linux, so that’s what I’ll cover.

You can have language files local to an application as well as global for all your site. To set up language files for e.g. English and Swedish, move to the root of your project (or the root of the application), and run:

mkdir locale
django-admin.py makemessages -l en
django-admin.py makemessages -l tr

Note that you need to create the locale directory manually before running makemessages, otherwise you will get an error message. Also, if you get this error message:

Error: errors happened while running xgettext on __init__.py
/bin/sh: xgettext: not found

… it’s because your Linux distribution is missing the xgettext program. In Ubuntu, it’s provided by the gettext package:

sudo apt-get install gettext

Now that the language files are set up as ./locale/<language>/LC_MESSAGE/django.po, you can edit them and provide translations of the “Hello” key for each locale. When you’re done, they need to be compiled to .mo files before Django can use them:

django-admin.py compilemessages

Step 4 — done!
That’s all! You can try changing the LANGUAGE_CODE setting to switch between languages, or change the preferred-languages setting in your web browser (under Tools->Options->Content->Languages in Firefox), and Django should adapt automatically.

Asp.net c# load xml illegal characters

You don’t show your source code, however I guess what you are doing is this:

string xml = ... retrieve ...;
XmlDocument doc = new XmlDocument();
doc.Load(xml); // error thrown here

The Load method expects a file name not an XML itself. To load an actual XML, just use the LoadXmlmethod:

... same code ...
doc.LoadXml(xml);

Similarly, using XDocument the Load(string) method expects a filename, not an actual XML. However, there’s no LoadXml method, so the correct way of loading the XML from a string is like this:

string xml = ... retrieve ...;
XDocument doc;
using (StringReader s = new StringReader(xml))
{
    doc = XDocument.Load(s);
}

As a matter of fact when developing anything, it’s a very good idea to pay attention to the semantics(meaning) of parameters not just their types. When the type of a parameter is a string it doesn’t mean one can feed in just anything that is a string.

Also in respect to your updated question, it makes no sense to use XmlDocument and XDocument at the same time. Choose one or the another.

Transact-SQL Joins

Joins

A join is a clause within a SELECT statement that specifies that the results will be obtained from two tables. It usually includes a join predicate, which is a conditional statement that determines exactly which rows from each of the tables will be joined by the query. Usually the join will be based upon a foreign key relationship and will only return combined results from the two tables when the key values in both tables match. However, it is possible to join tables based upon non-key values or even perform a cross join that has no predicate and returns all possible combinations of values from the two tables.

Usually normalisation results in a database with many related tables. You may therefore want to join more than two tables for a single set of results. In this case, you can include multiple joins in a SELECT statement. The first join combines the first two tables. The second join combines the results of the first join with a third table, and so on.

Performing Queries with Joins

Inner Joins

Possibly the most common form of join that you will use is the inner join. With this type of join, the two tables are combined based upon a join predicate. Wherever a row in one table matches a row in the other, the two rows are combined and added to the outputted results. If a row in either table matches several in the other, each combination will be included in the results. If a row in either table does not match any in the other table, it will be excluded from the results altogether.

The join clause, second table name and join predicate are included in the SELECT statement immediately after the name of the first table. The join uses the INNER JOIN clause and the predicate uses the ON clause. The basic syntax for the SELECT statement is as follows:

SELECT columns FROM table-1 INNER JOIN table-2 ON predicate

As an example, we can join the Jobs and Engineers tables. The following query returns a list of jobs and the details of the engineer that performed the work. In this case, the predicate specifies that the tables will be joined only where the EngineerId in both tables is a match. These columns are used in a foreign key relationship definition for the two tables, although this is not a requirement for the join to be executed. However, if non-key columns are frequently used in join operations, you should consider adding appropriate indexes to improve query performance.

SELECT * FROM Jobs INNER JOIN Engineers ON Jobs.EngineerId = Engineers.EngineerId

The query returns four results as each of the four jobs in the database has an engineer associated with it. However, not all of the engineers have been assigned work so the twenty-one that have not undertaken a job are not included in the results.

The example query returns every column from both tables. For larger tables, or when using multiple joins, this may include a lot of data that you do not require. In addition to making the results more difficult to read, it can also lengthen the processing time for the query and increase the amount of network traffic generated. You should therefore only return the columns that you require. This can be achieved by specifying a column list as usual. However, if the two tables include columns with the same name, the ambiguity can cause an error. Try executing the following query:

SELECT
    EngineerId,
    JobId,
    VisitDate,
    EngineerName
FROM
    Jobs
INNER JOIN
    Engineers
ON
    Jobs.EngineerId = Engineers.EngineerId

This query fails because the EngineerId column appears in both tables. You must therefore specify which table’s EngineerId column you require by prefixing it with the table name and a full-stop (period) character. The following query resolves the problem:

SELECT
    Jobs.EngineerId,
    JobId,
    VisitDate,
    EngineerName
FROM
    Jobs
INNER JOIN
    Engineers
ON
    Jobs.EngineerId = Engineers.EngineerId

When using joins, you can also use WHERE clauses, ORDER BY clauses, etc. As with the column selection, you must specify the table name for any columns with ambiguous names. For example:

SELECT
    Jobs.EngineerId,
    JobId,
    VisitDate,
    EngineerName
FROM
    Jobs
INNER JOIN
    Engineers
ON
    Jobs.EngineerId = Engineers.EngineerId
WHERE
    Jobs.EngineerId = 4
OR
    Jobs.EngineerId = 8
ORDER BY
    Jobs.EngineerId
*This article was extracted from another source : http://www.blackwasp.co.uk/SQLJoins.aspx

What’s new in OpenStack Folsom?

Introduction


« F » release is the next stable version of OpenStack.

Since Essex has been released in April 2012, we can see that many new features are coming thanks to developers. The biggest one is for sure that Quantum is now a core project and Virtual Networking is rapidly approaching. Volume service has now its own separated project : Cinder.

We are going to see here what you can’t miss to know for next release.

Note : Keep in mind the list is not exhaustive and I note here the highlights only.

 

Keystone


PTL for the next 6 months : Joe Heck

Features Description URL
API V3 in Draft
  • Domains (collections of projects)
  • Role API restructuring
  • Rename « tenant » to « project »
  • Extended policy-implementation-specific API
Blueprint
PKI Support
  • Improve the security of tokens
  • Provide more scalable and secured SSO
Blueprint

 

Glance


PTL for the next 6 months : Brian Waldon

Features Description URL
API V2
  • Users fall in 3 classes : Anonymous, Authenticated, Admins
  • Image management (rights, ownership, new API concepts)
Blueprint
bin/glance is deprecated In favor of python-glanceclient Blueprint
Store image data in tenant-specific swift accounts Store image data in the authenticated user’s swift account Blueprint
Glance Replication Copy images from one glance deployment to another

 

Nova


PTL for the next 6 months : Vish Ishaya

Features Description URL
Volumes decoupled Cinder can be run in standalone Blueprint
Host aggregation improvements
  • Decouple xen pool addition from host aggregate
  • Ensure multi-membership works
  • Decouple availability zone
  • Expose aggregate data to scheduler
Blueprint
Quantum API Integration New networking API designed for Quantum Blueprint
XenAPI Improvement
  • Boot from volume
  • Live migration
  • Live migration without Shared Storage
Deprecated Auth removed Only Keystone auth is supported now Blueprint
Hyper-V Support Use Hyper-V 2008 or 2012 as the Hypervisor Blueprint

 

Cinder


PTL for the next 6 months : John Griffith

Features Description URL
Migration from nova-volume Existing volumes should continue to work Blueprint
Availability zone Users can specify « availability zone » when they create volumes using Simple scheduler. Blueprint

 

Quantum


PTL for the next 6 months : Dan Wendlandt

Features Description URL
API V2 New API with new features described below Wiki
New CLI Commands to manage Quantum Blueprint
Melange integration IPAM into Quantum Blueprint
L3 + NAT Basic L3 + NAT forwarding Blueprint
DHCP DHCP support Blueprint
Notification support Used to push logging and usage information. Blueprint
Provider networks Other types of networks can be registered with Quantum Blueprint
Public networks Network that provides access to the Internet for example Blueprint
Authorization support Authorization support with keystone Blueprint
API quotas Limit the set of resources a tenant can consume in a flexible way Blueprint
Multi Plugin in Draft « metaplugin » will allow multi-plugin in same time (targeted for G release) Blueprint

I highly recommend to read this article to understand how works Quantum.

 

Horizon


PTL for the next 6 months : Gabriel Hurley

Features Description URL
 Compression  django-compressor implementation Blueprint
 Nova-volume is optionnal  Volumes has now a new panel Blueprint
Quantum Support
  • Public(shared) network can be created by admin role
  • L2 Support only (no Floating IP yet)
Cinder Support  Switch from nova-volumes to Cinder Blueprint
LESS transition  Transition of all of The Horizon CSS to LESS Blueprint
Support For Nested Swift Objects Support of pseudo folders within the dashboard Blueprint
Prevent from admin login If you are logged into admin, you have a warning when you manage other tenants -
UI Improvements A lot of new features to manage users, projects, create instances, etc -

 

Swift


PTL for the next 6 months : John Dickinson

Features Description URL
Changed db_preallocation to False  to avoid failures and degradations Review
Expand recon middleware support Support for account and container
servers
Review
Extract client library Separate swift & client.py into an other repo Blueprint
Move keystone middleware into swift - Blueprint
Move proxy server logging to middleware - Review
Adapt Swift for Webob 1.2b3 - Review

 

Conclusion


Congratulations to developers !

If you want to deploy OpenStack Folsom, you can use the guide I wrote in which I explain how to install Folsom packages into Ubuntu 12.04 with Ubuntu Folsom Testing PPA.

In the future, you will have to use Cloud Archive to upgrade into Folsom with Ubuntu 12.04, or to use Ubuntu 12.10.

 
*This article was extracted from another source : http://my1.fr/blog/whats-new-in-openstack-folsom/

Beşi Bir Yerde

 

 

 

 

 

 

 

 

 

 

 

 

Oyunda skor listeleme mevcut, oyunu oynayan herkesin skorlarını kolayca görebilirsiniz.

Bu oyun iPhone/iPod Touch için oluşturuldu.

Şuanda Türkçe, İngilizce, Almanca ve Fransızca dil desteği ile mevcut.

Amaç oyundaki aynı renkli en az 5 topu yatay veya dikey olarak aynı çizgiye getirmek. Herbir hamlenizde 2 adet top eklenir. Kaç tane topu yanyana getirirseniz o kadar yüksek puan kazanırsınız.

İyi Eğlenceler!

Web Services vs WCF Services

Many times I saw asking differences between web services and WCF services so this made me write this.

There are numbers of differences between both , so lets understand step by step.

–WCF offers much more flexibility and portability to develop a service when comparing to web service. Still we are having more advantages over Web service.

hope this will help you to understand.

If this help you in understanding the concept then like and share it to your friends.

Resource : http://sujeet21.wordpress.com/2012/04/05/webservice_wcfservices/