Mon HostProfile n'est plus compliant !

Nous avons rencontré un problème assez intéressant concernant les HostProfile.

Pour rappel, les HostProfile correspondent à des profils (jusque là, assez logique) dans lequel sont stockées des informations de configuration et qui peuvent être utilisés afin de répliquer cette configuration à d’autres serveurs hôtes. Par exemple, vous montez un cluster vSphere avec x nodes, vous effectuez la configuration type sur un des noeuds, et la répliquer sur tous les autres.

Cela permet notamment d’assurer une unicité dans la configuration des hôtes (pour éviter des problèmes divers comme des incidents lors de vMotion si l’orthographe des noms de PortGroup sont différents) et de facilité la mise à jour (on ne met à jour que le profil que l’on rapplique sur les hôtes).

Pour en revenir à notre problème, on avait une alerte dans le vCenter comme quoi un hôte n’était pas compliant sur le profil du cluster. L’alerte remontée était :

For port group xxx network policy property spec.policy.nicTeaming.failureCriteria doesn't match

Sur la console, dans la configuration du Teaming, on avait des valeurs identiques sur tous les hôtes, par exemple :

Nous nous sommes donc posé la question de savoir ce qu’attendait le HostProfile, en l’exportant en xml, on a eu pour la configuration de ce PortGroup :

<policy>
	<id>NetworkFailoverPolicy</id>
	<policyOption>
		<id>FixedFailoverCriteria</id>
		<parameter>
			<key>criteria</key>
			<value xsi:type="HostNicFailureCriteria">
				<checkSpeed>minimum</checkSpeed>
				<speed>10</speed>
				<checkDuplex>false</checkDuplex>
				<fullDuplex>false</fullDuplex>
				<checkErrorPercent>false</checkErrorPercent>
				<percentage>0</percentage>
				<checkBeacon>false</checkBeacon>
			</value>
		</parameter>
	</policyOption>
</policy>

En voyant tous les paramètres présent dans la configuration du HostProfile et après plusieurs vérifications, on a découvert que c’était certains paramètres du Teaming qui n’étais pas visibles sur la console qui différaient.

Pour s’en assurer, on a réaliser ce script d’affichage de ces paramètres :

$clusNameToCheck = "xxx"
$portGroupToCheck = "xxx"
$report = @()

$hostsClus = Get-Cluster -Name $clusNameToCheck | Get-VMHost | Get-View

foreach($esx in $hostsClus){
	$esx.Config.Network.PortGroup | where {$_.Key -eq "key-vim.host.PortGroup-$portGroupToCheck"} | %{
		$repEsx = "" | select-Object Name, checkSpeed, speed, checkDuplex, fullDuplex, checkErrorPercent, percentage, checkBeacon
		$repEsx.Name = $esx.name
		$repEsx.checkSpeed = $_.Spec.Policy.NicTeaming.FailureCriteria.checkSpeed
		$repEsx.speed = $_.Spec.Policy.NicTeaming.FailureCriteria.speed
		$repEsx.checkDuplex = $_.Spec.Policy.NicTeaming.FailureCriteria.checkDuplex
		$repEsx.fullDuplex = $_.Spec.Policy.NicTeaming.FailureCriteria.fullDuplex
		$repEsx.checkErrorPercent = $_.Spec.Policy.NicTeaming.FailureCriteria.checkErrorPercent
		$repEsx.percentage = $_.Spec.Policy.NicTeaming.FailureCriteria.percentage
		$repEsx.checkBeacon = $_.Spec.Policy.NicTeaming.FailureCriteria.checkBeacon
		$report += $repEsx
	}
}
$report | Format-Table -Autosize

Le retour de cela pour le cluster et le PortGroup qui faisait défaut a été :

Name checkSpeed speed checkDuplex fullDuplex chErrPerc perc checkBeacon
---- ---------- ----- ----------- ---------- --------- ---- -----------
xxx                 0       False      False     False    0       False
xxx  minimum       10       False      False     False    0       False
xxx  minimum       10       False      False     False    0       False
xxx  minimum       10       False      False     False    0       False
xxx  minimum       10       False      False     False    0       False
xxx                 0       False      False     False    0       False
xxx  minimum       10       False      False     False    0       False
xxx  minimum       10       False      False     False    0       False

