Meteor User Seed

I have been trying to build a site with Meteor and have slowly started getting stuff working.

One of the ways to populate your development data has been with database seeding.

I wanted to link a user account with a document in one of my collections so I worked this out from the documentation.

You add users to the users collection this returns the userId for the new user which you capture in a variable that you use to insert the userId into your second collection.

if (Meteor.users.find().count() === 0) {
  seed1UserId = Accounts.createUser({
    username: 'lance',
    email: 'l@oo.com',
    password: '123456'
  });
  seed2UserId = Accounts.createUser({
    username: 'david',
    email: 'd@oo.com',
    password: '123456'
  });
  seed3UserId = Accounts.createUser({
    username: 'glenn',
    email: 'g@oo.com',
    password: '123456'
  });
  seed4UserId = Accounts.createUser({
    username: 'martin',
    email: 'm@oo.com',
    password: '123456'
  });
}

if (MasterList.find().count() === 0) {
 
  MasterList.insert({
    firstname: "Lance",
    lastname: "James",
    user_id: seed1UserId
  });

  MasterList.insert({
    firstname: "David",
    lastname: "Cope"
    user_id: seed2UserId
  });

  MasterList.insert({
    firstname: "Glenn",
    lastname: "Manner",
    user_id: seed3UserId
  });
  
  MasterList.insert({
    firstname: "Martin",
    lastname: "Drone",
    user_id: seed4UserId
  });
} 
									

,

No Comments

Great Script to tidy Up our Photos

I was looking for a way to tidy up out photos on the NAS at home and have tried a number of things that just did not fit the bill.

they were either just to difficult or completely wrong.

i then stumbled upon this blog post http://falesafe.wordpress.com/2009/07/07/photo-management/

What a gem. if you can install ruby on a machine you have to sort your photos this is it.

The post is from 2009 and so I had to update some of the gems it uses as well as change some of the code. but it was not much work.

Thanks to Falesafe for making it available it had another bonus in that I found out that we have 76000 photos.

I feel some culling is needed.

EDIT:

I had to work with the script a bit as the EXIF attribute it was using was causing my photos to be sorted incorrectly namely (date_time).
So I have updated the script to use the (date_time_original) atribute and this has now sorted my photos properly for me. The original post that was written has comments that are closed so I will upload the adjusted script here if you want to use it.

 

#!/usr/bin/ruby
# == Synopsis
#
# This script examines a source directory for photos and movie files and moves them to
# a destination directory.  The destination directory will contain a date-hierarchy of folders.
#
# == Usage
#
# ruby photo_organizer.rb [ -h | --help ] source_dir destination_dir
#
# == Author
# Doug Fales, Falesafe Consulting, Inc.
# 
# == Change Log
# LANCE HAIG = changed the EXIF attribute used to determine photo date taken to .date_time_original
#
# == Copyright
# Copyright (c) 2009 Doug Fales.
# Licensed under the same terms as Ruby.
require 'rubygems'
require 'exifr'
require 'find'
require 'logger'
require 'optparse'
require 'pathname3'
require 'digest/sha3'

STDOUT.sync = true


#$log = Logger.new("photo_organizer.log", 3, 20*1024*1024)  # Log files up to 20MB, keep at least three around
#$log.info("Photo organizer started...")

def log
  @log ||= Logger.new("photo_organizer.log", 3, 20*1024*1024)  # Log files up to 20MB, keep at least three around
  @log
end

log.info("Photo organizer started...")


def usage()
puts <<-USAGE

   photo_organizer.rb takes a source directory and a destination directory.  All photos
   in the source directory will be scanned for EXIF timestamps and then moved to a
   folder path in the destination directory that corresponds to the year, month, and day
   found in the photo's EXIF data.  Movies will be moved to a "movies" directory
   under the destination dir.

      Usage: ruby photo_organizer.rb [ -h | --help ] source_directory destination_directory

USAGE
exit
end




if ARGV.length < 2
  usage
  exit
end

$file_counter = 0

@source_dir = Pathname.new(ARGV[0]).realpath
@dest_dir = Pathname.new(ARGV[1]).realpath
@movies_dir = File.expand_path(File.join(@dest_dir, "movies"))

log.info("Source: #{@source_dir}")
log.info("Destination: #{@dest_dir}")

