{"action":"created","comment":{"url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/pulls/comments/86162414","pull_request_review_id":6833481,"id":86162414,"diff_hunk":"@@ -106,1360 +56,800 @@ function Install-Prerequisites {\n     return $rebootNeeded\n }\n \n-function Get-OpenstackVersion {\n-    $distro = Get-JujuCharmConfig -Scope \"openstack-version\"\n-    if($distro -eq $false){\n-        $distro = Get-JujuCharmConfig -Scope \"openstack-origin\"\n-    }\n-    return $distro\n-}\n+function New-ExeServiceWrapper {\n+    $pythonDir = Get-PythonDir -InstallDir $NOVA_INSTALL_DIR\n+    $python = Join-Path $pythonDir \"python.exe\"\n+    $updateWrapper = Join-Path $pythonDir \"Scripts\\UpdateWrappers.py\"\n \n-function Get-NetType {\n-    $net_type = Get-JujuCharmConfig -Scope \"network-type\"\n+    $cmd = @($python, $updateWrapper, \"nova-compute = nova.cmd.compute:main\")\n+    Invoke-JujuCommand -Command $cmd\n \n-    $distro = Get-OpenstackVersion\n-    if($distro_urls[\"ovs\"] -eq $false -or (Get-IsNanoServer)){\n-        #force hyperv network manager for versions that do now support ovs\n-        $net_type = \"hyperv\"\n+    $version = Get-OpenstackVersion\n+    $consoleScript = \"neutron-hyperv-agent = neutron.cmd.eventlet.plugins.hyperv_neutron_agent:main\"\n+    if ($version -ge \"mitaka\") {\n+        $consoleScript = \"neutron-hyperv-agent = hyperv.neutron.l2_agent:main\"\n     }\n-    return $net_type\n+\n+    $cmd = @($python, $updateWrapper, $consoleScript)\n+    Invoke-JujuCommand -Command $cmd\n }\n \n-function Juju-GetVMSwitch {\n-    $VMswitchName = Get-JujuCharmConfig -Scope \"vmswitch-name\"\n-    if (!$VMswitchName){\n-        return \"br100\"\n+function Enable-MSiSCSI {\n+    Write-JujuInfo \"Enabling MSiSCSI\"\n+    $svc = Get-Service MSiSCSI -ErrorAction SilentlyContinue\n+    if ($svc) {\n+        Start-Service MSiSCSI\n+        Set-Service MSiSCSI -StartupType Automatic\n+    } else {\n+        Write-JujuWarning \"MSiSCSI service was not found\"\n     }\n-    return $VMswitchName\n }\n \n-function WaitFor-BondUp {\n-    Param(\n-    [Parameter(Mandatory=$true)]\n-    [string]$bond\n-    )\n+function Get-DataPorts {\n+    $netType = Get-NetType\n \n-    $b = Get-NetLbfoTeam -Name $bond -ErrorAction SilentlyContinue\n-    if (!$b){\n-        Write-JujuLog \"Bond interface $bond not found\"\n-        return $false\n+    if ($netType -eq \"ovs\") {\n+        Write-JujuInfo \"Fetching OVS data ports\"\n+\n+        $dataPorts = Get-OVSDataPorts\n+        return @($dataPorts, $false)\n     }\n-    Write-JujuLog \"Found bond: $bond\"\n-    $count = 0\n-    while ($count -lt 30){\n-        Write-JujuLog (\"Bond status is \" + $b.Status)\n-        $b = Get-NetLbfoTeam -Name $bond -ErrorAction SilentlyContinue\n-        if ($b.Status -eq \"Up\" -or $b.Status -eq \"Degraded\"){\n-            Write-JujuLog (\"bond interface status is \" + $b.Status)\n-            return $true\n-        }\n-        Start-Sleep 1\n-        $count ++\n+\n+    $cfg = Get-JujuCharmConfig\n+    $managementOS = $cfg['vmswitch-management']\n+\n+    Write-JujuInfo \"Fetching data port from config\"\n+\n+    $dataPorts = Get-InterfaceFromConfig\n+\n+    if (!$dataPorts.Count) {\n+        $fallbackAdapter = Get-FallbackNetadapter\n+        $dataPorts = @($fallbackAdapter)\n+        $managementOS = $true\n     }\n-    return $false\n+\n+    return @($dataPorts, $managementOS)\n }\n \n-function Get-PythonDir {\n-    $pythonDir = Join-Path $novaDir \"Python27\"\n-    if(!(Test-Path $pythonDir)){\n-        $pythonDir = Join-Path $novaDir \"Python\"\n-        if(!(Test-Path $pythonDir)) {\n-            Throw \"Could not find python directory\"\n-        }\n+function Start-ConfigureVMSwitch {\n+    $cfg = Get-JujuCharmConfig\n+    $vmSwitchName = $cfg['vmswitch-name']\n+    if (!$vmSwitchName) {\n+        $vmSwitchName = $NOVA_DEFAULT_SWITCH_NAME\n     }\n-    return $pythonDir\n-}\n \n-function Generate-ExeWrappers {\n-    if(!(Get-IsNanoServer)){\n-        return\n+    [array]$dataPorts, $managementOS = Get-DataPorts\n+    $dataPort = $dataPorts[0]\n+\n+    $stateParams = @{\n+        'Namespace' = \"novahyperv\"\n+        'Key' = \"vmswitch_name\"\n     }\n-    $pythonDir = Get-PythonDir\n-    $python = Join-Path $pythonDir \"python.exe\"\n-    $updateWrapper = Join-Path $pythonDir \"Scripts\\UpdateWrappers.py\"\n \n-    $cmd = @($python, $updateWrapper, \"nova-compute = nova.cmd.compute:main\")\n-    Invoke-JujuCommand -Command $cmd | Out-Null\n+    $vmSwitches = [array](Get-VMSwitch -SwitchType External -ErrorAction SilentlyContinue)\n+    foreach ($i in $vmSwitches) {\n+        if ($i.NetAdapterInterfaceDescription -eq $dataPort.InterfaceDescription) {\n+            $agentRestart = $false\n \n-    $cmd = @($python, $updateWrapper, \"neutron-hyperv-agent = neutron.cmd.eventlet.plugins.hyperv_neutron_agent:main\")\n-    Invoke-JujuCommand -Command $cmd\n-}\n+            if($i.Name -ne $vmSwitchName) {\n+                $agentRestart = $true\n+                Rename-VMSwitch $i -NewName $vmSwitchName | Out-Null\n+                Set-CharmState @stateParams -Value $vmSwitchName\n+            }\n \n-function New-BondInterface {\n-    if((Get-IsNanoServer)){\n-        # not supported on nano yet\n-        return $false\n-    }\n-    $name = Get-JujuCharmConfig -Scope \"bond-name\"\n-    $bondPorts = Get-InterfaceFromConfig -ConfigOption \"bond-ports\"\n-    if ($bondPorts.Length -eq 0) {\n-        return $false\n-    }\n+            if($i.AllowManagementOS -ne $managementOS) {\n+                $agentRestart = $true\n+                Set-VMSwitch -Name $vmSwitchName -AllowManagementOS $managementOS | Out-Null\n+            }\n \n-    $bondExists = Get-NetLbfoTeam -Name $name -ErrorAction SilentlyContinue\n-    if ($bondExists){\n-        return $true\n+            if($agentRestart) {\n+                $netType = Get-NetType\n+                if($netType -eq \"ovs\") {\n+                    $status = (Get-Service -Name \"ovs-vswitchd\").Status\n+                    if($status -eq [System.ServiceProcess.ServiceControllerStatus]::Running) {\n+                        Restart-Service \"ovs-vswitchd\" | Out-Null\n+                    }\n+                }\n+            }\n+            return\n+        }\n     }\n \n-    $bond = New-NetLbfoTeam -Name $name -TeamMembers $bondPorts.Name -TeamNicName $name -TeamingMode LACP -Confirm:$false\n-    $isUp = WaitFor-BondUp -bond $bond.Name\n-    if (!$isUp){\n-        Throw \"Failed to bring up $name\"\n+    $oldSwitchName = Get-CharmState @stateParams\n+    if($oldSwitchName) {\n+        Remove-VMSwitch -Name $oldSwitchName -Force -Confirm:$false\n+        Remove-CharmState @stateParams\n     }\n \n-    $adapter = Get-NetAdapter -Name $name\n-    if(!$adapter){\n-        Throw \"Failed to find $name\"\n+    Write-JujuInfo \"Adding new vmswitch: $vmSwitchName\"\n+\n+    New-VMSwitch -Name $vmSwitchName -NetAdapterName $dataPort.Name -AllowManagementOS $managementOS | Out-Null\n+    Set-CharmState @stateParams -Value $vmSwitchName\n+}\n+\n+function Install-NovaFromZip {\n+    Param(\n+        [Parameter(Mandatory=$true)]\n+        [string]$InstallerPath\n+    )\n+\n+    if ((Test-Path $NOVA_INSTALL_DIR)) {\n+        Remove-Item -Recurse -Force $NOVA_INSTALL_DIR\n     }\n-    $returnCode = Invoke-DHCPRenew $adapter\n-    if($returnCode -eq 1) {\n-        Invoke-JujuReboot -Now\n+\n+    Write-JujuInfo \"Unzipping '$InstallerPath' to '$NOVA_INSTALL_DIR'\"\n+\n+    Expand-ZipArchive -ZipFile $InstallerPath -Destination $NOVA_INSTALL_DIR | Out-Null\n+\n+    $configDir = Join-Path $NOVA_INSTALL_DIR \"etc\"\n+    if (!(Test-Path $configDir)) {\n+        New-Item -ItemType Directory $configDir | Out-Null\n+        $distro = Get-OpenstackVersion\n+        $templatesDir = Join-Path (Get-JujuCharmDir) \"templates\"\n+        $policyFile = Join-Path $templatesDir \"$distro\\policy.json\"\n+        Copy-Item $policyFile $configDir | Out-Null\n     }\n-    return $name\n-}\n \n-function Get-TemplatesDir {\n-    $charmDir = Get-JujuCharmDir\n-    $templates =  Join-Path $charmDir \"templates\"\n-    return $templates\n+    New-ExeServiceWrapper | Out-Null\n }\n \n-function Get-PackageDir {\n-    $charmDir = Get-JujuCharmDir\n-    $packages =  Join-Path $charmDir \"packages\"\n-    return $packages\n+function Install-NovaFromMSI {\n+    Param(\n+        [Parameter(Mandatory=$true)]\n+        [string]$InstallerPath\n+    )\n+\n+    $logFile = Join-Path $env:APPDATA \"nova-installer-log.txt\"\n+    $extraParams = @(\"SKIPNOVACONF=1\", \"INSTALLDIR=`\"$NOVA_INSTALL_DIR`\"\")\n+    Install-Msi -Installer $InstallerPath -LogFilePath $logFile -ExtraArgs $extraParams\n+\n+    # Delete the Windows services created by default by the MSI,\n+    # so the charm can create them later on.\n+    $charmServices = Get-CharmServices\n+    $serviceNames = $charmServices.Values | ForEach-Object { $_['service'] }\n+    Remove-WindowsServices -Names $serviceNames\n+\n+    $product = Get-InstalledOpenStackProduct -Project \"Nova\"\n+    if(!$product) {\n+        Throw \"Failed to get the installed OpenStack Nova product\"\n+    }\n+    Set-CharmState -Namespace \"novahyperv\" -Key \"product_name_installed\" -Value $product.Name\n }\n \n-function Get-FilesDir {\n-    $charmDir = Get-JujuCharmDir\n-    $packages =  Join-Path $charmDir \"files\"\n-    return $packages\n+function Install-Nova {\n+    Write-JujuInfo \"Running Nova install\"\n+\n+    $installerPath = Get-InstallerPath -Project 'Nova'\n+\n+    $installerExtension = $installerPath.Split('.')[-1]\n+    switch($installerExtension) {\n+        \"zip\" {\n+            Install-NovaFromZip $installerPath\n+        }\n+        \"msi\" {\n+            Install-NovaFromMSI $installerPath\n+        }\n+        default {\n+            Throw \"Unknown installer extension: $installerExtension\"\n+        }\n+    }\n+\n+    $release = Get-OpenstackVersion\n+    Set-JujuApplicationVersion -Version $NOVA_PRODUCT[$release]['version']\n+    Set-CharmState -Namespace \"novahyperv\" -Key \"product_release_installed\" -Value $release\n+\n+    Remove-Item $installerPath\n }\n \n-function Install-RootWrap {\n-    $template = Get-TemplatesDir\n-    $rootWrap = Join-Path $template \"ovs\\rootwrap.cmd\"\n+function Get-NeutronServiceName {\n+    <#\n+    .SYNOPSIS\n+    Returns the neutron service name.\n+    #>\n+\n+    $netType = Get-NetType\n+    $charmServices = Get-CharmServices\n \n-    if(!(Test-Path $rootWrap)){\n-        return $true\n+    if ($netType -eq \"hyperv\") {\n+        return $charmServices['neutron']['service']\n+    } elseif ($netType -eq \"ovs\") {\n+        return $charmServices['neutron-ovs']['service']\n     }\n \n-    $dst = Join-Path $novaDir \"bin\\rootwrap.cmd\"\n-    $parent = Split-Path -Path $dst -Parent\n-    $exists = Test-Path $parent\n-    if (!$exists){\n-        mkdir $parent | Out-Null\n+    Throw \"Unknown network type: $netType\"\n+}\n+\n+function Get-NovaServiceName {\n+    $charmServices = Get-CharmServices\n+    return $charmServices['nova']['service']\n+}\n+\n+function Enable-LiveMigration {\n+    Enable-VMMigration\n+    $name = Get-MainNetadapter\n+    $netAddresses = Get-NetIPAddress -InterfaceAlias $name -AddressFamily IPv4\n+    foreach($netAddress in $netAddresses) {\n+        $prefixLength = $netAddress.PrefixLength\n+        $netmask = ConvertTo-Mask -MaskLength $prefixLength\n+        $networkAddress = Get-NetworkAddress -IPAddress $netAddress.IPAddress -SubnetMask $netmask\n+        $migrationNet = Get-VMMigrationNetwork | Where-Object { $_.Subnet -eq \"$networkAddress/$prefixLength\" }\n+        if (!$migrationNet) {\n+            Add-VMMigrationNetwork -Subnet \"$networkAddress/$prefixLength\" -Confirm:$false\n+        }\n     }\n-    cp $rootWrap $dst\n-    return $true\n }\n \n-function Get-ServiceWrapper {\n-    Param(\n-        [Parameter(Mandatory=$false)]\n-        [string]$Service\n-    )\n-    PROCESS {\n-        $wrapperName = (\"OpenStackService{0}.exe\" -f $Service)\n-        $svcPath = Join-Path $novaDir (\"bin\\{0}\" -f $wrapperName)\n-        if(!(Test-Path $svcPath)) {\n-            $svcPath = Join-Path $novaDir \"bin\\OpenStackService.exe\"\n-            if(!(Test-Path $svcPath)) {\n-                Throw \"Failed to find service wrapper\"\n-            }\n+function Confirm-CharmPrerequisites {\n+    $charmServices = Get-CharmServices\n+\n+    foreach($svcName in $charmServices.Keys) {\n+        $agent = Get-Service $charmServices[$svcName][\"service\"] -ErrorAction SilentlyContinue\n+        if (!$agent) {\n+            New-Service -Name $charmServices[$svcName][\"service\"] `\n+                        -BinaryPathName $charmServices[$svcName][\"serviceBinPath\"] `\n+                        -DisplayName $charmServices[$svcName][\"display_name\"] -Confirm:$false\n+            Stop-Service $charmServices[$svcName][\"service\"]\n         }\n-        return $svcPath\n     }\n+\n+    Enable-MSiSCSI\n }\n \n-function Enable-MSiSCSI {\n-    Write-JujuWarning \"Enabling MSiSCSI\"\n-    $svc = Get-Service MSiSCSI -ErrorAction SilentlyContinue\n-    if($svc) {\n-        Start-Service MSiSCSI\n-        Set-Service MSiSCSI -StartupType Automatic\n-    } else {\n-        Write-JujuWarning \"MSiSCSI service was not found\"\n+function Start-ConfigureNeutronAgent {\n+    $services = Get-CharmServices\n+    $netType = Get-NetType\n+\n+    if($netType -eq \"hyperv\") {\n+        Stop-Service $services[\"neutron-ovs\"][\"service\"]\n+        Disable-Service $services[\"neutron-ovs\"][\"service\"]\n+\n+        Remove-CharmState -Namespace \"novahyperv\" -Key \"ovs_adapters_info\"\n+\n+        Disable-OVS\n+        Start-ConfigureVMSwitch\n+        Enable-Service $services[\"neutron\"][\"service\"]\n+\n+    } elseif($netType -eq \"ovs\") {\n+        Stop-Service $services[\"neutron\"][\"service\"]\n+        Disable-Service $services[\"neutron\"][\"service\"]\n+\n+        Install-OVS\n+\n+        Disable-OVS\n+        Start-ConfigureVMSwitch\n+        Enable-OVS\n+\n+        New-OVSInternalInterfaces\n+        Enable-Service $services[\"neutron-ovs\"][\"service\"]\n     }\n }\n \n+function Restart-Neutron {\n+    $serviceName = Get-NeutronServiceName\n+    Stop-Service $serviceName\n+    Start-Service $serviceName\n+}\n+\n+function Restart-Nova {\n+    $serviceName = Get-NovaServiceName\n+    Stop-Service $serviceName\n+    Start-Service $serviceName\n+}\n+\n function Get-CharmServices {\n-    $template_dir = Get-TemplatesDir\n     $distro = Get-OpenstackVersion\n-    $nova_config = Join-Path $novaDir \"etc\\nova.conf\"\n-    $neutron_config = Join-Path $novaDir \"etc\\neutron_hyperv_agent.conf\"\n-    $neutron_ml2 = Join-Path $novaDir \"etc\\ml2_conf.ini\"\n \n-    $pythonDir = Get-PythonDir\n+    $novaConf = Join-Path $NOVA_INSTALL_DIR \"etc\\nova.conf\"\n+    $neutronHypervConf = Join-Path $NOVA_INSTALL_DIR \"etc\\neutron_hyperv_agent.conf\"\n+    $neutronOVSConf = Join-Path $NOVA_INSTALL_DIR \"etc\\neutron_ovs_agent.conf\"\n+\n+    $serviceWrapperNova = Get-ServiceWrapper -Service \"Nova\" -InstallDir $NOVA_INSTALL_DIR\n+    $serviceWrapperNeutron = Get-ServiceWrapper -Service \"Neutron\" -InstallDir $NOVA_INSTALL_DIR\n+\n+    $pythonDir = Get-PythonDir -InstallDir $NOVA_INSTALL_DIR\n \n-    $serviceWrapperNova = Get-ServiceWrapper -Service Nova\n-    $serviceWrapperNeutron = Get-ServiceWrapper -Service Neutron\n     $novaExe = Join-Path $pythonDir \"Scripts\\nova-compute.exe\"\n     $neutronHypervAgentExe = Join-Path $pythonDir \"Scripts\\neutron-hyperv-agent.exe\"\n-    $neutronOpenvswitchExe = Join-Path $pythonDir \"Scripts\\neutron-openvswitch-agent.exe\"\n-\n-    $JujuCharmServices = @{\n-        \"nova\"=@{\n-            \"myname\"=\"nova\";\n-            \"template\"=\"$template_dir\\$distro\\nova.conf\";\n-            \"service\"=\"nova-compute\";\n-            \"binpath\"=\"$novaExe\";\n-            \"serviceBinPath\"=\"`\"$serviceWrapperNova`\" nova-compute `\"$novaExe`\" --config-file `\"$nova_config`\"\";\n-            \"config\"=\"$nova_config\";\n-            \"context_generators\"=@(\n+    $neutronOVSAgentExe = Join-Path $pythonDir \"Scripts\\neutron-openvswitch-agent.exe\"\n+\n+    $jujuCharmServices = @{\n+        \"nova\" = @{\n+            \"template\" = \"$distro\\nova.conf\"\n+            \"service\" = \"nova-compute\"\n+            \"binpath\" = \"$novaExe\"\n+            \"serviceBinPath\" = \"`\"$serviceWrapperNova`\" nova-compute `\"$novaExe`\" --config-file `\"$novaConf`\"\"\n+            \"config\" = \"$novaConf\"\n+            \"display_name\" = \"Nova Compute Hyper-V Agent\"\n+            \"context_generators\" = @(\n                 @{\n-                    \"generator\"=\"Get-RabbitMQContext\";\n-                    \"relation\"=\"amqp\";\n+                    \"generator\" = (Get-Item \"function:Get-RabbitMQContext\").ScriptBlock\n+                    \"relation\" = \"amqp\"\n+                    \"mandatory\" = $true\n                 },\n                 @{\n-                    \"generator\"=\"Get-NeutronContext\";\n-                    \"relation\"=\"cloud-compute\";\n+                    \"generator\" = (Get-Item \"function:Get-CloudComputeContext\").ScriptBlock\n+                    \"relation\" = \"cloud-compute\"\n+                    \"mandatory\" = $true\n                 },\n                 @{\n-                    \"generator\"=\"Get-GlanceContext\";\n-                    \"relation\"=\"image-service\";\n+                    \"generator\" = (Get-Item \"function:Get-GlanceContext\").ScriptBlock\n+                    \"relation\" = \"image-service\"\n+                    \"mandatory\" = $true\n                 },\n                 @{\n-                    \"generator\"=\"Get-CharmConfigContext\";\n-                    \"relation\"=\"config\";\n+                    \"generator\" = (Get-Item \"function:Get-CharmConfigContext\").ScriptBlock\n+                    \"relation\" = \"config\"\n+                    \"mandatory\" = $true\n                 },\n                 @{\n-                    \"generator\"=\"Get-SystemContext\";\n-                    \"relation\"=\"system\";\n+                    \"generator\" = (Get-Item \"function:Get-SystemContext\").ScriptBlock\n+                    \"relation\" = \"system\"\n+                    \"mandatory\" = $true\n                 },\n                 @{\n-                    \"generator\"=\"Get-S2DContext\";\n-                    \"relation\"=\"s2d\";\n-                }\n-            );\n-        };\n-        \"neutron\"=@{\n-            \"myname\"=\"neutron\";\n-            \"template\"=\"$template_dir\\$distro\\neutron_hyperv_agent.conf\"\n-            \"service\"=\"neutron-hyperv-agent\";\n-            \"binpath\"=\"$neutronHypervAgentExe\";\n-            \"serviceBinPath\"=\"`\"$serviceWrapperNeutron`\" neutron-hyperv-agent `\"$neutronHypervAgentExe`\" --config-file `\"$neutron_config`\"\";\n-            \"config\"=\"$neutron_config\";\n-            \"context_generators\"=@(\n-                @{\n-                    \"generator\"=\"Get-RabbitMQContext\";\n-                    \"relation\"=\"amqp\";\n+                    \"generator\" = (Get-Item \"function:Get-S2DContext\").ScriptBlock\n+                    \"relation\" = \"s2d\"\n+                    \"mandatory\" = $false\n                 },\n                 @{\n-                    \"generator\"=\"Get-NeutronContext\";\n-                    \"relation\"=\"cloud-compute\";\n-                },\n+                    \"generator\" = (Get-Item \"function:Get-FreeRDPContext\").ScriptBlock\n+                    \"relation\" = \"free-rdp\"\n+                    \"mandatory\" = $false\n+                }\n+            )\n+        }\n+\n+        \"neutron\" = @{\n+            \"template\" = \"$distro\\neutron_hyperv_agent.conf\"\n+            \"service\" = \"neutron-hyperv-agent\"\n+            \"binpath\" = \"$neutronHypervAgentExe\"\n+            \"serviceBinPath\" = \"`\"$serviceWrapperNeutron`\" neutron-hyperv-agent `\"$neutronHypervAgentExe`\" --config-file `\"$neutronHypervConf`\"\"\n+            \"config\" = \"$neutronHypervConf\"\n+            \"display_name\" = \"Neutron Hyper-V Agent\"\n+            \"context_generators\" = @(\n                 @{\n-                    \"generator\"=\"Get-CharmConfigContext\";\n-                    \"relation\"=\"config\";\n+                    \"generator\" = (Get-Item \"function:Get-RabbitMQContext\").ScriptBlock","path":"lib/Modules/ComputeHooks/ComputeHooks.psm1","position":634,"original_position":634,"commit_id":"4a1e4766f7cc97bc6179ef7316c0d0023ada84aa","original_commit_id":"4a1e4766f7cc97bc6179ef7316c0d0023ada84aa","user":{"login":"ionutbalutoiu","id":6170274,"avatar_url":"https://avatars.githubusercontent.com/u/6170274?v=3","gravatar_id":"","url":"https://api.github.com/users/ionutbalutoiu","html_url":"https://github.com/ionutbalutoiu","followers_url":"https://api.github.com/users/ionutbalutoiu/followers","following_url":"https://api.github.com/users/ionutbalutoiu/following{/other_user}","gists_url":"https://api.github.com/users/ionutbalutoiu/gists{/gist_id}","starred_url":"https://api.github.com/users/ionutbalutoiu/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ionutbalutoiu/subscriptions","organizations_url":"https://api.github.com/users/ionutbalutoiu/orgs","repos_url":"https://api.github.com/users/ionutbalutoiu/repos","events_url":"https://api.github.com/users/ionutbalutoiu/events{/privacy}","received_events_url":"https://api.github.com/users/ionutbalutoiu/received_events","type":"User","site_admin":false},"body":"Yep. Moreover, you can pass `-ComputerName` (the name of an AD computer) and `-ArgumentList` (function parameters) and you execute a local function with desired parameters on a remote comptuer.","created_at":"2016-11-02T15:04:49Z","updated_at":"2016-11-02T15:04:49Z","html_url":"https://github.com/cloudbase/nova-hyperv-charm/pull/2#discussion_r86162414","pull_request_url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/pulls/2","_links":{"self":{"href":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/pulls/comments/86162414"},"html":{"href":"https://github.com/cloudbase/nova-hyperv-charm/pull/2#discussion_r86162414"},"pull_request":{"href":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/pulls/2"}}},"pull_request":{"url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/pulls/2","id":74615215,"html_url":"https://github.com/cloudbase/nova-hyperv-charm/pull/2","diff_url":"https://github.com/cloudbase/nova-hyperv-charm/pull/2.diff","patch_url":"https://github.com/cloudbase/nova-hyperv-charm/pull/2.patch","issue_url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/issues/2","number":2,"state":"open","locked":false,"title":"Code clean-up & Newton Support","user":{"login":"ionutbalutoiu","id":6170274,"avatar_url":"https://avatars.githubusercontent.com/u/6170274?v=3","gravatar_id":"","url":"https://api.github.com/users/ionutbalutoiu","html_url":"https://github.com/ionutbalutoiu","followers_url":"https://api.github.com/users/ionutbalutoiu/followers","following_url":"https://api.github.com/users/ionutbalutoiu/following{/other_user}","gists_url":"https://api.github.com/users/ionutbalutoiu/gists{/gist_id}","starred_url":"https://api.github.com/users/ionutbalutoiu/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ionutbalutoiu/subscriptions","organizations_url":"https://api.github.com/users/ionutbalutoiu/orgs","repos_url":"https://api.github.com/users/ionutbalutoiu/repos","events_url":"https://api.github.com/users/ionutbalutoiu/events{/privacy}","received_events_url":"https://api.github.com/users/ionutbalutoiu/received_events","type":"User","site_admin":false},"body":"- Added support for upgrading OpenStack release\n- Created OpenStackCommon module\n- Added Newton support\n- Removed Kilo support\n- Fixed live migration\n- Fixed switching between \"ovs\" and \"hyperv\" network-types\n- Moved all the constants into a script that is dor sourced in the modules\n- Removed unnecessary code and module imports\n- Moved OVS code to its separate module\n- Removed unnecessary S2D context from the neutron charm services contexts\n- Sync charm helpers\n- Renamed neutron ovs config from ml2_conf.ini to neutron_ovs_agent.conf\n- Increased vif_plugin_timeout for Mitaka from 0 to 60\n- By default, now charm uses Microsoft certified OVS 2.5 installer\n- Charm is able to request more than a single S2D volume from the s2d-proxy charm\n- Added missing license headers\n- Properly clean extra disks & extra storage pools before enabling S2D\n- Updated icon\n","created_at":"2016-06-21T13:51:24Z","updated_at":"2016-11-02T15:04:49Z","closed_at":null,"merged_at":null,"merge_commit_sha":"01d74dbe894ea5326bfde3240c1eaaf10d8e9882","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/pulls/2/commits","review_comments_url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/pulls/2/comments","review_comment_url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/pulls/comments{/number}","comments_url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/issues/2/comments","statuses_url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/statuses/4a1e4766f7cc97bc6179ef7316c0d0023ada84aa","head":{"label":"ionutbalutoiu:master","ref":"master","sha":"4a1e4766f7cc97bc6179ef7316c0d0023ada84aa","user":{"login":"ionutbalutoiu","id":6170274,"avatar_url":"https://avatars.githubusercontent.com/u/6170274?v=3","gravatar_id":"","url":"https://api.github.com/users/ionutbalutoiu","html_url":"https://github.com/ionutbalutoiu","followers_url":"https://api.github.com/users/ionutbalutoiu/followers","following_url":"https://api.github.com/users/ionutbalutoiu/following{/other_user}","gists_url":"https://api.github.com/users/ionutbalutoiu/gists{/gist_id}","starred_url":"https://api.github.com/users/ionutbalutoiu/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ionutbalutoiu/subscriptions","organizations_url":"https://api.github.com/users/ionutbalutoiu/orgs","repos_url":"https://api.github.com/users/ionutbalutoiu/repos","events_url":"https://api.github.com/users/ionutbalutoiu/events{/privacy}","received_events_url":"https://api.github.com/users/ionutbalutoiu/received_events","type":"User","site_admin":false},"repo":{"id":61636101,"name":"nova-hyperv-charm","full_name":"ionutbalutoiu/nova-hyperv-charm","owner":{"login":"ionutbalutoiu","id":6170274,"avatar_url":"https://avatars.githubusercontent.com/u/6170274?v=3","gravatar_id":"","url":"https://api.github.com/users/ionutbalutoiu","html_url":"https://github.com/ionutbalutoiu","followers_url":"https://api.github.com/users/ionutbalutoiu/followers","following_url":"https://api.github.com/users/ionutbalutoiu/following{/other_user}","gists_url":"https://api.github.com/users/ionutbalutoiu/gists{/gist_id}","starred_url":"https://api.github.com/users/ionutbalutoiu/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ionutbalutoiu/subscriptions","organizations_url":"https://api.github.com/users/ionutbalutoiu/orgs","repos_url":"https://api.github.com/users/ionutbalutoiu/repos","events_url":"https://api.github.com/users/ionutbalutoiu/events{/privacy}","received_events_url":"https://api.github.com/users/ionutbalutoiu/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/ionutbalutoiu/nova-hyperv-charm","description":"OpenStack Nova Hyper-V juju charm","fork":true,"url":"https://api.github.com/repos/ionutbalutoiu/nova-hyperv-charm","forks_url":"https://api.github.com/repos/ionutbalutoiu/nova-hyperv-charm/forks","keys_url":"https://api.github.com/repos/ionutbalutoiu/nova-hyperv-charm/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ionutbalutoiu/nova-hyperv-charm/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ionutbalutoiu/nova-hyperv-charm/teams","hooks_url":"https://api.github.com/repos/ionutbalutoiu/nova-hyperv-charm/hooks","issue_events_url":"https://api.github.com/repos/ionutbalutoiu/nova-hyperv-charm/issues/events{/number}","events_url":"https://api.github.com/repos/ionutbalutoiu/nova-hyperv-charm/events","assignees_url":"https://api.github.com/repos/ionutbalutoiu/nova-hyperv-charm/assignees{/user}","branches_url":"https://api.github.com/repos/ionutbalutoiu/nova-hyperv-charm/branches{/branch}","tags_url":"https://api.github.com/repos/ionutbalutoiu/nova-hyperv-charm/tags","blobs_url":"https://api.github.com/repos/ionutbalutoiu/nova-hyperv-charm/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ionutbalutoiu/nova-hyperv-charm/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ionutbalutoiu/nova-hyperv-charm/git/refs{/sha}","trees_url":"https://api.github.com/repos/ionutbalutoiu/nova-hyperv-charm/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ionutbalutoiu/nova-hyperv-charm/statuses/{sha}","languages_url":"https://api.github.com/repos/ionutbalutoiu/nova-hyperv-charm/languages","stargazers_url":"https://api.github.com/repos/ionutbalutoiu/nova-hyperv-charm/stargazers","contributors_url":"https://api.github.com/repos/ionutbalutoiu/nova-hyperv-charm/contributors","subscribers_url":"https://api.github.com/repos/ionutbalutoiu/nova-hyperv-charm/subscribers","subscription_url":"https://api.github.com/repos/ionutbalutoiu/nova-hyperv-charm/subscription","commits_url":"https://api.github.com/repos/ionutbalutoiu/nova-hyperv-charm/commits{/sha}","git_commits_url":"https://api.github.com/repos/ionutbalutoiu/nova-hyperv-charm/git/commits{/sha}","comments_url":"https://api.github.com/repos/ionutbalutoiu/nova-hyperv-charm/comments{/number}","issue_comment_url":"https://api.github.com/repos/ionutbalutoiu/nova-hyperv-charm/issues/comments{/number}","contents_url":"https://api.github.com/repos/ionutbalutoiu/nova-hyperv-charm/contents/{+path}","compare_url":"https://api.github.com/repos/ionutbalutoiu/nova-hyperv-charm/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ionutbalutoiu/nova-hyperv-charm/merges","archive_url":"https://api.github.com/repos/ionutbalutoiu/nova-hyperv-charm/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ionutbalutoiu/nova-hyperv-charm/downloads","issues_url":"https://api.github.com/repos/ionutbalutoiu/nova-hyperv-charm/issues{/number}","pulls_url":"https://api.github.com/repos/ionutbalutoiu/nova-hyperv-charm/pulls{/number}","milestones_url":"https://api.github.com/repos/ionutbalutoiu/nova-hyperv-charm/milestones{/number}","notifications_url":"https://api.github.com/repos/ionutbalutoiu/nova-hyperv-charm/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ionutbalutoiu/nova-hyperv-charm/labels{/name}","releases_url":"https://api.github.com/repos/ionutbalutoiu/nova-hyperv-charm/releases{/id}","deployments_url":"https://api.github.com/repos/ionutbalutoiu/nova-hyperv-charm/deployments","created_at":"2016-06-21T13:29:42Z","updated_at":"2016-06-21T13:29:43Z","pushed_at":"2016-10-26T08:18:22Z","git_url":"git://github.com/ionutbalutoiu/nova-hyperv-charm.git","ssh_url":"git@github.com:ionutbalutoiu/nova-hyperv-charm.git","clone_url":"https://github.com/ionutbalutoiu/nova-hyperv-charm.git","svn_url":"https://github.com/ionutbalutoiu/nova-hyperv-charm","homepage":null,"size":1101,"stargazers_count":0,"watchers_count":0,"language":"PowerShell","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":0,"forks":1,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"cloudbase:master","ref":"master","sha":"c0cdafb1cbb8e985f3ff3729d46f989f2341b8a2","user":{"login":"cloudbase","id":2104303,"avatar_url":"https://avatars.githubusercontent.com/u/2104303?v=3","gravatar_id":"","url":"https://api.github.com/users/cloudbase","html_url":"https://github.com/cloudbase","followers_url":"https://api.github.com/users/cloudbase/followers","following_url":"https://api.github.com/users/cloudbase/following{/other_user}","gists_url":"https://api.github.com/users/cloudbase/gists{/gist_id}","starred_url":"https://api.github.com/users/cloudbase/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cloudbase/subscriptions","organizations_url":"https://api.github.com/users/cloudbase/orgs","repos_url":"https://api.github.com/users/cloudbase/repos","events_url":"https://api.github.com/users/cloudbase/events{/privacy}","received_events_url":"https://api.github.com/users/cloudbase/received_events","type":"Organization","site_admin":false},"repo":{"id":22217373,"name":"nova-hyperv-charm","full_name":"cloudbase/nova-hyperv-charm","owner":{"login":"cloudbase","id":2104303,"avatar_url":"https://avatars.githubusercontent.com/u/2104303?v=3","gravatar_id":"","url":"https://api.github.com/users/cloudbase","html_url":"https://github.com/cloudbase","followers_url":"https://api.github.com/users/cloudbase/followers","following_url":"https://api.github.com/users/cloudbase/following{/other_user}","gists_url":"https://api.github.com/users/cloudbase/gists{/gist_id}","starred_url":"https://api.github.com/users/cloudbase/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cloudbase/subscriptions","organizations_url":"https://api.github.com/users/cloudbase/orgs","repos_url":"https://api.github.com/users/cloudbase/repos","events_url":"https://api.github.com/users/cloudbase/events{/privacy}","received_events_url":"https://api.github.com/users/cloudbase/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/cloudbase/nova-hyperv-charm","description":"OpenStack Nova Hyper-V juju charm","fork":false,"url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm","forks_url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/forks","keys_url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/keys{/key_id}","collaborators_url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/teams","hooks_url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/hooks","issue_events_url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/issues/events{/number}","events_url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/events","assignees_url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/assignees{/user}","branches_url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/branches{/branch}","tags_url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/tags","blobs_url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/git/refs{/sha}","trees_url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/git/trees{/sha}","statuses_url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/statuses/{sha}","languages_url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/languages","stargazers_url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/stargazers","contributors_url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/contributors","subscribers_url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/subscribers","subscription_url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/subscription","commits_url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/commits{/sha}","git_commits_url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/git/commits{/sha}","comments_url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/comments{/number}","issue_comment_url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/issues/comments{/number}","contents_url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/contents/{+path}","compare_url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/compare/{base}...{head}","merges_url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/merges","archive_url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/downloads","issues_url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/issues{/number}","pulls_url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/pulls{/number}","milestones_url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/milestones{/number}","notifications_url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/labels{/name}","releases_url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/releases{/id}","deployments_url":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/deployments","created_at":"2014-07-24T15:02:37Z","updated_at":"2016-11-02T14:52:48Z","pushed_at":"2016-10-26T08:18:22Z","git_url":"git://github.com/cloudbase/nova-hyperv-charm.git","ssh_url":"git@github.com:cloudbase/nova-hyperv-charm.git","clone_url":"https://github.com/cloudbase/nova-hyperv-charm.git","svn_url":"https://github.com/cloudbase/nova-hyperv-charm","homepage":null,"size":1034,"stargazers_count":1,"watchers_count":1,"language":"PowerShell","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":3,"mirror_url":null,"open_issues_count":2,"forks":3,"open_issues":2,"watchers":1,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/pulls/2"},"html":{"href":"https://github.com/cloudbase/nova-hyperv-charm/pull/2"},"issue":{"href":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/issues/2"},"comments":{"href":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/issues/2/comments"},"review_comments":{"href":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/pulls/2/comments"},"review_comment":{"href":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/pulls/2/commits"},"statuses":{"href":"https://api.github.com/repos/cloudbase/nova-hyperv-charm/statuses/4a1e4766f7cc97bc6179ef7316c0d0023ada84aa"}}}}
{"actor":{"display_login":"ionutbalutoiu"}}