On voit bien que 2 des hôtes n’ont pas la même valeur que les autres (ceux qui apparaissent comme étant non-compliant)

Pour remettre les choses d’équerre, mettre le serveur hôte qui a le problème, réappliquer le HostProfile

Dans certains, cela ne suffira pas. Il sera donc possible d’effectuer cette manipulation en PowerCLI via le script suivant :

$hostESX = "xxx"</p>
$pgname = "xxx"
$vSwitch = "xxx"
$esx = Get-VMHost "$hostESX" | Get-View

$net = Get-View $esx.configmanager.networksystem

$portgroupspec = New-Object VMWare.Vim.HostPortGroupSpec
$portgroupSpec.vswitchname = $vSwitch
$portgroupspec.Name = $pgname
$portgroupspec.policy = New-object vmware.vim.HostNetworkPolicy
$portgroupspec.policy.NicTeaming = New-object vmware.vim.HostNicTeamingPolicy
$portgroupspec.policy.NicTeaming.failureCriteria = New-Object vmware.vim.HostNicFailureCriteria
$portgroupspec.policy.NicTeaming.failureCriteria.checkSpeed = "minimum"
$portgroupspec.policy.NicTeaming.failureCriteria.speed = 10

$net.UpdatePortGroup($pgname,$PortGroupSpec)

La méthode UpdatePortGroup ne provoque pas d’interruption réseau (contrairement à la modification du teaming active-standby), mais pour être sûre, tester auparavant !

LucD a réalisé un excellent document Word sur l’utilisation de PowerCLI pour le NIC Teaming sur vSphere, vous pouvez le trouver là : Portgroup – how to configure Nic Teaming, merci à lui !

Rapport du VMworld 2010 de Copenhague

Pour ceux qui ne le savait pas, VMware avait fait une session de rattrapage de l’évènement VMworld (billet disponible : vmworld 2010, cours de rattrapage) à Copenhague entre le 12 et le 14 octobre.

Si vous n’avez pas pu aller voir ce VMworld (l’année prochaine peut être :p), vous pouvez aller visiter le très bon virtualclouds.info de Remon Lam qui a créé un billet très complet de toutes les news, interviews, vidéos et articles ayant un rapport avec cet évènement VMware.

Le billet est détaillé en 4 jours et sont encore mis à jour !

Je vous conseille d’ailleurs l’excellente vidéo de l’interview d’Alan Renouff et Luc Dekens (disponible sur le jour 4, ou directement sur le site d’Eric Sloof) :

Une ballade à Londres le 8 octobre ?

Vendredi, Londres sera sous le signe de PowerCLI !

VMware organise un séminaire qui doit vraiment valloir le détour : Managing vSphere in large environments using APIs and PowerCLI