opts = OptionParser.new
opts.on("-h", "--help") { usage }
opts.parse!(ARGV) rescue usage

def increment_counter
  $file_counter += 1
  file_counter_string = sprintf("%10d", $file_counter)
  print(13.chr + "Processed: #{file_counter_string} Files")
end

def get_time(f)
  if(is_movie(f))
    time = File.ctime(f)
  else
    time = EXIFR::JPEG.new(f).date_time_original
  end
  log.info("Time for: #{f} is #{time}")
  return time
end

def get_dest_dirs(t)
  year = t.year.to_s
  month = t.strftime("%m_%b_%Y").upcase
  log.info("Destination will be: #{year}/#{month}")
  return [year, month]
end

def get_filename(t, f)
  "#{t.strftime("%Y%m%d")}_#{File.basename(f)}"
end

def rand_hash
  return Digest::SHA3.hexdigest(Time.now.to_i.to_s + rand(10000).to_s)[0..10]
end

def uniquefy(fname, destination)
  unique_name = File.join(destination, "#{File.basename(fname)}_#{rand_hash}#{File.extname(fname)}")
  while(File.exist?(unique_name))
    unique_name = File.join(destination, "#{File.basename(fname)}_#{rand_hash}#{File.extname(fname)}")
  end
  log.info("Made unique_name: #{unique_name}")
  unique_name
end

def exists_any_extension?(filename)
  ext = File.extname(filename)
  up_ext = ext.upcase
  dn_ext = ext.downcase
  return (File.exist?(filename.sub(ext, up_ext)) or File.exist?(filename.sub(ext, dn_ext)) or File.exist?(filename))
end

def move_movie(f)
  log.info("Destination directory is: #{@movies_dir}")
  filename = File.basename(f)
  destination_filename =  File.expand_path(File.join(@movies_dir, filename))
  log.info("Destination file is: #{destination_filename}")
  
  # Move to subdir, with new name
  if(exists_any_extension?(destination_filename))
    destination_filename = uniquefy(filename, @movies_dir)
  end
  
  if(File.exist?(destination_filename)) 
    log.info("ERROR: For some reason, #{destination_filename} still exists after uniquefy.  Will not attempt to move #{f}!")
    return false
  end
  log.info("Doing 'mv #{f} #{destination_filename}'")
  
  FileUtils.mv(f, destination_filename)
  return true
end

def move_image(f, time)
  (year, month) = get_dest_dirs(time)
  destination = File.expand_path(File.join(@dest_dir, year, month))
  log.info("Destination directory is: #{destination}")
  
  #    Make subdir
  FileUtils.mkpath(destination) unless File.exist?(destination)
  
  filename = get_filename(time, f)
  destination_filename =  File.expand_path(File.join(destination, filename))
  
  log.info("Destination file is: #{destination_filename}")
  
  # Move to subdir, with new name
  if(exists_any_extension?(destination_filename))
    destination_filename = uniquefy(filename, destination)
  end
  
  if(File.exist?(destination_filename)) 
    log.info("ERROR: For some reason, #{destination_filename} still exists after uniquefy.  Will not attempt to move #{f}!")
    return false
  end
  
  log.info("Doing 'mv #{f} #{destination_filename}'")
  FileUtils.mv(f, destination_filename)
  return true
end

def is_movie(f)
  return (File.extname(f) =~ /avi|mov|mpg|mp4|arw|raw/i)
end

def is_raw(f)
  return (File.extname(f) =~ /arw|raw/i)
end

unless File.exist?(@movies_dir)
  FileUtils.mkpath(@movies_dir)
end

Find.find(@source_dir) do |f|
  case
  when File.file?(f)

    if(is_movie(f))
      was_moved = move_movie(f)
      increment_counter if was_moved
      next
    end

    begin
      log.info("Processing file: #{f}")
      time = get_time(f)
    rescue => e
      if(f =~ /.DS_Store/)
        log.info("Skipping .DS_Store")
        next
      elsif (e.message =~ /malformed JPEG/)
        log.info("Malformed JPEG: #{f}")
        next
      end
    end

    if(time.nil?) 
      log.info("WARNING: No EXIF time for: #{f}.  Will skip it.")
      next
    end

    was_moved = move_image(f, time)
    increment_counter if was_moved

  when File.directory?(f)
    log.info("Processing directory: #{f}")
  else "?"
    log.info("Non-dir, non-file: #{f}")
  end
