Tuesday, October 19, 2010

Returning to Roots - Comparison of Ruby and C-Sharp

Ran into this while doing my morning reading.
This is a great video that compares C-Sharp and Ruby.
As I'm currently doing both side by side, this is really great review
of the plus and minus of each.

The presenter is great, and there lots of code.

http://vimeo.com/12803005

Wednesday, October 13, 2010

Limiting Data by User In Microsoft LightSwitch

I wanted to be able to limit my queries by user. In order to do this you need to add additional query code. This can only be done, if you create the query under the datasource. So for example, say I have a table, called
appointments, and the table also has a relationship to users. Right Click on Appointments, and Add A Query. If you try to do this under the screen, you will not be able to add the code.

Once you have the query, and rename it, you can click the Edit Additional Query Code button, on Properties.

The gorgous part of this, you can have a complex query, in my case there are three groups or'd togeather, and then on top of that we limit by user.

And it only takes a couple of lines.

 partial void MyTodaysAppointments_PreprocessQuery(ref IQueryable<Appointment> query)
  
     {
  
       query = from Appointments in query
  
           where Appointments.User.Name == Application.Current.User.Name
  
           select Appointments;
  
     }  

Wednesday, October 06, 2010

Minimal Telnet Parsing in C#

Ever wonder what the minimal parsing is needed to do a telnet server?
While the socket/listen is easy stuff, and life for low session counts
is easy using a thread per session, the issue is, what do I need to do
to get to the point I can talk to my device. In this case a scangun
with a telnet client.

Telnet actually is a protocol. The PC Micro link is a good write-up
which wikipedia was so nice to provide a link to.

I google for a while, and could not find anything other than expensive .net libraries, or basic protocol documentation.

Here is the code, so you dont have to search any longer.

private void HandleClientComm(object client)
        {
            TcpClient tcpClient = (TcpClient)client;
            NetworkStream clientStream = tcpClient.GetStream();

            byte[] message = new byte[4096];
            byte[] cmd = new byte[4096];
            int cmdcnt;
            int bpos;
            int bytesRead;
           
            const int tmode_normal = 0;
            const int tmode_iac = 1;
            const int tmode_option = 2;
            const int tmode_do = 3;
            const int tmode_will = 4;
            int mode;
            byte thebyte;
            BarCodeClient bci;
            
            cmdcnt = 0;
            bpos = 0;
            mode = tmode_normal;

           bci = new BarCodeClient(client);
       
            while (true)
            {
                bytesRead = 0;

                try
                {
                    //blocks until a client sends a message
                    bytesRead = clientStream.Read(message, 0, 4096);
                }
                catch
                {
                    //a socket error has occured
                    break;
                }

                if (bytesRead == 0)
                {
                    //the client has disconnected from the server
                    break;
                }
               
                bpos = 0;
                while( (cmdcnt < 4096) && (bpos < bytesRead)){
                    thebyte = message[bpos++];
                    switch (mode)
                    {
                        case tmode_normal:
                            switch (thebyte)
                            {
                                case telnet_iac:
                                    mode = tmode_iac;
                                    continue;
                                case 0x0a: // LineFeed
                                    break;
                                case 0x0d:
                                    string thecmd = Encoding.ASCII.GetString(cmd,0,cmdcnt);
                                    if (thecmd.Length > 0)
                                    {
                                        bci.Cmd(thecmd);
                                    }
                                    cmdcnt = 0;
                                    continue;
                                default:
                                    break;
                            }
                            cmd[cmdcnt++] = thebyte; 
                            break;
                        case tmode_iac:
                            switch (thebyte)
                            {
                                case telnet_do:
                                     mode = tmode_do;
                                     break;
                                case telnet_se:  // End Subnegotiation
                                     mode = tmode_normal;
                                     bci.Cmd(""); // Let the lower level know to force a screen refresh
                                     break;
                                case telnet_sb:
                                    mode = tmode_option;
                                    break;
                                case telnet_will:
                                    mode = tmode_will;
                                    break;
                                default:
                                    mode = tmode_normal;
                                    break;
                            }
                            break;
                        case tmode_do:
                            switch (thebyte)
                            {
                                default:
                                    mode = tmode_normal;
                                    break;
                            }
                            break;
                        case tmode_will:
                            switch (thebyte)
                             {
                                 default:
                                     mode = tmode_normal;
                                     break;
                             }
                            break;
                        case tmode_option:
                            switch (thebyte)
                            {
                                default:
                                    mode = tmode_normal;
                                    break;
                            }
                            break;
                        }
                    }
                
            }

            tcpClient.Close();
        }

Tuesday, October 05, 2010

Creating a debian iscsi shared raid for backup of vmware esx systems

I usually keep a backup image on one of my test boxes for the production
systems, so I can have a easy way of recoverying in event of disaster.
This previous was a openfiler but found it managed to lose its disk.
So I decided to setup a equivlent system using debian. So using
the minimal network install, I setup a base debian, then added software raid, and finally iscsi target support. Note this is all running as a VM on top of esxi, with raw disks mapped to local sata drives.

First, map your raw disk using vmkfstools

vmkfstools -r /vmfs/devices/disks/vml.0100000000202020202020202020202020395653334e595335535433313530 disk1.vmdk

Next you need to go into the vm, and add the raw vmdk into the vm's config

Now in debian, you will see the raw devices at boot

Next install mdadm

apt-get install mdadm

and you need to install the iscsi target kernel modules

apt-get install iscsitarget-modules-2.6.26-2-686

Now setup the raid
mdadm --create /dev/md0 --level=5 --raid-devices=5 /dev/sdb /dev/sdc /dev/sdd /dev/sde /dev/sdf

To check the status:
mdadm --detail /dev/md0

Now add the disk into the /etc/ietd.conf


Change the following:
#Assuming you want some security, a chap password on incoming user is useful
IncomingUser sinadmin xxyyzz



Target iqn.2001-04.com.rutledge:storage.disk0.sys1.md0
        # Fixup the security  
         IncomingUser sinadmin xxyyzz
        # Block devices, regular files, LVM, and RAID can be offered
        # to the initiators as a block device.
        Lun 0 Path=/dev/md0,Type=fileio


And finally:
invoke-rc.d iscsitarget restart

The get everything using our new config.

Surprisingly I found this no worse than using openfiler, and I know what is happening
behind the covers.