L’avantage ? c’est gratuit :) L’inconvénient ? les places sont limitées :(

Pour plus d’informations sur cet évènement, vous pouvez allez voir le très bon post de A. Renouf : http://www.virtu-al.net/2010/09/30/vmware-event-london-8th-oct-not-to-be-missed/

Edit : Alan Renouf vient de poster ici le début des interviews au format MP3 (ainsi que les vidéos FLV), je vous conseille tous d’aller y jetter un coup d’oeil, ça vaut vraiment le détour !

Wallies is ready !

Wallies ??? quoi c’est ?

Alors, en fait Wallies, qu’est ce que c’est ? C’est un programme en .NET qui permet de gérer un slideshow des fonds d’écran (oui, ça existe déjà) mais en multiscreen (là déjà moins, ou alors payant).

Ca a commencé lors de mon achat d’un 2ème écran. 2 écrans c’est bien, mais on trouve beaucoup moins de fond d’écran en 3840*1200 qu’en 1920*1200 (et les fond d’écrans monochromes sont pas pour moi)…

Certes, on en trouve quand même mais le choix est limité. J’ai donc commencé à les faire moi même mais j’avoue que le résultat est pas tiptop, et yen a toujours peu.

C’est là que Wallies est arrivé (^^). En fait Wallies est un petit programme qui va permettre d’afficher un fond d’écran par écran avec une fréquence de mise à jour.

J’ai un dossier qui contient énormément de photos/images que j’aime bien avoir en fond d’écran. Wallies va piocher 2 images dans ce dossier et en afficher une par écran.

Il se met dans la barre systray de Windows et va effectuer un changement de fond d’écran (comme le slideshow de Windows) toutes les 10 minutes (sachant que ce paramètres peu être changé)

Il prend 2 paramètres qui sont stockés dans le fichier .config avec le programme :

  • rootPathWallies : chemin d’accès aux différentes images
  • imageMergedPath : chemin d’enregistrement du fond d’écran recomposé

Le programme en lui même est basique, mais il fait ce qu’on lui demande et depuis, mes 2 écrans sont contents ^^

Utilisation de Wallies

Une fois lancé, il apparait donc dans le systray et permet d’effectuer 3 actions :

  • Sync Now : lance instantanément la modification des fonds d’écran
  • Change Interval : permet de définir une nouvelle fréquence de changement de fond d’écran automatique (de base = 10 minutes)
  • Exit : quitte l’application

Changement de fréquence

Les binaires

Le programme est composé de 3 fichiers :

  • favicon.ico : icone qui sera utilisé pour le systray
  • wallies.exe : l’exécutable
  • wallies.exe.config : fichier de configuration

Vous pouvez télécharger les binaires Windows ici : [download id="6"]

Mot de passe d’archive : cd3

Le code

Le programme est composé de peu de chose, une form et un module.

Je vous met le code directement ici :

mdl_Main.vb

Imports System.Diagnostics
Imports System.Text
Imports System.IO

Public Module modMain
    Public Structure structWallies
        Dim imageLeft As Image
        Dim imageRight As Image
        Dim imageLeftPath As String
        Dim imageRightPath As String
    End Structure

    Public notIcon As NotifyIcon
    Public WithEvents contMenu As ContextMenu
    Public WithEvents mobTimer As Timers.Timer
    Public intervalTimer As Integer = 600000 ' in ms
    Public wallies As New structWallies()
    Public rootPathWallies As String = My.Settings.rootPathWallies
    Public imageMergedPath As String = My.Settings.imageMergedPath

    Public Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA" (ByVal uAction As Integer, ByVal uParam As Integer, ByVal lpvParam As String, ByVal fuWinIni As Integer) As Integer
    Public Const SPI_SETDESKWALLPAPER = 20
    Public Const SPIF_UPDATEINIFILE = &H1

    Public Sub Main()
        Try
            ' Création de l'icone de systray
            notIcon = New NotifyIcon()
            notIcon.Visible = False
            contMenu = New ContextMenu()
            contMenu.MenuItems.Add(New MenuItem("Sync Now", New EventHandler(AddressOf SyncWallies)))
            contMenu.MenuItems.Add(New MenuItem("Change Interval", New EventHandler(AddressOf ChangeInterval)))
            contMenu.MenuItems.Add("-")
            contMenu.MenuItems.Add(New MenuItem("Exit", New EventHandler(AddressOf ExitWallies)))
            notIcon.ContextMenu = contMenu
            notIcon.Icon = New Icon("favicon.ico")
            contMenu.MenuItems(0).Enabled = True
            contMenu.MenuItems(1).Enabled = True
            contMenu.MenuItems(2).Enabled = True
            ' Initialisation du timer
            SetUpTimer(intervalTimer)
            notIcon.Visible = True
            ' Lancement de l'app
            Application.Run()
        Catch obEx As Exception
            Throw obEx
        End Try
    End Sub

    Public Sub SyncWallies()
        Try
            ' Récupération de 2 images en aléatoire
            pickWallies(rootPathWallies)
            ' Création de l'objet qui va recevoir l'assemblage des 2 images
            Dim myGraphic As System.Drawing.Graphics = Nothing
            Dim m As New Bitmap(3840, 1200)
            Dim destRectLeft As New Rectangle(0, 0, 1920, 1200)
            Dim destRectRight As New Rectangle(1920, 0, 1920, 1200)
            ' Construction de l'assemblage
            myGraphic = System.Drawing.Graphics.FromImage(m)
            myGraphic.DrawImage(wallies.imageLeft, destRectLeft)
            myGraphic.DrawImage(wallies.imageRight, destRectRight)
            myGraphic.Save()
            ' Sauvegarde en jpg pour que Windows puisse lire le fond d'écran
            m.Save(imageMergedPath, System.Drawing.Imaging.ImageFormat.Jpeg)
            ' Réinitialisation du fonc d'écran de Windows
            SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, imageMergedPath, SPIF_UPDATEINIFILE)
            ' Destruction des objets pour libération mémoire
            wallies.imageLeft.Dispose()
            wallies.imageLeftPath = Nothing
            wallies.imageRight.Dispose()
            wallies.imageRightPath = Nothing
            myGraphic.Dispose()
            m.Dispose()
            destRectLeft = Nothing
            destRectRight = Nothing
        Catch obEx As Exception
            Throw obEx
        End Try
    End Sub

    Public Sub ChangeInterval()
        ' Appel de la form de changement d'interval
        Try
            frm_IntervalTimer.Show()
        Catch obEx As Exception
            Throw obEx
        End Try
    End Sub

    Public Sub ExitWallies()
        ' Fermeture de l'application, suppression de l'icone de notification
        Try
            notIcon.Visible = False
            notIcon.Dispose()
            Application.Exit()
        Catch obEx As Exception
            Throw obEx
        End Try
    End Sub

    Public Sub pickWallies(ByVal path)
        Try
            Dim objFolder As DirectoryInfo = New DirectoryInfo(path)
            Dim r As New Random(System.DateTime.Now.Millisecond)
            Dim colWallies As New ArrayList
            Dim tmpLeft, tmpRight As String
            ' Parcours du dossier racine pour listing des fichiers
            For Each wally As FileInfo In objFolder.GetFiles("*.jpg")
                ' On remplit une liste avec les fichiers
                colWallies.Add(wally.FullName)
            Next
            ' Première génération alétoire
            tmpLeft = colWallies.Item(r.Next(0, colWallies.Count))
            wallies.imageLeft = Image.FromFile(tmpLeft)
            wallies.imageLeftPath = tmpLeft
            ' Deuxième générataion aléatoire
            tmpRight = colWallies.Item(r.Next(0, colWallies.Count))
            ' Vérification pour éviter 2 fois le même fond d'écran
            Do Until (tmpRight <> tmpLeft)
                tmpRight = colWallies.Item(r.Next(0, colWallies.Count))
            Loop
            wallies.imageRight = Image.FromFile(tmpRight)
            wallies.imageRightPath = tmpRight
            ' Destruction des objets
            objFolder = Nothing
            r = Nothing
            colWallies = Nothing
            tmpLeft = Nothing
            tmpRight = Nothing
        Catch obEx As Exception
            Throw obEx
        End Try
    End Sub

    Public Sub SetUpTimer(ByVal interval As Integer)
        ' Définition de l'objet timer qui permet de scheduler le changement de fond d'écran tous les x
        Try
            mobTimer = New Timers.Timer()
            With mobTimer
                .AutoReset = True
                .Interval = interval ' en millisecond
                .Start()
            End With
        Catch obEx As Exception
            Throw obEx
        End Try
    End Sub

    Public Sub mobTimer_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) Handles mobTimer.Elapsed
        ' A la fin du temps imparti, on relance le changement de fond d'écrans
        Try
            SyncWallies()
        Catch obEx As Exception
            Throw obEx
        End Try
    End Sub
End Module

frm_IntervalTimer.vb

Public Class frm_IntervalTimer

    Private Sub IntervalTimer_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        NumericUpDown1.Value = modMain.mobTimer.Interval / 60000
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        modMain.SetUpTimer(NumericUpDown1.Value * 60000)
        Me.Dispose()
    End Sub
End Class

Sinon, voici les sources (Visual Studio 2010) en fichier zip : [download id="7"]

Mot de passe d’archive : cd3

VMware et le Dude

Juste pour vous informer que je vais dorénavant plus me focaliser sur les produits VMware et relâcher un chouilla (pas trop quand même :p) la partie Exchange.

La raison de ce revirement ? Une évolution professionnelle et une opportunité qui j’espère me permettra de gagner mes ailes dans ce monde plein de nuages ….

J’en profite d’ailleurs pour remercier www.hypervisor.fr qui montre que la communauté francophone dans ce domaine est loin d’être inexistante et qui est une très bonne source d’information de qualité, je vous conseille vivement d’y aller faire un tour !

Donc normalement, la proportion de billets sur VMware et consort risque de bien évoluer dans le futur, bien qu’il me reste encore pas mal de choses à récupérer de l’existant qui sera plus accès sur AD/Exchange.