end

puts "nFinished."
									

, ,

No Comments

Quest NDS Migrator LogFile Parser

I am currently helping a customer migrate from Novell to Microsoft and they are using the Quest migrator product to move their data to new DFS servers.
They currently have a large amount of data stored on a number of volumes. The sheer number of volumes and data have required that they deploy a large number of the copy engine servers.
The copy engine does not utilize a central logging facility, it stores the logfiles in a folder alongside the copy engine.
This unfortunately has a side affect, that there are now quite a few log files and some are reaching over 1.5GB in size.
Trying to load these files into a text editor as proven impossible and unworkable and another way was needed.

I decided that the best way to achieve this was to use a script that would parse the log files and extract the errors from the files into another file that would be smaller and easier to work with.

I decided to use Powershell as the scripting language as it would run on the new infrastructure and could be run on a copy engine server with enough disk space.

I undertook quite a bit of research and trial and error but eventually I have a working script.

This script is not signed so you will either need to sign the script to run it or elevate the privileges with set-Executionpolicy on the system you are going to be using.

The script uses two files the main script file and a csv file with the volume names and copy engine server names.

Below you will find a copy of both. I have also created a git repository that you can find on GitHub if you would like to help make it better

Original PowerShell Script

# Quest Migrator Logfile Parser
$d = Get-Date
$logFileRPath = "D:Logslogs"
$logFilePath = "D:Logs"
$logFileEPath = "D:Logserrors"
$logFileDate = $d.Day - 1
$logFiles = Get-ChildItem $logFileRPath | where { $_.LastWriteTime.Day -eq $logFileDate}
# Add more copy machines to the file below.
$copyServers = Import-Csv $logFilePathqmcopyservers.csv
#Write-Host "LogDate Is" $logFileDate
Write-Host
Write-Host "Copy Servers To Use"
foreach ($server in $copyServers) {
        $copyMachine = $server.CopyMachine
        $copyVolume = $server.Volume
        $sourcePath = "\$copyMachinendsmigLogsFile Migration"
        Write-Host $copyMachine
        #Write-Host $sourcePath
        $sourceLog = Get-ChildItem $sourcePath*Scan.log | where { $_.LastWriteTime.Day -eq $logFileDate}
        #Write-Host $sourceLog.LastWriteTime
        Copy-Item -path $sourceLog -destination $logFileRPath"$copyVolume"-Scan.log
        }
Write-Host
Write-Host "Log Files Selected"
foreach ($logFile in $logFiles) {
        #Write-Host $logFile
        }
Write-Host 
foreach ($objFile in $logFiles) 
    {
        Write-Host "Processing LogFile" $objFile
        gc $logFileRPath$objFile -read 10000 | %{$_} | ? {$_ -like '*Error   *'} | Out-File $logFileEPath"$objFile"-errors.log
        }
									

Original CSV File

Volume, CopyMachine
NWVOLUME1,COPYMACHINE1
NWVOLUME2,COPYMACHINE2
NWVOLUME3,COPYMACHINE3
NWVOLUME4,COPYMACHINE4
NWVOLUME5,COPYMACHINE5
									

, , ,

1 Comment

Bongo Admin UI Images

I have uploaded some images of the new UI so you can see what it looks like without installing it.

Please let me know what you think.

 

 

 

, , ,

No Comments

Building the new Bongo Admin UI

A while ago Alex (so_solid_moo to the IRC channel) created a php binding for the Bongo API. He also created the start of the new UI that we are working towards.

We started with the admin ui for now as we have created a user interface with the roundcube project that Alex also integrated with.

I stared porting the current Dragonfly assets into the project and I tried to stick to the old design style as much as possible as I really loved it’s look and feel.

After a bout a week I was done and submitted it to the git repo of the new project.

Although I was glad that we had stared the project and that I had done as well as I could on the pretty bits I was not quite happy with the quality of the work.

I was going through my git repo’s this weekend and found the twitter git repo where they have open sourced all their CSS (Cascading Style Sheets) http://twitter.github.com/bootstrap/ this inspired me to see if I could use this as it was MUCH better quality CSS that what I could come up with.

