diff options
Diffstat (limited to 'packaging/windows')
-rw-r--r-- | packaging/windows/NetdataWhite.ico | bin | 0 -> 15134 bytes | |||
-rwxr-xr-x | packaging/windows/bash_execute.sh | 19 | ||||
-rw-r--r-- | packaging/windows/build.ps1 | 16 | ||||
-rw-r--r-- | packaging/windows/clion-msys-mingw64-environment.bat | 17 | ||||
-rw-r--r-- | packaging/windows/clion-msys-msys-environment.bat | 20 | ||||
-rwxr-xr-x | packaging/windows/compile-on-windows.sh | 60 | ||||
-rwxr-xr-x | packaging/windows/fetch-msys2-installer.py | 101 | ||||
-rw-r--r-- | packaging/windows/functions.ps1 | 31 | ||||
-rw-r--r-- | packaging/windows/install-dependencies.ps1 | 84 | ||||
-rw-r--r-- | packaging/windows/installer.nsi | 186 | ||||
-rw-r--r-- | packaging/windows/invoke-msys2.ps1 | 16 | ||||
-rwxr-xr-x | packaging/windows/msys2-dependencies.sh | 50 | ||||
-rwxr-xr-x | packaging/windows/package-windows.sh | 51 | ||||
-rw-r--r-- | packaging/windows/package.ps1 | 16 | ||||
-rw-r--r-- | packaging/windows/protoc.bat | 9 | ||||
-rw-r--r-- | packaging/windows/win-build-dir.sh | 20 | ||||
-rw-r--r-- | packaging/windows/windows-openssh-to-msys.bat | 118 |
17 files changed, 814 insertions, 0 deletions
diff --git a/packaging/windows/NetdataWhite.ico b/packaging/windows/NetdataWhite.ico Binary files differnew file mode 100644 index 000000000..857b88062 --- /dev/null +++ b/packaging/windows/NetdataWhite.ico diff --git a/packaging/windows/bash_execute.sh b/packaging/windows/bash_execute.sh new file mode 100755 index 000000000..4092db966 --- /dev/null +++ b/packaging/windows/bash_execute.sh @@ -0,0 +1,19 @@ +#!/usr/bin/bash + +convert_path() { + local ARG="$1" + ARG="${ARG//C:\\//c/}" + ARG="${ARG//c:\\//c/}" + ARG="${ARG//C:\///c/}" + ARG="${ARG//c:\///c/}" + + echo "$ARG" +} + +declare params=() +for x in "${@}" +do + params+=("$(convert_path "${x}")") +done + +"${params[@]}" diff --git a/packaging/windows/build.ps1 b/packaging/windows/build.ps1 new file mode 100644 index 000000000..f656ed568 --- /dev/null +++ b/packaging/windows/build.ps1 @@ -0,0 +1,16 @@ +# Run the build + +#Requires -Version 4.0 + +$ErrorActionPreference = "Stop" + +. "$PSScriptRoot\functions.ps1" + +$msysbash = Get-MSYS2Bash "$msysprefix" +$env:CHERE_INVOKING = 'yes' + +& $msysbash -l "$PSScriptRoot\compile-on-windows.sh" + +if ($LastExitcode -ne 0) { + exit 1 +} diff --git a/packaging/windows/clion-msys-mingw64-environment.bat b/packaging/windows/clion-msys-mingw64-environment.bat new file mode 100644 index 000000000..19035d8eb --- /dev/null +++ b/packaging/windows/clion-msys-mingw64-environment.bat @@ -0,0 +1,17 @@ +@echo off +:: In Clion Toolchains +:: 1. Add a MinGW profile +:: 2. Set Toolset to C:\msys64\mingw64 +:: 3. Add environment and set the full path to this file, like: +:: C:\msys64\home\costa\src\netdata-ktsaou.git\packaging\utils\clion-mingw64-environment.bat +:: 4. Let everything else to Bundled and auto-detected +:: +set "batch_dir=%~dp0" +set "batch_dir=%batch_dir:\=/%" +set MSYSTEM=MINGW64 +set GOROOT=C:\msys64\mingw64 +set PATH="%PATH%;C:\msys64\mingw64\bin;C:\msys64\usr\bin;C:\msys64\bin" +::set PKG_CONFIG_EXECUTABLE=C:\msys64\mingw64\bin\pkg-config.exe +::set CMAKE_C_COMPILER=C:\msys64\mingw64\bin\gcc.exe +::set CMAKE_CC_COMPILER=C:\msys64\mingw64\bin\g++.exe +set PROTOBUF_PROTOC_EXECUTABLE=C:/msys64/mingw64/bin/protoc.exe diff --git a/packaging/windows/clion-msys-msys-environment.bat b/packaging/windows/clion-msys-msys-environment.bat new file mode 100644 index 000000000..9f0c095d3 --- /dev/null +++ b/packaging/windows/clion-msys-msys-environment.bat @@ -0,0 +1,20 @@ +@echo off
+:: In Clion Toolchains
+:: 1. Add a MinGW profile
+:: 2. Set Toolset to C:\msys64\mingw64
+:: 3. Add environment and set the full path to this file, like:
+:: C:\msys64\home\costa\src\netdata-ktsaou.git\packaging\utils\clion-mingw64-environment.bat
+:: 4. Let everything else to Bundled and auto-detected
+::
+set "batch_dir=%~dp0"
+set "batch_dir=%batch_dir:\=/%"
+set MSYSTEM=MSYS
+
+:: go exists only mingw64 / ucrt64 / etc, not under msys profile
+set GOROOT=C:\msys64\mingw64
+
+set PATH="%PATH%;C:\msys64\usr\bin;C:\msys64\bin;C:\msys64\mingw64\bin"
+::set PKG_CONFIG_EXECUTABLE=C:\msys64\mingw64\bin\pkg-config.exe
+::set CMAKE_C_COMPILER=C:\msys64\mingw64\bin\gcc.exe
+::set CMAKE_CC_COMPILER=C:\msys64\mingw64\bin\g++.exe
+set PROTOBUF_PROTOC_EXECUTABLE=%batch_dir%/protoc.bat
diff --git a/packaging/windows/compile-on-windows.sh b/packaging/windows/compile-on-windows.sh new file mode 100755 index 000000000..ceb4f5502 --- /dev/null +++ b/packaging/windows/compile-on-windows.sh @@ -0,0 +1,60 @@ +#!/bin/bash + +REPO_ROOT="$(dirname "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" > /dev/null && pwd -P)")")" +CMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE:-RelWithDebInfo}" + +# shellcheck source=./win-build-dir.sh +. "${REPO_ROOT}/packaging/windows/win-build-dir.sh" + +set -exu -o pipefail + +if [ -d "${build}" ]; then + rm -rf "${build}" +fi + +generator="Unix Makefiles" +build_args="-j $(nproc)" + +if command -v ninja >/dev/null 2>&1; then + generator="Ninja" + build_args="-k 1" +fi + +COMMON_CFLAGS="-Wa,-mbig-obj -pipe -D_FILE_OFFSET_BITS=64 -D__USE_MINGW_ANSI_STDIO=1" + +if [ "${CMAKE_BUILD_TYPE}" = "Debug" ]; then + BUILD_CFLAGS="-fstack-protector-all -O0 -ggdb -Wall -Wextra -Wno-char-subscripts -DNETDATA_INTERNAL_CHECKS=1 ${COMMON_CFLAGS} ${CFLAGS:-}" +else + BUILD_CFLAGS="-O2 ${COMMON_CFLAGS} ${CFLAGS:-}" +fi + +${GITHUB_ACTIONS+echo "::group::Configuring"} +# shellcheck disable=SC2086 +CFLAGS="${BUILD_CFLAGS}" /usr/bin/cmake \ + -S "${REPO_ROOT}" \ + -B "${build}" \ + -G "${generator}" \ + -DCMAKE_INSTALL_PREFIX="/opt/netdata" \ + -DBUILD_FOR_PACKAGING=On \ + -DNETDATA_USER="${USER}" \ + -DENABLE_ACLK=On \ + -DENABLE_CLOUD=On \ + -DENABLE_H2O=Off \ + -DENABLE_ML=On \ + -DENABLE_PLUGIN_GO=On \ + -DENABLE_EXPORTER_PROMETHEUS_REMOTE_WRITE=Off \ + -DENABLE_BUNDLED_JSONC=On \ + -DENABLE_BUNDLED_PROTOBUF=Off \ + ${EXTRA_CMAKE_OPTIONS:-} +${GITHUB_ACTIONS+echo "::endgroup::"} + +${GITHUB_ACTIONS+echo "::group::Building"} +# shellcheck disable=SC2086 +cmake --build "${build}" -- ${build_args} +${GITHUB_ACTIONS+echo "::endgroup::"} + +if [ -t 1 ]; then + echo + echo "Compile with:" + echo "cmake --build \"${build}\"" +fi diff --git a/packaging/windows/fetch-msys2-installer.py b/packaging/windows/fetch-msys2-installer.py new file mode 100755 index 000000000..e30e7205c --- /dev/null +++ b/packaging/windows/fetch-msys2-installer.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python + +'''Fetch the MSYS2 installer.''' + +from __future__ import annotations + +import hashlib +import json +import shutil +import sys + +from pathlib import Path +from tempfile import TemporaryDirectory +from typing import Final +from urllib.request import Request, urlopen + +REPO: Final = 'msys2/msys2-installer' + + +def get_latest_release() -> tuple[str, str]: + '''Get the latest release for the repo.''' + REQUEST: Final = Request( + url=f'https://api.github.com/repos/{REPO}/releases', + headers={ + 'Accept': 'application/vnd.github+json', + 'X-GitHub-API-Version': '2022-11-28', + }, + method='GET', + ) + + print('>>> Fetching release list') + + with urlopen(REQUEST, timeout=15) as response: + if response.status != 200: + print(f'!!! Failed to fetch release list, status={response.status}') + sys.exit(1) + + data = json.load(response) + + data = list(filter(lambda x: x['name'] != 'Nightly Installer Build', data)) + + name = data[0]['name'] + version = data[0]['tag_name'].replace('-', '') + + return name, version + + +def fetch_release_asset(tmpdir: Path, name: str, file: str) -> Path: + '''Fetch a specific release asset.''' + REQUEST: Final = Request( + url=f'https://github.com/{REPO}/releases/download/{name}/{file}', + method='GET', + ) + TARGET: Final = tmpdir / file + + print(f'>>> Downloading {file}') + + with urlopen(REQUEST, timeout=15) as response: + if response.status != 200: + print(f'!!! Failed to fetch {file}, status={response.status}') + sys.exit(1) + + TARGET.write_bytes(response.read()) + + return TARGET + + +def main() -> None: + '''Core program logic.''' + if len(sys.argv) != 2: + print(f'{__file__} must be run with exactly one argument.') + + target = Path(sys.argv[1]) + tmp_target = target.with_name(f'.{target.name}.tmp') + + name, version = get_latest_release() + + with TemporaryDirectory() as tmpdir: + tmppath = Path(tmpdir) + + installer = fetch_release_asset(tmppath, name, f'msys2-base-x86_64-{version}.tar.zst') + checksums = fetch_release_asset(tmppath, name, f'msys2-base-x86_64-{version}.tar.zst.sha256') + + print('>>> Verifying SHA256 checksum') + expected_checksum = checksums.read_text().partition(' ')[0].casefold() + actual_checksum = hashlib.sha256(installer.read_bytes()).hexdigest().casefold() + + if expected_checksum != actual_checksum: + print('!!! Checksum mismatch') + print(f'!!! Expected: {expected_checksum}') + print(f'!!! Actual: {actual_checksum}') + sys.exit(1) + + print(f'>>> Copying to {target}') + + shutil.copy(installer, tmp_target) + tmp_target.replace(target) + + +if __name__ == '__main__': + main() diff --git a/packaging/windows/functions.ps1 b/packaging/windows/functions.ps1 new file mode 100644 index 000000000..a5f032daa --- /dev/null +++ b/packaging/windows/functions.ps1 @@ -0,0 +1,31 @@ +# Functions used by the PowerShell scripts in this directory. + +#Requires -Version 4.0 + +function Get-MSYS2Prefix { + if (-Not ($msysprefix)) { + if (Test-Path -Path C:\msys64\usr\bin\bash.exe) { + return "C:\msys64" + } elseif ($env:ChocolateyToolsLocation) { + if (Test-Path -Path "$env:ChocolateyToolsLocation\msys64\usr\bin\bash.exe") { + Write-Host "Found MSYS2 installed via Chocolatey" + Write-Host "This will work for building Netdata, but not for packaging it" + return "$env:ChocolateyToolsLocation\msys64" + } + } + } + + return "" +} + +function Get-MSYS2Bash { + $msysprefix = $args[0] + + if (-Not ($msysprefix)) { + $msysprefix = Get-MSYS2Prefix + } + + Write-Host "Using MSYS2 from $msysprefix" + + return "$msysprefix\usr\bin\bash.exe" +} diff --git a/packaging/windows/install-dependencies.ps1 b/packaging/windows/install-dependencies.ps1 new file mode 100644 index 000000000..66ec73160 --- /dev/null +++ b/packaging/windows/install-dependencies.ps1 @@ -0,0 +1,84 @@ +# Set up Windows build dependencies. +# +# This script first sees if msys is installed. If so, it just uses it. If not, it tries to bootstrap it with chocolatey or winget. + +#Requires -Version 4.0 + +$ErrorActionPreference = "Stop" + +. "$PSScriptRoot\functions.ps1" + +$msysprefix = Get-MSYS2Prefix + +function Check-FileHash { + $file_path = $args[0] + + Write-Host "Checking SHA256 hash of $file_path" + + $actual_hash = (Get-FileHash -Algorithm SHA256 -Path $file_path).Hash.toLower() + $expected_hash = (Get-Content "$file_path.sha256").split()[0] + + if ($actual_hash -ne $expected_hash) { + Write-Host "SHA256 hash mismatch!" + Write-Host "Expected: $expected_hash" + Write-Host "Actual: $actual_hash" + exit 1 + } +} + +function Install-MSYS2 { + $repo = 'msys2/msys2-installer' + $uri = "https://api.github.com/repos/$repo/releases" + $headers = @{ + 'Accept' = 'application/vnd.github+json' + 'X-GitHub-API-Version' = '2022-11-28' + } + $installer_path = "$env:TEMP\msys2-base.exe" + + if ($env:PROCESSOR_ARCHITECTURE -ne "AMD64") { + Write-Host "We can only install MSYS2 for 64-bit x86 systems, but you appear to have a different processor architecture ($env:PROCESSOR_ARCHITECTURE)." + Write-Host "You will need to install MSYS2 yourself instead." + exit 1 + } + + Write-Host "Determining latest release" + $release_list = Invoke-RestMethod -Uri $uri -Headers $headers -TimeoutSec 30 + + $release = $release_list[0] + $release_name = $release.name + $version = $release.tag_name.Replace('-', '') + $installer_url = "https://github.com/$repo/releases/download/$release_name/msys2-x86_64-$version.exe" + + Write-Host "Fetching $installer_url" + Invoke-WebRequest $installer_url -OutFile $installer_path + Write-Host "Fetching $installer_url.sha256" + Invoke-WebRequest "$installer_url.sha256" -OutFile "$installer_path.sha256" + + Write-Host "Checking file hash" + Check-FileHash $installer_path + + Write-Host "Installing" + & $installer_path in --confirm-command --accept-messages --root C:/msys64 + + return "C:\msys64" +} + +if (-Not ($msysprefix)) { + Write-Host "Could not find MSYS2, attempting to install it" + $msysprefix = Install-MSYS2 +} + +$msysbash = Get-MSYS2Bash "$msysprefix" +$env:CHERE_INVOKING = 'yes' + +& $msysbash -l "$PSScriptRoot\msys2-dependencies.sh" + +if ($LastExitcode -ne 0) { + Write-Host "First update attempt failed. This is expected if the msys-runtime package needed updated, trying again." + + & $msysbash -l "$PSScriptRoot\msys2-dependencies.sh" + + if ($LastExitcode -ne 0) { + exit 1 + } +} diff --git a/packaging/windows/installer.nsi b/packaging/windows/installer.nsi new file mode 100644 index 000000000..88d160a1d --- /dev/null +++ b/packaging/windows/installer.nsi @@ -0,0 +1,186 @@ +!include "MUI2.nsh" +!include "nsDialogs.nsh" +!include "FileFunc.nsh" + +Name "Netdata" +Outfile "netdata-installer.exe" +InstallDir "$PROGRAMFILES\Netdata" +RequestExecutionLevel admin + +!define MUI_ICON "NetdataWhite.ico" +!define MUI_UNICON "NetdataWhite.ico" + +!define ND_UININSTALL_REG "Software\Microsoft\Windows\CurrentVersion\Uninstall\Netdata" + +!define MUI_ABORTWARNING +!define MUI_UNABORTWARNING + +!insertmacro MUI_PAGE_WELCOME +!insertmacro MUI_PAGE_LICENSE "C:\msys64\cloud.txt" +!insertmacro MUI_PAGE_LICENSE "C:\msys64\gpl-3.0.txt" +!insertmacro MUI_PAGE_DIRECTORY +!insertmacro MUI_PAGE_INSTFILES +Page Custom NetdataConfigPage NetdataConfigLeave +!insertmacro MUI_PAGE_FINISH + +!insertmacro MUI_UNPAGE_CONFIRM +!insertmacro MUI_UNPAGE_INSTFILES +!insertmacro MUI_UNPAGE_FINISH + +!insertmacro MUI_LANGUAGE "English" + +var hStartMsys +var startMsys + +var hCloudToken +var cloudToken +var hCloudRoom +var cloudRoom + +Function .onInit + nsExec::ExecToLog '$SYSDIR\sc.exe stop Netdata' + pop $0 + ${If} $0 == 0 + nsExec::ExecToLog '$SYSDIR\sc.exe delete Netdata' + pop $0 + ${EndIf} + + StrCpy $startMsys ${BST_UNCHECKED} +FunctionEnd + +Function NetdataConfigPage + !insertmacro MUI_HEADER_TEXT "Netdata configuration" "Claim your agent on Netdata Cloud" + + nsDialogs::Create 1018 + Pop $0 + ${If} $0 == error + Abort + ${EndIf} + + ${NSD_CreateLabel} 0 0 100% 12u "Enter your Token and Cloud Room." + ${NSD_CreateLabel} 0 15% 100% 12u "Optionally, you can open a terminal to execute additional commands." + + ${NSD_CreateLabel} 0 35% 20% 10% "Token" + Pop $0 + ${NSD_CreateText} 21% 35% 79% 10% "" + Pop $hCloudToken + + ${NSD_CreateLabel} 0 55% 20% 10% "Room" + Pop $0 + ${NSD_CreateText} 21% 55% 79% 10% "" + Pop $hCloudRoom + + ${NSD_CreateCheckbox} 0 70% 100% 10u "Open terminal" + Pop $hStartMsys + nsDialogs::Show +FunctionEnd + +Function NetdataConfigLeave + ${NSD_GetText} $hCloudToken $cloudToken + ${NSD_GetText} $hCloudRoom $cloudRoom + ${NSD_GetState} $hStartMsys $startMsys + + StrLen $0 $cloudToken + StrLen $1 $cloudRoom + ${If} $0 == 125 + ${AndIf} $0 == 36 + # We should start our new claiming software here + MessageBox MB_OK "$cloudToken | $cloudRoom | $startMsys" + ${EndIf} + + ${If} $startMsys == 1 + nsExec::ExecToLog '$INSTDIR\msys2.exe' + pop $0 + ${EndIf} +FunctionEnd + +Function NetdataUninstallRegistry + ClearErrors + WriteRegStr HKLM "${ND_UININSTALL_REG}" \ + "DisplayName" "Netdata - Real-time system monitoring." + WriteRegStr HKLM "${ND_UININSTALL_REG}" \ + "DisplayIcon" "$INSTDIR\Uninstall.exe,0" + WriteRegStr HKLM "${ND_UININSTALL_REG}" \ + "UninstallString" "$INSTDIR\Uninstall.exe" + WriteRegStr HKLM "${ND_UININSTALL_REG}" \ + "RegOwner" "Netdata Inc." + WriteRegStr HKLM "${ND_UININSTALL_REG}" \ + "RegCompany" "Netdata Inc." + WriteRegStr HKLM "${ND_UININSTALL_REG}" \ + "Publisher" "Netdata Inc." + WriteRegStr HKLM "${ND_UININSTALL_REG}" \ + "HelpLink" "https://learn.netdata.cloud/" + WriteRegStr HKLM "${ND_UININSTALL_REG}" \ + "URLInfoAbout" "https://www.netdata.cloud/" + WriteRegStr HKLM "${ND_UININSTALL_REG}" \ + "DisplayVersion" "${CURRVERSION}" + WriteRegStr HKLM "${ND_UININSTALL_REG}" \ + "VersionMajor" "${MAJORVERSION}" + WriteRegStr HKLM "${ND_UININSTALL_REG}" \ + "VersionMinor" "${MINORVERSION}" + + IfErrors 0 +2 + MessageBox MB_ICONEXCLAMATION|MB_OK "Unable to create an entry in the Control Panel!" IDOK end + + ClearErrors + ${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2 + IntFmt $0 "0x%08X" $0 + WriteRegDWORD HKLM "${ND_UININSTALL_REG}" "EstimatedSize" "$0" + + IfErrors 0 +2 + MessageBox MB_ICONEXCLAMATION|MB_OK "Cannot estimate the installation size." IDOK end + end: +FunctionEnd + +Section "Install Netdata" + SetOutPath $INSTDIR + SetCompress off + + File /r "C:\msys64\opt\netdata\*.*" + + ClearErrors + nsExec::ExecToLog '$SYSDIR\sc.exe create Netdata binPath= "$INSTDIR\usr\bin\netdata.exe" start= delayed-auto' + pop $0 + ${If} $0 != 0 + DetailPrint "Warning: Failed to create Netdata service." + ${EndIf} + + ClearErrors + nsExec::ExecToLog '$SYSDIR\sc.exe description Netdata "Real-time system monitoring service"' + pop $0 + ${If} $0 != 0 + DetailPrint "Warning: Failed to add Netdata service description." + ${EndIf} + + ClearErrors + nsExec::ExecToLog '$SYSDIR\sc.exe start Netdata' + pop $0 + ${If} $0 != 0 + DetailPrint "Warning: Failed to start Netdata service." + ${EndIf} + + WriteUninstaller "$INSTDIR\Uninstall.exe" + + Call NetdataUninstallRegistry +SectionEnd + +Section "Uninstall" + ClearErrors + nsExec::ExecToLog '$SYSDIR\sc.exe stop Netdata' + pop $0 + ${If} $0 != 0 + DetailPrint "Warning: Failed to stop Netdata service." + ${EndIf} + + ClearErrors + nsExec::ExecToLog '$SYSDIR\sc.exe delete Netdata' + pop $0 + ${If} $0 != 0 + DetailPrint "Warning: Failed to delete Netdata service." + ${EndIf} + + RMDir /r "$INSTDIR" + + DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Netdata" +SectionEnd + diff --git a/packaging/windows/invoke-msys2.ps1 b/packaging/windows/invoke-msys2.ps1 new file mode 100644 index 000000000..bffa7f90b --- /dev/null +++ b/packaging/windows/invoke-msys2.ps1 @@ -0,0 +1,16 @@ +# Invoke the specified script using MSYS2 + +#Requires -Version 4.0 + +$ErrorActionPreference = "Stop" + +. "$PSScriptRoot\functions.ps1" + +$msysbash = Get-MSYS2Bash "$msysprefix" +$env:CHERE_INVOKING = 'yes' + +& $msysbash -l $args[0] + +if ($LastExitcode -ne 0) { + exit 1 +} diff --git a/packaging/windows/msys2-dependencies.sh b/packaging/windows/msys2-dependencies.sh new file mode 100755 index 000000000..95a1952df --- /dev/null +++ b/packaging/windows/msys2-dependencies.sh @@ -0,0 +1,50 @@ +#!/bin/bash +# +# Install the dependencies we need to build Netdata on MSYS2 + +. /etc/profile + +set -euo pipefail + +${GITHUB_ACTIONS+echo "::group::Updating MSYS2"} +pacman -Syuu --noconfirm +${GITHUB_ACTIONS+echo "::endgroup::"} + +${GITHUB_ACTIONS+echo "::group::Installing dependencies"} +pacman -S --noconfirm --needed \ + base-devel \ + cmake \ + git \ + liblz4-devel \ + libutil-linux \ + libutil-linux-devel \ + libyaml-devel \ + libzstd-devel \ + mingw64/mingw-w64-x86_64-brotli \ + mingw64/mingw-w64-x86_64-go \ + mingw64/mingw-w64-x86_64-libuv \ + mingw64/mingw-w64-x86_64-lz4 \ + mingw64/mingw-w64-x86_64-nsis \ + mingw64/mingw-w64-x86_64-openssl \ + mingw64/mingw-w64-x86_64-pcre2 \ + mingw64/mingw-w64-x86_64-protobuf \ + mingw64/mingw-w64-x86_64-zlib \ + mingw-w64-ucrt-x86_64-toolchain \ + mingw-w64-x86_64-toolchain \ + msys2-devel \ + msys/brotli-devel \ + msys/libuv-devel \ + msys/pcre2-devel \ + msys/zlib-devel \ + openssl-devel \ + protobuf-devel \ + python \ + ucrt64/mingw-w64-ucrt-x86_64-brotli \ + ucrt64/mingw-w64-ucrt-x86_64-go \ + ucrt64/mingw-w64-ucrt-x86_64-libuv \ + ucrt64/mingw-w64-ucrt-x86_64-lz4 \ + ucrt64/mingw-w64-ucrt-x86_64-openssl \ + ucrt64/mingw-w64-ucrt-x86_64-pcre2 \ + ucrt64/mingw-w64-ucrt-x86_64-protobuf \ + ucrt64/mingw-w64-ucrt-x86_64-zlib +${GITHUB_ACTIONS+echo "::endgroup::"} diff --git a/packaging/windows/package-windows.sh b/packaging/windows/package-windows.sh new file mode 100755 index 000000000..03f72a692 --- /dev/null +++ b/packaging/windows/package-windows.sh @@ -0,0 +1,51 @@ +#!/bin/bash + +repo_root="$(dirname "$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" > /dev/null && pwd -P)")")" + +if [ -n "${BUILD_DIR}" ]; then + build="${BUILD_DIR}" +elif [ -n "${OSTYPE}" ]; then + if [ -n "${MSYSTEM}" ]; then + build="${repo_root}/build-${OSTYPE}-${MSYSTEM}" + else + build="${repo_root}/build-${OSTYPE}" + fi +elif [ "$USER" = "vk" ]; then + build="${repo_root}/build" +else + build="${repo_root}/build" +fi + +set -exu -o pipefail + +${GITHUB_ACTIONS+echo "::group::Installing"} +cmake --install "${build}" +${GITHUB_ACTIONS+echo "::endgroup::"} + +if [ ! -f "/msys2-latest.tar.zst" ]; then + ${GITHUB_ACTIONS+echo "::group::Fetching MSYS2 files"} + "${repo_root}/packaging/windows/fetch-msys2-installer.py" /msys2-latest.tar.zst + ${GITHUB_ACTIONS+echo "::endgroup::"} +fi + +${GITHUB_ACTIONS+echo "::group::Licenses"} +if [ ! -f "/gpl-3.0.txt" ]; then + curl -o /gpl-3.0.txt "https://www.gnu.org/licenses/gpl-3.0.txt" +fi + +if [ ! -f "/cloud.txt" ]; then + curl -o /cloud.txt "https://raw.githubusercontent.com/netdata/netdata/master/src/web/gui/v2/LICENSE.md" +fi +${GITHUB_ACTIONS+echo "::endgroup::"} + +${GITHUB_ACTIONS+echo "::group::Packaging"} +tar -xf /msys2-latest.tar.zst -C /opt/netdata/ || exit 1 +cp -R /opt/netdata/msys64/* /opt/netdata/ || exit 1 +rm -rf /opt/netdata/msys64/ +NDVERSION=$"$(grep 'CMAKE_PROJECT_VERSION:STATIC' "${build}/CMakeCache.txt"| cut -d= -f2)" +NDMAJORVERSION=$"$(grep 'CMAKE_PROJECT_VERSION_MAJOR:STATIC' "${build}/CMakeCache.txt"| cut -d= -f2)" +NDMINORVERSION=$"$(grep 'CMAKE_PROJECT_VERSION_MINOR:STATIC' "${build}/CMakeCache.txt"| cut -d= -f2)" + +/mingw64/bin/makensis.exe -DCURRVERSION="${NDVERSION}" -DMAJORVERSION="${NDMAJORVERSION}" -DMINORVERSION="${NDMINORVERSION}" "${repo_root}/packaging/windows/installer.nsi" +${GITHUB_ACTIONS+echo "::endgroup::"} + diff --git a/packaging/windows/package.ps1 b/packaging/windows/package.ps1 new file mode 100644 index 000000000..828e105f1 --- /dev/null +++ b/packaging/windows/package.ps1 @@ -0,0 +1,16 @@ +# Package the build + +#Requires -Version 4.0 + +$ErrorActionPreference = "Stop" + +. "$PSScriptRoot\functions.ps1" + +$msysbash = Get-MSYS2Bash "$msysprefix" +$env:CHERE_INVOKING = 'yes' + +& $msysbash -l "$PSScriptRoot\package-windows.sh" + +if ($LastExitcode -ne 0) { + exit 1 +} diff --git a/packaging/windows/protoc.bat b/packaging/windows/protoc.bat new file mode 100644 index 000000000..fe7a76f27 --- /dev/null +++ b/packaging/windows/protoc.bat @@ -0,0 +1,9 @@ +@echo off +:: +:: The problem with /usr/bin/protoc is that it accepts colon separated (:) paths at its parameters. +:: This makes C:/ being parsed as 2 paths: C and /, which of course both fail. +:: To overcome this problem, we use bash_execute.sh, which replaces all occurences of C: with /c. +:: +set "batch_dir=%~dp0" +set "batch_dir=%batch_dir:\=/%" +C:\msys64\usr\bin\bash.exe %batch_dir%/bash_execute.sh protoc %* diff --git a/packaging/windows/win-build-dir.sh b/packaging/windows/win-build-dir.sh new file mode 100644 index 000000000..09dd6b977 --- /dev/null +++ b/packaging/windows/win-build-dir.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +if [ -n "${BUILD_DIR}" ]; then + if (echo "${BUILD_DIR}" | grep -q -E "^[A-Z]:\\\\"); then + build="$(echo "${BUILD_DIR}" | sed -e 's/\\/\//g' -e 's/^\([A-Z]\):\//\/\1\//' -)" + else + build="${BUILD_DIR}" + fi +elif [ -n "${OSTYPE}" ]; then + if [ -n "${MSYSTEM}" ]; then + build="${REPO_ROOT}/build-${OSTYPE}-${MSYSTEM}" + else + build="${REPO_ROOT}/build-${OSTYPE}" + fi +elif [ "$USER" = "vk" ]; then + build="${REPO_ROOT}/build" +else + # shellcheck disable=SC2034 + build="${REPO_ROOT}/build" +fi diff --git a/packaging/windows/windows-openssh-to-msys.bat b/packaging/windows/windows-openssh-to-msys.bat new file mode 100644 index 000000000..829cb4845 --- /dev/null +++ b/packaging/windows/windows-openssh-to-msys.bat @@ -0,0 +1,118 @@ +@echo off +:: +:: This script will: +:: +:: 1. install the windows OpenSSH server (either via dsim or download it) +:: 2. activate the windows OpenSSH service +:: 3. open OpenSSH TCP port at windows firewall +:: 4. create a small batch file to start an MSYS session +:: 5. Set the default OpenSSH startup script to start the MSYS session +:: +:: Problems: +:: On older windows versions, terminal emulation is broken. +:: So, on windows 10 or windows server before 2019, the ssh session +:: will not have proper terminal emulation and will be not be able to +:: be used for editing files. +:: For more info check: +:: https://github.com/PowerShell/Win32-OpenSSH/issues/1260 +:: + +:: Check if OpenSSH Server is already installed +sc query sshd >nul 2>&1 +if %errorlevel% neq 0 ( + echo "OpenSSH Server not found. Attempting to install via dism..." + goto :install_openssh_dism +) else ( + echo "OpenSSH Server is already installed." + goto :configure_openssh +) + +:: Install OpenSSH using dism +:install_openssh_dism +dism /online /Enable-Feature /FeatureName:OpenSSH-Client /All >nul 2>&1 +dism /online /Enable-Feature /FeatureName:OpenSSH-Server /All >nul 2>&1 + +:: Check if dism succeeded in installing OpenSSH +sc query sshd >nul 2>&1 +if %errorlevel% neq 0 ( + echo "OpenSSH installation via dism failed or is unavailable." + goto :install_openssh_manual +) else ( + echo "OpenSSH installed successfully using dism." + goto :configure_openssh +) + +:: Function to Install OpenSSH manually if dism fails +:install_openssh_manual +echo "Installing OpenSSH manually..." + +:: Download the latest OpenSSH release +set DOWNLOAD_URL=https://github.com/PowerShell/Win32-OpenSSH/releases/download/v9.5.0.0p1-Beta/OpenSSH-Win64.zip +set DOWNLOAD_FILE=%temp%\OpenSSH-Win64.zip +set INSTALL_DIR=C:\Program Files\OpenSSH-Win64 + +:: Create the installation directory if it doesn't exist +if not exist "%INSTALL_DIR%" mkdir "%INSTALL_DIR%" + +:: Attempt to download OpenSSH using Invoke-WebRequest and TLS configuration +powershell -Command "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; try { Invoke-WebRequest -Uri '%DOWNLOAD_URL%' -OutFile '%DOWNLOAD_FILE%' -UseBasicParsing; exit 0 } catch { exit 1 }" +if %errorlevel% neq 0 ( + echo "Invoke-WebRequest download failed. Attempting to download using curl..." + curl -L -o "%DOWNLOAD_FILE%" "%DOWNLOAD_URL%" + if %errorlevel% neq 0 ( + echo "Failed to download OpenSSH using curl. Exiting..." + exit /b 1 + ) +) + +:: Unzip directly to INSTALL_DIR (flatten the folder structure) +powershell -Command "Expand-Archive -Path '%DOWNLOAD_FILE%' -DestinationPath '%INSTALL_DIR%' -Force" +if %errorlevel% neq 0 ( + echo "Failed to unzip OpenSSH package." + exit /b 1 +) + +:: Move inner contents to INSTALL_DIR if nested OpenSSH-Win64 folder exists +if exist "%INSTALL_DIR%\OpenSSH-Win64" ( + xcopy "%INSTALL_DIR%\OpenSSH-Win64\*" "%INSTALL_DIR%\" /s /e /y + rmdir "%INSTALL_DIR%\OpenSSH-Win64" /s /q +) + +:: Add the OpenSSH binaries to the system PATH +setx /M PATH "%INSTALL_DIR%;%PATH%" + +:: Register OpenSSH utilities as services using PowerShell +powershell -ExecutionPolicy Bypass -Command "& '%INSTALL_DIR%\install-sshd.ps1'" + +:: Verify if manual installation succeeded +sc query sshd >nul 2>&1 +if %errorlevel% neq 0 ( + echo "Manual OpenSSH installation failed. Exiting..." + exit /b 1 +) else ( + echo "OpenSSH installed successfully manually." + goto :configure_openssh +) + +:configure_openssh +:: Ensure OpenSSH Server service is set to start automatically and start the service +sc config sshd start= auto +net start sshd + +:: Create msys2.bat file with specific content +set MSYS2_PATH=C:\msys64 +if not exist "%MSYS2_PATH%" ( + echo "Error: %MSYS2_PATH% does not exist." + exit /b 1 +) + +echo @%MSYS2_PATH%\msys2_shell.cmd -defterm -here -no-start -msys > %MSYS2_PATH%\msys2.bat + +:: Run PowerShell command to set default shell +powershell -Command "New-ItemProperty -Path 'HKLM:\SOFTWARE\OpenSSH' -Name 'DefaultShell' -Value '%MSYS2_PATH%\msys2.bat' -PropertyType String -Force" + +:: Open the Windows Firewall for sshd (using PowerShell) +powershell -Command "New-NetFirewallRule -Name 'OpenSSH-Server-In-TCP' -DisplayName 'OpenSSH Server (sshd) Incoming' -Description 'Allow incoming SSH traffic via OpenSSH server' -Enabled True -Direction Inbound -Protocol TCP -LocalPort 22 -Action Allow" + +echo "OpenSSH has been successfully configured with MSYS2 as the default shell, and the firewall has been opened for sshd." +pause |