diff --git a/.github/workflows/BuildMissingImages.yaml b/.github/workflows/BuildMissingImages.yaml index f0ce2e1..0962712 100644 --- a/.github/workflows/BuildMissingImages.yaml +++ b/.github/workflows/BuildMissingImages.yaml @@ -7,20 +7,9 @@ on: description: Generic Tag (leave empty to use value in generic/tag.txt) required: false default: '' - Agents: - description: Number of agents to create (0 = use existing) - required: false - default: '2' PushToProd: description: Push to production (Y/N) - required: false - default: 'Y' - -env: - resGroup: "buildgeneric" - resLocation: "Sweden Central" - ARMbranch: "master" - ARMtemplate: "buildagent" + type: boolean permissions: contents: read @@ -33,179 +22,72 @@ jobs: AnalyzeImages: runs-on: [ windows-latest ] outputs: - generic: ${{ steps.Analyze.outputs.generic }} - genericcount: ${{ steps.Analyze.outputs.genericcount }} - filesonly: ${{ steps.Analyze.outputs.filesonly }} - filesonlycount: ${{ steps.Analyze.outputs.filesonlycount }} + missing: ${{ steps.Analyze.outputs.missing }} + missingcount: ${{ steps.Analyze.outputs.missingcount }} steps: - uses: actions/checkout@v4 - name: Analyze id: Analyze + env: + genericTag: ${{ github.event.inputs.GenericTag }} run: | $erroractionpreference = "STOP" try { - $unsupportedWindowsVersions = @("10.0.14300.*","10.0.16299.*","10.0.18363.*","10.0.18362.*","10.0.17134.*") # "10.0.14393.*","10.0.19041.*","10.0.19042.*" + $servercoretags = @('ltsc2016','ltsc2019','ltsc2022') Set-Location "generic" - $genericTag = '' - if ($env:GITHUB_EVENT_NAME -eq "workflow_dispatch") { - $genericTag = '${{ github.event.inputs.GenericTag }}' - } + $genericTag = "$env:genericTag" if ($genericTag -eq '') { $genericTag = Get-Content -path 'tag.txt' } [System.Version]$genericTag | Out-Null Write-Host "Using generic Tag $genericTag" - $genericTag = "-$genericTag" $webclient = New-Object System.Net.WebClient $webclient.Headers.Add('Accept', "application/json") - $alltags = (($webclient.DownloadString("https://mcr.microsoft.com/v2/businesscentral/tags/list") | ConvertFrom-Json)).tags - $version = [System.Version]"0.0.0.0" - $versions = @($alltags | Where-Object { $_ -like "*$generictag" } | Where-Object { [System.Version]::TryParse($_.SubString(0,$_.Length-$generictag.Length), [ref] $version) } | Where-Object { -not ($UnsupportedWindowsVersions | Where-Object { "$version" -like $_ }) } | ForEach-Object { $version }) - $filesOnlyVersions = @($alltags | Where-Object { $_ -like "*$generictag-filesonly" } | Where-Object { [System.Version]::TryParse($_.SubString(0,$_.Length-$generictag.Length-10), [ref] $version) } | Where-Object { -not ($UnsupportedWindowsVersions | Where-Object { "$version" -like $_ }) } | ForEach-Object { $version }) - $missingImages = @{} - $missingFilesOnlyImages = @{} - $alldotnetFrameworkTags = (($webclient.DownloadString("https://mcr.microsoft.com/v2/dotnet/framework/runtime/tags/list") | ConvertFrom-Json)).tags - $alldotnetFrameworkTags | Where-Object { $_.startswith("4.8-w") -or $_.startswith("4.8-20") } | ForEach-Object { - $osVersion = [System.Version](($webclient.DownloadString("https://mcr.microsoft.com/v2/dotnet/framework/runtime/manifests/$_") | ConvertFrom-Json).history[0].v1Compatibility | ConvertFrom-Json)."os.version" - if (-not ($UnsupportedWindowsVersions | Where-Object { "$osVersion" -like $_ })) { - Write-Host -NoNewline "Test $_ ($OSVersion)" - if ($versions.Contains($osversion)) { - Write-Host -NoNewline " - OK" - } - else { - $missingImages."$osversion" = $_ - Write-Host -NoNewline " - Missing" - } - if ($filesOnlyVersions.Contains($osversion)) { - Write-Host " - OK" - } - else { - $missingFilesOnlyImages."$osversion" = $_ - Write-Host " - Missing" - } - } + $neededBcTags = $serverCoreTags | ForEach-Object { + $osVersion = [System.Version](($webclient.DownloadString("https://mcr.microsoft.com/v2/dotnet/framework/runtime/manifests/4.8-windowsservercore-$_") | ConvertFrom-Json).history[0].v1Compatibility | ConvertFrom-Json)."os.version" + "$osVersion-$genericTag|mcr.microsoft.com/dotnet/framework/runtime:4.8-windowsservercore-$_|$_" + "$osVersion-$genericTag-24|mcr.microsoft.com/windows/servercore:$_|$_" + "$osVersion-$genericTag-filesonly|mcr.microsoft.com/dotnet/framework/runtime:4.8-windowsservercore-$_|$_" + "$osVersion-$genericTag-24-filesonly|mcr.microsoft.com/windows/servercore:$_|$_" } - $genericarray = @($missingImages.GetEnumerator() | Where-Object { $_ } | ForEach-Object { "$($_.name)|$($_.value)" }) - $genericcount = $genericarray.Count - $generic = $genericarray | ConvertTo-Json -Compress - Add-Content -Path $ENV:GITHUB_OUTPUT -Value "generic=[$("$generic".Trim('[]'))]" - Write-Host "generic=[$("$generic".Trim('[]'))]" - Add-Content -Path $ENV:GITHUB_OUTPUT -Value "genericcount=$genericcount" - Write-Host "genericcount=$genericcount" - $filesonlyarray = @($missingFilesOnlyImages.GetEnumerator() | Where-Object { $_ } | ForEach-Object { "$($_.name)-filesonly|$($_.value)" }) - $filesonlycount = $filesonlyarray.Count - $filesonly = $filesonlyarray | ConvertTo-Json -Compress - Add-Content -Path $ENV:GITHUB_OUTPUT -Value "filesonly=[$("$filesonly".Trim('[]'))]" - Write-Host "filesonly=[$("$filesonly".Trim('[]'))]" - Add-Content -Path $ENV:GITHUB_OUTPUT -Value "filesonlycount=$filesonlycount" - Write-Host "filesonlycount=$filesonlycount" + Write-Host "Needed Tags ($($neededBcTags.Count))" + $neededBcTags | ForEach-Object { Write-Host "- $_" } + $alltags = (($webclient.DownloadString("https://mcr.microsoft.com/v2/businesscentral/tags/list") | ConvertFrom-Json)).tags + $missingBcTags = @($neededBcTags | Where-Object { $alltags -notcontains $_ }) + Write-Host "Missing Tags ($($missingBcTags.Count))" + if ($missingBcTags) { + $missingBcTags | ForEach-Object { Write-Host "- $_" } + } + else { + Write-Host '- none' + } + $json = ConvertTo-Json -InputObject $missingBcTags -Compress + $json | Out-Host + Add-Content -encoding utf8 -Path $ENV:GITHUB_OUTPUT -Value "missing=$json" + Write-Host "missing=$json" + Add-Content -encoding utf8 -Path $ENV:GITHUB_OUTPUT -Value "missingcount=$($missingBcTags.Count)" + Write-Host "missingcount=$($missingBcTags.Count)" } catch { Write-Host "::Error::Error analyzing images. Error was $($_.Exception.Message)" $host.SetShouldExit(1) } - CreateAgents: - runs-on: [ windows-latest ] + Missing: + runs-on: [ Windows-Latest ] needs: [ AnalyzeImages ] - if: ${{ needs.AnalyzeImages.outputs.genericcount > 0 || needs.AnalyzeImages.outputs.filesonlycount > 0 }} - steps: - - uses: actions/checkout@v4 - - - uses: azure/login@v1 - with: - creds: ${{ secrets.AZURE_CREDENTIALS }} - enable-AzPSSession: true - - - name: Run Azure PowerShell script - uses: azure/powershell@v1 - env: - GH_TOKEN: ${{ secrets.GH_TOKEN }} - agents: ${{ github.event.inputs.Agents }} - with: - azPSVersion: "latest" - inlineScript: | - if ($env:agents -eq "0") { - Write-Host "Using existing agents" - } - else { - $resGroup = $env:resGroup - $resLocation = $env:resLocation - $repo = $env:GITHUB_REPOSITORY - $agents = [int]$env:agents - Write-Host "Resource Group is $resGroup" - $resourceGroup = Get-AzResourceGroup -name $resGroup -ErrorAction Ignore - if ($resourceGroup) { - Write-Host "Removing Resource Group $resGroup" - Remove-AzResourceGroup -Name $resGroup -Force | Out-Host - Write-Host "Done" - } - $runners = (gh api /repos/$repo/actions/runners | ConvertFrom-Json).runners - $runners | Where-Object { $_.status -eq "offline" } | ForEach-Object { - Write-host "Unregistering runner $($_.name)" - $id = $_.id - gh api -X DELETE /repos/$repo/actions/runners/$id - Write-Host "Done" - } - Write-Host "Creating resource group $resGroup in $resLocation" - $resourceGroup = New-AzResourceGroup -Name $resGroup -Location $resLocation -Force - Write-Host "Done" - 1..$agents | ForEach-Object { - # Deployment - $no = $_ - # ARM template - $templateUri = "https://raw.githubusercontent.com/microsoft/nav-arm-templates/$($env:ARMbranch)/$($env:ARMtemplate).json" - $registrationToken = (gh api -X POST /repos/$repo/actions/runners/registration-token | ConvertFrom-Json).token - $headers = @{ - "Accept" = "application/json" - "Authorization" = "token $env:GH_TOKEN" - } - $uri = "https://api.github.com/repos/actions/runner/releases" - [Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12 - $result = Invoke-WebRequest -UseBasicParsing -Headers $headers -Uri $uri - $releases = $result.Content | ConvertFrom-Json - $asset = $releases[0].assets | Where-Object { $_.name -like "actions-runner-win-x64-*.*.?.zip" } - $Parameters = @{ - "VmName" = "$resgroup$no" - "Remotedesktopaccess" = "-" - "OperatingSystem" = "Windows Server 2022" - "VmSize" = "Standard_D4as_v5" - "OSDiskSize" = 128 - "StorageAccountType" = "Premium_LRS" - "AdminPassword" = [SecureString](ConvertTo-SecureString -String $env:GH_TOKEN -AsPlainText -Force) - "Count" = 1 - "Token" = $registrationToken - "Organization" = "https://github.com/$repo" - "LabelsOrPool" = "buildgeneric" - "AgentUrl" = $asset.browser_download_url - "InstallHyperV" = "Yes" - "RunInsideDocker" = "No" - "FinalSetupScriptUrl" = "additional-installforbuildagent.ps1" - } - $err = $resourceGroup | Test-AzResourceGroupDeployment -TemplateUri $templateUri -TemplateParameterObject $Parameters - if ($err) { - $err - throw "stop" - } - Write-Host "Creating Azure VM $($parameters.VmName)" - $resourceGroup | New-AzResourceGroupDeployment -TemplateUri $templateUri -TemplateParameterObject $Parameters -Name $Parameters.vmName -ErrorAction Ignore -AsJob - Start-Sleep -Seconds 60 - Write-Host "VM creation started" - } - } - - Generic: - runs-on: [ buildgeneric ] - needs: [ AnalyzeImages, CreateAgents ] + if: ${{ needs.AnalyzeImages.outputs.missingcount > 0 }} strategy: matrix: - version: ${{fromJson(needs.AnalyzeImages.outputs.generic)}} + tag: ${{fromJson(needs.AnalyzeImages.outputs.missing)}} fail-fast: false - max-parallel: 5 steps: - name: Checkout uses: actions/checkout@v4 - name: Build Image + env: + PushToProd: ${{ github.event.inputs.PushToProd }} + GenericTag: ${{ github.event.inputs.GenericTag }} run: | $erroractionpreference = "STOP" Set-StrictMode -version 2.0 @@ -223,32 +105,50 @@ jobs: $genericTag = '' $pushToProd = $true if ($env:GITHUB_EVENT_NAME -eq "workflow_dispatch") { - $genericTag = '${{ github.event.inputs.GenericTag }}' - $pushToProd = '${{ github.event.inputs.PushToProd }}' -eq 'Y' + $genericTag = $env:GenericTag + $pushToProd = $env:PushToProd -eq 'True' } if ($genericTag -eq '') { $genericTag = Get-Content -path 'tag.txt' } [System.Version]$genericTag | Out-Null - $osversion = '${{ matrix.version }}'.split('|')[0].split('-')[0] - $filesonly = '' - if ('${{ matrix.version }}' -like '*-filesonly|*') { - $filesonly = '-filesonly' - } - $dotnetFrameworkTag = '${{ matrix.version }}'.split('|')[1] - $baseimage = "mcr.microsoft.com/dotnet/framework/runtime:$dotnetFrameworkTag" - + $osversion = '${{ matrix.tag }}'.split('|')[0].split('-')[0] + $filesonly = ('${{ matrix.tag }}' -like '*-filesonly|*') + $only24 = ('${{ matrix.tag }}' -like '*-24|*' -or '${{ matrix.tag }}' -like '*-24-filesonly|*') + $baseImage = '${{ matrix.tag }}'.split('|')[1] + $ltscTag = '${{ matrix.tag }}'.split('|')[2] $rootPath = Get-Location - $dockerfile = Join-Path $rootPath "DOCKERFILE$filesonly" - - $image = "my:$osversion-$genericTag$filesonly" + $dockerfile = Join-Path $rootPath "DOCKERFILE" + $strFilesOnly = '' + $str24 = '' + if ($only24) { + $str24 = "-24" + } + if ($filesOnly) { + $strFilesOnly = "-filesonly" + $dockerfile += '-filesonly' + } + $image = "my:$osversion-$genericTag$str24$strFilesOnly" + $newtags = @( + "$pushRegistry/public/businesscentral:$osversion$str24$strFilesonly-dev" + "$pushRegistry/public/businesscentral:$ltscTag$str24$strFilesonly-dev" + ) + if ($pushToProd) { + $newtags += @( + "$pushRegistry/public/businesscentral:$osversion$str24$strFilesonly" + "$pushRegistry/public/businesscentral:$osversion-$genericTag$str24$strFilesonly" + "$pushRegistry/public/businesscentral:$ltscTag$str24$strFilesonly" + ) + } + $newTags | out-host $created = [DateTime]::Now.ToUniversalTime().ToString("yyyyMMddHHmm") docker pull $baseimage $inspect = docker inspect $baseimage | ConvertFrom-Json - $success = $false docker build --build-arg baseimage=$baseimage ` --build-arg created=$created ` --build-arg tag="$genericTag" ` --build-arg osversion="$osversion" ` + --build-arg filesonly="$filesonly" ` + --build-arg only24="$only24" ` --isolation=hyperv ` --memory 8G ` --tag $image ` @@ -262,165 +162,13 @@ jobs: if (!$success) { throw "Error building image" } - $newtags = @( - "$pushRegistry/public/businesscentral:$osversion$filesonly-dev" - ) - if ($pushToProd) { - $newtags += @( - "$pushRegistry/public/businesscentral:$osversion$filesonly" - "$pushRegistry/public/businesscentral:$osversion-$genericTag$filesonly" - ) - } $newtags | ForEach-Object { Write-Host "Push $_" docker tag $image $_ docker push $_ } - $newtags | ForEach-Object { - docker rmi $_ - } - docker rmi $image - docker rmi $baseimage - docker system prune --force } catch { Write-Host "::Error::Error building images. Error was $($_.Exception.Message)" $host.SetShouldExit(1) } - - FilesOnly: - runs-on: [ buildgeneric ] - needs: [ AnalyzeImages, CreateAgents ] - strategy: - matrix: - version: ${{fromJson(needs.AnalyzeImages.outputs.filesonly)}} - fail-fast: false - max-parallel: 5 - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Build Image - run: | - $erroractionpreference = "STOP" - Set-StrictMode -version 2.0 - try { - $pushRegistry = "mcrbusinesscentral.azurecr.io" - $job = start-job -ScriptBlock { Param($username, $token, $registry) - Write-Output $token | docker login --username $username --password-stdin $registry - } -ArgumentList '${{ secrets.PushUsername }}', '${{ secrets.PushToken }}', $pushRegistry - $job | Wait-Job -ErrorAction SilentlyContinue -WarningAction SilentlyContinue | Out-Null - $result = Receive-Job -ErrorAction SilentlyContinue -WarningAction SilentlyContinue $job 2> $NULL - if ($result -ne 'Login Succeeded') { - throw "docker login failed" - } - Set-Location "generic" - $genericTag = '' - $pushToProd = $true - if ($env:GITHUB_EVENT_NAME -eq "workflow_dispatch") { - $genericTag = '${{ github.event.inputs.GenericTag }}' - $pushToProd = '${{ github.event.inputs.PushToProd }}' -eq 'Y' - } - if ($genericTag -eq '') { $genericTag = Get-Content -path 'tag.txt' } - [System.Version]$genericTag | Out-Null - $osversion = '${{ matrix.version }}'.split('|')[0].split('-')[0] - $filesonly = '' - if ('${{ matrix.version }}' -like '*-filesonly|*') { - $filesonly = '-filesonly' - } - $dotnetFrameworkTag = '${{ matrix.version }}'.split('|')[1] - $baseimage = "mcr.microsoft.com/dotnet/framework/runtime:$dotnetFrameworkTag" - - $rootPath = Get-Location - $dockerfile = Join-Path $rootPath "DOCKERFILE$filesonly" - - $image = "my:$osversion-$genericTag$filesonly" - $created = [DateTime]::Now.ToUniversalTime().ToString("yyyyMMddHHmm") - docker pull $baseimage - $inspect = docker inspect $baseimage | ConvertFrom-Json - - $success = $false - docker build --build-arg baseimage=$baseimage ` - --build-arg created=$created ` - --build-arg tag="$genericTag" ` - --build-arg osversion="$osversion" ` - --isolation=hyperv ` - --memory 8G ` - --tag $image ` - --file $dockerfile ` - $RootPath | % { - $_ | Out-Host - if ($_ -like "Successfully built*") { - $success = $true - } - } - if (!$success) { - throw "Error building image" - } - $newtags = @( - "$pushRegistry/public/businesscentral:$osversion$filesonly-dev" - ) - if ($pushToProd) { - $newtags += @( - "$pushRegistry/public/businesscentral:$osversion$filesonly" - "$pushRegistry/public/businesscentral:$osversion-$genericTag$filesonly" - ) - } - $newtags | ForEach-Object { - Write-Host "Push $_" - docker tag $image $_ - docker push $_ - } - $newtags | ForEach-Object { - docker rmi $_ - } - docker rmi $image - docker rmi $baseimage - docker system prune --force - } - catch { - Write-Host "::Error::Error building images. Error was $($_.Exception.Message)" - $host.SetShouldExit(1) - } - - RemoveAgents: - runs-on: [ windows-latest ] - needs: [ AnalyzeImages, CreateAgents, Generic, FilesOnly ] - steps: - - uses: actions/checkout@v4 - - - uses: azure/login@v1 - with: - creds: ${{ secrets.AZURE_CREDENTIALS }} - enable-AzPSSession: true - - - name: Run Azure PowerShell script - uses: azure/powershell@v1 - env: - GH_TOKEN: ${{ secrets.GH_TOKEN }} - agents: ${{ github.event.inputs.Agents }} - with: - azPSVersion: "latest" - inlineScript: | - if ($env:agents -eq "0") { - Write-Host "Used existing agents" - } - else { - $resGroup = $env:resGroup - $resLocation = $env:resLocation - $repo = $env:GITHUB_REPOSITORY - Write-Host "Resource Group is $resGroup" - $resourceGroup = Get-AzResourceGroup -name $resGroup -ErrorAction Ignore - if ($resourceGroup) { - Write-Host "Removing Resource Group $resGroup" - Remove-AzResourceGroup -Name $resGroup -Force | Out-Host - Write-Host "Done" - } - $runners = (gh api /repos/$repo/actions/runners | ConvertFrom-Json).runners - $runners | Where-Object { $_.status -eq "offline" } | ForEach-Object { - Write-host "Unregistering runner $($_.name)" - $id = $_.id - gh api -X DELETE /repos/$repo/actions/runners/$id - Write-Host "Done" - } - } diff --git a/.github/workflows/CreateAgents.yaml b/.github/workflows/CreateAgents.yaml deleted file mode 100644 index 1684a1d..0000000 --- a/.github/workflows/CreateAgents.yaml +++ /dev/null @@ -1,142 +0,0 @@ -name: Create Self-Hosted Agents - -on: - workflow_dispatch: - inputs: - Count: - description: Number of agents to create? - required: true - default: 2 - -permissions: - contents: read - -defaults: - run: - shell: PowerShell - -env: - resGroup: "buildgeneric" - resLocation: "West Europe" - machines: "5" - ARMbranch: "master" - ARMtemplate: "buildagent" - -jobs: - Preparation: - runs-on: [ windows-latest ] - outputs: - matrix: ${{steps.CalculateMatrix.outputs.matrix}} - steps: - - name: Azure Login - uses: azure/login@v1 - with: - creds: ${{ secrets.AZURE_CREDENTIALS }} - enable-AzPSSession: true - - - name: Remove Old Agents - uses: azure/powershell@v1 - env: - GH_TOKEN: ${{ secrets.GH_TOKEN }} - with: - azPSVersion: "latest" - inlineScript: | - $resGroup = $env:resGroup - $repo = $env:GITHUB_REPOSITORY - Write-Host "Resource Group is $resGroup" - Write-Host - $resourceGroup = Get-AzResourceGroup -name $resGroup -ErrorAction Ignore - if ($resourceGroup) { - Write-Host "Removing Resource Group $resGroup" - Remove-AzResourceGroup -Name $resGroup -Force | Out-Host - Write-Host "Done" - } - $runners = (gh api /repos/$repo/actions/runners | ConvertFrom-Json).runners - $runners | Where-Object { $_.status -eq "offline" } | ForEach-Object { - Write-host "Unregistering runner $($_.name)" - $id = $_.id - gh api -X DELETE /repos/$repo/actions/runners/$id - Write-Host "Done" - } - - - name: Create Resource Group - uses: azure/powershell@v1 - env: - GH_TOKEN: ${{ secrets.GH_TOKEN }} - with: - azPSVersion: "latest" - inlineScript: | - $resGroup = $env:resGroup - $resLocation = $env:resLocation - Write-Host "Creating resource group $resGroup in $resLocation" - $resourceGroup = New-AzResourceGroup -Name $resGroup -Location $resLocation -Force - Write-Host "Done" - - - name: Calculate Matrix - id: CalculateMatrix - env: - count: ${{ github.event.inputs.Count }} - run: | - $count = [int]$env:count - $matrix = @{ "machine" = @(1..$count) } | ConvertTo-Json -compress - Add-Content -path $ENV:GITHUB_OUTPUT -value "matrix=$matrix" - Write-Host $matrix - - CreateAgents: - runs-on: [ windows-latest ] - needs: [ Preparation ] - strategy: - matrix: ${{fromJson(needs.Preparation.outputs.matrix)}} - fail-fast: true - steps: - - uses: azure/login@v1 - with: - creds: ${{ secrets.AZURE_CREDENTIALS }} - enable-AzPSSession: true - - - name: Create Azure VM - uses: azure/powershell@v1 - env: - machine: ${{ matrix.machine }} - GH_TOKEN: ${{ secrets.GH_TOKEN }} - with: - azPSVersion: "latest" - inlineScript: | - $resGroup = $env:resGroup - $repo = $env:GITHUB_REPOSITORY - $no = $env:machine - $templateUri = "https://raw.githubusercontent.com/microsoft/nav-arm-templates/$($env:ARMbranch)/$($env:ARMtemplate).json" - $registrationToken = (gh api -X POST /repos/$repo/actions/runners/registration-token | ConvertFrom-Json).token - $headers = @{ - "Accept" = "application/json" - } - $uri = "https://api.github.com/repos/actions/runner/releases" - $result = Invoke-WebRequest -UseBasicParsing -Headers $headers -Uri $uri - $releases = $result.Content | ConvertFrom-Json - $asset = $releases[0].assets | Where-Object { $_.name -like "actions-runner-win-x64-*.*.?.zip" } - $Parameters = @{ - "VmName" = "$resgroup$no" - "Remotedesktopaccess" = "-" - "OperatingSystem" = "Windows Server 2022" - "VmSize" = "Standard_D4as_v5" - "OSDiskSize" = 1000 - "StorageAccountType" = "Premium_LRS" - "AdminPassword" = [SecureString](ConvertTo-SecureString -String $env:GH_TOKEN -AsPlainText -Force) - "Count" = 1 - "Token" = $registrationToken - "Organization" = "https://github.com/$repo" - "LabelsOrPool" = "buildgeneric" - "AgentUrl" = $asset.browser_download_url - "InstallHyperV" = "Yes" - "RunInsideDocker" = "No" - "FinalSetupScriptUrl" = "additional-installforbuildagent.ps1" - } - $resourceGroup = Get-AzResourceGroup -name $resGroup - $err = $resourceGroup | Test-AzResourceGroupDeployment -TemplateUri $templateUri -TemplateParameterObject $Parameters - if ($err) { - $err - throw "stop" - } - Write-Host "Creating Azure VM $($parameters.VmName)" - $resourceGroup | New-AzResourceGroupDeployment -TemplateUri $templateUri -TemplateParameterObject $Parameters -Name $Parameters.vmName -ErrorAction Ignore - Write-Host "Done" diff --git a/.github/workflows/RemoveAgents.yaml b/.github/workflows/RemoveAgents.yaml deleted file mode 100644 index fc68f54..0000000 --- a/.github/workflows/RemoveAgents.yaml +++ /dev/null @@ -1,51 +0,0 @@ -name: Remove Self-Hosted Agents - -on: - workflow_dispatch: - -permissions: - contents: read - -defaults: - run: - shell: PowerShell - -env: - resGroup: "buildgeneric" - -jobs: - Preparation: - runs-on: [ windows-latest ] - outputs: - matrix: ${{steps.CalculateMatrix.outputs.matrix}} - steps: - - name: Azure Login - uses: azure/login@v1 - with: - creds: ${{ secrets.AZURE_CREDENTIALS }} - enable-AzPSSession: true - - - name: Remove Old Agents - uses: azure/powershell@v1 - env: - GH_TOKEN: ${{ secrets.GH_TOKEN }} - with: - azPSVersion: "latest" - inlineScript: | - $resGroup = $env:resGroup - $repo = $env:GITHUB_REPOSITORY - Write-Host "Resource Group is $resGroup" - Write-Host - $resourceGroup = Get-AzResourceGroup -name $resGroup -ErrorAction Ignore - if ($resourceGroup) { - Write-Host "Removing Resource Group $resGroup" - Remove-AzResourceGroup -Name $resGroup -Force | Out-Host - Write-Host "Done" - } - $runners = (gh api /repos/$repo/actions/runners | ConvertFrom-Json).runners - $runners | Where-Object { $_.status -eq "offline" } | ForEach-Object { - Write-host "Unregistering runner $($_.name)" - $id = $_.id - gh api -X DELETE /repos/$repo/actions/runners/$id - Write-Host "Done" - } diff --git a/.github/workflows/Test.yaml b/.github/workflows/Test.yaml deleted file mode 100644 index 3d12f3e..0000000 --- a/.github/workflows/Test.yaml +++ /dev/null @@ -1,96 +0,0 @@ -name: Azure test - -on: - workflow_dispatch: - -permissions: - contents: read - -jobs: - build-and-deploy: - runs-on: windows-latest - steps: - - # Checkout code - - uses: actions/checkout@v4 - - # Log into Azure - - uses: azure/login@v1 - with: - creds: ${{ secrets.AZURE_CREDENTIALS }} - enable-AzPSSession: true - - - name: Run Azure PowerShell script - uses: azure/powershell@v1 - env: - GH_TOKEN: ${{ secrets.GH_TOKEN }} - with: - azPSVersion: "latest" - inlineScript: | - $resGroup = "buildgeneric" - $resLocation = "West Europe" - $repo = "microsoft/nav-docker" - $machines = 2 - $offset = 0 - Write-Host "Resource Group is $resGroup" - $resourceGroup = Get-AzResourceGroup -name $resGroup -ErrorAction Ignore - if ($resourceGroup) { - Write-Host "Removing Resource Group $resGroup" - Remove-AzResourceGroup -Name $resGroup -Force | Out-Host - Write-Host "Done" - } - $runners = (gh api /repos/$repo/actions/runners | ConvertFrom-Json).runners - $runners | Where-Object { $_.status -eq "offline" } | ForEach-Object { - Write-host "Unregistering runner $($_.name)" - $id = $_.id - gh api -X DELETE /repos/$repo/actions/runners/$id - Write-Host "Done" - } - Write-Host "Creating resource group $resGroup in $resLocation" - $resourceGroup = New-AzResourceGroup -Name $resGroup -Location $resLocation -Force - Write-Host "Done" - 1..$machines | ForEach-Object { - # Deployment - $no = $offset + $_ - $branch = "dev" - $template = "buildagent" - - # ARM template - $templateUri = "https://raw.githubusercontent.com/microsoft/nav-arm-templates/$branch/$template.json" - - $registrationToken = (gh api -X POST /repos/$repo/actions/runners/registration-token | ConvertFrom-Json).token - $headers = @{ - "Accept" = "application/json" - } - $uri = "https://api.github.com/repos/actions/runner/releases" - $result = Invoke-WebRequest -UseBasicParsing -Headers $headers -Uri $uri - $releases = $result.Content | ConvertFrom-Json - $asset = $releases[0].assets | Where-Object { $_.name -like "actions-runner-win-x64-*.*.?.zip" } - - $Parameters = @{ - "VmName" = "$resgroup$no" - "Remotedesktopaccess" = "-" - "OperatingSystem" = "Windows Server 2022" - "VmSize" = "Standard_D4as_v5" - "OSDiskSize" = 128 - "StorageAccountType" = "Premium_LRS" - "AdminPassword" = [SecureString](ConvertTo-SecureString -String $env:GH_TOKEN -AsPlainText -Force) - "Count" = 1 - "Token" = $registrationToken - "Organization" = "https://github.com/$repo" - "LabelsOrPool" = "buildgeneric" - "AgentUrl" = $asset.browser_download_url - "InstallHyperV" = "Yes" - "RunInsideDocker" = "No" - "FinalSetupScriptUrl" = "additional-installforbuildagent.ps1" - } - - $err = $resourceGroup | Test-AzResourceGroupDeployment -TemplateUri $templateUri -TemplateParameterObject $Parameters - if ($err) { - $err - throw "stop" - } - Write-Host "Creating Azure VM $($parameters.VmName)" - $resourceGroup | New-AzResourceGroupDeployment -TemplateUri $templateUri -TemplateParameterObject $Parameters -Name $Parameters.vmName -ErrorAction Ignore - Write-Host "Done" - } diff --git a/generic/DOCKERFILE b/generic/DOCKERFILE index a6bd783..f5c39a2 100644 --- a/generic/DOCKERFILE +++ b/generic/DOCKERFILE @@ -2,68 +2,134 @@ ARG baseimage FROM $baseimage -ARG created -ARG tag -ARG osversion +ARG created \ + tag \ + osversion \ + filesonly \ + only24 + +ENV only24=$only24 \ + filesonly=$filesonly SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] -# Install the prerequisites first to be able reuse the cache when changing only the scripts. -# Temporary workaround for Windows DNS client weirdness (need to check if the issue is still present or not). - -RUN [Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12 ; \ - Add-WindowsFeature Web-Server,web-AppInit,web-Asp-Net45,web-Windows-Auth,web-Dyn-Compression,web-WebSockets; \ - Stop-Service 'W3SVC' ; \ - Set-Service 'W3SVC' -startuptype manual ; \ - Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters' -Name ServerPriorityTimeLimit -Value 0 -Type DWord; \ - Set-ItemProperty -Path "HKLM:\system\CurrentControlSet\control" -name ServicesPipeTimeout -Value 300000 -Type DWORD -Force; \ - Invoke-WebRequest -Uri 'https://bcartifacts.blob.core.windows.net/prerequisites/SQLEXPR2019_X64_ENU.EXE' -OutFile sqlexpress.exe ; \ - Start-Process -Wait -FilePath .\sqlexpress.exe -ArgumentList /qs, /x:setup ; \ - .\setup\setup.exe /q /ACTION=Install /INSTANCENAME=SQLEXPRESS /FEATURES=SQLEngine /UPDATEENABLED=0 /SQLSVCACCOUNT='NT AUTHORITY\System' /SQLSYSADMINACCOUNTS='BUILTIN\Administrators' /TCPENABLED=1 /NPENABLED=0 /IACCEPTSQLSERVERLICENSETERMS ; \ - While (!(get-service 'MSSQL$SQLEXPRESS' -ErrorAction SilentlyContinue)) { Start-Sleep -Seconds 5 } ; \ - Stop-Service 'MSSQL$SQLEXPRESS' ; \ - Set-itemproperty -path 'HKLM:\software\microsoft\microsoft sql server\mssql15.SQLEXPRESS\mssqlserver\supersocketnetlib\tcp\ipall' -name tcpdynamicports -value '' ; \ - Set-itemproperty -path 'HKLM:\software\microsoft\microsoft sql server\mssql15.SQLEXPRESS\mssqlserver\supersocketnetlib\tcp\ipall' -name tcpport -value 1433 ; \ - Set-itemproperty -path 'HKLM:\software\microsoft\microsoft sql server\mssql15.SQLEXPRESS\mssqlserver\' -name LoginMode -value 2 ; \ - Set-Service 'MSSQL$SQLEXPRESS' -startuptype manual ; \ - Set-Service 'SQLTELEMETRY$SQLEXPRESS' -startuptype manual ; \ - Set-Service 'SQLWriter' -startuptype manual ; \ - Set-Service 'SQLBrowser' -startuptype manual ; \ - Remove-Item -Recurse -Force sqlexpress.exe, setup - COPY Run /Run/ -RUN [Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12 ; \ - Invoke-WebRequest -Uri 'https://bcdocker.blob.core.windows.net/public/nav-docker-install.zip' -OutFile 'nav-docker-install.zip' ; \ +RUN Write-Host ('FilesOnly='+$env:filesOnly); \ + Write-Host ('only24='+$env:only24); \ + $filesonly = $env:filesonly -eq 'true'; \ + $only24 = $env:only24 -eq 'true'; \ + if ($only24) { Remove-Item -Recurse -Force Run/70,Run/71,Run/80,Run/90,Run/100,Run/110,Run/130,Run/150,Run/150-new,Run/210,Run/210-new }; \ + [Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12 ; \ [Reflection.Assembly]::LoadWithPartialName('System.IO.Compression.Filesystem') | Out-Null ; \ - [System.IO.Compression.ZipFile]::ExtractToDirectory('.\nav-docker-install.zip', 'c:\run') ; \ - Remove-Item -Force 'nav-docker-install.zip' ; \ + Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters' -Name ServerPriorityTimeLimit -Value 0 -Type DWord; \ + Set-ItemProperty -Path 'HKLM:\system\CurrentControlSet\control' -name ServicesPipeTimeout -Value 300000 -Type DWORD -Force; \ + New-Item 'temp' -ItemType Directory | Out-Null; \ + if (-not $filesonly) { \ + if ($only24) { \ + Write-Host 'Adding Windows Features for BC 24+'; \ + Add-WindowsFeature Web-Server,web-AppInit,web-Windows-Auth,web-Dyn-Compression,web-WebSockets; \ + Stop-Service 'W3SVC' ; \ + Set-Service 'W3SVC' -startuptype manual ; \ + } \ + else { \ + Write-Host 'Adding Windows Features for BC'; \ + Add-WindowsFeature Web-Server,web-AppInit,web-Asp-Net45,web-Windows-Auth,web-Dyn-Compression,web-WebSockets; \ + Stop-Service 'W3SVC' ; \ + Set-Service 'W3SVC' -startuptype manual ; \ + } \ + Write-Host 'Downloading SQL Server 2019 Express'; \ + Invoke-RestMethod -Method Get -UseBasicParsing -Uri 'https://go.microsoft.com/fwlink/p/?linkid=866658' -OutFile 'temp\SQL2019-SSEI-Expr.exe'; \ + $configFileLocation = 'c:\run\SQLConf.ini'; \ + Write-Host 'Installing SQL Server 2019 Express'; \ + $process = Start-Process -FilePath 'temp\SQL2019-SSEI-Expr.exe' -ArgumentList /Action=Install, /ConfigurationFile=$configFileLocation, /IAcceptSQLServerLicenseTerms, /Quiet -NoNewWindow -Wait -PassThru; \ + if (($null -ne $process.ExitCode) -and ($process.ExitCode -ne 0)) { Write-Host ('EXIT CODE '+$process.ExitCode) } else { Write-Host 'Success' }; \ + Write-Host 'Downloading SQL Server 2019 Cumulative Update'; \ + Invoke-RestMethod -Method Get -UseBasicParsing -Uri 'https://download.microsoft.com/download/6/e/7/6e72dddf-dfa4-4889-bc3d-e5d3a0fd11ce/SQLServer2019-KB5033688-x64.exe' -OutFile 'temp\SQL2019CU.exe'; \ + Write-Host 'Installing SQL Server 2019 Cumulative Update'; \ + $process = Start-Process -FilePath 'temp\SQL2019CU.exe' -ArgumentList /Action=Patch, /Quiet, /IAcceptSQLServerLicenseTerms, /AllInstances, /SuppressPrivacyStatementNotice -NoNewWindow -Wait -PassThru; \ + if (($null -ne $process.ExitCode) -and ($process.ExitCode -ne 0)) { Write-Host ('EXIT CODE '+$process.ExitCode) } else { Write-Host 'Success' }; \ + Write-Host 'Configuring SQL Server 2019 Express'; \ + Set-itemproperty -path 'HKLM:\software\microsoft\microsoft sql server\mssql15.SQLEXPRESS\mssqlserver\supersocketnetlib\tcp\ipall' -name tcpdynamicports -value '' ; \ + Set-itemproperty -path 'HKLM:\software\microsoft\microsoft sql server\mssql15.SQLEXPRESS\mssqlserver\supersocketnetlib\tcp\ipall' -name tcpport -value 1433 ; \ + Set-itemproperty -path 'HKLM:\software\microsoft\microsoft sql server\mssql15.SQLEXPRESS\mssqlserver\' -name LoginMode -value 2 ; \ + Set-Service 'MSSQL$SQLEXPRESS' -startuptype manual ; \ + Set-Service 'SQLTELEMETRY$SQLEXPRESS' -startuptype manual ; \ + Set-Service 'SQLWriter' -startuptype manual ; \ + Set-Service 'SQLBrowser' -startuptype manual ; \ + Write-Host 'Removing SQL Server 2019 Express Install Files'; \ + Remove-Item -Recurse -Force -ErrorAction SilentlyContinue 'SQL2019'; \ + Remove-Item -Recurse -Force -ErrorAction SilentlyContinue 'C:\Program Files\Microsoft SQL Server\150\Setup Bootstrap'; \ + Remove-Item -Recurse -Force -ErrorAction SilentlyContinue 'C:\Program Files\Microsoft SQL Server\150\SSEI'; \ + Remove-Item -Recurse -Force -ErrorAction SilentlyContinue 'C:\Program Files\Microsoft SQL Server\MSSQL15.SQLEXPRESS\MSSQL\Template Data'; \ + Remove-Item -Recurse -Force -ErrorAction SilentlyContinue 'C:\Program Files\Microsoft SQL Server\MSSQL15.SQLEXPRESS\MSSQL\Log\*'; \ + } \ + Write-Host 'Downloading NAV/BC Docker Install Files'; \ + Invoke-RestMethod -Method Get -UseBasicParsing -Uri 'https://bcdocker.blob.core.windows.net/public/nav-docker-install.zip' -OutFile 'temp\nav-docker-install.zip' ; \ + Write-Host 'Extracting NAV/BC Docker Install Files'; \ + [System.IO.Compression.ZipFile]::ExtractToDirectory('temp\nav-docker-install.zip', 'c:\run') ; \ + Write-Host 'Updating PowerShell Execution Policy to Unrestricted'; \ . C:\Run\UpdatePowerShellExeConfig.ps1 ; \ . C:\Run\helperfunctions.ps1 ; \ - Start-Service -Name $SqlBrowserServiceName -ErrorAction Ignore -WarningAction Ignore ; \ - Start-Service -Name $SqlWriterServiceName -ErrorAction Ignore -WarningAction Ignore ; \ - Start-Service -Name $SqlServiceName -ErrorAction Ignore -WarningAction Ignore ; \ - Invoke-WebRequest -Uri 'https://download.microsoft.com/download/1/2/8/128E2E22-C1B9-44A4-BE2A-5859ED1D4592/rewrite_amd64_en-US.msi' -OutFile rewrite_amd64.msi ; \ - start-process -Wait -FilePath .\rewrite_amd64.msi -ArgumentList /quiet, /qn, /passive ; \ - Invoke-WebRequest -Uri 'https://bcartifacts.blob.core.windows.net/prerequisites/OpenXMLSDKv25.msi' -OutFile OpenXMLSDKV25.msi ; \ - start-process -Wait -FilePath .\OpenXMLSDKV25.msi -ArgumentList /quiet, /qn, /passive ; \ - Invoke-WebRequest -Uri 'https://download.visualstudio.microsoft.com/download/pr/05726c49-3a3d-4862-9ff8-0660d9dc3c52/71c295f9287faad89e2d3233a38b44fb/dotnet-hosting-5.0.17-win.exe' -OutFile DotNet-Win5.exe ; \ - start-process -Wait -FilePath .\DotNet-Win5.exe -ArgumentList /quiet ; \ - Invoke-WebRequest -Uri 'https://download.visualstudio.microsoft.com/download/pr/04389c24-12a9-4e0e-8498-31989f30bb22/141aef28265938153eefad0f2398a73b/dotnet-hosting-6.0.27-win.exe' -OutFile DotNet6-Win.exe ; \ - start-process -Wait -FilePath .\DotNet6-Win.exe -ArgumentList /quiet ; \ - Invoke-WebRequest -Uri 'https://download.visualstudio.microsoft.com/download/pr/98ff0a08-a283-428f-8e54-19841d97154c/8c7d5f9600eadf264f04c82c813b7aab/dotnet-hosting-8.0.2-win.exe' -OutFile DotNet8-Win.exe ; \ - start-process -Wait -FilePath .\DotNet8-Win.exe -ArgumentList /quiet ; \ - Invoke-WebRequest -Uri 'https://github.com/PowerShell/PowerShell/releases/download/v7.4.1/PowerShell-7.4.1-win-x64.msi' -OutFile powershell-7.4.1-win-x64.msi ; \ - start-process -Wait -FilePath .\powershell-7.4.1-win-x64.msi -ArgumentList /quiet ; \ - Invoke-WebRequest -Uri 'https://download.microsoft.com/download/B/E/D/BED73AAC-3C8A-43F5-AF4F-EB4FEA6C8F3A/ENU/x64/sqlncli.msi' -OutFile sqlncli.msi ; \ - start-process -Wait -FilePath .\sqlncli.msi -ArgumentList /quiet, /qn, /passive ; \ - Invoke-WebRequest -Uri 'https://aka.ms/highdpimfc2013x86enu' -OutFile vcredist_x86.exe ; \ - start-process -Wait -FilePath .\vcredist_x86.exe -ArgumentList /q, /norestart ; \ - Invoke-WebRequest -Uri 'https://aka.ms/highdpimfc2013x64enu' -OutFile vcredist_x64.exe ; \ - start-process -Wait -FilePath .\vcredist_x64.exe -ArgumentList /q, /norestart ; \ - Invoke-WebRequest -Uri 'https://aka.ms/vs/17/release/vc_redist.x64.exe' -OutFile vcredist_x64_140.exe ; \ - start-process -Wait -FilePath .\vcredist_x64_140.exe -ArgumentList /q, /norestart ; \ - Remove-Item -Recurse -Force rewrite_amd64.msi, OpenXMLSDKV25.msi, DotNet-Win5.exe, DotNet6-Win.exe, DotNet8-Win.exe, powershell-7.4.1-win-x64.msi, sqlncli.msi, vcredist_x86.exe, vcredist_x64.exe, vcredist_x64_140.exe + if (-not $filesonly) { \ + Write-Host 'Starting SQL Server Services'; \ + Start-Service -Name $SqlBrowserServiceName -ErrorAction Ignore -WarningAction Ignore ; \ + Start-Service -Name $SqlWriterServiceName -ErrorAction Ignore -WarningAction Ignore ; \ + Start-Service -Name $SqlServiceName -ErrorAction Ignore -WarningAction Ignore ; \ + Write-Host 'Downloading rewrite_amd64'; \ + Invoke-RestMethod -Method Get -UseBasicParsing -Uri 'https://download.microsoft.com/download/1/2/8/128E2E22-C1B9-44A4-BE2A-5859ED1D4592/rewrite_amd64_en-US.msi' -OutFile 'temp\rewrite_amd64.msi' ; \ + Write-Host 'Installing rewrite_amd64'; \ + $process = start-process -Wait -FilePath 'temp\rewrite_amd64.msi' -ArgumentList /quiet, /qn, /passive ; \ + if (($null -ne $process.ExitCode) -and ($process.ExitCode -ne 0)) { Write-Host ('EXIT CODE '+$process.ExitCode) } else { Write-Host 'Success' }; \ + Write-Host 'Downloading SQL Server Native Client'; \ + Invoke-RestMethod -Method Get -UseBasicParsing -Uri 'https://download.microsoft.com/download/B/E/D/BED73AAC-3C8A-43F5-AF4F-EB4FEA6C8F3A/ENU/x64/sqlncli.msi' -OutFile 'temp\sqlncli.msi' ; \ + Write-Host 'Installing SQL Server Native Client'; \ + $process = start-process -Wait -FilePath 'temp\sqlncli.msi' -ArgumentList /quiet, /qn, /passive ; \ + if (($null -ne $process.ExitCode) -and ($process.ExitCode -ne 0)) { Write-Host ('EXIT CODE '+$process.ExitCode) } else { Write-Host 'Success' }; \ + } \ + Write-Host 'Downloading OpenXMLSDKV25'; \ + Invoke-RestMethod -Method Get -UseBasicParsing -Uri 'https://bcartifacts.blob.core.windows.net/prerequisites/OpenXMLSDKv25.msi' -OutFile 'temp\OpenXMLSDKV25.msi' ; \ + Write-Host 'Installing OpenXMLSDKV25'; \ + $process = start-process -Wait -FilePath 'temp\OpenXMLSDKV25.msi' -ArgumentList /quiet, /qn, /passive ; \ + if (($null -ne $process.ExitCode) -and ($process.ExitCode -ne 0)) { Write-Host ('EXIT CODE '+$process.ExitCode) } else { Write-Host 'Success' }; \ + Write-Host 'Downloading dotnet 6'; \ + Invoke-RestMethod -Method Get -UseBasicParsing -Uri 'https://download.visualstudio.microsoft.com/download/pr/04389c24-12a9-4e0e-8498-31989f30bb22/141aef28265938153eefad0f2398a73b/dotnet-hosting-6.0.27-win.exe' -OutFile 'temp\DotNet6-Win.exe' ; \ + Write-Host 'Installing dotnet 6'; \ + $process = start-process -Wait -FilePath 'temp\DotNet6-Win.exe' -ArgumentList /quiet ; \ + if (($null -ne $process.ExitCode) -and ($process.ExitCode -ne 0)) { Write-Host ('EXIT CODE '+$process.ExitCode) } else { Write-Host 'Success' }; \ + Write-Host 'Downloading dotnet 8'; \ + Invoke-RestMethod -Method Get -UseBasicParsing -Uri 'https://download.visualstudio.microsoft.com/download/pr/98ff0a08-a283-428f-8e54-19841d97154c/8c7d5f9600eadf264f04c82c813b7aab/dotnet-hosting-8.0.2-win.exe' -OutFile 'temp\DotNet8-Win.exe' ; \ + Write-Host 'Installing dotnet 8'; \ + $process = start-process -Wait -FilePath 'temp\DotNet8-Win.exe' -ArgumentList /quiet ; \ + if (($null -ne $process.ExitCode) -and ($process.ExitCode -ne 0)) { Write-Host ('EXIT CODE '+$process.ExitCode) } else { Write-Host 'Success' }; \ + Write-Host 'Downloading PowerShell 7.4.1'; \ + Invoke-RestMethod -Method Get -UseBasicParsing -Uri 'https://github.com/PowerShell/PowerShell/releases/download/v7.4.1/PowerShell-7.4.1-win-x64.msi' -OutFile 'temp\powershell-7.4.1-win-x64.msi' ; \ + Write-Host 'Installing PowerShell 7.4.1'; \ + $process = start-process -Wait -FilePath 'temp\powershell-7.4.1-win-x64.msi' -ArgumentList /quiet ; \ + if (($null -ne $process.ExitCode) -and ($process.ExitCode -ne 0)) { Write-Host ('EXIT CODE '+$process.ExitCode) } else { Write-Host 'Success' }; \ + if (-not $only24) { \ + Write-Host 'Downloading vcredist_x86'; \ + Invoke-RestMethod -Method Get -UseBasicParsing -Uri 'https://aka.ms/highdpimfc2013x86enu' -OutFile 'temp\vcredist_x86.exe' ; \ + Write-Host 'Installing vcredist_x86'; \ + $process = start-process -Wait -FilePath 'temp\vcredist_x86.exe' -ArgumentList /q, /norestart ; \ + if (($null -ne $process.ExitCode) -and ($process.ExitCode -ne 0)) { Write-Host ('EXIT CODE '+$process.ExitCode) } else { Write-Host 'Success' }; \ + Write-Host 'Downloading vcredist_x64'; \ + Invoke-RestMethod -Method Get -UseBasicParsing -Uri 'https://aka.ms/highdpimfc2013x64enu' -OutFile 'temp\vcredist_x64.exe' ; \ + Write-Host 'Installing vcredist_x64'; \ + $process = start-process -Wait -FilePath 'temp\vcredist_x64.exe' -ArgumentList /q, /norestart ; \ + if (($null -ne $process.ExitCode) -and ($process.ExitCode -ne 0)) { Write-Host ('EXIT CODE '+$process.ExitCode) } else { Write-Host 'Success' }; \ + } \ + Write-Host 'Downloading vcredist_x64_140'; \ + Invoke-RestMethod -Method Get -UseBasicParsing -Uri 'https://aka.ms/vs/17/release/vc_redist.x64.exe' -OutFile 'temp\vcredist_x64_140.exe' ; \ + Write-Host 'Installing vcredist_x64_140'; \ + $process = start-process -Wait -FilePath 'temp\vcredist_x64_140.exe' -ArgumentList /q, /norestart ; \ + if (($null -ne $process.ExitCode) -and ($process.ExitCode -ne 0)) { Write-Host ('EXIT CODE '+$process.ExitCode) } else { Write-Host 'Success' }; \ + Write-Host 'Removing temp folder'; \ + Remove-Item -Recurse -Force -ErrorAction SilentlyContinue 'temp'; \ + Write-Host 'Cleanup temporary files'; \ + Remove-Item -Recurse -Force -ErrorAction SilentlyContinue $env:TEMP\*; \ + Write-Host 'Remove x86 dotnet files'; \ + Remove-Item -Recurse -Force -ErrorAction SilentlyContinue 'C:\Program Files (x86)\dotnet' HEALTHCHECK --interval=30s --timeout=10s CMD [ "powershell", ".\\Run\\HealthCheck.ps1" ] diff --git a/generic/DOCKERFILE-filesonly b/generic/DOCKERFILE-filesonly index a8d7f79..34514a7 100644 --- a/generic/DOCKERFILE-filesonly +++ b/generic/DOCKERFILE-filesonly @@ -2,38 +2,138 @@ ARG baseimage FROM $baseimage -ARG created -ARG tag -ARG osversion +ARG created \ + tag \ + osversion \ + filesonly \ + only24 + +ENV only24=$only24 \ + filesonly=$filesonly SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] COPY Run /Run/ -RUN [Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12 ; \ - Invoke-WebRequest -Uri 'https://bcdocker.blob.core.windows.net/public/nav-docker-install.zip' -OutFile 'nav-docker-install.zip' ; \ +RUN Write-Host ('FilesOnly='+$env:filesOnly); \ + Write-Host ('only24='+$env:only24); \ + $filesonly = $env:filesonly -eq 'true'; \ + $only24 = $env:only24 -eq 'true'; \ + if ($only24) { Remove-Item -Recurse -Force Run/70,Run/71,Run/80,Run/90,Run/100,Run/110,Run/130,Run/150,Run/150-new,Run/210,Run/210-new }; \ + [Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12 ; \ [Reflection.Assembly]::LoadWithPartialName('System.IO.Compression.Filesystem') | Out-Null ; \ - [System.IO.Compression.ZipFile]::ExtractToDirectory('.\nav-docker-install.zip', 'c:\run') ; \ - Remove-Item -Force 'nav-docker-install.zip' ; \ + Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters' -Name ServerPriorityTimeLimit -Value 0 -Type DWord; \ + Set-ItemProperty -Path 'HKLM:\system\CurrentControlSet\control' -name ServicesPipeTimeout -Value 300000 -Type DWORD -Force; \ + New-Item 'temp' -ItemType Directory | Out-Null; \ + if (-not $filesonly) { \ + if ($only24) { \ + Write-Host 'Adding Windows Features for BC 24+'; \ + Add-WindowsFeature Web-Server,web-AppInit,web-Windows-Auth,web-Dyn-Compression,web-WebSockets; \ + Stop-Service 'W3SVC' ; \ + Set-Service 'W3SVC' -startuptype manual ; \ + } \ + else { \ + Write-Host 'Adding Windows Features for BC'; \ + Add-WindowsFeature Web-Server,web-AppInit,web-Asp-Net45,web-Windows-Auth,web-Dyn-Compression,web-WebSockets; \ + Stop-Service 'W3SVC' ; \ + Set-Service 'W3SVC' -startuptype manual ; \ + } \ + Write-Host 'Downloading SQL Server 2019 Express'; \ + Invoke-RestMethod -Method Get -UseBasicParsing -Uri 'https://go.microsoft.com/fwlink/p/?linkid=866658' -OutFile 'temp\SQL2019-SSEI-Expr.exe'; \ + $configFileLocation = 'c:\run\SQLConf.ini'; \ + Write-Host 'Installing SQL Server 2019 Express'; \ + $process = Start-Process -FilePath 'temp\SQL2019-SSEI-Expr.exe' -ArgumentList /Action=Install, /ConfigurationFile=$configFileLocation, /IAcceptSQLServerLicenseTerms, /Quiet -NoNewWindow -Wait -PassThru; \ + if (($null -ne $process.ExitCode) -and ($process.ExitCode -ne 0)) { Write-Host ('EXIT CODE '+$process.ExitCode) } else { Write-Host 'Success' }; \ + Write-Host 'Downloading SQL Server 2019 Cumulative Update'; \ + Invoke-RestMethod -Method Get -UseBasicParsing -Uri 'https://download.microsoft.com/download/6/e/7/6e72dddf-dfa4-4889-bc3d-e5d3a0fd11ce/SQLServer2019-KB5033688-x64.exe' -OutFile 'temp\SQL2019CU.exe'; \ + Write-Host 'Installing SQL Server 2019 Cumulative Update'; \ + $process = Start-Process -FilePath 'temp\SQL2019CU.exe' -ArgumentList /Action=Patch, /Quiet, /IAcceptSQLServerLicenseTerms, /AllInstances, /SuppressPrivacyStatementNotice -NoNewWindow -Wait -PassThru; \ + if (($null -ne $process.ExitCode) -and ($process.ExitCode -ne 0)) { Write-Host ('EXIT CODE '+$process.ExitCode) } else { Write-Host 'Success' }; \ + Write-Host 'Configuring SQL Server 2019 Express'; \ + Set-itemproperty -path 'HKLM:\software\microsoft\microsoft sql server\mssql15.SQLEXPRESS\mssqlserver\supersocketnetlib\tcp\ipall' -name tcpdynamicports -value '' ; \ + Set-itemproperty -path 'HKLM:\software\microsoft\microsoft sql server\mssql15.SQLEXPRESS\mssqlserver\supersocketnetlib\tcp\ipall' -name tcpport -value 1433 ; \ + Set-itemproperty -path 'HKLM:\software\microsoft\microsoft sql server\mssql15.SQLEXPRESS\mssqlserver\' -name LoginMode -value 2 ; \ + Set-Service 'MSSQL$SQLEXPRESS' -startuptype manual ; \ + Set-Service 'SQLTELEMETRY$SQLEXPRESS' -startuptype manual ; \ + Set-Service 'SQLWriter' -startuptype manual ; \ + Set-Service 'SQLBrowser' -startuptype manual ; \ + Write-Host 'Removing SQL Server 2019 Express Install Files'; \ + Remove-Item -Recurse -Force -ErrorAction SilentlyContinue 'SQL2019'; \ + Remove-Item -Recurse -Force -ErrorAction SilentlyContinue 'C:\Program Files\Microsoft SQL Server\150\Setup Bootstrap'; \ + Remove-Item -Recurse -Force -ErrorAction SilentlyContinue 'C:\Program Files\Microsoft SQL Server\150\SSEI'; \ + Remove-Item -Recurse -Force -ErrorAction SilentlyContinue 'C:\Program Files\Microsoft SQL Server\MSSQL15.SQLEXPRESS\MSSQL\Template Data'; \ + Remove-Item -Recurse -Force -ErrorAction SilentlyContinue 'C:\Program Files\Microsoft SQL Server\MSSQL15.SQLEXPRESS\MSSQL\Log\*'; \ + } \ + Write-Host 'Downloading NAV/BC Docker Install Files'; \ + Invoke-RestMethod -Method Get -UseBasicParsing -Uri 'https://bcdocker.blob.core.windows.net/public/nav-docker-install.zip' -OutFile 'temp\nav-docker-install.zip' ; \ + Write-Host 'Extracting NAV/BC Docker Install Files'; \ + [System.IO.Compression.ZipFile]::ExtractToDirectory('temp\nav-docker-install.zip', 'c:\run') ; \ + Write-Host 'Updating PowerShell Execution Policy to Unrestricted'; \ . C:\Run\UpdatePowerShellExeConfig.ps1 ; \ . C:\Run\helperfunctions.ps1 ; \ - Invoke-WebRequest -Uri 'https://bcartifacts.blob.core.windows.net/prerequisites/OpenXMLSDKv25.msi' -OutFile OpenXMLSDKV25.msi ; \ - start-process -Wait -FilePath .\OpenXMLSDKV25.msi -ArgumentList /quiet, /qn, /passive ; \ - Invoke-WebRequest -Uri 'https://download.visualstudio.microsoft.com/download/pr/05726c49-3a3d-4862-9ff8-0660d9dc3c52/71c295f9287faad89e2d3233a38b44fb/dotnet-hosting-5.0.17-win.exe' -OutFile DotNet-Win5.exe ; \ - start-process -Wait -FilePath .\DotNet-Win5.exe -ArgumentList /quiet ; \ - Invoke-WebRequest -Uri 'https://download.visualstudio.microsoft.com/download/pr/04389c24-12a9-4e0e-8498-31989f30bb22/141aef28265938153eefad0f2398a73b/dotnet-hosting-6.0.27-win.exe' -OutFile DotNet6-Win.exe ; \ - start-process -Wait -FilePath .\DotNet6-Win.exe -ArgumentList /quiet ; \ - Invoke-WebRequest -Uri 'https://download.visualstudio.microsoft.com/download/pr/98ff0a08-a283-428f-8e54-19841d97154c/8c7d5f9600eadf264f04c82c813b7aab/dotnet-hosting-8.0.2-win.exe' -OutFile DotNet8-Win.exe ; \ - start-process -Wait -FilePath .\DotNet8-Win.exe -ArgumentList /quiet ; \ - Invoke-WebRequest -Uri 'https://github.com/PowerShell/PowerShell/releases/download/v7.4.1/PowerShell-7.4.1-win-x64.msi' -OutFile powershell-7.4.1-win-x64.msi ; \ - start-process -Wait -FilePath .\powershell-7.4.1-win-x64.msi -ArgumentList /quiet ; \ - Invoke-WebRequest -Uri 'https://aka.ms/highdpimfc2013x86enu' -OutFile vcredist_x86.exe ; \ - start-process -Wait -FilePath .\vcredist_x86.exe -ArgumentList /q, /norestart ; \ - Invoke-WebRequest -Uri 'https://aka.ms/highdpimfc2013x64enu' -OutFile vcredist_x64.exe ; \ - start-process -Wait -FilePath .\vcredist_x64.exe -ArgumentList /q, /norestart ; \ - Invoke-WebRequest -Uri 'https://aka.ms/vs/17/release/vc_redist.x64.exe' -OutFile vcredist_x64_140.exe ; \ - start-process -Wait -FilePath .\vcredist_x64_140.exe -ArgumentList /q, /norestart ; \ - Remove-Item -Recurse -Force OpenXMLSDKV25.msi, DotNet-Win5.exe, DotNet6-Win.exe, DotNet8-Win.exe, powershell-7.4.1-win-x64.msi, vcredist_x86.exe, vcredist_x64.exe, vcredist_x64_140.exe + if (-not $filesonly) { \ + Write-Host 'Starting SQL Server Services'; \ + Start-Service -Name $SqlBrowserServiceName -ErrorAction Ignore -WarningAction Ignore ; \ + Start-Service -Name $SqlWriterServiceName -ErrorAction Ignore -WarningAction Ignore ; \ + Start-Service -Name $SqlServiceName -ErrorAction Ignore -WarningAction Ignore ; \ + Write-Host 'Downloading rewrite_amd64'; \ + Invoke-RestMethod -Method Get -UseBasicParsing -Uri 'https://download.microsoft.com/download/1/2/8/128E2E22-C1B9-44A4-BE2A-5859ED1D4592/rewrite_amd64_en-US.msi' -OutFile 'temp\rewrite_amd64.msi' ; \ + Write-Host 'Installing rewrite_amd64'; \ + $process = start-process -Wait -FilePath 'temp\rewrite_amd64.msi' -ArgumentList /quiet, /qn, /passive ; \ + if (($null -ne $process.ExitCode) -and ($process.ExitCode -ne 0)) { Write-Host ('EXIT CODE '+$process.ExitCode) } else { Write-Host 'Success' }; \ + Write-Host 'Downloading SQL Server Native Client'; \ + Invoke-RestMethod -Method Get -UseBasicParsing -Uri 'https://download.microsoft.com/download/B/E/D/BED73AAC-3C8A-43F5-AF4F-EB4FEA6C8F3A/ENU/x64/sqlncli.msi' -OutFile 'temp\sqlncli.msi' ; \ + Write-Host 'Installing SQL Server Native Client'; \ + $process = start-process -Wait -FilePath 'temp\sqlncli.msi' -ArgumentList /quiet, /qn, /passive ; \ + if (($null -ne $process.ExitCode) -and ($process.ExitCode -ne 0)) { Write-Host ('EXIT CODE '+$process.ExitCode) } else { Write-Host 'Success' }; \ + } \ + Write-Host 'Downloading OpenXMLSDKV25'; \ + Invoke-RestMethod -Method Get -UseBasicParsing -Uri 'https://bcartifacts.blob.core.windows.net/prerequisites/OpenXMLSDKv25.msi' -OutFile 'temp\OpenXMLSDKV25.msi' ; \ + Write-Host 'Installing OpenXMLSDKV25'; \ + $process = start-process -Wait -FilePath 'temp\OpenXMLSDKV25.msi' -ArgumentList /quiet, /qn, /passive ; \ + if (($null -ne $process.ExitCode) -and ($process.ExitCode -ne 0)) { Write-Host ('EXIT CODE '+$process.ExitCode) } else { Write-Host 'Success' }; \ + Write-Host 'Downloading dotnet 6'; \ + Invoke-RestMethod -Method Get -UseBasicParsing -Uri 'https://download.visualstudio.microsoft.com/download/pr/04389c24-12a9-4e0e-8498-31989f30bb22/141aef28265938153eefad0f2398a73b/dotnet-hosting-6.0.27-win.exe' -OutFile 'temp\DotNet6-Win.exe' ; \ + Write-Host 'Installing dotnet 6'; \ + $process = start-process -Wait -FilePath 'temp\DotNet6-Win.exe' -ArgumentList /quiet ; \ + if (($null -ne $process.ExitCode) -and ($process.ExitCode -ne 0)) { Write-Host ('EXIT CODE '+$process.ExitCode) } else { Write-Host 'Success' }; \ + Write-Host 'Downloading dotnet 8'; \ + Invoke-RestMethod -Method Get -UseBasicParsing -Uri 'https://download.visualstudio.microsoft.com/download/pr/98ff0a08-a283-428f-8e54-19841d97154c/8c7d5f9600eadf264f04c82c813b7aab/dotnet-hosting-8.0.2-win.exe' -OutFile 'temp\DotNet8-Win.exe' ; \ + Write-Host 'Installing dotnet 8'; \ + $process = start-process -Wait -FilePath 'temp\DotNet8-Win.exe' -ArgumentList /quiet ; \ + if (($null -ne $process.ExitCode) -and ($process.ExitCode -ne 0)) { Write-Host ('EXIT CODE '+$process.ExitCode) } else { Write-Host 'Success' }; \ + Write-Host 'Downloading PowerShell 7.4.1'; \ + Invoke-RestMethod -Method Get -UseBasicParsing -Uri 'https://github.com/PowerShell/PowerShell/releases/download/v7.4.1/PowerShell-7.4.1-win-x64.msi' -OutFile 'temp\powershell-7.4.1-win-x64.msi' ; \ + Write-Host 'Installing PowerShell 7.4.1'; \ + $process = start-process -Wait -FilePath 'temp\powershell-7.4.1-win-x64.msi' -ArgumentList /quiet ; \ + if (($null -ne $process.ExitCode) -and ($process.ExitCode -ne 0)) { Write-Host ('EXIT CODE '+$process.ExitCode) } else { Write-Host 'Success' }; \ + if (-not $only24) { \ + Write-Host 'Downloading vcredist_x86'; \ + Invoke-RestMethod -Method Get -UseBasicParsing -Uri 'https://aka.ms/highdpimfc2013x86enu' -OutFile 'temp\vcredist_x86.exe' ; \ + Write-Host 'Installing vcredist_x86'; \ + $process = start-process -Wait -FilePath 'temp\vcredist_x86.exe' -ArgumentList /q, /norestart ; \ + if (($null -ne $process.ExitCode) -and ($process.ExitCode -ne 0)) { Write-Host ('EXIT CODE '+$process.ExitCode) } else { Write-Host 'Success' }; \ + Write-Host 'Downloading vcredist_x64'; \ + Invoke-RestMethod -Method Get -UseBasicParsing -Uri 'https://aka.ms/highdpimfc2013x64enu' -OutFile 'temp\vcredist_x64.exe' ; \ + Write-Host 'Installing vcredist_x64'; \ + $process = start-process -Wait -FilePath 'temp\vcredist_x64.exe' -ArgumentList /q, /norestart ; \ + if (($null -ne $process.ExitCode) -and ($process.ExitCode -ne 0)) { Write-Host ('EXIT CODE '+$process.ExitCode) } else { Write-Host 'Success' }; \ + } \ + Write-Host 'Downloading vcredist_x64_140'; \ + Invoke-RestMethod -Method Get -UseBasicParsing -Uri 'https://aka.ms/vs/17/release/vc_redist.x64.exe' -OutFile 'temp\vcredist_x64_140.exe' ; \ + Write-Host 'Installing vcredist_x64_140'; \ + $process = start-process -Wait -FilePath 'temp\vcredist_x64_140.exe' -ArgumentList /q, /norestart ; \ + if (($null -ne $process.ExitCode) -and ($process.ExitCode -ne 0)) { Write-Host ('EXIT CODE '+$process.ExitCode) } else { Write-Host 'Success' }; \ + Write-Host 'Removing temp folder'; \ + Remove-Item -Recurse -Force -ErrorAction SilentlyContinue 'temp'; \ + Write-Host 'Cleanup temporary files'; \ + Remove-Item -Recurse -Force -ErrorAction SilentlyContinue $env:TEMP\*; \ + Write-Host 'Remove x86 dotnet files'; \ + Remove-Item -Recurse -Force -ErrorAction SilentlyContinue 'C:\Program Files (x86)\dotnet' + +HEALTHCHECK --interval=30s --timeout=10s CMD [ "powershell", ".\\Run\\HealthCheck.ps1" ] + +EXPOSE 1433 80 8080 443 7045-7049 7083 CMD .\Run\start.ps1 diff --git a/generic/Run/240/navinstall.ps1 b/generic/Run/240/navinstall.ps1 index 1972e29..0150987 100644 --- a/generic/Run/240/navinstall.ps1 +++ b/generic/Run/240/navinstall.ps1 @@ -87,17 +87,10 @@ if (!$skipDb) { Start-Service -name $IisServiceName } - Write-Host "Copying Service Tier Files" RoboCopyFiles -Source "$NavDvdPath\ServiceTier\Program Files" -Destination "C:\Program Files" -e RoboCopyFiles -Source "$NavDvdPath\ServiceTier\System64Folder" -Destination "C:\Windows\System32" -Files "NavSip.dll" -e -Write-Host "Copying PowerShell Scripts" -RoboCopyFiles -Source "$navDvdPath\WindowsPowerShellScripts\Cloud\NAVAdministration" -Destination "$runPath\NAVAdministration" -e -if (Test-Path "$navDvdPath\WindowsPowerShellScripts\WebSearch") { - RoboCopyFiles -Source "$navDvdPath\WindowsPowerShellScripts\WebSearch" -Destination "$runPath\WebSearch" -e -} - Write-Host "Copying Web Client Files" RoboCopyFiles -Source "$NavDvdPath\WebClient\Microsoft Dynamics NAV" -Destination "C:\Program Files\Microsoft Dynamics NAV" -e diff --git a/generic/Run/SQLConf.ini b/generic/Run/SQLConf.ini new file mode 100644 index 0000000..144425b --- /dev/null +++ b/generic/Run/SQLConf.ini @@ -0,0 +1,30 @@ +;SQL Server 2019 Configuration File +[OPTIONS] +ACTION="Install" +SUPPRESSPRIVACYSTATEMENTNOTICE="True" +ENU="True" +QUIET="True" +SUPPRESSPAIDEDITIONNOTICE="True" +FEATURES=SQLENGINE +INSTANCENAME="SQLEXPRESS" +INSTALLSHAREDDIR="C:\Program Files\Microsoft SQL Server" +INSTALLSHAREDWOWDIR="C:\Program Files (x86)\Microsoft SQL Server" +INSTANCEID="SQLEXPRESS" +SQLTELSVCACCT="NT Service\SQLTELEMETRY$SQLEXPRESS" +SQLTELSVCSTARTUPTYPE="Manual" +INSTANCEDIR="C:\Program Files\Microsoft SQL Server" +AGTSVCACCOUNT="NT AUTHORITY\System" +AGTSVCSTARTUPTYPE="Disabled" +SQLSVCSTARTUPTYPE="Manual" +FILESTREAMLEVEL="0" +SQLMAXDOP="0" +ENABLERANU="False" +SQLCOLLATION="SQL_Latin1_General_CP1_CI_AS" +SQLSVCACCOUNT="NT AUTHORITY\System" +SQLSYSADMINACCOUNTS="BUILTIN\Administrators" +ADDCURRENTUSERASSQLADMIN="False" +TCPENABLED="1" +NPENABLED="0" +BROWSERSVCSTARTUPTYPE="Manual" +SQLMAXMEMORY="2147483647" +SQLMINMEMORY="0" diff --git a/generic/Run/navstart.ps1 b/generic/Run/navstart.ps1 index 2ddff40..1ca4974 100644 --- a/generic/Run/navstart.ps1 +++ b/generic/Run/navstart.ps1 @@ -125,7 +125,8 @@ else { $roleTailoredClientFolder = "" } $WebClientFolder = (Get-Item "C:\Program Files\Microsoft Dynamics NAV\*\Web Client")[0] -$NAVAdministrationScriptsFolder = (Get-Item "$runPath\NAVAdministration").FullName +$NAVAdministrationScriptsFolder = "$runPath\NAVAdministration" +if (!(Test-Path $NAVAdministrationScriptsFolder)) { $NAVAdministrationScriptsFolder = '' } $CustomConfigFile = Join-Path $serviceTierFolder "CustomSettings.config" $CustomConfig = [xml](Get-Content $CustomConfigFile) $serverInstance = $CustomConfig.SelectSingleNode("//appSettings/add[@key='ServerInstance']").Value diff --git a/generic/Run/start.ps1 b/generic/Run/start.ps1 index e825b7f..028bd2b 100644 --- a/generic/Run/start.ps1 +++ b/generic/Run/start.ps1 @@ -183,8 +183,8 @@ try { } } - Write-Host "Using installer from $versionFolder" - if ($versionFolder -ne "") { + if ($versionFolder) { + Write-Host "Using installer from $versionFolder" if (Test-Path "c:\run\navinstall.ps1") { Write-Host "navinstall was overridden" Remove-Item "$versionFolder\navinstall.ps1" @@ -199,6 +199,9 @@ try { } Copy-Item -Path "$versionFolder\*" -Destination "C:\Run" -Recurse -Force } + elseif (!(Test-Path 'c:\run\navinstall.ps1')) { + throw "No installer found to use for version $versionNo" + } # Remove version specific folders Get-ChildItem -Path "C:\Run" -Directory | where-object { [Int]::TryParse($_.Name, [ref]$null) } | % { diff --git a/generic/build.ps1 b/generic/build.ps1 index a07a3a9..d40eba3 100644 --- a/generic/build.ps1 +++ b/generic/build.ps1 @@ -1,72 +1,74 @@ $RootPath = $PSScriptRoot +$ErrorActionPreference = "stop" +Set-StrictMode -Version 2.0 -. (Join-Path $RootPath "settings.ps1") +$osVersion = [System.Version]'10.0.19042.1889' # 20H2 +$osVersion = [System.Version]'10.0.19041.1415' # 2004 + +$isolation = "hyperv" $filesOnly = $false -$os = (Get-CimInstance Win32_OperatingSystem) -if ($os.OSType -ne 18 -or !$os.Version.StartsWith("10.0.")) { - throw "Unknown Host Operating System" -} -$UBR = (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' -Name UBR).UBR -$hostOsVersion = [System.Version]::Parse("$($os.Version).$UBR") +$only24 = $false +$image = "mygeneric" +$genericTag = (Get-Content -Raw -Path (Join-Path $RootPath 'tag.txt')).Trim(@(13,10,32)) +$created = [DateTime]::Now.ToUniversalTime().ToString("yyyyMMddHHmm") -Write-Host "Host OS Version is $hostOsVersion" +Write-Host "Using OS Version $osVersion" -$baseImage = "" -$webclient = New-Object System.Net.WebClient -$basetags = (Get-NavContainerImageTags -imageName "mcr.microsoft.com/dotnet/framework/runtime").tags | Where-Object { $_.StartsWith('4.8-20') } | Sort-Object -Descending | Where-Object { -not $_.endswith("-1803") } -$basetags | ForEach-Object { - if (!($baseImage)) { - $manifest = (($webclient.DownloadString("https://mcr.microsoft.com/v2/dotnet/framework/runtime/manifests/$_") | ConvertFrom-Json).history[0].v1Compatibility | ConvertFrom-Json) - if ($hostOsVersion -eq $manifest.'os.version') { - $baseImage = "mcr.microsoft.com/dotnet/framework/runtime:$_" - Write-Host "$baseImage matches the host OS version" - } - } -} -if (!($baseImage)) { - Write-Error "Unable to find a matching mcr.microsoft.com/dotnet/framework/runtime docker image" +if ($only24) { + $baseimage = "mcr.microsoft.com/windows/servercore:$osVersion" } else { - - if ($filesOnly) { - $dockerfile = Join-Path $RootPath "DOCKERFILE-filesonly" - } - else { - $dockerfile = Join-Path $RootPath "DOCKERFILE" - } - - $image = "mygeneric" - - docker pull $baseimage - $osversion = docker inspect --format "{{.OsVersion}}" $baseImage - - if ($hostOsVersion.Build -ge 20348 -or $osversion.Build -eq $hostOsVersion.Build) { - $isolation = "process" - } - else { - $isolation = "hyperv" - } - - docker images --format "{{.Repository}}:{{.Tag}}" | % { - if ($_ -eq $image) - { - docker rmi $image -f + $baseImage = "" + $webclient = New-Object System.Net.WebClient + $basetags = (Get-NavContainerImageTags -imageName "mcr.microsoft.com/dotnet/framework/runtime").tags | Where-Object { $_.StartsWith('4.8-20') } | Sort-Object -Descending | Where-Object { -not $_.endswith("-1803") } + $basetags | ForEach-Object { + if (!($baseImage)) { + $manifest = (($webclient.DownloadString("https://mcr.microsoft.com/v2/dotnet/framework/runtime/manifests/$_") | ConvertFrom-Json).history[0].v1Compatibility | ConvertFrom-Json) + Write-Host "$osVersion == $($manifest.'os.version')" + if ($osVersion -eq $manifest.'os.version') { + $baseImage = "mcr.microsoft.com/dotnet/framework/runtime:$_" + Write-Host "$baseImage matches the host OS version" + } } } - - docker build --build-arg baseimage=$baseimage ` - --build-arg created=$created ` - --build-arg tag="$genericTag" ` - --build-arg osversion="$osversion" ` - --isolation=$isolation ` - --tag $image ` - --file $dockerfile ` - $RootPath - - if ($LASTEXITCODE -ne 0) { - Write-Error "Failed with exit code $LastExitCode" - } - else { - Write-Host "SUCCESS" + if (!($baseImage)) { + Write-Error "Unable to find a matching mcr.microsoft.com/dotnet/framework/runtime docker image" } } + +$dockerfile = Join-Path $RootPath "DOCKERFILE" +if ($only24) { + $image += "-24" +} +if ($filesOnly) { + $dockerfile += '-filesonly' + $image += '-filesonly' +} +docker pull $baseimage +$osversion = docker inspect --format "{{.OsVersion}}" $baseImage + +docker images --format "{{.Repository}}:{{.Tag}}" | % { + if ($_ -eq $image) + { + docker rmi $image -f + } +} + +docker build --build-arg baseimage=$baseimage ` + --build-arg created=$created ` + --build-arg tag="$genericTag" ` + --build-arg osversion="$osversion" ` + --build-arg filesonly="$filesonly" ` + --build-arg only24="$only24" ` + --isolation=$isolation ` + --memory 64G ` + --tag $image ` + --file $dockerfile ` + $RootPath + +if ($LASTEXITCODE -ne 0) { + Write-Error "Failed with exit code $LastExitCode" +} +else { + Write-Host "SUCCESS" +} diff --git a/generic/tag.txt b/generic/tag.txt index 7106553..677520c 100644 --- a/generic/tag.txt +++ b/generic/tag.txt @@ -1 +1 @@ -1.0.2.16 +1.0.2.17