So I started work on the migration as an experiment and from the word go it was so much easier. Their default styles just make sense and to alter or add my customisation took only a very few lines of CSS code.

I was extremely grateful for this as it will enable us to improve our UI as we go along. you can find the new webui in Alex’s github project here.

Thanks twitter

, , ,

No Comments

My interesting way to end a week.

This is an account of Thursday the 29th of September 2011 when my cynical view on Londoners only thinking of themselves and not wanting to get involved with other peoples troubles was blown completely out of the water thanks to some really amazing people who I don’t have names for but would really love to thank from the depths of my heart for everything they did for me.

The story begins as I am making my way from Hertfordshire down to Camden on my commute to get to the office.

At about 08:22 in the morning I was driving down Hawley Road on my motorcycle and stopped for a Red traffic light at the junction with Jeffrey’s and Camden Street after a short while the light turned orange and then green for us. As this is normally when a load of cyclists jump the red light on the Kentish Town Road part of this junction I made sure to check that none had done so and then started to travel across the junction, once I had reached about ¾ of the way across the junction I felt the most unbelievable pain on my left side, felt myself hit the road surface on my right hand side and heard my self screaming. (and no it was not like a girl but close though)

The pain was something that was indescribable and all I could see was my bike over my left shoulder and the smell petrol that was leaking out of the petrol tank around me. I looked up to see if any cars were coming and unable to stop but thankfully none were.

(This is where people who I have never known stepped into my life to my eternal thanks)

Almost immediately I gentleman in a dark suite was leaning over me looking through my visor and asking if I was ok, All I could feel at the time was the screaming pain in my left foot and answered yes. I looked over my shoulder and saw another gentleman talking to a young lad in a grey helmet all I could hear was did you not see the red light.

Out of the corner of my eye I saw another gentleman in a black helmet and a white shirt (I think) take off his helmet and say “are you ok mate?”, “Do you know your Name?” I tried to answer him as best I could. I then realised that I had not hurt my head or hands or arms so decided to take off my helmet so I could see and hear better as I use earplugs in my ears to protect them from the motorway sounds.

After taking off my helmet and taking out my ear plugs the intense loads sounds flooded into my brain and I realised that my helmet had cut off my ability to realise that there were so many more people who had stopped on there way to work to help me.

I looked behind me and could see the young chap who had ridden into me sitting against the railings on the pavements clearly in a great deal of shock and I became worried for him as he was really pale. A bit further over I looked at what was left of his Vespa and thought Bloody hell how am I still conscious and he sitting there.

A wonderful vision in dayglo yellow cyclists gear was a lady who promptly informed me that she had called the ambulance and the police and that they would soon be here.

My attention was grabbed by a tapping on my Right hand shoulder another man in motorcycle helmet leaned in and said “I was right behind you and saw it all, here is my business card I will be a witness for you”, and with that he was off and climbed on his bike and road off. I did not even have time to say thanks.

All this time the gentlemen in the dark suite and white shirt kept talking to me asking me if I still felt ok. He asked me if I would like to get out of the road to which I agreed but then I realised that at 118 kgs and being over 6feet would make things difficult for them so I crawled towards the pavement.

I remained calm which I was pleasantly surprised about and this helped I think everyone around me to keep focussed on what they needed to do to help me.

For some reason I was worried about my laptop that was in the storage on the back of my bike and so asked the gentleman in the white shirt if he would mind getting it out for me. He duly did and I can only thank him for that. I was after my mobile phone so I could call my wife as I did not want anyone calling her first and scaring her. The gentleman in the white shirt said just use mine I don’t mind.

It was about 3 minutes later that the first ambulance arrived on the scene and two lady ambulance paramedics climbed out and started to do there work on me.

After a short while I was in the ambulance and through the open door I could see the man in the suite and the one in the white shirt smile at each other and then as if to say well no one else will do this they shrugged their shoulders and these wonderful people physically righted motorbike and wheel it onto the pavement.

The ambulance staff (I wish I had taken their names) then closed the door and started going through their procedures Blood pressure finger pricks blood oxygen levels etc… and they did this with a smile on their faces and in their voices. To anyone who ever says anything bad about the NHS ambulance staff I think you are completely mistaken.

