diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index 48bd28dcad..e0124388e5 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -57,7 +57,6 @@ jobs: build_options: /p:ReleaseJIT='True' configurations: '["Debug", "FuzzerDebug", "Release"]' - onebranch: strategy: matrix: @@ -103,7 +102,7 @@ jobs: # Exclude [processes] test that CodeCoverage can't work with. test_command: .\unit_tests.exe -d yes ~[processes] build_artifact: Build-x64 - environment: windows-2022 + environment: '["windows-2022"]' code_coverage: true gather_dumps: true capture_etw: true @@ -121,7 +120,7 @@ jobs: # Exclude [processes] test that CodeCoverage can't work with. test_command: .\unit_tests.exe -d yes ~[processes] build_artifact: Build-x64 - environment: windows-2022 + environment: '["windows-2022"]' code_coverage: true gather_dumps: true capture_etw: true @@ -138,7 +137,7 @@ jobs: # Exclude [processes] test that CodeCoverage can't work with. test_command: .\unit_tests.exe -d yes ~[processes] build_artifact: Build-x64-native-only - environment: windows-2022 + environment: '["windows-2022"]' code_coverage: true gather_dumps: true capture_etw: true @@ -156,7 +155,7 @@ jobs: pre_test: appverif -enable Exceptions Handles Heaps Leak Locks Memory SRWLock Threadpool TLS DangerousAPIs DirtyStacks TimeRollOver -for unit_tests.exe test_command: .\netebpfext_unit.exe -d yes build_artifact: Build-x64 - environment: windows-2022 + environment: '["windows-2022"]' code_coverage: true gather_dumps: true capture_etw: true @@ -172,7 +171,7 @@ jobs: test_command: .\bpf2c_tests.exe -d yes name: bpf2c build_artifact: Build-x64 - environment: windows-2022 + environment: '["windows-2022"]' vs_dev: true code_coverage: true gather_dumps: true @@ -189,7 +188,7 @@ jobs: test_command: .\bpf_conformance_runner.exe --test_file_directory %SOURCE_ROOT%\external\ebpf-verifier\external\bpf_conformance\tests --cpu_version v4 --plugin_path bpf2c_plugin.exe --debug true --plugin_options "--include %SOURCE_ROOT%\include" name: bpf2c_conformance build_artifact: Build-x64 - environment: windows-2022 + environment: '["windows-2022"]' vs_dev: true code_coverage: true gather_dumps: true @@ -208,7 +207,7 @@ jobs: post_test: .\cleanup_ebpf_cicd_tests.ps1 -KmTracing $true name: driver_ws2019 build_artifact: Build-x64 - environment: ebpf_cicd_tests_ws2019 + environment: '["self-hosted", "1ES.Pool=ebpf-cicd-runner-pool-server-2019", "1ES.ImageOverride=ebpf-cicd-image-server-2019"]' # driver test copies dumps to testlog folder. gather_dumps: false # driver tests manually gather code coverage @@ -227,7 +226,7 @@ jobs: post_test: .\cleanup_ebpf_cicd_tests.ps1 -KmTracing $true name: driver_ws2022 build_artifact: Build-x64 - environment: ebpf_cicd_tests_ws2022 + environment: '["self-hosted", "1ES.Pool=ebpf-cicd-runner-pool-server-2019", "1ES.ImageOverride=ebpf-cicd-image-server-2022"]' # driver test copies dumps to testlog folder. gather_dumps: false # driver tests manually gather code coverage @@ -246,7 +245,7 @@ jobs: post_test: .\cleanup_ebpf_cicd_tests.ps1 -KmTracing $true name: driver_native_only_ws2019 build_artifact: Build-x64-native-only - environment: ebpf_cicd_tests_ws2019 + environment: '["self-hosted", "1ES.Pool=ebpf-cicd-runner-pool-server-2019", "1ES.ImageOverride=ebpf-cicd-image-server-2019"]' # driver test copies dumps to testlog folder. gather_dumps: false # driver tests manually gather code coverage @@ -265,7 +264,7 @@ jobs: post_test: .\cleanup_ebpf_cicd_tests.ps1 -KmTracing $true name: driver_native_only_ws2022 build_artifact: Build-x64-native-only - environment: ebpf_cicd_tests_ws2022 + environment: '["self-hosted", "1ES.Pool=ebpf-cicd-runner-pool-server-2019", "1ES.ImageOverride=ebpf-cicd-image-server-2022"]' # driver test copies dumps to testlog folder. gather_dumps: false # driver tests manually gather code coverage @@ -285,7 +284,7 @@ jobs: post_test: .\cleanup_ebpf_cicd_tests.ps1 -KmTracing $true name: regression_driver_ws2022 build_artifact: Build-x64 - environment: ebpf_cicd_tests_ws2022 + environment: '["self-hosted", "1ES.Pool=ebpf-cicd-runner-pool-server-2019", "1ES.ImageOverride=ebpf-cicd-image-server-2022"]' # driver test copies dumps to testlog folder. gather_dumps: false # driver tests manually gather code coverage @@ -332,7 +331,7 @@ jobs: name: bpf2c_fuzzer test_command: .\bpf2c_fuzzer.exe bpf2c_fuzzer_corpus -use_value_profile=1 -max_total_time=300 -artifact_prefix=Artifacts\ build_artifact: Build-x64 - environment: windows-2022 + environment: '["windows-2022"]' code_coverage: false gather_dumps: true configurations: '["FuzzerDebug"]' @@ -345,7 +344,7 @@ jobs: name: bpf2c_fuzzer test_command: .\bpf2c_fuzzer.exe bpf2c_fuzzer_corpus -use_value_profile=1 -max_total_time=900 -artifact_prefix=Artifacts\ build_artifact: Build-x64 - environment: windows-2022 + environment: '["windows-2022"]' code_coverage: false gather_dumps: true configurations: '["FuzzerDebug"]' @@ -359,7 +358,7 @@ jobs: name: execution_context_fuzzer test_command: .\execution_context_fuzzer.exe execution_context_fuzzer_corpus -use_value_profile=1 -runs=3000 -artifact_prefix=Artifacts\ build_artifact: Build-x64 - environment: windows-2022 + environment: '["windows-2022"]' code_coverage: false gather_dumps: true configurations: '["FuzzerDebug"]' @@ -374,7 +373,7 @@ jobs: name: verifier_fuzzer test_command: .\verifier_fuzzer.exe verifier_corpus -use_value_profile=1 -max_total_time=300 -artifact_prefix=Artifacts\ build_artifact: Build-x64 - environment: windows-2022 + environment: '["windows-2022"]' code_coverage: false gather_dumps: true configurations: '["FuzzerDebug"]' @@ -388,7 +387,7 @@ jobs: name: verifier_fuzzer test_command: .\verifier_fuzzer.exe verifier_corpus -use_value_profile=1 -max_total_time=900 -artifact_prefix=Artifacts\ build_artifact: Build-x64 - environment: windows-2022 + environment: '["windows-2022"]' code_coverage: false gather_dumps: true configurations: '["FuzzerDebug"]' @@ -402,7 +401,7 @@ jobs: name: core_helper_fuzzer test_command: .\core_helper_fuzzer core_helper_corpus -max_len=139 -runs=1000 -use_value_profile=1 -artifact_prefix=Artifacts\ build_artifact: Build-x64 - environment: windows-2022 + environment: '["windows-2022"]' code_coverage: false gather_dumps: true configurations: '["FuzzerDebug"]' @@ -416,7 +415,7 @@ jobs: name: netebpfext_fuzzer test_command: .\netebpfext_fuzzer netebpfext_corpus -max_len=12 -runs=1000 -use_value_profile=1 -artifact_prefix=Artifacts\ build_artifact: Build-x64 - environment: windows-2022 + environment: '["windows-2022"]' code_coverage: false gather_dumps: true configurations: '["FuzzerDebug"]' @@ -431,7 +430,7 @@ jobs: name: cilium_tests test_command: .\cilium_tests.exe -d yes build_artifact: Build-x64 - environment: windows-2022 + environment: '["windows-2022"]' code_coverage: false gather_dumps: true @@ -446,7 +445,7 @@ jobs: # Until there is a dedicated stress test, re-use the perf test. test_command: .\ebpf_performance.exe -d yes build_artifact: Build-x64 - environment: windows-2022 + environment: '["windows-2022"]' # No code coverage on stress. code_coverage: false gather_dumps: true @@ -461,7 +460,7 @@ jobs: # Exclude [processes] test that ASAN can't work with. test_command: .\unit_tests.exe -d yes ~[processes] build_artifact: Build-x64-Sanitize - environment: windows-2022 + environment: '["windows-2022"]' code_coverage: false gather_dumps: true capture_etw: true @@ -475,7 +474,7 @@ jobs: name: fault_injection test_command: .\unit_tests.exe build_artifact: Build-x64 - environment: windows-2022 + environment: '["windows-2022"]' code_coverage: true gather_dumps: true fault_injection: true @@ -490,7 +489,7 @@ jobs: name: netebpfext_fault_injection test_command: .\netebpfext_unit.exe build_artifact: Build-x64 - environment: windows-2022 + environment: '["windows-2022"]' code_coverage: true gather_dumps: true fault_injection: true @@ -506,7 +505,7 @@ jobs: name: quick_user_mode_multi_threaded_stress test_command: .\ebpf_stress_tests_um -tt=8 -td=2 build_artifact: Build-x64 - environment: windows-2022 + environment: '["windows-2022"]' code_coverage: false leak_detection: false gather_dumps: true @@ -535,7 +534,7 @@ jobs: name: fault_injection_full test_command: .\unit_tests.exe build_artifact: Build-x64 - environment: windows-2022 + environment: '["windows-2022"]' code_coverage: false gather_dumps: true fault_injection: true @@ -551,7 +550,7 @@ jobs: name: netebpfext_fault_injection_full test_command: .\netebpfext_unit.exe build_artifact: Build-x64 - environment: windows-2022 + environment: '["windows-2022"]' code_coverage: false gather_dumps: true fault_injection: true @@ -565,7 +564,7 @@ jobs: name: user_mode_multi_threaded_stress test_command: .\ebpf_stress_tests_um -tt=8 -td=10 build_artifact: Build-x64 - environment: windows-2022 + environment: '["windows-2022"]' code_coverage: false leak_detection: false gather_dumps: true @@ -575,7 +574,9 @@ jobs: # against the kernel mode eBPF sub-system. km_mt_stress_tests: needs: regular - if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' + # TODO - revert this back + # if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' + if: github.event_name == 'schedule' || github.event_name == 'pull_request' || github.event_name == 'push' || github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch' uses: ./.github/workflows/reusable-test.yml with: name: km_mt_stress_tests @@ -583,7 +584,7 @@ jobs: test_command: .\execute_ebpf_cicd_tests.ps1 -TestMode "Stress" post_test: .\cleanup_ebpf_cicd_tests.ps1 -KmTracing $true build_artifact: Build-x64 - environment: ebpf_cicd_tests_ws2019 + environment: '["self-hosted", "1ES.Pool=ebpf-cicd-runner-pool-server-2019", "1ES.ImageOverride=ebpf-cicd-image-server-2019"]' code_coverage: false # For this test, we only want kernel mode dumps and not user mode dumps. gather_dumps: false @@ -592,7 +593,9 @@ jobs: # against the kernel mode eBPF sub-system. km_mt_stress_tests_restart_extension: needs: regular - if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' + # TODO - revert this back + # if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' + if: github.event_name == 'schedule' || github.event_name == 'pull_request' || github.event_name == 'push' || github.event_name == 'merge_group' || github.event_name == 'workflow_dispatch' uses: ./.github/workflows/reusable-test.yml with: name: km_mt_stress_tests_restart_extension @@ -600,11 +603,13 @@ jobs: test_command: .\execute_ebpf_cicd_tests.ps1 -TestMode "Stress" -Options @("RestartExtension") post_test: .\cleanup_ebpf_cicd_tests.ps1 -KmTracing $true build_artifact: Build-x64 - environment: ebpf_cicd_tests_ws2019 + environment: '["self-hosted", "1ES.Pool=ebpf-cicd-runner-pool-server-2019", "1ES.ImageOverride=ebpf-cicd-image-server-2019"]' code_coverage: false # For this test, we only want kernel mode dumps and not user mode dumps. gather_dumps: false + # TODO - figure this out... + # Not sure what perf is - probably selfhosted runner, but do we need to support this now? performance: needs: regular if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' diff --git a/.github/workflows/reusable-test.yml b/.github/workflows/reusable-test.yml index 9ad4ca2e5e..2133224b5b 100644 --- a/.github/workflows/reusable-test.yml +++ b/.github/workflows/reusable-test.yml @@ -69,7 +69,9 @@ jobs: strategy: matrix: configurations: ${{ fromJSON(inputs.configurations) }} - runs-on: ${{inputs.environment}} + + runs-on: ${{ fromJSON(inputs.environment) }} + env: # Configuration type to build. SOURCE_ROOT: ${{github.workspace}} @@ -89,6 +91,12 @@ jobs: with: egress-policy: audit + - name: Configure runner (Move to setup script directly later) + id: configure-runner + if: contains(inputs.environment, 'self-hosted') + run: | + powershell.exe "cd C:\bin\CloudTestWorker\ProvisioningScript; dir; .\Setup_orig.ps1" + - name: Print CPU information run: Get-WmiObject -Class Win32_Processor | Select-Object -Property Name, NumberOfCores, NumberOfLogicalProcessors @@ -109,7 +117,7 @@ jobs: # Perform shallow checkout for self-hosted runner. - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - if: (inputs.environment == 'ebpf_cicd_tests_ws2019' || inputs.environment == 'ebpf_cicd_tests_ws2022' || inputs.environment == 'ebpf_cicd_perf_ws2022') && (steps.skip_check.outputs.should_skip != 'true') + if: contains(inputs.environment, 'self-hosted') && (steps.skip_check.outputs.should_skip != 'true') with: ref: ${{ github.event.workflow_run.head_branch }} @@ -158,7 +166,7 @@ jobs: - name: Set up OpenCppCoverage and add to PATH id: set_up_opencppcoverage - if: (inputs.code_coverage == true) && (inputs.environment != 'ebpf_cicd_tests_ws2019' && inputs.environment != 'ebpf_cicd_tests_ws2022' && inputs.environment != 'ebpf_cicd_perf_ws2022') && (steps.skip_check.outputs.should_skip != 'true') + if: (inputs.code_coverage == true) && !contains(inputs.environment, 'self-hosted') && (steps.skip_check.outputs.should_skip != 'true') run: | choco install -y --requirechecksum=true --checksum=2295A733DA39412C61E4F478677519DD0BB1893D88313CE56B468C9E50517888 --checksum-type=sha256 OpenCppCoverage echo "C:\Program Files\OpenCppCoverage" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append @@ -175,7 +183,7 @@ jobs: New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" -Name "DumpFolder" -Value "$dump_path" -PropertyType ExpandString -ErrorAction SilentlyContinue - name: Remove existing artifacts - if: (inputs.environment == 'ebpf_cicd_tests_ws2019' || inputs.environment == 'ebpf_cicd_tests_ws2022' || inputs.environment == 'ebpf_cicd_perf_ws2022') && (steps.skip_check.outputs.should_skip != 'true') + if: contains(inputs.environment, 'self-hosted') && (steps.skip_check.outputs.should_skip != 'true') run: | Remove-Item -Path ${{github.workspace}}\${{env.BUILD_PLATFORM}}\${{env.BUILD_CONFIGURATION}} -Recurse -Force -ErrorAction SilentlyContinue @@ -232,14 +240,14 @@ jobs: .\export_program_info_sample.exe - name: Run pre test command - if: steps.skip_check.outputs.should_skip != 'true' && (inputs.environment != 'ebpf_cicd_tests_ws2019' && inputs.environment != 'ebpf_cicd_tests_ws2022' && inputs.environment != 'ebpf_cicd_perf_ws2022') + if: steps.skip_check.outputs.should_skip != 'true' && !contains(inputs.environment, 'self-hosted') id: run_pre_test_command working-directory: ./${{env.BUILD_PLATFORM}}/${{env.BUILD_CONFIGURATION}} run: | ${{env.PRE_COMMAND}} - name: Run pre test command on self-hosted runner - if: steps.skip_check.outputs.should_skip != 'true' && (inputs.environment == 'ebpf_cicd_tests_ws2019' || inputs.environment == 'ebpf_cicd_tests_ws2022' || inputs.environment == 'ebpf_cicd_perf_ws2022') + if: steps.skip_check.outputs.should_skip != 'true' && contains(inputs.environment, 'self-hosted') id: run_pre_test_command_self_hosted working-directory: ./${{env.BUILD_PLATFORM}}/${{env.BUILD_CONFIGURATION}} run: | @@ -281,14 +289,14 @@ jobs: OpenCppCoverage.exe -q --sources %CD% --excluded_sources %CD%\external\Catch2 --export_type cobertura:ebpf_for_windows.xml --working_dir ${{env.BUILD_PLATFORM}}\${{env.BUILD_CONFIGURATION}} -- powershell .\Run-Test.ps1 ${{env.DUMP_PATH}} ${{env.TEST_TIMEOUT}} ${{env.TEST_COMMAND}} - name: Run test on self-hosted runner - if: (inputs.code_coverage == false) && (steps.skip_check.outputs.should_skip != 'true') && (inputs.environment == 'ebpf_cicd_tests_ws2019' || inputs.environment == 'ebpf_cicd_tests_ws2022' || inputs.environment == 'ebpf_cicd_perf_ws2022') && (inputs.fault_injection != true) + if: (inputs.code_coverage == false) && (steps.skip_check.outputs.should_skip != 'true') && contains(inputs.environment, 'self-hosted') && (inputs.fault_injection != true) id: run_test_self_hosted working-directory: ./${{env.BUILD_PLATFORM}}/${{env.BUILD_CONFIGURATION}} run: | ${{env.TEST_COMMAND}} -LogFileName ${{ runner.name }}.log -SelfHostedRunnerName ${{ runner.name }} - name: Run test without Code Coverage - if: (inputs.code_coverage == false) && (steps.skip_check.outputs.should_skip != 'true') && (inputs.environment != 'ebpf_cicd_tests_ws2019' && inputs.environment != 'ebpf_cicd_tests_ws2022' && inputs.environment != 'ebpf_cicd_perf_ws2022') && (inputs.fault_injection != true) + if: (inputs.code_coverage == false) && (steps.skip_check.outputs.should_skip != 'true') && !contains(inputs.environment, 'self-hosted') && (inputs.fault_injection != true) id: run_test_without_code_coverage working-directory: ./${{env.BUILD_PLATFORM}}/${{env.BUILD_CONFIGURATION}} shell: cmd @@ -298,7 +306,7 @@ jobs: - name: Run post test command # Run the post test command even if the workflow has failed. - if: (success() || failure()) && (steps.skip_check.outputs.should_skip != 'true') && (inputs.environment != 'ebpf_cicd_tests_ws2019' && inputs.environment != 'ebpf_cicd_tests_ws2022' && inputs.environment != 'ebpf_cicd_perf_ws2022') + if: (success() || failure()) && (steps.skip_check.outputs.should_skip != 'true') && !contains(inputs.environment, 'self-hosted') id: run_post_test_command working-directory: ./${{env.BUILD_PLATFORM}}/${{env.BUILD_CONFIGURATION}} run: | @@ -306,7 +314,7 @@ jobs: - name: Run post test command on self-hosted runner # Run the post test command even if the workflow has failed. - if: (success() || failure()) && (steps.skip_check.outputs.should_skip != 'true') && (inputs.environment == 'ebpf_cicd_tests_ws2019' || inputs.environment == 'ebpf_cicd_tests_ws2022' || inputs.environment == 'ebpf_cicd_perf_ws2022') + if: (success() || failure()) && (steps.skip_check.outputs.should_skip != 'true') && contains(inputs.environment, 'self-hosted') id: run_post_test_command_self_hosted working-directory: ./${{env.BUILD_PLATFORM}}/${{env.BUILD_CONFIGURATION}} run: | @@ -523,4 +531,4 @@ jobs: title: title, body: body, labels: label_array, - }); + }); \ No newline at end of file diff --git a/1es/Setup.ps1 b/1es/Setup.ps1 new file mode 100644 index 0000000000..70ef1753a1 --- /dev/null +++ b/1es/Setup.ps1 @@ -0,0 +1,33 @@ +# Copyright (c) eBPF for Windows contributors +# SPDX-License-Identifier: MIT +# param( +# [Parameter(Mandatory=$False)][string]$VmUsername='Administrator', +# [Parameter(Mandatory=$False)][string]$VmPassword='P@ssw0rd', + +# [Parameter(Mandatory=$False)][string]$BaseUnattendPath='.\unattend.xml', +# [Parameter(Mandatory=$False)][string]$BaseVhdDirPath='.\', +# [Parameter(Mandatory=$False)][string]$WorkingPath='.\working', +# [Parameter(Mandatory=$False)][string]$OutVhdDirPath='.\exported_vhds', +# [Parameter(Mandatory=$False)][string]$ExternalSwitchName='VMExternalSwitch', + +# [Parameter(Mandatory=$False)][string]$VMCpuCount=4, +# [Parameter(Mandatory=$False)][string]$VMMemoryStartupBytes=512MB +# ) + +# $ErrorActionPreference = "Stop" + +# # Import helper functions +# Import-Module .\prepare_vm_helpers.psm1 -Force + +$hyperV = (Get-WindowsFeature -Name 'Hyper-V').Installed +Log-Message -Message "Hyper-V is installed: $hyperV" + +$names = (Get-NetAdapter).Name +Log-Message -Message "Network adapters: $names" + +$switches = Get-VMSwitch +Log-Message -Message "VM switches: $switches" + + + +# TODO - eventually, setup_orig will become setup.ps1 \ No newline at end of file diff --git a/1es/Setup_orig.ps1 b/1es/Setup_orig.ps1 new file mode 100644 index 0000000000..b256d7a48d --- /dev/null +++ b/1es/Setup_orig.ps1 @@ -0,0 +1,98 @@ +# Copyright (c) eBPF for Windows contributors +# SPDX-License-Identifier: MIT +param( + [Parameter(Mandatory=$False)][string]$VmUsername='Administrator', + [Parameter(Mandatory=$False)][string]$VmStandardUserName='VMStandardUser', + [Parameter(Mandatory=$False)][string]$VmPassword='P@ssw0rd', + + [Parameter(Mandatory=$False)][string]$BaseUnattendPath='.\unattend.xml', + [Parameter(Mandatory=$False)][string]$BaseVhdDirPath='.\', + # [Parameter(Mandatory=$False)][string]$WorkingPath='.\working', + [Parameter(Mandatory=$False)][string]$WorkingPath='C:\vms', + # [Parameter(Mandatory=$False)][string]$OutVhdDirPath='.\exported_vhds', + + [Parameter(Mandatory=$False)][string]$VMCpuCount=4, + [Parameter(Mandatory=$False)][string]$VMMemory=4096MB +) + +$ErrorActionPreference = "Stop" + +# Import helper functions +Import-Module .\prepare_vm_helpers.psm1 -Force + +if (-not (Test-Path -Path $BaseUnattendPath)) { + throw "Unattend file not found at $BaseUnattendPath" +} + +if (-not (Test-Path -Path $BaseVhdDirPath)) { + throw "VHD directory not found at $BaseVhdDirPath" +} + +Create-VMSwitchIfNeeded -SwitchName 'VMInternalSwitch' -SwitchType 'Internal' +Create-VMSwitchIfNeeded -SwitchName 'VMExternalSwitch' -SwitchType 'External' +# Stored credentials doesn't seem to be working... +# Create-VMStoredCredential -CredentialName "TEST_VM" -Username $VmUsername -Password $VmPassword +# Create-VMStoredCredential -CredentialName "TEST_VM_STANDARD" -Username $VmStandardUserName -Password $VmPassword +Create-DirectoryIfNotExists -Path $WorkingPath + +# Unzip any VHDs +Log-Message "Processing VHDs in $BaseVhdDirPath" +$zipFiles = Get-ChildItem -Path $BaseVhdDirPath -Filter *.zip +foreach ($zipFile in $zipFiles) { + Log-Message "Extracting VHDs from $($zipFile.FullName)" + $outDir = Join-Path -Path $BaseVhdDirPath -ChildPath $zipFile.BaseName + if (-not (Test-Path -Path $outDir)) { + Expand-Archive -Path $zipFile.FullName -DestinationPath $outDir + + # Move the VHDs to the base directory + $vhdFiles = @() + $vhdFiles += Get-ChildItem -Path $outDir -Filter *.vhd -ErrorAction Ignore + $vhdFiles += Get-ChildItem -Path $outDir -Filter *.vhdx -ErrorAction Ignore + foreach ($vhdFile in $vhdFiles) { + Move-Item -Path $vhdFile.FullName -Destination $BaseVhdDirPath + } + } + Log-Message "Successfully processed $($zipFile.FullName)" +} + +# Read the input VHDs +$vhds = @() +$vhds += Get-ChildItem -Path $BaseVhdDirPath -Filter *.vhd -ErrorAction Ignore +$vhds += Get-ChildItem -Path $BaseVhdDirPath -Filter *.vhdx -ErrorAction Ignore +if ($vhds.Count -eq 0) { + throw "No VHDs found in $BaseVhdDirPath" +} +Log-Message "Successfully processed VHDs" + +for ($i = 0; $i -lt $vhds.Count; $i++) { + try { + $vhd = $vhds[$i] + Log-Message -Message "Creating VM from VHD: $($vhd.FullName)" + $vmName = "runner_vm" + if ($i -gt 0) { + $vmName += "_$i" + } + $outVMPath = Join-Path -Path $WorkingPath -ChildPath $VMName + + Create-VM ` + -VmName $vmName ` + -VhdPath $vhd.FullName ` + -VmStoragePath $outVMPath ` + -VMMemory $VMMemory ` + -UnattendPath $BaseUnattendPath ` + -VmUsername $VmUsername ` + -VmPassword $VmPassword + + Configure-VM ` + -VmName $vmName ` + -VmUsername $VmUsername ` + -VmPassword $VmPassword ` + -VMCpuCount $VMCpuCount + + Log-Message "VM $vmName created successfully" + } catch { + Log-Message "Failed to create VM $vmName with error $_" + } +} + +Log-Message "Setup.ps1 complete!" \ No newline at end of file diff --git a/1es/artifacts.json b/1es/artifacts.json new file mode 100644 index 0000000000..0acb5a104b --- /dev/null +++ b/1es/artifacts.json @@ -0,0 +1,8 @@ +{ + "license":["Copyright (c) eBPF for Windows contributors", "SPDX-License-Identifier: MIT"], + "artifacts": [ + { + "name": "windows-server-install-feature-hyperv" + } + ] +} \ No newline at end of file diff --git a/1es/configure_vm.ps1 b/1es/configure_vm.ps1 new file mode 100644 index 0000000000..43e5f3ce05 --- /dev/null +++ b/1es/configure_vm.ps1 @@ -0,0 +1,131 @@ +# Copyright (c) eBPF for Windows contributors +# SPDX-License-Identifier: MIT + +########## Helper Functions ########## +# Download and extract PSExec to run tests as SYSTEM. +function Get-PSExec { + $url = "https://download.sysinternals.com/files/PSTools.zip" + $DownloadPath = "$pwd\psexec" + mkdir $DownloadPath + Write-Host "Downloading PSExec from $url to $DownloadPath" + $ProgressPreference = 'SilentlyContinue' + Invoke-WebRequest $url -OutFile "$DownloadPath\pstools.zip" + cd $DownloadPath + Expand-Archive -Path "$DownloadPath\pstools.zip" -Force + cd .. + Move-Item -Path "$DownloadPath\PSTools\PsExec64.exe" -Destination $pwd -Force + Remove-Item -Path $DownloadPath -Force -Recurse +} + +function Get-ZipFileFromUrl { + param( + [Parameter(Mandatory=$True)][string] $Url, + [Parameter(Mandatory=$True)][string] $DownloadFilePath, + [Parameter(Mandatory=$True)][string] $OutputDir + ) + + for ($i = 0; $i -lt 5; $i++) { + try { + Write-Host "Downloading $Url to $DownloadFilePath" + $ProgressPreference = 'SilentlyContinue' + Invoke-WebRequest -Uri $Url -OutFile $DownloadFilePath + + Write-Host "Extracting $DownloadFilePath to $OutputDir" + Expand-Archive -Path $DownloadFilePath -DestinationPath $OutputDir -Force + break + } catch { + Write-Host "Iteration $i failed to download $Url. Removing $DownloadFilePath" -ForegroundColor Red + Remove-Item -Path $DownloadFilePath -Force -ErrorAction Ignore + Start-Sleep -Seconds 5 + } + } +} + +# Copied from https://github.com/microsoft/msquic/blob/main/scripts/prepare-machine.ps1 +function Get-Duonic { + # Download and extract https://github.com/microsoft/corenet-ci. + $DownloadPath = "$pwd\corenet-ci" + mkdir $DownloadPath + Write-Host "Downloading CoreNet-CI to $DownloadPath" + Get-ZipFileFromUrl -Url "https://github.com/microsoft/corenet-ci/archive/refs/heads/main.zip" -DownloadFilePath "$DownloadPath\corenet-ci.zip" -OutputDir $DownloadPath + Move-Item -Path "$DownloadPath\corenet-ci-main\vm-setup\duonic\*" -Destination $pwd -Force + Move-Item -Path "$DownloadPath\corenet-ci-main\vm-setup\procdump64.exe" -Destination $pwd -Force + Move-Item -Path "$DownloadPath\corenet-ci-main\vm-setup\notmyfault64.exe" -Destination $pwd -Force + Remove-Item -Path $DownloadPath -Force -Recurse +} + +function Initialize-NetworkInterfacesOnVMs +{ + # param([parameter(Mandatory=$true)] $VMMap) + + # foreach ($VM in $VMMap) + # { + # $VMName = $VM.Name + + # Write-Log "Initializing network interfaces on $VMName" + # $TestCredential = New-Credential -Username $Admin -AdminPassword $AdminPassword + + # Invoke-Command -VMName $VMName -Credential $TestCredential -ScriptBlock { + # param([Parameter(Mandatory=$True)] [string] $WorkingDirectory) + + # Push-Location "$env:SystemDrive\$WorkingDirectory" + + Write-Host "Installing DuoNic driver" + .\duonic.ps1 -Install -NumNicPairs 2 + # Disable Duonic's fake checksum offload and force TCP/IP to calculate it. + Set-NetAdapterAdvancedProperty duo? -DisplayName Checksum -RegistryValue 0 + + # Pop-Location + # } -ArgumentList ("eBPF") -ErrorAction Stop + # } +} + +########## Main Execution ########## + +# Enable test signing. +bcdedit -set TESTSIGNING ON + +# Enable user-mode dumps. +New-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" -ErrorAction SilentlyContinue +New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" -Name "DumpType" -Value 2 -PropertyType DWord -ErrorAction SilentlyContinue +New-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps" -Name "DumpFolder" -Value "c:\dumps" -PropertyType ExpandString -ErrorAction SilentlyContinue -Force + +# Enable kernel dumps. +New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\CrashControl" -ErrorAction SilentlyContinue +New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\CrashControl" -Name "CrashDumpEnabled" -Value 2 -PropertyType DWord -ErrorAction SilentlyContinue + +# Enable driver verifier on the eBPF platform drivers. +verifier /standard /bootmode persistent /driver ebpfcore.sys netebpfext.sys sample_ebpf_ext.sys + +# TODO - this will either need to be done post VM creation, or run on the host and copied into the VM +# # Install duonic and configure it. +# Get-Duonic +# Initialize-NetworkInterfacesOnVMs + +# # Get PSExec to run tests as SYSTEM. +# Get-PSExec + +# Loop through each adapter and enable IPv4 and IPv6 +$adapters = Get-NetAdapter +foreach ($adapter in $adapters) { + try { + # Enable IPv4 (usually enabled by default) + Enable-NetAdapterBinding -Name $adapter.Name -ComponentID ms_tcpip + + # Enable IPv6 + Enable-NetAdapterBinding -Name $adapter.Name -ComponentID ms_tcpip6 + + Write-Host "Enabled IPv4 and IPv6 on adapter: $($adapter.Name)" + } catch { + Write-Host "Failed to enable IPv4 and IPv6 on adapter: $($adapter.Name)" + } +} + +Get-NetAdapterBinding -AllBindings | Out-String + +ipconfig /all + +Get-NetIPInterface | Out-String + +# Reboot the machine to apply the changes. +Restart-Computer -Force \ No newline at end of file diff --git a/1es/prepare_vm_helpers.psm1 b/1es/prepare_vm_helpers.psm1 new file mode 100644 index 0000000000..3bbf64d565 --- /dev/null +++ b/1es/prepare_vm_helpers.psm1 @@ -0,0 +1,359 @@ +# Copyright (c) eBPF for Windows contributors +# SPDX-License-Identifier: MIT +$ErrorActionPreference = "Stop" + +function Log-Message { + param( + [Parameter(Mandatory=$True)][string]$Message, + [Parameter(Mandatory=$False)][string]$ForegroundColor='White' + ) + + # Get timestamp + $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" + + Write-Host "[$timestamp] - $Message" -ForegroundColor $ForegroundColor +} + +function Create-DirectoryIfNotExists { + param ( + [Parameter(Mandatory=$True)][string]$Path + ) + + try { + if (-not (Test-Path -Path $Path -PathType Container)) { + New-Item -Path $Path -ItemType Directory -Force # -ErrorAction Ignore | Out-Null + } + + if (-not (Test-Path -PathType Container $Path)) { + throw "Failed to create directory: $Path" + } + } catch { + throw "Failed to create directory: $Path with error $_" + } +} + +function Create-VMCredential { + param ( + [Parameter(Mandatory=$True)][string]$VmUsername, + [Parameter(Mandatory=$True)][string]$VmPassword + ) + + try { + $secureVmPassword = ConvertTo-SecureString $VmPassword -AsPlainText -Force + return New-Object System.Management.Automation.PSCredential($VmUsername, $secureVmPassword) + } catch { + throw "Failed to create VM credential: $_" + } +} + +function Replace-PlaceholderStrings { + param ( + [Parameter(Mandatory=$True)][string]$FilePath, + [Parameter(Mandatory=$True)][string]$SearchString, + [Parameter(Mandatory=$True)][string]$ReplaceString + ) + + try { + $content = Get-Content -Path $FilePath + $content = $content -replace $SearchString, $ReplaceString + Set-Content -Path $FilePath -Value $content + } catch { + throw "Failed to replace placeholder strings in file: $FilePath. Error: $_" + } +} + +function Execute-CommandOnVM { + param ( + [Parameter(Mandatory=$True)][string]$VMName, + [Parameter(Mandatory=$True)][System.Management.Automation.PSCredential]$VmCredential, + [Parameter(Mandatory=$True)][string]$Command + ) + + try { + $result = Invoke-Command -VMName $VMName -Credential $VmCredential -ScriptBlock { + param($Command) + Invoke-Expression $Command + } -ArgumentList $Command + + Log-Message -Message "Executed command on VM: $VMName. Command: $Command. Result: $result" + } catch { + throw "Failed to execute command on VM: $VMName with error: $_" + } +} + +function Wait-ForVMReady { + param ( + [Parameter(Mandatory=$True)][string]$VMName, + [Parameter(Mandatory=$True)][System.Management.Automation.PSCredential]$VmCredential, + [Parameter(Mandatory=$False)][int]$TimeoutInMinutes=30 + ) + + # Attempt for a maximum of 30 minutes + $limit = (Get-Date).AddMinutes($TimeoutInMinutes) + while ((Get-Date) -le $limit) { + try { + # Ensure the VM is in running state + while ((Get-VM -Name $VMName).State -ne 'Running') { + Log-Message -Message "Waiting for $VMName to reach running state..." + Start-Sleep -Seconds 5 + } + + # Trivial command to ensure that we can connect to the VM. + try { + Execute-CommandOnVM -VMName $VMName -VmCredential $VmCredential -Command 'hostname' + } catch { + Log-Message -Message "Failed to connect to $VMName. Retrying..." + Start-Sleep -Seconds 5 + continue + } + + Log-Message -Message "Successfully connected to $VMName" + return + } catch { + # Do nothing. We will retry if we failed to connect to the VM. + } + + Log-Message -Message "Failed to connect to $VMName. Retrying..." + Start-Sleep -Seconds 5 + } + + # If we reached here, we failed to connect to the VM. + throw "Failed to connect to $VMName after timeout..." +} + +# function Update-VM { +# param ( +# [Parameter(Mandatory=$True)][string]$VMName, +# [Parameter(Mandatory=$True)][System.Management.Automation.PSCredential]$VmCredential +# ) + +# # TODO debugging output - remove later +# Get-VMNetworkAdapter -All +# try { Execute-CommandOnVM -VMName $VmName -VmCredential $VmCredential -Command "ipconfig /all" } catch { Log-Message -Message "Failed to query IP config: $_" -ForegroundColor Red } + +# try { Execute-CommandOnVM -VMName $VmName -VmCredential $VmCredential -Command "Invoke-WebRequest bing.com" } catch { Log-Message -Message "Failed to connect to the internet: $_" -ForegroundColor Red } + +# try { Execute-CommandOnVM -VMName $VmName -VmCredential $VmCredential -Command "Install-PackageProvider -Name NuGet -Force" } catch { Log-Message -Message "Failed to install NuGet provider: $_" -ForegroundColor Red } +# try { Execute-CommandOnVM -VMName $VmName -VmCredential $VmCredential -Command "Install-Module -Name PSWindowsUpdate -Force" } catch { Log-Message -Message "Failed to install PSWindowsUpdate module: $_" -ForegroundColor Red } +# try { Execute-CommandOnVM -VMName $VmName -VmCredential $VmCredential -Command "Get-WindowsUpdate -Install -AcceptAll -AutoReboot" } catch { Log-Message -Message "Failed to install updates: $_" -ForegroundColor Red } + +# Sleep -Seconds 300 # Sleep for 5 minutes to let the VM start fetching updates, etc... +# Wait-ForVMReady -VMName $VMName -VmCredential $VmCredential +# Log-Message -Message "Successfully updated VM: $VMName" -ForegroundColor Green +# } + +function Create-VM { + param( + [Parameter(Mandatory=$True)][string]$VmName, + [Parameter(Mandatory=$True)][string]$VmUsername, + [Parameter(Mandatory=$True)][string]$VmPassword, + [Parameter(Mandatory=$True)][string]$VhdPath, + [Parameter(Mandatory=$True)][string]$VmStoragePath, + [Parameter(Mandatory=$True)][Int64]$VMMemory, + [Parameter(Mandatory=$True)][string]$UnattendPath + ) + + try { + ## Check for any pre-requisites + # Check that the VHD exists + if (-not (Test-Path -Path $VhdPath)) { + throw "VHD not found at $VhdPath" + } + + ## Create the VM + # Create storage directory for the VM + Create-DirectoryIfNotExists -Path $VmStoragePath + + # Move the VHD to the path + Log-Message "Moving $VhdPath to $VmStoragePath" + Move-Item -Path $VhdPath -Destination $VmStoragePath -Force + $VmVhdPath = Join-Path -Path $VmStoragePath -ChildPath (Split-Path -Path $VhdPath -Leaf) + + # Move unattend to the path + Log-Message "Moving $UnattendPath file to $VmStoragePath" + Move-Item -Path $UnattendPath -Destination $VmStoragePath -Force + $VmUnattendPath = Join-Path -Path $VmStoragePath -ChildPath (Split-Path -Path $UnattendPath -Leaf) + Replace-PlaceholderStrings -FilePath $VmUnattendPath -SearchString 'PLACEHOLDER_USERNAME' -ReplaceString $VmUsername + Replace-PlaceholderStrings -FilePath $VmUnattendPath -SearchString 'PLACEHOLDER_PASSWORD' -ReplaceString $VmPassword + + # Configure the VHD with the unattend file. + Log-Message "Mounting VHD and applying unattend file" + $VmMountPath = Join-Path -Path $VmStoragePath -ChildPath 'mountedVhd' + if (-not (Test-Path -Path $VmMountPath)) { + New-Item -ItemType Directory -Path $VmMountPath + } + Mount-WindowsImage -ImagePath $VmVhdPath -Index 1 -Path $VmMountPath -ErrorAction Stop | Out-Null + Copy-Item -Path $VmUnattendPath -Destination $VmMountPath\Unattend.xml + Apply-WindowsUnattend -Path $VmMountPath -UnattendPath $VmMountPath\Unattend.xml -ErrorAction Stop | Out-Null + Dismount-WindowsImage -Path $VmMountPath -Save -ErrorAction Stop + + # Create the VM + Log-Message "Creating the VM" + New-VM -Name $VmName -VhdPath $VmVhdPath + $vmSwitches = Get-VMSwitch -ErrorAction Ignore + foreach ($switch in $vmSwitches) { + Log-Message "Adding network adapter to VM: $VmName with switch: $($switch.Name)" + Add-VMNetworkAdapter -VMName $VmName -SwitchName $switch.Name + } + Set-VMMemory -VMName $VmName -DynamicMemoryEnabled $false -StartupBytes $VMMemory + + if ((Get-VM -VMName $vmName) -eq $null) { + throw "Failed to create VM: $VMName" + } + + Log-Message -Message "Successfully created VM: $VMName" -ForegroundColor Green + } catch { + throw "Failed to create VM: $VmName with error: $_" + } +} + +function Configure-VM { + param( + [Parameter(Mandatory=$True)][string]$VmName, + [Parameter(Mandatory=$True)][string]$VmUsername, + [Parameter(Mandatory=$True)][string]$VmPassword, + [Parameter(Mandatory=$True)][int]$VMCpuCount, + [Parameter(Mandatory=$False)][string]$VMWorkingDirectory='C:\ebpf_cicd', + [Parameter(Mandatory=$False)][string]$VMSetupScript='.\configure_vm.ps1' + ) + + try { + Log-Message "Configuring VM: $VmName" + + # Post VM creation configuration steps. + Log-Message "Setting VM processor count to $VMCpuCount" + Set-VMProcessor -VMName $VmName -Count $VMCpuCount + Log-Message "Enabling Guest Service Interface" + Enable-VMIntegrationService -VMName $VMName -Name 'Guest Service Interface' + + # Get the VM credential + $VmCredential = Create-VMCredential -VmUsername $VmUsername -VmPassword $VmPassword + + # Start the VM + Log-Message "Starting VM: $VmName" + Start-VM -Name $VmName + Wait-ForVMReady -VMName $VmName -VmCredential $VmCredential + + Log-Message "Sleeping for 1 minute to let the VM get into a steady state" + Sleep -Seconds 60 # Sleep for 1 minute to let the VM get into a steady state. + + # # Fetch all updates on the VM + # Log-Message "Fetching Updates on the VM" + # # Update-VM -VMName $VmName -VmCredential $VmCredential + # Log-Message -Message "Successfully updated VM: $VMName" -ForegroundColor Green + + # Copy setup script to the VM and execute it. + Log-Message "Executing VM configuration script ($VMSetupScript) on VM: $VmName" + Copy-VMFile -VMName $VmName -FileSource Host -SourcePath $VMSetupScript -DestinationPath "$VMWorkingDirectory\$VMSetupScript" -CreateFullPath + Execute-CommandOnVM -VMName $VmName -VmCredential $VmCredential -Command "cd $VMWorkingDirectory; .\$VMSetupScript" + Log-Message "Sleeping for 1 minute to let the VM get into a steady state" + Sleep -Seconds 60 # Sleep for 1 minute to let the VM get into a steady state. + Log-Message -Message "Successfully executed VM configuration script ($VMSetupScript) on VM: $VmName" -ForegroundColor Green + + Wait-ForVMReady -VMName $VmName -VmCredential $VmCredential + + # Checkpoint the VM. This can sometimes fail if other operations are in progress. + for ($i = 0; $i -lt 5; $i += 1) { + try { + Log-Message "Checkpointing VM: $VmName" + Checkpoint-VM -Name $VMName -SnapshotName 'baseline' + Log-Message -Message "Successfully added 'baseline' checkpoint for VM: $VMName" -ForegroundColor Green + break + } catch { + Log-Message "Failed to checkpoint VM: $VmName. Retrying..." + Start-Sleep -Seconds 5 + continue + } + } + + Log-Message "Successfully configured VM: $VmName" -ForegroundColor Green + } catch { + throw "Failed to configure VM: $VmName with error: $_" + } +} + +########## Helpers for the host machine ########## +function Install-HyperVIfNeeded { + try { + if ((Get-WindowsFeature -Name 'Hyper-V').Installed) { + Log-Message -Message 'Hyper-V is already installed on this host' + } else { + Log-Message -Message 'Hyper-V is not installed on this host. Installing now...' + + Import-Module ServerManager + Install-WindowsFeature -Name 'Hyper-V' -IncludeManagementTools + Restart-Computer -Force + exit 1 + } + } catch { + throw "Failed to install Hyper-V with error: $_" + } +} + +function Create-VMSwitchIfNeeded { + param ( + [Parameter(Mandatory=$true)][string]$SwitchName, + [Parameter(Mandatory=$true)][string]$SwitchType + ) + if ($SwitchType -eq 'External') { + # Check to see if an external switch already exists + $ExternalSwitches = (Get-VMSwitch -SwitchType External -ErrorAction Ignore) + if ($ExternalSwitches -ne $null) { + Log-Message -Message "External switch already exists: $($ExternalSwitches[0].Name)" + return + } + + # Try to create the external switch + $NetAdapterNames = (Get-NetAdapter -Name 'Ethernet*' | Where-Object { $_.Status -eq 'Up' }).Name + $index = 0 + foreach ($NetAdapterName in $NetAdapterNames) { + try { + if ([string]::IsNullOrEmpty($NetAdapterName)) { + continue + } + $currSwitchName = $SwitchName + '-' + $index + Log-Message "Attempting to creating external switch: $currSwitchName with NetAdapter: $NetAdapterName" + New-VMSwitch -Name $currSwitchName -NetAdapterName $NetAdapterName -AllowManagementOS $true + $index += 1 + # break + } catch { + Log-Message "Failed to create external switch for NetAdapter: $NetAdapterName with error: $_" + } + } + } elseif ($SwitchType -eq 'Internal') { + # Check to see if an internal switch already exists + $InternalSwitches = (Get-VMSwitch -SwitchType Internal -ErrorAction Ignore) + if ($InternalSwitches -ne $null) { + Log-Message -Message "Internal switch already exists: $($InternalSwitches[0].Name)" + return + } + + # Try to create the internal switch + try { + Log-Message "Creating internal switch" + New-VMSwitch -Name 'VMInternalSwitch' -SwitchType Internal + } catch { + throw "Failed to create internal switch with error: $_" + } + } else { + throw "Invalid switch type: $SwitchType" + } + + Log-Message "Successfully created $SwitchType switch with name: $SwitchName" -ForegroundColor Green +} + +function Create-VMStoredCredential { + param ( + [Parameter(Mandatory=$True)][string]$CredentialName, + [Parameter(Mandatory=$True)][string]$Username, + [Parameter(Mandatory=$True)][string]$Password + ) + try { + Install-Module -Name CredentialManager -Scope AllUsers -Force + Import-Module CredentialManager -Force + + New-StoredCredential -Target $CredentialName -UserName $Username -Password $Password -Type Generic -Persist LocalMachine + } catch { + Log-Message "Failed to create stored credential with error $_" -ForegroundColor Red + } +} \ No newline at end of file diff --git a/1es/unattend.xml b/1es/unattend.xml new file mode 100644 index 0000000000..27515d26ff --- /dev/null +++ b/1es/unattend.xml @@ -0,0 +1,52 @@ + + + + + + + + true + true + true + true + true + true + true + + + + PLACEHOLDER_PASSWORD + true</PlainText> + </AdministratorPassword> + <LocalAccounts> + <LocalAccount> + <Password> + <Value>PLACEHOLDER_PASSWORD</Value> + <PlainText>true</PlainText> + </Password> + <Description>Standard User Account</Description> + <DisplayName>VMStandardUser</DisplayName> + <Name>VMStandardUser</Name> + </LocalAccount> + </LocalAccounts> + </UserAccounts> + <AutoLogon> + <Password> + <Value>PLACEHOLDER_PASSWORD</Value> + <PlainText>true</PlainText> + </Password> + <Enabled>true</Enabled> + <LogonCount>9999</LogonCount> + <Username>PLACEHOLDER_USERNAME</Username> + </AutoLogon> + </component> + </settings> + <!-- <settings pass="specialize"> + <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <ComputerName>%ComputerNamePlaceholder%</ComputerName> + <DoNotCleanTaskBar>true</DoNotCleanTaskBar> + </component> + </settings> --> +</unattend> diff --git a/libs/execution_context/ebpf_core.c b/libs/execution_context/ebpf_core.c index d08b51c281..f44a400366 100644 --- a/libs/execution_context/ebpf_core.c +++ b/libs/execution_context/ebpf_core.c @@ -1203,8 +1203,9 @@ _ebpf_core_protocol_program_test_run_complete( { ebpf_operation_program_test_run_reply_t* reply = (ebpf_operation_program_test_run_reply_t*)completion_context; if (result == EBPF_SUCCESS) { - reply->header.length = (uint16_t)(EBPF_OFFSET_OF(ebpf_operation_program_test_run_reply_t, data) + - options->data_size_out + options->context_size_out); + reply->header.length = (uint16_t)( + EBPF_OFFSET_OF(ebpf_operation_program_test_run_reply_t, data) + options->data_size_out + + options->context_size_out); reply->return_value = options->return_value; reply->context_offset = (uint16_t)options->data_size_out; reply->duration = options->duration; @@ -1800,8 +1801,8 @@ _ebpf_core_protocol_serialize_map_info_reply( &required_serialization_length); if (result != EBPF_SUCCESS) { - map_info_reply->header.length = (uint16_t)(required_serialization_length + - EBPF_OFFSET_OF(ebpf_operation_get_pinned_map_info_reply_t, data)); + map_info_reply->header.length = (uint16_t)( + required_serialization_length + EBPF_OFFSET_OF(ebpf_operation_get_pinned_map_info_reply_t, data)); } else { map_info_reply->map_count = map_count; } diff --git a/libs/execution_context/ebpf_maps.c b/libs/execution_context/ebpf_maps.c index 68cddb9a0d..66a15a8027 100644 --- a/libs/execution_context/ebpf_maps.c +++ b/libs/execution_context/ebpf_maps.c @@ -144,7 +144,7 @@ typedef uint8_t* ebpf_lru_entry_t; ((uint8_t*)(((uint8_t*)entry) + EBPF_LRU_ENTRY_KEY_OFFSET(map->partition_count))) #define EBPF_LOG_MAP_OPERATION(flags, operation, map, key) \ - if (((flags) & EBPF_MAP_FLAG_HELPER) && (map)->ebpf_map_definition.key_size != 0) { \ + if (((flags)&EBPF_MAP_FLAG_HELPER) && (map)->ebpf_map_definition.key_size != 0) { \ EBPF_LOG_MESSAGE_UTF8_STRING( \ EBPF_TRACELOG_LEVEL_VERBOSE, EBPF_TRACELOG_KEYWORD_MAP, "Map "##operation, &(map)->name); \ EBPF_LOG_MESSAGE_BINARY( \ diff --git a/libs/execution_context/ebpf_program.c b/libs/execution_context/ebpf_program.c index 24aed2a872..7f867e166c 100644 --- a/libs/execution_context/ebpf_program.c +++ b/libs/execution_context/ebpf_program.c @@ -171,8 +171,7 @@ ebpf_program_initiate() void ebpf_program_terminate() -{ -} +{} _Requires_lock_not_held_(program->lock) static void _ebpf_program_detach_links(_Inout_ ebpf_program_t* program) { diff --git a/libs/runtime/ebpf_epoch.c b/libs/runtime/ebpf_epoch.c index ef0e69c369..0face817b2 100644 --- a/libs/runtime/ebpf_epoch.c +++ b/libs/runtime/ebpf_epoch.c @@ -453,14 +453,13 @@ __drv_allocatesMem(Mem) _Must_inspect_result_ return header; } -_Must_inspect_result_ -_Ret_writes_maybenull_(size) void* ebpf_epoch_allocate(size_t size) +_Must_inspect_result_ _Ret_writes_maybenull_(size) void* ebpf_epoch_allocate(size_t size) { return ebpf_epoch_allocate_with_tag(size, EBPF_POOL_TAG_EPOCH); } _Must_inspect_result_ -_Ret_writes_maybenull_(size) void* ebpf_epoch_allocate_cache_aligned_with_tag(size_t size, uint32_t tag) + _Ret_writes_maybenull_(size) void* ebpf_epoch_allocate_cache_aligned_with_tag(size_t size, uint32_t tag) { ebpf_assert(size); ebpf_epoch_allocation_header_t* header; diff --git a/libs/runtime/ebpf_platform.c b/libs/runtime/ebpf_platform.c index 78c43d89d7..2c10cc92cc 100644 --- a/libs/runtime/ebpf_platform.c +++ b/libs/runtime/ebpf_platform.c @@ -39,9 +39,7 @@ ebpf_lock_destroy(_In_ _Post_invalid_ ebpf_lock_t* lock) } _Requires_lock_not_held_(*lock) _Acquires_lock_(*lock) _IRQL_requires_max_(DISPATCH_LEVEL) _IRQL_saves_ - _IRQL_raises_(DISPATCH_LEVEL) -ebpf_lock_state_t -ebpf_lock_lock(_Inout_ ebpf_lock_t* lock) + _IRQL_raises_(DISPATCH_LEVEL) ebpf_lock_state_t ebpf_lock_lock(_Inout_ ebpf_lock_t* lock) { KIRQL old_irql = KeGetCurrentIrql(); diff --git a/libs/service/api_service.cpp b/libs/service/api_service.cpp index 5dbc056e0f..c13a47a84d 100644 --- a/libs/service/api_service.cpp +++ b/libs/service/api_service.cpp @@ -364,7 +364,7 @@ ebpf_verify_and_load_program( } ubpf_set_error_print( - vm, reinterpret_cast<int (*)(FILE* stream, const char* format, ...)>(log_function_address)); + vm, reinterpret_cast<int (*)(FILE * stream, const char* format, ...)>(log_function_address)); if (ubpf_load( vm, byte_code_data, static_cast<uint32_t>(byte_code_size), const_cast<char**>(error_message)) < 0) { diff --git a/scripts/cleanup_ebpf_cicd_tests.ps1 b/scripts/cleanup_ebpf_cicd_tests.ps1 index e718e14715..bc6e0698cb 100644 --- a/scripts/cleanup_ebpf_cicd_tests.ps1 +++ b/scripts/cleanup_ebpf_cicd_tests.ps1 @@ -12,8 +12,15 @@ param ([parameter(Mandatory=$false)][string] $Target = "TEST_VM", Push-Location $WorkingDirectory Import-Module .\common.psm1 -Force -ArgumentList ($LogFileName) -WarningAction SilentlyContinue - -$TestVMCredential = Get-StoredCredential -Target $Target -ErrorAction Stop +$SelfHostedRunnerName = "runner_host" +Write-Host "SelfHostedRunnerName: $SelfHostedRunnerName, Target: $Target" +try { + $TestVMCredential = Get-StoredCredential -Target $Target -ErrorAction Stop +} catch { + Write-Host "Failed to get credentials for $Target. Using default credentials." + $securePassword = ConvertTo-SecureString -String "P@ssw0rd" -AsPlainText -Force + $TestVMCredential = New-Credential -UserName 'Administrator' -AdminPassword $securePassword +} # Read the test execution json. $Config = Get-Content ("{0}\{1}" -f $PSScriptRoot, $TestExecutionJsonFileName) | ConvertFrom-Json @@ -48,6 +55,12 @@ $Job = Start-Job -ScriptBlock { -VMName $VMName ` -Credential $TestVMCredential ` -ScriptBlock { + # TODO - remove this debugging output + ipconfig /all + Get-NetIPInterface | Out-String + Get-NetAdapter | Out-String + Get-NetAdapterBinding -AllBindings | Out-String + Test-Path -Path "c:\windows\memory.dmp" -PathType leaf } @@ -88,5 +101,4 @@ Pop-Location if ($JobTimedOut) { exit 1 -} - +} \ No newline at end of file diff --git a/scripts/common.psm1 b/scripts/common.psm1 index a4d4f6d536..2842653d74 100644 --- a/scripts/common.psm1 +++ b/scripts/common.psm1 @@ -3,6 +3,12 @@ param ([parameter(Mandatory=$True)] [string] $LogFileName) +try { + Import-Module CredentialManager -Force -ErrorAction Ignore +} catch { + Write-Host "Failed to import CredentialManager module. Using default credentials." +} + # # Common helper functions. # @@ -55,23 +61,42 @@ function Compress-File # Retry 3 times to ensure compression operation succeeds. # To mitigate error message: "The process cannot access the file <filename> because it is being used by another process." $retryCount = 1 - while ($retryCount -lt 4) { - $error.clear() - Compress-Archive ` - -Path $SourcePath ` - -DestinationPath $DestinationPath ` - -CompressionLevel Fastest ` - -Force - if ($error[0] -ne $null) { - $ErrorMessage = "*** ERROR *** Failed to compress kernel mode dump files: $error. Retrying $retryCount" + while ($retryCount -lt 6) { + try { + $error.clear() + Compress-Archive ` + -Path $SourcePath ` + -DestinationPath $DestinationPath ` + -CompressionLevel Fastest ` + -Force + if ($error[0] -ne $null) { + $ErrorMessage = "*** ERROR *** Failed to compress kernel mode dump files: $error. Retrying $retryCount" + Write-Output $ErrorMessage + Start-Sleep -seconds (5 * $retryCount) + $retryCount++ + } else { + # Compression succeeded. + if (Test-Path $DestinationPath) { + Write-Log "Successfully compressed $SourcePath -> $DestinationPath" + break; + } else { + $ErrorMessage = "*** ERROR *** Failed to compress kernel mode dump files: $error. Retrying $retryCount" + Write-Output $ErrorMessage + Start-Sleep -seconds (5 * $retryCount) + $retryCount++ + } + } + } catch { + $ErrorMessage = "*** ERROR *** Failed to compress kernel mode dump files: $_. Retrying $retryCount" Write-Output $ErrorMessage Start-Sleep -seconds (5 * $retryCount) $retryCount++ - } else { - # Compression succeeded. - break; } } + + if (!(Test-Path $DestinationPath)) { + Write-Log "Failed to compress kernel mode dump files after retries" + } } function Wait-TestJobToComplete @@ -94,7 +119,7 @@ function Wait-TestJobToComplete if ($Job.State -eq "Running") { $VMList = $Config.VMMap.$SelfHostedRunnerName # currently one VM runs per runner. - $TestVMName = $VMList[0].Name + $TestVMName = $VMList[0].Name Write-Host "Running kernel tests on $TestVMName has timed out after one hour" -ForegroundColor Yellow $Timestamp = Get-Date -Format 'yyyy-MM-dd_HH-mm-ss' $CheckpointName = "$CheckpointPrefix-$TestVMName-Checkpoint-$Timestamp" @@ -111,4 +136,18 @@ function Wait-TestJobToComplete $JobOutput | ForEach-Object { Write-Host $_ } return $JobTimedOut -} \ No newline at end of file +} + +function Create-VMCredential { + param ( + [Parameter(Mandatory=$True)][string]$VmUsername, + [Parameter(Mandatory=$True)][string]$VmPassword + ) + + try { + $secureVmPassword = ConvertTo-SecureString $VmPassword -AsPlainText -Force + return New-Object System.Management.Automation.PSCredential($VmUsername, $secureVmPassword) + } catch { + throw "Failed to create VM credential: $_" + } +} diff --git a/scripts/config_test_vm.psm1 b/scripts/config_test_vm.psm1 index 25b8efa8bc..f265e3417d 100644 --- a/scripts/config_test_vm.psm1 +++ b/scripts/config_test_vm.psm1 @@ -315,7 +315,7 @@ function Compress-KernelModeDumpOnVM $KernelModeDumpFileSourcePath = "$Env:WinDir" $KernelModeDumpFileDestinationPath = "$Env:SystemDrive\KernelDumps" - + # Create the compressed dump folder if doesn't exist. if (!(Test-Path $KernelModeDumpFileDestinationPath)) { Write-Log "Creating $KernelModeDumpFileDestinationPath directory." @@ -540,6 +540,29 @@ function Initialize-NetworkInterfacesOnVMs # Disable Duonic's fake checksum offload and force TCP/IP to calculate it. Set-NetAdapterAdvancedProperty duo? -DisplayName Checksum -RegistryValue 0 + # TODO - remove this debugging output + ipconfig /all + Get-NetIPInterface | Out-String + Get-NetAdapter | Out-String + Get-NetAdapterBinding -AllBindings | Out-String + + # Loop through each adapter and enable IPv4 and IPv6 + $adapters = Get-NetAdapter + foreach ($adapter in $adapters) { + try { + # Enable IPv4 (usually enabled by default) + Enable-NetAdapterBinding -Name $adapter.Name -ComponentID ms_tcpip + + # Enable IPv6 + Enable-NetAdapterBinding -Name $adapter.Name -ComponentID ms_tcpip6 + + Write-Host "Enabled IPv4 and IPv6 on adapter: $($adapter.Name)" + } catch { + Write-Host "Failed to enable IPv4 and IPv6 on adapter: $($adapter.Name)" + } + } + Get-NetAdapterBinding -AllBindings | Out-String + Pop-Location } -ArgumentList ("eBPF", $LogFileName) -ErrorAction Stop } diff --git a/scripts/execute_ebpf_cicd_tests.ps1 b/scripts/execute_ebpf_cicd_tests.ps1 index 84a056da07..be1bafefdb 100644 --- a/scripts/execute_ebpf_cicd_tests.ps1 +++ b/scripts/execute_ebpf_cicd_tests.ps1 @@ -18,16 +18,25 @@ Push-Location $WorkingDirectory Import-Module $WorkingDirectory\common.psm1 -Force -ArgumentList ($LogFileName) -ErrorAction Stop -$AdminTestVMCredential = Get-StoredCredential -Target $AdminTarget -ErrorAction Stop -$StandardUserTestVMCredential = Get-StoredCredential -Target $StandardUserTarget -ErrorAction Stop +$SelfHostedRunnerName = "runner_host" +Write-Host "SelfHostedRunnerName: $SelfHostedRunnerName, AdminTarget: $AdminTarget, StandardUserTarget: $StandardUserTarget" +try { + $AdminTestVMCredential = Get-StoredCredential -Target $AdminTarget -ErrorAction Stop + $StandardUserTestVMCredential = Get-StoredCredential -Target $StandardUserTarget -ErrorAction Stop +} catch { + Write-Host "Failed to get credentials for $AdminTarget or $StandardUserTarget. Using default credentials." + $securePassword = ConvertTo-SecureString -String "P@ssw0rd" -AsPlainText -Force + $AdminTestVMCredential = New-Credential -UserName 'Administrator' -AdminPassword $securePassword + $StandardUserTestVMCredential = New-Credential -UserName 'VMStandardUser' -AdminPassword $securePassword +} # Read the test execution json. $Config = Get-Content ("{0}\{1}" -f $PSScriptRoot, $TestExecutionJsonFileName) | ConvertFrom-Json $Job = Start-Job -ScriptBlock { param ([Parameter(Mandatory = $True)] [PSCredential] $AdminTestVMCredential, - [Parameter(Mandatory = $True)] [PSCredential] $StandardUserTestVMCredential, - [Parameter(Mandatory = $true)] [PSCustomObject] $Config, + [Parameter(Mandatory = $True)] [PSCredential] $StandardUserTestVMCredential, + [Parameter(Mandatory = $true)] [PSCustomObject] $Config, [Parameter(Mandatory = $true)] [string] $SelfHostedRunnerName, [Parameter(Mandatory = $True)] [string] $WorkingDirectory, [Parameter(Mandatory = $True)] [string] $LogFileName, diff --git a/scripts/run_driver_tests.psm1 b/scripts/run_driver_tests.psm1 index 01720f4ba5..ab691bbb35 100644 --- a/scripts/run_driver_tests.psm1 +++ b/scripts/run_driver_tests.psm1 @@ -157,6 +157,13 @@ function Process-TestCompletion [Parameter(Mandatory = $false)] [int] $TestHangTimeout = (10*60), # 10 minutes default timeout. [Parameter(Mandatory = $false)] [bool] $NeedKernelDump = $true) + if ($TestProcess -eq $null) { + Write-Log "Process-TestCompletion: Failed to start $TestCommand" + throw "Failed to start $TestCommand" + } + + Write-Log "Process-TestCompletion invoked for $TestProcess and $TestCommand" + # Use Wait-Process for the process to terminate or timeout. # See https://stackoverflow.com/a/23797762 Wait-Process -InputObject $TestProcess -Timeout $TestHangTimeout -ErrorAction SilentlyContinue @@ -187,8 +194,22 @@ function Process-TestCompletion Write-Log "Throwing TestHungException for $TestCommand" -ForegroundColor Red throw [System.TimeoutException]::new("Test $TestCommand execution hang timeout ($TestHangTimeout seconds) expired.") } else { - # Ensure the process has completely exited. - Wait-Process -InputObject $TestProcess + Write-Log "Process-TestCompletion: command should have completed" + try { + $currExitCode = $TestProcess.ExitCode + $temp = $TestProcess | Out-String + Write-Log "Maige - test output: $temp" + Write-Log "MAIGE - $TestCommand exited with code $currExitCode" + } catch { + Write-Log "maige - failed" + } + + # # Ensure the process has completely exited. + # Wait-Process -InputObject $TestProcess + # $currExitCode = $TestProcess.ExitCode + # $temp = $TestProcess | Out-String + # Write-Log "Maige - test output: $temp" + # Write-Log "MAIGE - $TestCommand exited with code $currExitCode" # Read and display the output (if any) from the temporary output file. $TempOutputFile = "$env:TEMP\app_output.log" # Log for standard output @@ -202,7 +223,9 @@ function Process-TestCompletion } $TestExitCode = $TestProcess.ExitCode - if ($TestExitCode -ne 0) { + Write-Log "Maige - Test exit code: $TestExitCode" + if ($TestExitCode -ne $null -and $TestExitCode -ne 0) { + # if ($TestExitCode -ne 0) { $TempErrorFile = "$env:TEMP\app_error.log" # Log for standard error if ((Test-Path $TempErrorFile) -and (Get-Item $TempErrorFile).Length -gt 0) { Write-Log "$TestCommand Error Output:`n" -ForegroundColor Red @@ -260,33 +283,38 @@ function Invoke-Test [Parameter(Mandatory = $True)][bool] $VerboseLogs, [Parameter(Mandatory = $True)][int] $TestHangTimeout) - # Initialize arguments. - if ($TestArgs -ne "") { - $ArgumentsList = @($TestArgs) - } + try { + # Initialize arguments. + if ($TestArgs -ne "") { + $ArgumentsList = @($TestArgs) + } - if ($VerboseLogs -eq $true) { - $ArgumentsList += '-s' - } + if ($VerboseLogs -eq $true) { + $ArgumentsList += '-s' + } - # Execute Test. - Write-Log "Executing $TestName $TestArgs" - $TestFilePath = "$pwd\$TestName" - $TempOutputFile = "$env:TEMP\app_output.log" # Log for standard output - $TempErrorFile = "$env:TEMP\app_error.log" # Log for standard error - if ($ArgumentsList) { - $TestProcess = Start-Process -FilePath $TestFilePath -ArgumentList $ArgumentsList -PassThru -NoNewWindow -RedirectStandardOutput $TempOutputFile -RedirectStandardError $TempErrorFile -ErrorAction Stop - } else { - $TestProcess = Start-Process -FilePath $TestFilePath -PassThru -NoNewWindow -RedirectStandardOutput $TempOutputFile -RedirectStandardError $TempErrorFile -ErrorAction Stop - } - if ($InnerTestName -ne "") { - Process-TestCompletion -TestProcess $TestProcess -TestCommand $InnerTestName -NestedProcess $True -TestHangTimeout $TestHangTimeout - } else { - Process-TestCompletion -TestProcess $TestProcess -TestCommand $TestName -TestHangTimeout $TestHangTimeout - } + # Execute Test. + Write-Log "Executing $TestName $TestArgs" + $TestFilePath = "$pwd\$TestName" + $TempOutputFile = "$env:TEMP\app_output.log" # Log for standard output + $TempErrorFile = "$env:TEMP\app_error.log" # Log for standard error + if ($ArgumentsList) { + $TestProcess = Start-Process -FilePath $TestFilePath -ArgumentList $ArgumentsList -PassThru -NoNewWindow -RedirectStandardOutput $TempOutputFile -RedirectStandardError $TempErrorFile -ErrorAction Stop + } else { + $TestProcess = Start-Process -FilePath $TestFilePath -PassThru -NoNewWindow -RedirectStandardOutput $TempOutputFile -RedirectStandardError $TempErrorFile -ErrorAction Stop + } + if ($InnerTestName -ne "") { + Process-TestCompletion -TestProcess $TestProcess -TestCommand $InnerTestName -NestedProcess $True -TestHangTimeout $TestHangTimeout + } else { + Process-TestCompletion -TestProcess $TestProcess -TestCommand $TestName -TestHangTimeout $TestHangTimeout + } - Write-Log "Test `"$TestName $TestArgs`" Passed" -ForegroundColor Green - Write-Log "`n==============================`n" + Write-Log "Test `"$TestName $TestArgs`" Passed" -ForegroundColor Green + Write-Log "`n==============================`n" + } catch { + $ErrorMessage = $_.Exception.Message + ThrowWithErrorMessage -ErrorMessage "Test `"$TestName $TestArgs`" Failed with $ErrorMessage" + } } # Function to create a tuple with default values for Arguments and Timeout @@ -358,22 +386,35 @@ function Invoke-XDPTest Push-Location $WorkingDirectory - Write-Log "Executing $XDPTestName with remote address: $RemoteIPV4Address" - $TestRunScript = ".\Run-Self-Hosted-Runner-Test.ps1" - $TestCommand = ".\xdp_tests.exe" - $TestArguments = "$XDPTestName --remote-ip $RemoteIPV4Address" - $TestProcess = Start-Process -FilePath $TestCommand -ArgumentList $TestArguments -PassThru -NoNewWindow - Process-TestCompletion -TestProcess $TestProcess -TestCommand $TestCommand - - Write-Log "Executing $XDPTestName with remote address: $RemoteIPV6Address" - $TestRunScript = ".\Run-Self-Hosted-Runner-Test.ps1" - $TestCommand = ".\xdp_tests.exe" - $TestArguments = "$XDPTestName --remote-ip $RemoteIPV6Address" - $TestProcess = Start-Process -FilePath $TestCommand -ArgumentList $TestArguments -PassThru -NoNewWindow - Process-TestCompletion -TestProcess $TestProcess -TestCommand $TestCommand + try { + Write-Log "Executing $XDPTestName with remote address: $RemoteIPV4Address" + $TestRunScript = ".\Run-Self-Hosted-Runner-Test.ps1" + $TestCommand = ".\xdp_tests.exe" + $TestArguments = "$XDPTestName --remote-ip $RemoteIPV4Address" + $TestProcess = Start-Process -FilePath $TestCommand -ArgumentList $TestArguments -PassThru -NoNewWindow + if ($TestProcess -eq $null) { + Write-Log "Failed to start $TestCommand with arguments $TestArguments" + throw "Failed to start $TestCommand with arguments $TestArguments" + } + Process-TestCompletion -TestProcess $TestProcess -TestCommand $TestCommand + + Write-Log "Executing $XDPTestName with remote address: $RemoteIPV6Address" + $TestRunScript = ".\Run-Self-Hosted-Runner-Test.ps1" + $TestCommand = ".\xdp_tests.exe" + $TestArguments = "$XDPTestName --remote-ip $RemoteIPV6Address" + $TestProcess = Start-Process -FilePath $TestCommand -ArgumentList $TestArguments -PassThru -NoNewWindow + if ($TestProcess -eq $null) { + Write-Log "Failed to start $TestCommand with arguments $TestArguments" + throw "Failed to start $TestCommand with arguments $TestArguments" + } + Process-TestCompletion -TestProcess $TestProcess -TestCommand $TestCommand - Write-Log "$XDPTestName Test Passed" -ForegroundColor Green - Write-Log "`n`n" + Write-Log "$XDPTestName Test Passed" -ForegroundColor Green + Write-Log "`n`n" + } catch { + $ErrorMessage = $_.Exception.Message + ThrowWithErrorMessage -ErrorMessage "XDP test Failed with $ErrorMessage" + } Pop-Location } @@ -395,63 +436,67 @@ function Invoke-ConnectRedirectTest Push-Location $WorkingDirectory - $TestRunScript = ".\Run-Self-Hosted-Runner-Test.ps1" - $TestCommand = ".\connect_redirect_tests.exe" - - ## First run the test with both v4 and v6 programs attached. - $TestArguments = - " --virtual-ip-v4 $VirtualIPv4Address" + - " --virtual-ip-v6 $VirtualIPv6Address" + - " --local-ip-v4 $LocalIPv4Address" + - " --local-ip-v6 $LocalIPv6Address" + - " --remote-ip-v4 $RemoteIPv4Address" + - " --remote-ip-v6 $RemoteIPv6Address" + - " --destination-port $DestinationPort" + - " --proxy-port $ProxyPort" + - " --user-name $StandardUserName" + - " --password $StandardUserPassword" + - " --user-type $UserType" - - Write-Log "Executing connect redirect tests with v4 and v6 programs. Arguments: $TestArguments" - $TestProcess = Start-Process -FilePath $TestCommand -ArgumentList $TestArguments -PassThru -NoNewWindow - Process-TestCompletion -TestProcess $TestProcess -TestCommand $TestCommand - - - ## Run test with only v4 program attached. - $TestArguments = - " --virtual-ip-v4 $VirtualIPv4Address" + - " --local-ip-v4 $LocalIPv4Address" + - " --remote-ip-v4 $RemoteIPv4Address" + - " --destination-port $DestinationPort" + - " --proxy-port $ProxyPort" + - " --user-name $StandardUserName" + - " --password $StandardUserPassword" + - " --user-type $UserType" + - " [connect_authorize_redirect_tests_v4]" - - Write-Log "Executing connect redirect tests with v4 programs. Arguments: $TestArguments" - $TestProcess = Start-Process -FilePath $TestCommand -ArgumentList $TestArguments -PassThru -NoNewWindow - Process-TestCompletion -TestProcess $TestProcess -TestCommand $TestCommand - - - ## Run tests with only v6 program attached. - $TestArguments = - " --virtual-ip-v6 $VirtualIPv6Address" + - " --local-ip-v6 $LocalIPv6Address" + - " --remote-ip-v6 $RemoteIPv6Address" + - " --destination-port $DestinationPort" + - " --proxy-port $ProxyPort" + - " --user-name $StandardUserName" + - " --password $StandardUserPassword" + - " --user-type $UserType" + - " [connect_authorize_redirect_tests_v6]" - - Write-Log "Executing connect redirect tests with v6 programs. Arguments: $TestArguments" - $TestProcess = Start-Process -FilePath $TestCommand -ArgumentList $TestArguments -PassThru -NoNewWindow - Process-TestCompletion -TestProcess $TestProcess -TestCommand $TestCommand - - - Write-Log "Connect-Redirect Test Passed" -ForegroundColor Green + try { + $TestRunScript = ".\Run-Self-Hosted-Runner-Test.ps1" + $TestCommand = ".\connect_redirect_tests.exe" + + ## First run the test with both v4 and v6 programs attached. + $TestArguments = + " --virtual-ip-v4 $VirtualIPv4Address" + + " --virtual-ip-v6 $VirtualIPv6Address" + + " --local-ip-v4 $LocalIPv4Address" + + " --local-ip-v6 $LocalIPv6Address" + + " --remote-ip-v4 $RemoteIPv4Address" + + " --remote-ip-v6 $RemoteIPv6Address" + + " --destination-port $DestinationPort" + + " --proxy-port $ProxyPort" + + " --user-name $StandardUserName" + + " --password $StandardUserPassword" + + " --user-type $UserType" + + Write-Log "Executing connect redirect tests with v4 and v6 programs. Arguments: $TestArguments" + $TestProcess = Start-Process -FilePath $TestCommand -ArgumentList $TestArguments -PassThru -NoNewWindow + Process-TestCompletion -TestProcess $TestProcess -TestCommand $TestCommand + + + ## Run test with only v4 program attached. + $TestArguments = + " --virtual-ip-v4 $VirtualIPv4Address" + + " --local-ip-v4 $LocalIPv4Address" + + " --remote-ip-v4 $RemoteIPv4Address" + + " --destination-port $DestinationPort" + + " --proxy-port $ProxyPort" + + " --user-name $StandardUserName" + + " --password $StandardUserPassword" + + " --user-type $UserType" + + " [connect_authorize_redirect_tests_v4]" + + Write-Log "Executing connect redirect tests with v4 programs. Arguments: $TestArguments" + $TestProcess = Start-Process -FilePath $TestCommand -ArgumentList $TestArguments -PassThru -NoNewWindow + Process-TestCompletion -TestProcess $TestProcess -TestCommand $TestCommand + + + ## Run tests with only v6 program attached. + $TestArguments = + " --virtual-ip-v6 $VirtualIPv6Address" + + " --local-ip-v6 $LocalIPv6Address" + + " --remote-ip-v6 $RemoteIPv6Address" + + " --destination-port $DestinationPort" + + " --proxy-port $ProxyPort" + + " --user-name $StandardUserName" + + " --password $StandardUserPassword" + + " --user-type $UserType" + + " [connect_authorize_redirect_tests_v6]" + + Write-Log "Executing connect redirect tests with v6 programs. Arguments: $TestArguments" + $TestProcess = Start-Process -FilePath $TestCommand -ArgumentList $TestArguments -PassThru -NoNewWindow + Process-TestCompletion -TestProcess $TestProcess -TestCommand $TestCommand + + Write-Log "Connect-Redirect Test Passed" -ForegroundColor Green + } catch { + $ErrorMessage = $_.Exception.Message + ThrowWithErrorMessage -ErrorMessage "Connect-Redirect Test Failed with $ErrorMessage" + } Pop-Location } @@ -471,14 +516,30 @@ function Invoke-CICDStressTests $LASTEXITCODE = 0 - $TestCommand = "ebpf_stress_tests_km" + $TestCommand = "ebpf_stress_tests_km.exe" $TestArguments = " " if ($RestartExtension -eq $false) { $TestArguments = "-tt=8 -td=5" } else { $TestArguments = "-tt=8 -td=5 -erd=1000 -er=1" } + + # TODO - remove debugging output + Write-Log "Items from .\" + Get-ChildItem '.\' + Write-Log "Items from $WorkingDirectory" + Get-ChildItem $WorkingDirectory + Write-Log "Starting $TestCommand with arguments: $TestArguments" + + # Valid that the test command exists. + if (-not (Test-Path $TestCommand)) { + ThrowWithErrorMessage -ErrorMessage "*** ERROR *** $TestCommand not found under $WorkingDirectory." + } + $TestProcess = Start-Process -FilePath $TestCommand -ArgumentList $TestArguments -PassThru -NoNewWindow + if ($TestProcess -eq $null) { + ThrowWithErrorMessage -ErrorMessage "*** ERROR *** Failed to start $TestCommand." + } Process-TestCompletion -TestProcess $TestProcess -TestCommand $TestCommand diff --git a/scripts/setup_ebpf_cicd_tests.ps1 b/scripts/setup_ebpf_cicd_tests.ps1 index f2d715fc5b..f5f2fa6d9b 100644 --- a/scripts/setup_ebpf_cicd_tests.ps1 +++ b/scripts/setup_ebpf_cicd_tests.ps1 @@ -15,10 +15,17 @@ param ([parameter(Mandatory=$false)][string] $Target = "TEST_VM", Push-Location $WorkingDirectory -$TestVMCredential = Get-StoredCredential -Target $Target -ErrorAction Stop - # Load other utility modules. Import-Module .\common.psm1 -Force -ArgumentList ($LogFileName) -WarningAction SilentlyContinue +$SelfHostedRunnerName = "runner_host" +try { + $TestVMCredential = Get-StoredCredential -Target $Target -ErrorAction Stop +} catch { + Write-Host "Failed to get credentials for $Target. Using default credentials." + $securePassword = ConvertTo-SecureString -String "P@ssw0rd" -AsPlainText -Force + $TestVMCredential = New-Credential -UserName 'Administrator' -AdminPassword $securePassword +} + Import-Module .\config_test_vm.psm1 -Force -ArgumentList ($TestVMCredential.UserName, $TestVMCredential.Password, $WorkingDirectory, $LogFileName) -WarningAction SilentlyContinue # Read the test execution json. @@ -27,10 +34,6 @@ $VMList = $Config.VMMap.$SelfHostedRunnerName # Delete old log files if any. Remove-Item "$env:TEMP\$LogFileName" -ErrorAction SilentlyContinue -foreach($VM in $VMList) { - $VMName = $VM.Name - Remove-Item $env:TEMP\$LogFileName -ErrorAction SilentlyContinue -} Remove-Item ".\TestLogs" -Recurse -Confirm:$false -ErrorAction SilentlyContinue if ($TestMode -eq "Regression") { diff --git a/scripts/test_execution.json b/scripts/test_execution.json index 779f47e643..ffa9f24949 100644 --- a/scripts/test_execution.json +++ b/scripts/test_execution.json @@ -3,106 +3,10 @@ "VMMap": { - "TK5-3WP08R0904_WS2019_1": + "runner_host" : [ { - "Name": "vm1_ws2019" - } - ], - "TK5-3WP08R0904_WS2019_2": - [ - { - "Name": "vm2_ws2019" - } - ], - "TK5-3WP08R0907_WS2019_1": - [ - { - "Name": "vm1_ws2019" - } - ], - "TK5-3WP08R0907_WS2019_2": - [ - { - "Name": "vm2_ws2019" - } - ], - "TK5-3WP07R0703_WS2019_1": - [ - { - "Name": "vm1_ws2019" - } - ], - "TK5-3WP07R0703_WS2019_2": - [ - { - "Name": "vm2_ws2019" - } - ], - "TK5-3WP07R0703_WS2019_3": - [ - { - "Name": "vm3_ws2019" - } - ], - "TK5-3WP07R0703_WS2019_4": - [ - { - "Name": "vm4_ws2019" - } - ], - "TK5-3WP07R0703_WS2022_1": - [ - { - "Name": "vm1_ws2022" - } - ], - "TK5-3WP07R0703_WS2022_2": - [ - { - "Name": "vm2_ws2022" - } - ], - "TK5-3WP07R0703_WS2022_3": - [ - { - "Name": "vm3_ws2022" - } - ], - "TK5-3WP07R0703_WS2022_4": - [ - { - "Name": "vm4_ws2022" - } - ], - "TK5-3WP07R0703_WS2022_5": - [ - { - "Name": "vm5_ws2022" - } - ], - "TK5-3WP07R0703_WS2022_6": - [ - { - "Name": "vm6_ws2022" - } - ], - "TK5-3WP07R0703_WS2022_7": - [ - { - "Name": "vm7_ws2022" - } - ], - "TK5-3WP07R0703_WS2022_8": - [ - { - "Name": "vm8_ws2022" - } - ], - "TK5-3WP07R0703_WS2022_PERF_1": - [ - { - "Name": "vm_perf_ws2022" + "Name": "runner_vm" } ] },