We then heard the police siren and a Metropolitan police officer PC Barker knocked on the door and entered again these guys were the nicest people to talk to and were a credit to their profession.

After a few more questions and answers we were free to go and I was taken to the Royal Free Hamsted hospital where I was taken to the Minors 4 cubical where some really great medical staff came to my aid and scanned and prodded and x-rayed me whilst some learner Dr’s etc.. looked on and I am glad I could add one more addition to their education a RTC between two motorcycles.

The orthopedic staff determined that I had a fractured ankle and would not need screws etc.. (whew) and a cast would be all that is needed to med these broken bones.

My wonderful wife then walked in to the cubical and I relaxed quite a bit as I knew that my day could only get better from then on. After getting a back slab plaster cast and with strict instructions not to walk on my leg and a booked appointment for the fracture clinic next Thursday We dutifully made our way out of the hospital. I had not used crutches in a very long time so it was slow going.

The wonderful people at the company I work for help arrange transport home from the hospital to home where I was happy to sit on the couch with my foot up. My motor mechanic friend woke up at 4am and went to pick up my motorbike on Friday I can’t that Duncan enough.

So to all you wonderful people

  • Gentleman in the Dark suite
  • Gentleman in the White Shirt
  • Lady cyclist dressed in dayglo yellow
  • Gentleman who gave me his business card.
  • The people who helped roll my motorbike to the pavement
  • The two ladies who drove the ambulance
  • PC Barker and his partner
  • The medical staff at the Royal Free Hamstead hospital
  • Duncan from Bikers realm

I wish I had had the forethought to get all your names so I could thank you in person all I can do unfortunately is thank you from the bottom of my heart and on behalf of my Mother, Father,Wife and kids thank you for helping to get me safely home.

No Comments

How to copy custom attributes when migrating vmware vcenter to new database

I recently had to move hosts and guests to a new vcenter server as the old server had become corrupt and full of issues.
The current vcenter has a few custom attributes and notes that would not be transferred as part of the move.
So I wanted to use powercli to read the attributes out and put them back.

To export the attributes I used the script below.
You will need to add as many Key Value pairs as you have custom attributes

#load Vmware Module
Add-PSSnapin VMware.VimAutomation.Core

Connect-VIServer -User 'VMUSER' -Password 'USerPasswd221' -Server 'vcenter1'

$vmlist = get-vm 
$Report =@()
    foreach ($vm in $vmlist) {
        $row = "" | Select Name, Notes, Key, Value, Key1, Value1, Key2, Value2, Key3, Value3
        $row.name = $vm.Name
        $row.Notes = $vm | select -ExpandProperty Notes
        $customattribs = $vm | select -ExpandProperty CustomFields
        $row.Key = $customattribs[0].Key
        $row.Value = $customattribs[0].value
        $row.Key1 = $customattribs[1].Key
        $row.Value1 = $customattribs[1].value
        $row.Key2 = $customattribs[2].Key
        $row.Value2 = $customattribs[2].value
        $row.Key3 = $customattribs[3].Key
        $row.Value3 = $customattribs[3].value    
        $Report += $row
    }

$report | Export-Csv "c:vms-with-notes-and-attributes.csv" -NoTypeInformation
									

It should produce a csv file that looks something like this

VMNAME,NOTES,CREATEDATE,CREATOR,DEPLOYDATE,TEAM
vmguest1,note1,12/29/2011,Bob,12/30/2011,Web
vmguest2,note2,12/29/2011,John,12/30/2011,Accounts
vmguest3,note3,12/29/2011,Paul,12/30/2011,Database
									

Once you have exported the file you need to import it into the new vCenter
again adding Key Value pairs as needed.

#load Vmware Module
Add-PSSnapin VMware.VimAutomation.Core

Connect-VIServer -User 'VMUSER' -Password 'USerPasswd221' -Server 'vcenter2'


$NewAttribs = Import-Csv "C:vms-with-notes-and-attributes.csv"

    foreach ($line in $NewAttribs) {
        set-vm -vm $line.Name -Description $line.Notes -Confirm:$false
        Set-CustomField -Entity (get-vm $line.Name) -Name $line.Key -Value $line.Value -confirm:$false
        Set-CustomField -Entity (get-vm $line.Name) -Name $line.Key1 -Value $line.Value1 -confirm:$false
        Set-CustomField -Entity (get-vm $line.Name) -Name $line.Key2 -Value $line.Value2 -confirm:$false
        Set-CustomField -Entity (get-vm $line.Name) -Name $line.Key3 -Value $line.Value3 -confirm:$false
    
    }

									

Hope this helps someone.

,

2 Comments

Creating a Two Node Mysql Cluster On Ubuntu With DRBD Part 2

This blog is a follow on from a blog post I wrote ages ago and have eventually got round to finishing it off

In this part of the process we will create the disks and setup the DRBD devices
First we need to connect to the Virtual Machines from a terminal session as it makes life much easier and quicker when you connect remotely.
You will need to make sure that your servers have static IP addresses.
For this document I will be using the following IP addresses for my servers.

drbdnode1 = 172.16.71.139
drbdnode2 = 172.16.71.140
drbdmstr = 172.16.71.141 (clustered IP address)
Subnet Mask = 255.255.255.0
Gateway = 172.16.71.1
DNS Servers = 8.8.8.8 and 4.4.4.4
									


So to set the IP address as fixed you need to do the following.
Connect to the console of drbdnode1 and login
now we need to edit the file that contains the IP address of the network card
enter the following command and press return

sudo nano /etc/network/interfaces
									


enter the password for the user you are logged in as
You should see the following screen

now use your arrow keys on your keyboard and move the white cursor to the section that starts with iface eth0
press Ctrl K to remove the line then add the lines below with your IP address details

auto eth0
iface eth0 inet static
address 172.16.71.139
netmask 255.255.255.0
network 172.16.71.0
broadcast 172.16.71.255
gateway 172.16.71.1
									


It should end up looking like this

Now press Ctrl X to exit
Then Y
Then press Enter to save
Now type in the following

sudo /etc/init.d/networking restart
									


Do the same for drbdnode2
Now that we have given each server a static Ip address we can connect via ssh to the server to do the admin remotely.
To do this you need to have a machine that has an ssh client installed most linux and osx clients have one already installed if you are on windows look for putty and use that.
So open a terminal on your machine and the in the following

ssh cluster@172.16.71.139 and press enter.
									


You need to substitute the username you created on your server when setting it up for the word cluster in the above command.
You will be prompted to accept a key for the server. Type yes and press enter.
Now enter the password for the user and press enter.
You should see a screen like this

Connect to both cluster nodes to make sure you are not stopped down the line to fix the problem.
You are now ready to work on your cluster.
First we need to create host records for the two servers
type the following into your terminal session

sudo nano /etc/hosts
									


and add a record for each server it should look something like this

Save the file as before and do the same for node2 but swap the names and ipadresses
Now we need to install a few packages that will allow us to use drbd
in the terminal on drbdnode1 type

apt-get install heartbeat drbd8-utils
									


and press enter you should have a screen like this

Press Y and then Enter to install the software. Do this on drbdnode2 as well
Now we need to create the partitions that we will use for the drbd cluster
to find out which disk we will be using run the command

sudo fdisk -l
									


to see which disks have not been partitioned your screen should look like this

As you can see at the end is the disk /dev/sdb does not have a partition table
look for the line “ Disk /dev/sdb doesn’t contain a valid partition table “
to create a partition table we need to run the following commands

sudo fdisk /dev/sdb
n (to create a new partition)
p (to select a primary partition)
1 (for the first partition)
Enter (to select the start cylinder)
and enter (to select the end cylinder)
w (to write the changes)
									


the screen should look like this

Do this on both servers
once this is complete we now need to edit the drbd configuration files to set up our clustered filesystem.
In your terminal on drbdnode1 enter the command

sudo nano /etc/drbd.d/clusterdisk.res
									


Enter the password for your user and edit the file
Copy and paste the following code into your terminal screen and then change the details to match your server names and ipaddresses

resource clusterdisk { # name of resources

protocol C;

on drbdnode1 { # first server hostname

device /dev/drbd0; # Name of DRBD device

disk /dev/sdb1; # Partition to use, which was created using fdisk

address 172.16.71.139:7788; # IP addres and port number used by drbd

meta-disk internal; # where to store metadata meta-data

}

on drbdnode2 { # second server hostname

device /dev/drbd0;

disk /dev/sdb1;

address 172.16.71.140:7788;

meta-disk internal;

}

disk {

on-io-error detach;

}

net {

max-buffers 2048;

ko-count 4;

}

syncer {

rate 10M;

al-extents 257;

}

startup {

wfc-timeout 0;

degr-wfc-timeout 120; # 2 minutos.

}

}
									


The screen should look similar to this

ctrl x (to exit)
y (to save the changed file)
enter (to overwrite the file)
Now we need to create the DRBD resource
enter the following command into your terminal session

sudo drbdadm create-md clusterdisk
									


After running this command you should see a screen similar to this

On drbdnode1 enter the following command

drbdadm -- --overwrite-data-of-peer primary all
									


this will activate it as the primary drbd node
to see if this has worked you can run the following command

sudo drbdadm status
									


the result should look like this on drbdnode1

and like this on drbdnode2

you will see that drbdnode1 has a status of
cs=”SyncSource”
and drbdnode2 has a status of
cs=”SyncTarget”
this tells you what role they are playing in the cluster
at the end of this line you will see a status resynced_percent=”3.8″
this tells you how much the drbd disk has synced.
Once the sync is complete connect to drbdnode1 and run the following command

sudo mkfs.ext4 /dev/drbd0
									


this will create an ext4 partition on the drbd file system. Which will sync across to drbdnode2

Configuring heartbeat resource

Now we need to setup the Mysql resource in the heartbeat configuration
firstly we need to create a file called authkeys. The file should be created in /etc/ha.d directory. You can do this with the following command

nano /etc/ha.d/authkeys
									


in this file you need to add the following text.

auth 3

3 md5 [SECRETWORD]
									


Replace [SECRETWORD] with a key you have generated.
This file needs to be on both servers in the /etc/ha.d directory.
After you have created the file you need to change the permissions on the file to make it more secure. This can be done with the following command

chmod 600 /etc/ha.d/authkeys
									


do this on both servers
Now we need to create the /etc/ha.d/ha.cf file to store the cluster config.
You can do this with the following command

nano /etc/ha.d/ha.cf
									


copy and paste this code into the file

logfile /var/log/ha-log

keepalive 2

deadtime 30

udpport 695

bcast eth0
auto_failback off
stonith_host drbdnode1 meatware drbdnode2
stonith_host drbdnode2 meatware drbdnode1
node drbdnode1 drbdnode2
									


do the same for both servers
next is the haresources file. Create the file here

nano /etc/ha.d/haresources
									


paste this code in there

dhcp-1 IPaddr::172.16.71.141 /24/eth0 drbddisk::clusterdisk Filesystem::/dev/drbd0::/var/lib/mysql::ext4 mysql
									


Your cluster is now ready to role.
All you now need to do is test the cluster which I will tell you how to do in a future blog post
Let me know how you get on

, , ,

7 Comments

ESX Trunk VLAN config for Storage

I was struggeling with an install of ESXi on a cisco 6509 switch where the management and VM LAN connectivity worked just fine but for some reason the SAN NFS VLAN just did not want to communicate with the Nexenta on that VLAn.

After some searching and trial and error I was able to utilise this post http://blogs.egroup-us.com/?p=2453 to get the port-channel and the ports configured correctly. I did not use all the settings from this post but it did remind me to check my port0-channel config.

, , ,

No Comments

Connecting ESXi 4.1 to extreme x650 10G switches

I am busy working on a contract with a comonay that is implementing a 10G network for their ESX cluster.

We have been using extreme X650 10G copper switches for the core.

Migrating the current servers to the 10G environment was relatively easy and went with minimal issues.

Over the last 2 weeks I have been trying to get a new server to connect to the cluster ahnd have been frustrated. I have been unable to get the server communicating on the management VLAN. the server was configured correctly and so was the switch or so I thought.

It seems that to make this work you need to add the network cards to the vlan in the extreme os as untagged which then allows you to connect the server to vCenter and then once you add your NIC’s to the dv switch you lose connectivity again and have to readd the ports to the management vlan as tagged.

this post is more fo rme to be able to look it up in the future.

,

No Comments