diff --git a/.github/workflows/_reusable_build_package.yml b/.github/workflows/_reusable_build_package.yml
index c7b71034..ba3fff95 100644
--- a/.github/workflows/_reusable_build_package.yml
+++ b/.github/workflows/_reusable_build_package.yml
@@ -38,6 +38,10 @@ on:
required: false
type: boolean
default: false
+ packagecloud_go_version:
+ required: false
+ type: string
+ default: "0.2.2"
secrets:
gh_artifacts_token:
required: true
@@ -61,6 +65,14 @@ on:
required: true
packagecloud_token:
required: true
+ aws_access_key_id:
+ required: true
+ aws_secret_access_key:
+ required: true
+ outputs:
+ otc_build_number:
+ description: "The build number of the package"
+ value: ${{ jobs.build_package.outputs.otc_build_number }}
defaults:
run:
@@ -72,23 +84,12 @@ jobs:
name: Build (CMake)
if: inputs.build_tool == 'cmake'
outputs:
+ otc_build_number: ${{ steps.get-build-number.outputs.otc_build_number }}
package_path: ${{ steps.package.outputs.path }}
steps:
- name: Checkout
uses: actions/checkout@v4
- - name: Download packagecloud-go tool
- run: |
- baseURL="https://github.com/amdprophet/packagecloud-go/releases/download"
- version="0.1.5"
- file="packagecloud-go_${version}_linux_amd64.tar.gz"
- curl -Lo /tmp/packagecloud-go.tar.gz $baseURL/$version/$file
-
- - name: Install packagecloud-go tool
- run: |
- tar -C /tmp -zxf /tmp/packagecloud-go.tar.gz
- sudo mv /tmp/packagecloud /usr/local/bin
-
- name: Workflow URL for sumologic-otel-collector
if: ${{ !inputs.use_release_artifacts && inputs.workflow_id != '' }}
run: |
@@ -97,6 +98,15 @@ jobs:
workflow_id="${{ inputs.workflow_id }}"
echo "https://github.com/${org}/${repo}/actions/runs/${workflow_id}"
+ # Only output build number on one target so that it can be read by other
+ # jobs
+ - name: Output Build Number
+ if: inputs.cmake_target == 'otc_linux_amd64_deb'
+ id: get-build-number
+ run: |
+ build_number="${{ inputs.otc_build_number }}"
+ echo "otc_build_number=${build_number}" >> $GITHUB_OUTPUT
+
- name: Determine if MacOS package should be signed
if: runner.os == 'macOS'
env:
@@ -228,12 +238,37 @@ jobs:
path: ./build/${{ steps.package.outputs.path }}
if-no-files-found: error
- - name: Publish package to Packagecloud
+ - name: Publish packages
if: runner.os == 'Linux'
uses: ./ci/github-actions/make
with:
target: publish-package
packagecloud-token: ${{ secrets.PACKAGECLOUD_TOKEN }}
+ aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
+ aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
+
+ - name: Publish packages
+ if: runner.os != 'Linux'
+ working-directory: build
+ env:
+ AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
+ AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
+ PACKAGECLOUD_TOKEN: ${{ secrets.PACKAGECLOUD_TOKEN }}
+ run: make publish-package
+
+ - name: Wait for Packagecloud packages to be indexed
+ if: runner.os == 'Linux'
+ uses: ./ci/github-actions/make
+ with:
+ target: wait-for-packagecloud-indexing
+ packagecloud-token: ${{ secrets.PACKAGECLOUD_TOKEN }}
+
+ - name: Wait for Packagecloud packages to be indexed
+ if: runner.os == 'Linux'
+ uses: ./ci/github-actions/make
+ with:
+ target: wait-for-packagecloud-indexing
+ packagecloud-token: ${{ secrets.PACKAGECLOUD_TOKEN }}
test_package:
runs-on: ${{ inputs.runs_on }}
@@ -259,6 +294,7 @@ jobs:
name: Build (WiX) ${{ inputs.fips && 'FIPS' || '' }}
if: inputs.build_tool == 'wix'
env:
+ OTC_VERSION: ${{ inputs.otc_version }}-${{ inputs.otc_build_number }}
PRODUCT_VERSION: ${{ inputs.otc_version }}.${{ inputs.otc_build_number }}
steps:
- name: Checkout
@@ -363,6 +399,17 @@ jobs:
path: ${{ steps.build.outputs.package_path }}
if-no-files-found: error
+ - name: Publish packages
+ env:
+ AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
+ AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
+ AWS_REGION: us-west-2
+ PKG_PATH: ${{ steps.build.outputs.package_path }}
+ PKG_NAME: ${{ steps.build.outputs.package_filename }}
+ S3_BUCKET: sumologic-osc-ci-builds
+ run: |
+ aws.exe s3 cp --debug $PKG_PATH s3://${S3_BUCKET}/${OTC_VERSION}/${PKG_NAME}
+
test_wixext:
name: Test (SumoLogic.wixext)
if: inputs.build_tool == 'wix'
diff --git a/.github/workflows/build_packages.yml b/.github/workflows/build_packages.yml
index a7f313d0..cbcf73d5 100644
--- a/.github/workflows/build_packages.yml
+++ b/.github/workflows/build_packages.yml
@@ -75,6 +75,10 @@ on:
type: boolean
required: false
default: false
+ is_latest:
+ type: boolean
+ required: false
+ default: false
jobs:
determine_workflow:
@@ -199,6 +203,8 @@ jobs:
microsoft_description: ${{ secrets.MICROSOFT_DESCRIPTION }}
gh_ci_token: ${{ secrets.GH_CI_TOKEN }}
packagecloud_token: ${{ secrets.PACKAGECLOUD_TOKEN }}
+ aws_access_key_id: ${{ secrets.AWS_ACCESS_KEY_ID }}
+ aws_secret_access_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
strategy:
matrix:
@@ -249,6 +255,16 @@ jobs:
install-script:
name: Store install script
runs-on: ubuntu-latest
+ needs:
+ - determine_version
+ - build_packages
+ env:
+ AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
+ AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
+ AWS_DEFAULT_REGION: us-east-1
+ AWS_S3_BUCKET: sumologic-osc-ci-builds
+ OTC_VERSION: ${{ needs.determine_version.outputs.otc_version }}
+ BUILD_NUMBER: ${{ needs.build_packages.outputs.otc_build_number }}
steps:
- uses: actions/checkout@v4
@@ -266,6 +282,22 @@ jobs:
path: ./install-script/install.ps1
if-no-files-found: error
+ - name: Store install scripts on S3
+ run: |
+ version="${OTC_VERSION}-${BUILD_NUMBER}"
+ s3_path="${version}/"
+ aws s3 cp install-script/install.ps1 s3://${AWS_S3_BUCKET}/${s3_path}
+ aws s3 cp install-script/install.sh s3://${AWS_S3_BUCKET}/${s3_path}
+
+ - name: Create latest_version file
+ env:
+ AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
+ AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
+ run: |
+ version="${OTC_VERSION}-${BUILD_NUMBER}"
+ echo "${version}" >> latest_version
+ aws s3 cp --content-type "text/plain" latest_version s3://${AWS_S3_BUCKET}/
+
publish_release:
name: Publish Release
runs-on: ubuntu-latest
@@ -331,3 +363,74 @@ jobs:
This release packages [${{ env.OTC_APP_VERSION }}](https://github.com/SumoLogic/sumologic-otel-collector/releases/tag/${{ env.OTC_APP_VERSION }}).
The changelog below is for the package itself, rather than the Sumo Logic Distribution for OpenTelemetry Collector.
+
+ test-install-script:
+ name: Test Install Script
+ runs-on: ${{ matrix.runs_on }}
+ timeout-minutes: 60
+ needs:
+ - determine_version
+ - build_packages
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - arch_os: linux_amd64
+ runs_on: ubuntu-20.04
+ - arch_os: darwin_amd64
+ runs_on: macos-latest
+ - arch_os: windows_amd64
+ runs_on: windows-2022
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ GH_CI_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ OTC_VERSION: ${{ needs.determine_version.outputs.otc_version }}
+ OTC_BUILD_NUMBER: ${{ github.run_number }}
+ PACKAGECLOUD_MASTER_TOKEN: ${{ secrets.PACKAGECLOUD_MASTER_TOKEN }}
+ PACKAGECLOUD_REPO: ci-builds
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Check if test related files changed
+ id: changed-files
+ uses: tj-actions/changed-files@v44
+ with:
+ files: |
+ install-script/**/*
+ .github/**
+
+ - name: Setup go
+ if: steps.changed-files.outputs.any_changed == 'true'
+ uses: WillAbides/setup-go-faster@v1
+ with:
+ go-version: stable
+
+ - name: Download macOS package and use it for install.sh
+ if: ${{ steps.changed-files.outputs.any_changed == 'true' && runner.os == 'macOS' }}
+ uses: actions/download-artifact@v4
+ with:
+ path: artifacts/
+ pattern: otelcol-sumo_*-intel.pkg
+
+ - name: Show packages
+ if: ${{ steps.changed-files.outputs.any_changed == 'true' && runner.os == 'macOS' }}
+ run: |
+ ls -l artifacts/
+ ls -l artifacts/**/*
+
+ - name: Set DARWIN_PKG_URL
+ if: ${{ steps.changed-files.outputs.any_changed == 'true' && runner.os == 'macOS' }}
+ run: |
+ fp="$(readlink -f artifacts/otelcol-sumo_*-intel.pkg/otelcol-sumo_*-intel.pkg)"
+ echo DARWIN_PKG_URL="file://${fp}" >> $GITHUB_ENV
+
+ - name: Run install script tests (*nix)
+ if: steps.changed-files.outputs.any_changed == 'true' && runner.os != 'Windows'
+ working-directory: install-script/test
+ run: make test
+
+ - name: Run install script tests (Windows)
+ shell: powershell
+ if: steps.changed-files.outputs.any_changed == 'true' && runner.os == 'Windows'
+ working-directory: install-script/test
+ run: make test
diff --git a/.github/workflows/releases.yml b/.github/workflows/releases.yml
new file mode 100644
index 00000000..326e05f7
--- /dev/null
+++ b/.github/workflows/releases.yml
@@ -0,0 +1,168 @@
+name: 'Publish release'
+
+run-name: >
+ ${{ format('Publish Release for Workflow: {0}', inputs.workflow_id) }}
+
+on:
+ workflow_dispatch:
+ inputs:
+ workflow_id:
+ description: |
+ Workflow Run ID from this repository to fetch artifacts from for this
+ release.
+ required: true
+ type: string
+
+defaults:
+ run:
+ shell: bash
+
+jobs:
+ get-version:
+ name: Get application version for this revision
+ runs-on: ubuntu-latest
+ outputs:
+ git-sha: ${{ steps.get-version.outputs.git-sha }}
+ otc-version: ${{ steps.get-version.outputs.otc-version }}
+ sumo-version: ${{ steps.get-version.outputs.sumo-version }}
+ binary-version: ${{ steps.get-version.outputs.binary-version }}
+ version: ${{ steps.get-version.outputs.version }}
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Outuput Workflow ID
+ run: echo ::notice title=Workflow ID::${{ inputs.workflow_id }}
+
+ - name: Output Workflow URL
+ run: |
+ repo_url="https://github.com/SumoLogic/sumologic-otel-collector-packaging"
+ url="${repo_url}/actions/runs/${{ inputs.workflow_id }}"
+ echo ::notice title=Workflow URL::${url}
+
+ - name: Determine Workflow Run ID from workflow
+ id: get-run-number
+ run: |
+ workflow="11673248730"
+ run_number=$(gh run view "${workflow}" --json number -t '{{.number}}')
+ echo "run-number=$run_number" >> $GITHUB_OUTPUT
+
+ - name: Output Workflow Run Number
+ run: |
+ run_number=${{ steps.get-run-number.outputs.run-number }}
+ echo ::notice title=Workflow Run Number::${run_number}
+
+ - name: Download otelcol-sumo artifact from workflow
+ uses: actions/download-artifact@v4
+ with:
+ name: otelcol-sumo-linux_amd64
+ path: artifacts/
+ merge-multiple: true
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ run-id: ${{ inputs.workflow_id }}
+
+ - name: Determine version from artifact
+ id: get-version
+ run: |
+ artifact="artifacts/otelcol-sumo-linux_amd64"
+ chmod +x "${artifact}"
+ script="ci/get_version_from_binary.sh"
+ core="$("$script" core "${artifact}")"
+ sumo="$("$script" sumo "${artifact}")"
+ run_number=${{ steps.get-run-number.outputs.run-number }}
+ echo "otc-version=$core" >> $GITHUB_OUTPUT
+ echo "sumo-version=$sumo" >> $GITHUB_OUTPUT
+ echo "binary-version=${core}-sumo-${sumo}" >> $GITHUB_OUTPUT
+ echo "version=${core}-${run_number}" >> $GITHUB_OUTPUT
+
+ - name: Output Binary Version
+ run: |
+ binary_version=${{ steps.get-version.outputs.binary-version }}
+ echo ::notice title=Binary Version::${binary_version}
+
+ - name: Output Package Version
+ run: |
+ package_version=${{ steps.get-version.outputs.version }}
+ echo ::notice title=Package Version::${package_version}
+
+ - name: Determine Git SHA of workflow
+ id: get-sha
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: |
+ workflow=${{ inputs.workflow_id }}
+ sha="$(gh run view ${workflow} --json headSha -t '{{.headSha}}')"
+ echo "git-sha=$sha" >> $GITHUB_OUTPUT
+
+ - name: Output Git SHA
+ run: |
+ echo ::notice title=Git SHA::${{ steps.get-sha.outputs.git-sha }}
+
+ # Store the install script from the packaging repository as a release
+ # artifact.
+ install-script:
+ name: Store install script
+ runs-on: ubuntu-latest
+ needs:
+ - get-version
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ ref: ${{ needs.get-version.outputs.git-sha }}
+
+ - name: Store Linux install script as action artifact
+ uses: actions/upload-artifact@v4
+ with:
+ name: install.sh
+ path: ./install-script/install.sh
+ if-no-files-found: error
+
+ - name: Store Windows install script as action artifact
+ uses: actions/upload-artifact@v4
+ with:
+ name: install.ps1
+ path: ./install-script/install.ps1
+ if-no-files-found: error
+
+ create-release:
+ name: Create Github release
+ runs-on: ubuntu-20.04
+ needs:
+ - get-version
+ permissions:
+ contents: write
+ steps:
+ - name: Download all artifacts from workflow
+ uses: actions/download-artifact@v4
+ with:
+ path: artifacts/
+ merge-multiple: true
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ run-id: ${{ inputs.workflow_id }}
+
+ - uses: ncipollo/release-action@v1
+ with:
+ name: v${{ needs.get-version.outputs.version }}
+ commit: ${{ needs.get-version.outputs.git-sha }}
+ tag: v${{ needs.get-version.outputs.version }}
+
+ draft: true
+ generateReleaseNotes: true
+ prerelease: false
+
+ allowUpdates: true
+ omitBodyDuringUpdate: true
+ omitNameDuringUpdate: true
+
+ artifacts: "artifacts/*/*"
+ artifactErrorsFailBuild: true
+ replacesArtifacts: true
+
+ body: |
+ This release packages
+ [${{ needs.get-version.outputs.version }}](https://github.com/SumoLogic/sumologic-otel-collector/releases/tag/v${{ needs.get-version.outputs.binary-version }}).
+
+ The changelog below is for the package itself, rather than the Sumo
+ Logic Distribution for OpenTelemetry Collector. The changelog for
+ the Sumo Logic Distribution for OpenTelemetry Collector can be found
+ on the collector's
+ [release page](https://github.com/SumoLogic/sumologic-otel-collector/releases/tag/v${{ needs.get-version.outputs.binary-version }}).
diff --git a/.github/workflows/test-install-script.yml b/.github/workflows/test-install-script.yml
deleted file mode 100644
index 15eefe6a..00000000
--- a/.github/workflows/test-install-script.yml
+++ /dev/null
@@ -1,50 +0,0 @@
-name: 'Test install script'
-
-defaults:
- run:
- shell: bash
-
-on:
- pull_request:
-
-jobs:
- test-install-script:
- name: Test Install Script
- runs-on: ${{ matrix.runs_on }}
- strategy:
- fail-fast: false
- matrix:
- include:
- - arch_os: linux_amd64
- runs_on: ubuntu-20.04
- - arch_os: darwin_amd64
- runs_on: macos-latest
- - arch_os: windows_amd64
- runs_on: windows-2022
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- GH_CI_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- steps:
- - uses: actions/checkout@v4
-
- - name: Check if test related files changed
- id: changed-files
- uses: tj-actions/changed-files@v44
- with:
- files: |
- install-script/**/*
- .github/**
-
- - name: Setup go
- if: steps.changed-files.outputs.any_changed == 'true'
- uses: WillAbides/setup-go-faster@v1
- with:
- go-version: stable
-
- - name: Install otelcol-config
- run: go install github.com/SumoLogic/sumologic-otel-collector/pkg/tools/otelcol-config@latest
-
- - name: Run install script tests
- if: steps.changed-files.outputs.any_changed == 'true'
- working-directory: install-script/test
- run: make test
diff --git a/.gitignore b/.gitignore
index 11530c4c..37e3d589 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,3 +18,6 @@ wix/packages
msi/wix/packages
msi/SumoLogic.wixext/packages
install-script/test/sumologic_scripts_tests.test
+
+# 1Password
+.op/
diff --git a/CMakeLists.txt b/CMakeLists.txt
index bee55ed6..7dbefff8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.24.1 FATAL_ERROR)
# Required and optional programs. Attempts to find required and optional
# programs used to build the packages.
-find_program(PACKAGECLOUD_PROGRAM packagecloud REQUIRED)
+find_program(PACKAGECLOUD_PROGRAM packagecloud)
# Set version information
include("${CMAKE_SOURCE_DIR}/version.cmake")
diff --git a/Dockerfile b/Dockerfile
index cc7607cc..baa2e385 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -16,7 +16,8 @@ RUN apk add --no-cache \
curl \
bash \
tar \
- gzip
+ gzip \
+ aws-cli
COPY docker/install-deps.sh /install-deps.sh
diff --git a/Makefile b/Makefile
index 5dce5e65..0cccb15a 100644
--- a/Makefile
+++ b/Makefile
@@ -42,6 +42,8 @@ publish-package:
-v "$(mkfile_dir):/src" \
-v "$(build_dir):/build" \
-e PACKAGECLOUD_TOKEN="$(PACKAGECLOUD_TOKEN)" \
+ -e AWS_ACCESS_KEY_ID="$(AWS_ACCESS_KEY_ID)" \
+ -e AWS_SECRET_ACCESS_KEY="$(AWS_SECRET_ACCESS_KEY)"
otelcol-sumo/cmake \
make publish-package
diff --git a/assets/.keep b/assets/.keep
new file mode 100644
index 00000000..e69de29b
diff --git a/assets/conf.d/ephemeral.yaml b/assets/conf.d/ephemeral.yaml
new file mode 100644
index 00000000..4aa2d995
--- /dev/null
+++ b/assets/conf.d/ephemeral.yaml
@@ -0,0 +1,3 @@
+extensions:
+ sumologic:
+ ephemeral: true
diff --git a/assets/productbuild/uninstall.sh b/assets/productbuild/uninstall.sh
index c17d1b34..5cce4d9e 100755
--- a/assets/productbuild/uninstall.sh
+++ b/assets/productbuild/uninstall.sh
@@ -43,19 +43,19 @@ collector_files=(
"/etc/otelcol-sumo/sumologic.yaml"
"/etc/otelcol-sumo/conf.d"
"/etc/otelcol-sumo/conf.d-available"
+ "/etc/otelcol-sumo/conf.d-available/ephemeral.yaml"
+ "/etc/otelcol-sumo/conf.d-available/hostmetrics.yaml"
"/etc/otelcol-sumo"
+ "/etc/otelcol-sumo/opamp.d"
"/usr/local/bin/otelcol-config"
"/usr/local/bin/otelcol-sumo"
+ "/usr/local/share/otelcol-sumo/otelcol-sumo.sh"
+ "/usr/local/share/otelcol-sumo"
"/var/lib/otelcol-sumo/file_storage"
"/var/lib/otelcol-sumo"
"/var/log/otelcol-sumo"
)
-# A list of files & directories to remove for hostmetrics
-hostmetrics_files=(
- "/etc/otelcol-sumo/conf.d-available/hostmetrics.yaml"
-)
-
function package_is_registered() {
package_id="$1"
pkgutil --pkg-info "$package_id"
@@ -114,7 +114,6 @@ function uninstall_package() {
stop_service "${service_plist_file}"
uninstall_package "com.sumologic.otelcol-sumo" "${collector_files[@]}"
-uninstall_package "com.sumologic.otelcol-sumo-hostmetrics" "${hostmetrics_files[@]}"
# remove the directory that this script belongs to
SCRIPT_DIR="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"
diff --git a/assets/services/launchd/com.sumologic.otelcol-sumo.plist b/assets/services/launchd/com.sumologic.otelcol-sumo.plist
index 0aaaf732..b1aec424 100644
--- a/assets/services/launchd/com.sumologic.otelcol-sumo.plist
+++ b/assets/services/launchd/com.sumologic.otelcol-sumo.plist
@@ -6,12 +6,13 @@
otelcol-sumo
ProgramArguments
- /usr/local/bin/otelcol-sumo
- --config
- /etc/otelcol-sumo/sumologic.yaml
- --config
- glob:/etc/otelcol-sumo/conf.d/*.yaml
+ /usr/local/share/otelcol-sumo/otelcol-sumo.sh
+ EnvironmentVariables
+
+ SUMOLOGIC_INSTALLATION_TOKEN
+
+
UserName
_otelcol-sumo
diff --git a/assets/services/systemd/otelcol-sumo.service b/assets/services/systemd/otelcol-sumo.service
index cc56b3ba..d435184b 100644
--- a/assets/services/systemd/otelcol-sumo.service
+++ b/assets/services/systemd/otelcol-sumo.service
@@ -2,7 +2,7 @@
Description=Sumo Logic Distribution for OpenTelemetry Collector
[Service]
-ExecStart=/usr/local/bin/otelcol-sumo --config /etc/otelcol-sumo/sumologic.yaml --config "glob:/etc/otelcol-sumo/conf.d/*.yaml"
+ExecStart=/usr/share/otelcol-sumo/otelcol-sumo.sh
User=otelcol-sumo
Group=otelcol-sumo
MemoryHigh=2000M
diff --git a/ci/github-actions/make/action.yml b/ci/github-actions/make/action.yml
index 85391fd1..0c348636 100644
--- a/ci/github-actions/make/action.yml
+++ b/ci/github-actions/make/action.yml
@@ -7,12 +7,20 @@ inputs:
packagecloud-token:
required: false
type: string
+ aws-access-key-id:
+ required: false
+ type: string
+ aws-secret-access-key:
+ required: false
+ type: string
runs:
using: 'docker'
image: '../../../Dockerfile'
env:
PACKAGECLOUD_TOKEN: ${{ inputs.packagecloud-token }}
+ AWS_ACCESS_KEY_ID: ${{ inputs.aws-access-key-id }}
+ AWS_SECRET_ACCESS_KEY: ${{ inputs.aws-secret-access-key }}
args:
- make
- ${{ inputs.target }}
diff --git a/ci/verify_installer.sh b/ci/verify_installer.sh
index 12a16d94..26a7314f 100755
--- a/ci/verify_installer.sh
+++ b/ci/verify_installer.sh
@@ -37,6 +37,7 @@ system_files=(
"usr"
"usr/local"
"usr/local/bin"
+ "usr/local/share"
"var"
"var/lib"
"var/log"
@@ -48,23 +49,23 @@ expected_collector_files=(
"etc/otelcol-sumo/conf.d"
"etc/otelcol-sumo/conf.d/common.yaml"
"etc/otelcol-sumo/conf.d-available"
+ "etc/otelcol-sumo/conf.d-available/ephemeral.yaml"
+ "etc/otelcol-sumo/conf.d-available/hostmetrics.yaml"
"etc/otelcol-sumo/conf.d-available/examples"
+ "etc/otelcol-sumo/opamp.d"
"etc/otelcol-sumo/sumologic.yaml"
"Library/Application Support/otelcol-sumo"
"Library/Application Support/otelcol-sumo/uninstall.sh"
"Library/LaunchDaemons/com.sumologic.otelcol-sumo.plist"
"usr/local/bin/otelcol-config"
"usr/local/bin/otelcol-sumo"
+ "usr/local/share/otelcol-sumo"
+ "usr/local/share/otelcol-sumo/otelcol-sumo.sh"
"var/lib/otelcol-sumo"
"var/lib/otelcol-sumo/file_storage"
"var/log/otelcol-sumo"
)
-# a list of files that the hostmetrics package should install
-expected_hostmetrics_files=(
- "etc/otelcol-sumo/conf.d-available/hostmetrics.yaml"
-)
-
function install_package() {
mpkg="$1"
mpkg_basename="$2"
@@ -184,15 +185,9 @@ while IFS= read -r -d $'\0'; do
collector_pkg+=("$REPLY")
done < <(find . -name "*-otelcol-sumo.pkg" -type d -print0)
-# create an array of hostmetrics packages (only one is expected)
-hostmetrics_pkg=()
-while IFS= read -r -d $'\0'; do
- hostmetrics_pkg+=("$REPLY")
-done < <(find . -name "*-otelcol-sumo-hostmetrics.pkg" -type d -print0)
-
# verify that the expected number of sub-packages were found
pkg_count="${#all_pkgs[@]}"
-expected_pkg_count=2
+expected_pkg_count=1
if [ "$pkg_count" -ne $expected_pkg_count ]; then
echo "error: ${expected_pkg_count} sub-packages were expected but found ${pkg_count}"
@@ -205,12 +200,6 @@ if [ "${#collector_pkg[@]}" -gt 1 ]; then
exit 1
fi
-# only one hostmetrics sub-package should exist
-if [ "${#hostmetrics_pkg[@]}" -gt 1 ]; then
- echo "error: more than one hostmetrics sub-package was found"
- exit 1
-fi
-
# get a list of files installed by the collector sub-package excluding system
# files
collector_pkg_name="$(echo "${collector_pkg[0]}" | cut -d/ -f2-)"
@@ -243,41 +232,6 @@ for f in "${all_collector_files[@]}"; do
collector_files+=("$collector_file")
done
-cd "$expanded_dir" || exit
-
-# get a list of files installed by the hostmetrics sub-package excluding both
-# system files and collector files
-hostmetrics_pkg_name="$(echo "${hostmetrics_pkg[0]}" | cut -d/ -f2-)"
-cd "${hostmetrics_pkg_name}/Payload" || exit
-all_hostmetrics_files=()
-while IFS= read -r -d $'\0'; do
- all_hostmetrics_files+=("$REPLY")
-done < <(find . ! -name '.' -print0)
-
-hostmetrics_files=()
-
-for f in "${all_hostmetrics_files[@]}"; do
- hostmetrics_file="$(echo "$f" | cut -d/ -f2-)"
-
- # shellcheck disable=SC2076
- if [[ " ${system_files[*]} " =~ " ${hostmetrics_file} " ]]; then
- continue
- fi
-
- # shellcheck disable=SC2076
- if [[ " ${collector_files[*]} " =~ " ${hostmetrics_file} " ]]; then
- continue
- fi
-
- # shellcheck disable=SC2076
- if [[ ! " ${expected_collector_files[*]} " =~ " ${collector_file} " ]]; then
- echo "error: unexpected file installed by hostmetrics sub-package: ${hostmetrics_file}"
- exit 1
- fi
-
- hostmetrics_files+=("$hostmetrics_file")
-done
-
cd "$exec_dir" || exit
install_package "$mpkg" "$mpkg_basename"
@@ -287,7 +241,6 @@ echo "##########################################################################
echo "Verifying installation: ${mpkg}"
echo "################################################################################"
verify_installation "com.sumologic.otelcol-sumo" "${expected_collector_files[@]}"
-verify_installation "com.sumologic.otelcol-sumo-hostmetrics" "${expected_hostmetrics_files[@]}"
echo
echo "################################################################################"
@@ -305,6 +258,5 @@ echo "##########################################################################
echo "Verifying uninstallation: ${mpkg}"
echo "################################################################################"
verify_uninstallation "com.sumologic.otelcol-sumo" "${expected_collector_files[@]}"
-verify_uninstallation "com.sumologic.otelcol-sumo-hostmetrics" "${expected_hostmetrics_files[@]}"
echo "Success!"
diff --git a/components/otelcol-sumo.cmake b/components/otelcol-sumo.cmake
index 147949fe..60d441e8 100644
--- a/components/otelcol-sumo.cmake
+++ b/components/otelcol-sumo.cmake
@@ -1,29 +1,34 @@
macro(default_otc_linux_install)
- create_otc_components()
install_otc_config_directory()
install_otc_config_fragment_directory()
+ install_otc_config_fragments_available_directory()
install_otc_config_examples()
install_otc_user_env_directory()
+ install_otc_opampd_directory()
install_otc_state_directory()
install_otc_filestorage_state_directory()
install_otc_sumologic_yaml()
install_otc_common_yaml()
+ install_otc_linux_hostmetrics_yaml()
+ install_otc_ephemeral_yaml()
install_otc_token_env()
install_otc_binary()
install_otc_config_binary()
endmacro()
macro(default_otc_darwin_install)
- create_otc_components()
install_otc_config_directory()
install_otc_config_fragment_directory()
+ install_otc_config_fragments_available_directory()
install_otc_config_examples()
+ install_otc_opampd_directory()
install_otc_state_directory()
install_otc_filestorage_state_directory()
install_otc_log_directory()
install_otc_sumologic_yaml()
install_otc_common_yaml()
install_otc_darwin_hostmetrics_yaml()
+ install_otc_ephemeral_yaml()
install_otc_binary()
install_otc_config_binary()
install_otc_uninstall_script()
@@ -40,12 +45,6 @@ macro(create_otc_components)
REQUIRED
GROUP "otelcol-sumo-group"
)
-
- cpack_add_component("otelcol-sumo-hostmetrics"
- DISPLAY_NAME "Collect Host Metrics"
- GROUP "otelcol-sumo-group"
- DISABLED
- )
endmacro()
# e.g. /etc/otelcol-sumo
@@ -58,7 +57,7 @@ macro(install_otc_config_directory)
DESTINATION "${OTC_CONFIG_DIR}"
DIRECTORY_PERMISSIONS
OWNER_READ OWNER_WRITE OWNER_EXECUTE
- GROUP_READ GROUP_EXECUTE
+ GROUP_READ GROUP_WRITE GROUP_EXECUTE
WORLD_EXECUTE
COMPONENT otelcol-sumo
)
@@ -117,8 +116,8 @@ macro(install_otc_config_examples)
FILES "${example}"
DESTINATION "${OTC_CONFIG_FRAGMENTS_AVAILABLE_DIR}/examples"
PERMISSIONS
- OWNER_READ OWNER_WRITE OWNER_EXECUTE
- GROUP_READ GROUP_WRITE GROUP_EXECUTE
+ OWNER_READ OWNER_WRITE
+ GROUP_READ GROUP_WRITE
COMPONENT otelcol-sumo
)
endforeach(example)
@@ -139,6 +138,21 @@ macro(install_otc_user_env_directory)
)
endmacro()
+# e.g. /etc/otelcol-sumo/opamp.d
+macro(install_otc_opampd_directory)
+ require_variables(
+ "OTC_OPAMPD_DIR"
+ )
+ install(
+ DIRECTORY
+ DESTINATION "${OTC_OPAMPD_DIR}"
+ DIRECTORY_PERMISSIONS
+ OWNER_READ OWNER_WRITE OWNER_EXECUTE
+ GROUP_READ GROUP_WRITE GROUP_EXECUTE
+ COMPONENT otelcol-sumo
+ )
+endmacro()
+
# e.g. /var/lib/otelcol-sumo
macro(install_otc_state_directory)
require_variables(
@@ -149,7 +163,7 @@ macro(install_otc_state_directory)
DESTINATION "${OTC_STATE_DIR}"
DIRECTORY_PERMISSIONS
OWNER_READ OWNER_WRITE OWNER_EXECUTE
- GROUP_READ GROUP_EXECUTE
+ GROUP_READ GROUP_WRITE GROUP_EXECUTE
COMPONENT otelcol-sumo
)
endmacro()
@@ -164,7 +178,7 @@ macro(install_otc_filestorage_state_directory)
DESTINATION "${OTC_FILESTORAGE_STATE_DIR}"
DIRECTORY_PERMISSIONS
OWNER_READ OWNER_WRITE OWNER_EXECUTE
- GROUP_READ GROUP_EXECUTE
+ GROUP_READ GROUP_WRITE GROUP_EXECUTE
COMPONENT otelcol-sumo
)
endmacro()
@@ -254,8 +268,8 @@ macro(install_otc_sumologic_yaml)
FILES "${ASSETS_DIR}/sumologic.yaml"
DESTINATION "${OTC_CONFIG_DIR}"
PERMISSIONS
- OWNER_READ
- GROUP_READ
+ OWNER_READ OWNER_WRITE
+ GROUP_READ GROUP_WRITE
RENAME "${OTC_SUMOLOGIC_CONFIG}"
COMPONENT otelcol-sumo
)
@@ -293,7 +307,7 @@ macro(install_otc_common_yaml)
)
endmacro()
-# e.g. /etc/otelcol-sumo/conf.d/hostmetrics.yaml
+# e.g. /etc/otelcol-sumo/conf.d-available/hostmetrics.yaml
macro(install_otc_darwin_hostmetrics_yaml)
require_variables(
"ASSETS_DIR"
@@ -305,13 +319,12 @@ macro(install_otc_darwin_hostmetrics_yaml)
RENAME "hostmetrics.yaml"
PERMISSIONS
OWNER_READ OWNER_WRITE
- GROUP_READ
- WORLD_READ
- COMPONENT otelcol-sumo-hostmetrics
+ GROUP_READ GROUP_WRITE
+ COMPONENT otelcol-sumo
)
endmacro()
-# e.g. /etc/otelcol-sumo/conf.d/hostmetrics.yaml
+# e.g. /etc/otelcol-sumo/conf.d-available/hostmetrics.yaml
macro(install_otc_linux_hostmetrics_yaml)
require_variables(
"ASSETS_DIR"
@@ -323,9 +336,24 @@ macro(install_otc_linux_hostmetrics_yaml)
RENAME "hostmetrics.yaml"
PERMISSIONS
OWNER_READ OWNER_WRITE
- GROUP_READ
- WORLD_READ
- COMPONENT otelcol-sumo-hostmetrics
+ GROUP_READ GROUP_WRITE
+ COMPONENT otelcol-sumo
+ )
+endmacro()
+
+# e.g. /etc/otelcol-sumo/conf.d-available/ephemeral.yaml
+macro(install_otc_ephemeral_yaml)
+ require_variables(
+ "ASSETS_DIR"
+ "OTC_CONFIG_FRAGMENTS_AVAILABLE_DIR"
+ )
+ install(
+ FILES "${ASSETS_DIR}/conf.d/ephemeral.yaml"
+ DESTINATION "${OTC_CONFIG_FRAGMENTS_AVAILABLE_DIR}"
+ PERMISSIONS
+ OWNER_READ OWNER_WRITE
+ GROUP_READ GROUP_WRITE
+ COMPONENT otelcol-sumo
)
endmacro()
@@ -333,10 +361,12 @@ endmacro()
macro(install_otc_service_systemd)
require_variables(
"ASSETS_DIR"
+ "OTC_SYSTEMD_CONFIG"
"OTC_SYSTEMD_DIR"
)
+ install_otc_service_script()
install(
- FILES "${ASSETS_DIR}/services/systemd/otelcol-sumo.service"
+ FILES "${ASSETS_DIR}/services/systemd/${OTC_SYSTEMD_CONFIG}"
DESTINATION "${OTC_SYSTEMD_DIR}"
PERMISSIONS
OWNER_READ OWNER_WRITE
@@ -350,10 +380,12 @@ endmacro()
macro(install_otc_service_launchd)
require_variables(
"ASSETS_DIR"
+ "OTC_LAUNCHD_CONFIG"
"OTC_LAUNCHD_DIR"
)
+ install_otc_service_script()
install(
- FILES "${ASSETS_DIR}/services/launchd/com.sumologic.otelcol-sumo.plist"
+ FILES "${ASSETS_DIR}/services/launchd/${OTC_LAUNCHD_CONFIG}"
DESTINATION "${OTC_LAUNCHD_DIR}"
PERMISSIONS
OWNER_READ OWNER_WRITE
@@ -361,3 +393,21 @@ macro(install_otc_service_launchd)
COMPONENT otelcol-sumo
)
endmacro()
+
+# e.g. /usr/share/otelcol-sumo/otelcol-sumo.sh
+macro(install_otc_service_script)
+ require_variables(
+ "ASSETS_DIR"
+ "OTC_SERVICE_SCRIPT"
+ "OTC_SHARE_DIR"
+ )
+ install(
+ FILES "${ASSETS_DIR}/${OTC_SERVICE_SCRIPT}"
+ DESTINATION "${OTC_SHARE_DIR}"
+ PERMISSIONS
+ OWNER_READ OWNER_WRITE OWNER_EXECUTE
+ GROUP_READ GROUP_EXECUTE
+ WORLD_READ WORLD_EXECUTE
+ COMPONENT otelcol-sumo
+ )
+endmacro()
diff --git a/distributions.cmake b/distributions.cmake
index 98758fa5..a517f18c 100644
--- a/distributions.cmake
+++ b/distributions.cmake
@@ -1,3 +1,6 @@
+# Checks if the Packagecloud distro supports the package architecture and if it
+# does it will be added to the list of Packagecloud distributions to upload the
+# package to.
macro(check_architecture_support)
if(NOT ${package_arch} IN_LIST _supported_architectures)
message(FATAL_ERROR "${_distro_name} does not support architecture: ${package_arch}")
diff --git a/docker/install-deps.sh b/docker/install-deps.sh
index 23ff7f82..007958cf 100755
--- a/docker/install-deps.sh
+++ b/docker/install-deps.sh
@@ -4,7 +4,7 @@ set -euxo pipefail
targetarch="$1"
-PACKAGECLOUD_GO_VERSION="0.1.5"
+PACKAGECLOUD_GO_VERSION="0.2.2"
# Convert between Docker CPU architecture names and other names such as Go's
# GOARCH.
diff --git a/docs/release.md b/docs/release.md
new file mode 100644
index 00000000..9ae1dc91
--- /dev/null
+++ b/docs/release.md
@@ -0,0 +1,122 @@
+# Releasing
+
+## How to release
+
+### Check end-to-end tests
+
+Check if the Sumo internal e2e tests are passing.
+
+### Determine the Workflow Run ID to release
+
+We can begin the process of creating a release once QE has given a thumbs up for
+a given package version and the [collector release steps][collector_release]
+have already been performed. We can determine the Workflow Run ID to use for a
+release using the following steps:
+
+#### Find the package build number
+
+Each package has a build number and it's included in the package version &
+filename. For example, if the package version that QE validates is 0.108.0-1790
+then the build number is 1790.
+
+#### Find the collector workflow run
+
+We can find the workflow used to build the packages by using the package build
+number.
+
+The build number corresponds directly to the GitHub Run Number for a packaging
+workflow run in GitHub Actions. Unfortunately, there does not currently appear to
+be a way to reference a workflow run using the run number. Instead, we can use
+one of two methods to find the workflow run:
+
+#### Option 1 - Use the `gh` cli tool to find the workflow
+
+```shell
+PAGER=""; BUILD_NUMBER="1790"; \
+gh run list -R sumologic/sumologic-otel-collector-packaging -s success \
+-w build_packages.yml -L 200 -b main --json displayTitle,databaseId,number,url \
+-q ".[] | select(.number == ${BUILD_NUMBER})"
+```
+
+This will output a number of fields, for example:
+
+```json
+{
+ "databaseId": 11673248730,
+ "displayTitle": "Build for Remote Workflow: 11672946742, Version: 0.108.0-sumo-1\n",
+ "number": 1790,
+ "url": "https://github.com/SumoLogic/sumologic-otel-collector-packaging/actions/runs/11673248730"
+}
+```
+
+The number in the `databaseId` field is the ID for the workflow run that built
+the packages.
+
+The workflow run can be viewed by visiting the URL in the `url` field.
+
+#### Option 2 - Search the GitHub website manually
+
+Manually search for the run number on the
+[Build packages workflow][build_workflow] page. Search for the build number
+(e.g. 1790) until you find the corresponding workflow.
+
+![Finding the packaging workflow run][release_0]
+
+Once you've found the packaging workflow run, click it to navigate to the
+details of the workflow run. The Workflow Run ID can be found in the last part
+of the URL in the address bar:
+
+![Finding the packaging workflow ID][release_1]
+
+### Trigger the release
+
+Now that we have the Workflow Run ID we can trigger a release. There are two
+methods of doing this.
+
+#### Option 1 - Use the `gh` cli tool to trigger the release
+
+A release can be triggered by using the following command (be sure to replace
+`WORKFLOW_ID` with the Workflow Run ID from the previous step):
+
+```shell
+PAGER=""; WORKFLOW_ID="11673248730"; \
+gh workflow run build_packages.yml \
+-R sumologic/sumologic-otel-collector-packaging -f workflow_id=${WORKFLOW_ID}
+```
+
+The status of running workflows can be viewed with the `gh run watch` command.
+You will have to manually select the correct workflow run. The name of the run
+should have a title similiar to `Publish Release for Workflow: x`). Once you
+have selected the correct run the screen will periodically update to show the
+status of the run's jobs.
+
+#### Option 2 - Use the GitHub website to trigger the release
+
+Navigate to the [Publish release][releases_workflow] workflow in GitHub Actions.
+Find and click the `Run workflow` button on the right-hand side of the page.
+Fill in the Workflow Run ID from the previous step. If the release should be
+considered to be the latest version, click the checkbox for `Latest version`.
+Click the `Run workflow` button to trigger the release.
+
+![Triggering a release][release_2]
+
+### Publish GitHub release
+
+The GitHub release is created as draft by the
+[releases](../.github/workflows/releases.yml) GitHub Action.
+
+After the release draft is created, go to [GitHub releases](https://github.com/SumoLogic/sumologic-otel-collector-packaging/releases),
+edit the release draft and fill in missing information:
+
+- Specify versions for upstream OT core and contrib releases
+- Copy and paste the Changelog entry for this release from [CHANGELOG.md][changelog]
+
+After verifying that the release text and all links are good, publish the release.
+
+[build_workflow]: https://github.com/SumoLogic/sumologic-otel-collector-packaging/actions/workflows/build_packages.yml?query=branch%3Amain
+[changelog]: https://github.com/SumoLogic/sumologic-otel-collector/blob/main/CHANGELOG.md
+[collector_release]: https://github.com/SumoLogic/sumologic-otel-collector/blob/main/docs/release.md
+[release_0]: ../images/release_0.png
+[release_1]: ../images/release_1.png
+[release_1]: ../images/release_2.png
+[releases_workflow]: https://github.com/SumoLogic/sumologic-otel-collector-packaging/actions/workflows/releases.yml
diff --git a/images/release_0.png b/images/release_0.png
new file mode 100644
index 00000000..2847d3ec
Binary files /dev/null and b/images/release_0.png differ
diff --git a/images/release_1.png b/images/release_1.png
new file mode 100644
index 00000000..6e365b97
Binary files /dev/null and b/images/release_1.png differ
diff --git a/images/release_2.png b/images/release_2.png
new file mode 100644
index 00000000..8961b7f5
Binary files /dev/null and b/images/release_2.png differ
diff --git a/install-script/install.ps1 b/install-script/install.ps1
index 92e7c629..75f9d14e 100644
--- a/install-script/install.ps1
+++ b/install-script/install.ps1
@@ -31,11 +31,32 @@ param (
[string] $Api,
# The OpAmp Endpoint used to communicate with the OpAmp backend
- [string] $OpAmpApi
+ [string] $OpAmpApi,
+
+ # OverrideArch overrides the architecture detected by this script. This can
+ # enable installation of x64 packages on an ARM64 system.
+ [string] $OverrideArch,
+
+ # S3Bucket is used to specify which S3 bucket to download the MSI package
+ # from. The default value is set to the value of the S3_BUCKET environment
+ # variable.
+ [string] $S3Bucket = $env:S3_BUCKET,
+
+ # S3Region is used to specify which S3 region to download the MSI package
+ # from. The default value is set to the value of the S3_REGION environment
+ # variable.
+ [string] $S3Region = $env:S3_REGION
)
-$PackageGithubOrg = "SumoLogic"
-$PackageGithubRepo = "sumologic-otel-collector-packaging"
+if ($S3Bucket -eq "") {
+ $S3Bucket = "sumologic-osc-ci-builds"
+}
+
+if ($S3Region -eq "") {
+ $S3Region = "us-west-2"
+}
+
+$S3URI = "https://" + $S3Bucket + ".s3." + $S3Region + ".amazonaws.com"
##
# Security tweaks
@@ -146,6 +167,11 @@ function Get-OSName
}
function Get-ArchName {
+ param (
+ [Parameter(Mandatory, Position=0)]
+ [bool] $AllowUnsupported
+ )
+
Write-Host "Detecting architecture..."
[int] $archId = (Get-CimInstance Win32_Processor)[0].Architecture
@@ -160,13 +186,26 @@ function Get-ArchName {
switch ($arch)
{
+ x86 { $archName = "x86" }
x64 { $archName = "x64" }
+ MIPS { $archName = "MIPS" }
+ Alpha { $archName = "Alpha" }
+ PowerPC { $archName = "PowerPC" }
+ ia64 { $archName = "ia64" }
+ ARM64 { $archName = "ARM64" }
default {
Write-Error "Unsupported architecture:`t${arch}" -ErrorAction Stop
}
}
+ # Only x64 is supported at the moment
+ if (!($AllowUnsupported)) {
+ if ($archName -ne "x64") {
+ Write-Error "Unsupported architecture:`t${archName}" -ErrorAction Stop
+ }
+ }
+
return $archName
}
@@ -210,98 +249,15 @@ function Get-InstalledPackageVersion {
return $package.Version.Replace("-", ".")
}
-function Get-Version {
+function Get-LatestVersion {
param (
- [Parameter(Mandatory, Position=0)]
- [ValidateSet("All", "Latest")]
- [string] $Command,
-
[Parameter(Mandatory, Position=1)]
[HttpClient] $HttpClient
)
- switch ($Command) {
- All {
- $request = [HttpRequestMessage]::new()
- $request.Method = "GET"
- $request.RequestURI = "https://api.github.com/repos/" + $PackageGithubOrg + "/" + $PackageGithubRepo + "/releases"
- $request.Headers.Add("Accept", "application/vnd.github+json")
- $request.Headers.Add("X-GitHub-Api-Version", "2022-11-28")
-
- $response = $HttpClient.SendAsync($request).GetAwaiter().GetResult()
- if (!($response.IsSuccessStatusCode)) {
- $statusCode = [int]$response.StatusCode
- $reasonPhrase = $response.StatusCode.ToString()
- $errMsg = "${statusCode} ${reasonPhrase}"
-
- if ($response.Content -ne $null) {
- $content = $response.Content.ReadAsStringAsync().GetAwaiter().GetResult()
- $errMsg += ": ${content}"
- }
-
- Write-Error $errMsg -ErrorAction Stop
- }
-
- $content = $response.Content.ReadAsStringAsync().GetAwaiter().GetResult()
- $releases = $content | ConvertFrom-Json
- $filtered = @()
-
- foreach ($release in $releases) {
- # Skip draft releases
- if ($release.Draft -eq $true) {
- Write-Debug "Skipping draft release: ${release.Name}"
- continue
- }
-
- # Skip prereleases
- if ($release.Prerelease -eq $true) {
- Write-Debug "Skipping prerelease: ${release.Name}"
- continue
- }
-
- $filtered += $release.Tag_name.TrimStart("v")
- }
-
- return $filtered
- }
-
- Latest {
- $request = [HttpRequestMessage]::new()
- $request.Method = "GET"
- $request.RequestURI = "https://github.com/" + $PackageGithubOrg + "/" + $PackageGithubRepo + "/releases/latest"
- $request.Headers.Add("Accept", "application/json")
-
- $response = $HttpClient.SendAsync($request).GetAwaiter().GetResult()
- if (!($response.IsSuccessStatusCode)) {
- $statusCode = [int]$response.StatusCode
- $reasonPhrase = $response.StatusCode.ToString()
- $errMsg = "${statusCode} ${reasonPhrase}"
-
- if ($response.Content -ne $null) {
- $content = $response.Content.ReadAsStringAsync().GetAwaiter().GetResult()
- $errMsg += ": ${content}"
- }
-
- Write-Error $errMsg -ErrorAction Stop
- }
-
- $content = $response.Content.ReadAsStringAsync().GetAwaiter().GetResult()
- $release = $content | ConvertFrom-Json
-
- return $release.Tag_name.TrimStart("v")
- }
- }
-}
-
-function Get-Changelog {
- param (
- [Parameter(Mandatory, Position=0)]
- [HttpClient] $HttpClient
- )
-
$request = [HttpRequestMessage]::new()
$request.Method = "GET"
- $request.RequestURI = "https://raw.githubusercontent.com/SumoLogic/sumologic-otel-collector/main/CHANGELOG.md"
+ $request.RequestURI = $S3URI + "/latest_version"
$response = $HttpClient.SendAsync($request).GetAwaiter().GetResult()
if (!($response.IsSuccessStatusCode)) {
@@ -317,53 +273,14 @@ function Get-Changelog {
Write-Error $errMsg -ErrorAction Stop
}
- return $response.Content.ReadAsStringAsync().GetAwaiter().GetResult()
+ $content = $response.Content.ReadAsStringAsync().GetAwaiter().GetResult()
+ return $content -replace "`n","" -replace "`r",""
}
-function Show-BreakingChanges {
+function Get-BinaryFromURI {
param (
[Parameter(Mandatory, Position=0)]
- [string[]] $Versions,
-
- [Parameter(Mandatory, Position=1)]
- [string] $Changelog
- )
-
- $splitChangelog = $Changelog -Split "\n"
- $breakingVersions = @()
-
- foreach ($version in $Versions) {
- # Get lines matching the following and join them into a string:
- # * ##
- # * ## Breaking
- # * breaking changes
- $matchingRegex = "^## |^### Breaking|breaking changes"
- $matchingLines = (
- $splitChangelog | Select-String -Pattern $matchingRegex
- ) -Join "`r`n"
-
- # Find the section for $version and get the content between it and the
- # next version section.
- $isBreakingRegex = "(?s)(?<=## \[v${version}\]).*?(?=\r\n## )"
- $isBreakingChange = (
- $matchingLines | Select-String -Pattern $isBreakingRegex
- ).Matches.Value -ne ""
-
- if ($isBreakingChange) {
- $breakingVersions += $version
- }
- }
-
- if ($breakingVersions.Count -gt 0) {
- $versionsStr = $breakingVersions -Join ", v"
- Write-Host "The following versions contain breaking changes: v${versionsStr}! Please make sure to read the linked Changelog file."
- }
-}
-
-function Get-BinaryFromUri {
- param (
- [Parameter(Mandatory, Position=0)]
- [string] $Uri,
+ [string] $URI,
[Parameter(Mandatory, Position=1)]
[string] $Path,
@@ -377,10 +294,10 @@ function Get-BinaryFromUri {
Remove-Item $Path
}
- Write-Host "Preparing to download ${Uri}"
- $requestUri = [System.Uri]$Uri
+ Write-Host "Preparing to download ${URI}"
+ $requestURI = [System.Uri]$URI
$optReadHeaders = [System.Net.Http.HttpCompletionOption]::ResponseHeadersRead
- $response = $HttpClient.GetAsync($requestUri, $optReadHeaders).GetAwaiter().GetResult()
+ $response = $HttpClient.GetAsync($requestURI, $optReadHeaders).GetAwaiter().GetResult()
$responseMsg = $response.EnsureSuccessStatusCode()
$httpStream = $response.Content.ReadAsStreamAsync().GetAwaiter().GetResult()
@@ -391,7 +308,7 @@ function Get-BinaryFromUri {
)
$copier = $httpStream.CopyToAsync($fileStream)
- Write-Host "Downloading ${requestUri}"
+ Write-Host "Downloading ${requestURI}"
$copier.Wait()
$fileStream.Close()
$httpStream.Close()
@@ -409,10 +326,16 @@ try {
}
$osName = Get-OSName
- $archName = Get-ArchName
Write-Host "Detected OS type:`t${osName}"
+
+ $archName = Get-ArchName -AllowUnsupported ($OverrideArch -ne "")
Write-Host "Detected architecture:`t${archName}"
+ if ($OverrideArch -ne "") {
+ $archName = $OverrideArch
+ Write-Host "Architecture overridden: `t${archName}"
+ }
+
$handler = New-Object HttpClientHandler
$handler.AllowAutoRedirect = $true
@@ -443,47 +366,22 @@ try {
Write-Host "Installed app version:`t${installedAppVersionStr}"
Write-Host "Installed package version:`t${installedPackageVersionStr}"
- # Get versions, but ignore errors as we fallback to other methods later
- Write-Host "Getting versions..."
- $versions = Get-Version -Command All -HttpClient $httpClient
-
# Use user's version if set, otherwise get latest version from API (or website)
if ($Version -eq "") {
- if ($versions.Count -eq 1) {
- $Version = $versions
- } elseif ($versions.Count -gt 1) {
- $Version = $versions[0]
- } else {
- $Version = Get-Version -Command Latest -HttpClient $httpClient
- }
+ Write-Host "Getting latest version..."
+ $Version = Get-LatestVersion -HttpClient $httpClient
}
- # tags in the packaging repository have a dash before the build number, the Windows convention is a stop
- $Tag = $Version
- $Version = $Version.Replace("-", ".")
+ # versions have a dash before the build number, the Windows convention is a dot
+ $msiVersion = $Version.Replace("-", ".")
Write-Host "Package version to install:`t${Version}"
# Check if otelcol is already in newest version
- if ($installedPackageVersion -eq $Version) {
- Write-Host "OpenTelemetry collector is already in newest (${Version}) version"
- } else {
- # add newline before breaking changes and changelog
- Write-Host ""
- if (($installedVersion -ne "") -And ($versions -ne $null)) {
- # Take versions from installed up to the newest
- $index = $versions.IndexOf($installedVersion)
- if ($index -gt 0) {
- $changelog = Get-Changelog $httpClient
- Show-BreakingChanges $versions[0..($index-1)] $changelog
- }
- }
+ if ($installedPackageVersion -eq $msiVersion) {
+ Write-Host "OpenTelemetry collector is already in newest (${msiVersion}) version"
}
- Write-Host "Changelog:`t`thttps://github.com/SumoLogic/sumologic-otel-collector/blob/main/CHANGELOG.md"
- # add newline after breaking changes and changelog
- Write-Host ""
-
# Add -fips to the msi filename if necessary
$fipsSuffix = ""
if ($Fips -eq $true) {
@@ -493,11 +391,10 @@ try {
# Download MSI
$msiLanguage = "en-US"
- $msiFileName = "otelcol-sumo_${Version}_${msiLanguage}.${archName}${fipsSuffix}.msi"
- $msiUri = "https://github.com/" + $PackageGithubOrg + "/" + $PackageGithubRepo + "/releases/download/"
- $msiUri += "v${Tag}/${msiFileName}"
+ $msiFileName = "otelcol-sumo_${msiVersion}_${msiLanguage}.${archName}${fipsSuffix}.msi"
+ $msiURI = $S3URI + "/" + $Version + "/" + $msiFileName
$msiPath = "${env:TEMP}\${msiFileName}"
- Get-BinaryFromUri $msiUri -Path $msiPath -HttpClient $httpClient
+ Get-BinaryFromURI $msiURI -Path $msiPath -HttpClient $httpClient
# Install MSI
[string[]] $msiProperties = @()
@@ -533,4 +430,6 @@ try {
msiexec.exe /i "$msiPath" /passive $msiProperties
} catch [HttpRequestException] {
Write-Error $_.Exception.InnerException.Message
-}
\ No newline at end of file
+}
+
+Write-Host "Installation successful"
diff --git a/install-script/install.sh b/install-script/install.sh
index 433a7440..a80a2294 100755
--- a/install-script/install.sh
+++ b/install-script/install.sh
@@ -21,10 +21,10 @@ ARG_SHORT_FIPS='f'
ARG_LONG_FIPS='fips'
ARG_SHORT_YES='y'
ARG_LONG_YES='yes'
-ARG_SHORT_SKIP_CONFIG='s'
-ARG_LONG_SKIP_CONFIG='skip-config'
ARG_SHORT_UNINSTALL='u'
ARG_LONG_UNINSTALL='uninstall'
+ARG_SHORT_UPGRADE='g'
+ARG_LONG_UPGRADE='upgrade'
ARG_SHORT_PURGE='p'
ARG_LONG_PURGE='purge'
ARG_SHORT_SKIP_TOKEN='k'
@@ -51,22 +51,19 @@ ARG_LONG_EPHEMERAL='ephemeral'
ARG_SHORT_TIMEOUT='m'
ARG_LONG_TIMEOUT='download-timeout'
-PACKAGE_GITHUB_ORG="SumoLogic"
-PACKAGE_GITHUB_REPO="sumologic-otel-collector-packaging"
-
readonly ARG_SHORT_TOKEN ARG_LONG_TOKEN ARG_SHORT_HELP ARG_LONG_HELP ARG_SHORT_API ARG_LONG_API
readonly ARG_SHORT_TAG ARG_LONG_TAG ARG_SHORT_VERSION ARG_LONG_VERSION ARG_SHORT_YES ARG_LONG_YES
readonly ARG_SHORT_UNINSTALL ARG_LONG_UNINSTALL
+readonly ARG_SHORT_UPGRADE ARG_LONG_UPGRADE
readonly ARG_SHORT_PURGE ARG_LONG_PURGE ARG_SHORT_DOWNLOAD ARG_LONG_DOWNLOAD
readonly ARG_SHORT_CONFIG_BRANCH ARG_LONG_CONFIG_BRANCH ARG_SHORT_BINARY_BRANCH ARG_LONG_CONFIG_BRANCH
-readonly ARG_SHORT_BRANCH ARG_LONG_BRANCH ARG_SHORT_SKIP_CONFIG ARG_LONG_SKIP_CONFIG
+readonly ARG_SHORT_BRANCH ARG_LONG_BRANCH
readonly ARG_SHORT_SKIP_TOKEN ARG_LONG_SKIP_TOKEN ARG_SHORT_FIPS ARG_LONG_FIPS ENV_TOKEN
readonly ARG_SHORT_INSTALL_HOSTMETRICS ARG_LONG_INSTALL_HOSTMETRICS
readonly ARG_SHORT_REMOTELY_MANAGED ARG_LONG_REMOTELY_MANAGED
readonly ARG_SHORT_EPHEMERAL ARG_LONG_EPHEMERAL
readonly ARG_SHORT_TIMEOUT ARG_LONG_TIMEOUT
readonly DEPRECATED_ARG_LONG_TOKEN DEPRECATED_ENV_TOKEN DEPRECATED_ARG_LONG_SKIP_TOKEN
-readonly PACKAGE_GITHUB_ORG PACKAGE_GITHUB_REPO
############################ Variables (see set_defaults function for default values)
@@ -89,10 +86,8 @@ CONTINUE=false
CONFIG_DIRECTORY=""
USER_ENV_DIRECTORY=""
UNINSTALL=""
+UPGRADE=""
SUMO_BINARY_PATH=""
-SKIP_TOKEN=""
-SKIP_CONFIG=false
-CONFIG_PATH=""
COMMON_CONFIG_PATH=""
PURGE=""
DOWNLOAD_ONLY=""
@@ -115,6 +110,15 @@ KEEP_DOWNLOADS=false
CURL_MAX_TIME=1800
+# NB: the S3 variables are only used on Darwin
+S3_BUCKET="${S3_BUCKET:-sumologic-osc-ci-builds}"
+S3_REGION="${S3_REGION:-us-west-2}"
+S3_URI="https://${S3_BUCKET}.s3.${S3_REGION}.amazonaws.com"
+
+PACKAGECLOUD_ORG="${PACKAGECLOUD_ORG:-sumologic}"
+PACKAGECLOUD_REPO="${PACKAGECLOUD_REPO:-stable}"
+PACKAGECLOUD_MASTER_TOKEN="${PACKAGECLOUD_MASTER_TOKEN:-}"
+
############################ Functions
function usage() {
@@ -130,6 +134,7 @@ Supported arguments:
-${ARG_SHORT_TAG}, --${ARG_LONG_TAG} Sets tag for collector. This argument can be use multiple times. One per tag.
-${ARG_SHORT_DOWNLOAD}, --${ARG_LONG_DOWNLOAD} Download new binary only and skip configuration part. (Mac OS only)
+ -${ARG_SHORT_UPGRADE}, --${ARG_LONG_UPGRADE} Upgrades the collector using the system package manager.
-${ARG_SHORT_UNINSTALL}, --${ARG_LONG_UNINSTALL} Removes Sumo Logic Distribution for OpenTelemetry Collector from the system and
disable Systemd service eventually.
Use with '--purge' to remove all configurations as well.
@@ -138,7 +143,6 @@ Supported arguments:
-${ARG_SHORT_API}, --${ARG_LONG_API} API URL, forces the collector to use non-default API
-${ARG_SHORT_OPAMP_API}, --${ARG_LONG_OPAMP_API} OpAmp API URL, forces the collector to use non-default OpAmp API
- -${ARG_SHORT_SKIP_CONFIG}, --${ARG_LONG_SKIP_CONFIG} Do not create default configuration.
-${ARG_SHORT_VERSION}, --${ARG_LONG_VERSION} Version of Sumo Logic Distribution for OpenTelemetry Collector to install, e.g. 0.57.2-sumo-1.
By default it gets latest version.
-${ARG_SHORT_FIPS}, --${ARG_LONG_FIPS} Install the FIPS 140-2 compliant binary on Linux.
@@ -159,10 +163,8 @@ function set_defaults() {
DOWNLOAD_CACHE_DIR="/var/cache/otelcol-sumo" # this is in case we want to keep downloaded binaries
CONFIG_DIRECTORY="/etc/otelcol-sumo"
SUMO_BINARY_PATH="/usr/local/bin/otelcol-sumo"
- REMOTE_CONFIG_DIRECTORY="${CONFIG_DIRECTORY}/opamp.d"
USER_ENV_DIRECTORY="${CONFIG_DIRECTORY}/env"
TOKEN_ENV_FILE="${USER_ENV_DIRECTORY}/token.env"
- CONFIG_PATH="${CONFIG_DIRECTORY}/sumologic.yaml"
LAUNCHD_CONFIG="/Library/LaunchDaemons/com.sumologic.otelcol-sumo.plist"
LAUNCHD_ENV_KEY="EnvironmentVariables"
@@ -173,12 +175,6 @@ function set_defaults() {
}
function parse_options() {
- if [[ $# == 0 && -z "${SUMOLOGIC_INSTALLATION_TOKEN}" ]]; then
- echo "Installation token has not been provided. Please set the 'SUMOLOGIC_INSTALLATION_TOKEN' environment variable."
- usage
- exit 2
- fi
-
# Transform long options to short ones
for arg in "$@"; do
@@ -206,9 +202,6 @@ function parse_options() {
"--${ARG_LONG_YES}")
set -- "$@" "-${ARG_SHORT_YES}"
;;
- "--${ARG_LONG_SKIP_CONFIG}")
- set -- "$@" "-${ARG_SHORT_SKIP_CONFIG}"
- ;;
"--${ARG_LONG_VERSION}")
set -- "$@" "-${ARG_SHORT_VERSION}"
;;
@@ -218,10 +211,14 @@ function parse_options() {
"--${ARG_LONG_UNINSTALL}")
set -- "$@" "-${ARG_SHORT_UNINSTALL}"
;;
+ "--${ARG_LONG_UPGRADE}")
+ set -- "$@" "-${ARG_SHORT_UPGRADE}"
+ ;;
"--${ARG_LONG_PURGE}")
set -- "$@" "-${ARG_SHORT_PURGE}"
;;
"--${ARG_LONG_SKIP_TOKEN}")
+ echo "--${ARG_LONG_SKIP_TOKEN}" is deprecated and no longer affects the installation. An installation token is required.
set -- "$@" "-${ARG_SHORT_SKIP_TOKEN}"
;;
"--${DEPRECATED_ARG_LONG_SKIP_TOKEN}")
@@ -246,7 +243,7 @@ function parse_options() {
"--${ARG_LONG_TIMEOUT}")
set -- "$@" "-${ARG_SHORT_TIMEOUT}"
;;
- "-${ARG_SHORT_TOKEN}"|"-${ARG_SHORT_HELP}"|"-${ARG_SHORT_API}"|"-${ARG_SHORT_OPAMP_API}"|"-${ARG_SHORT_TAG}"|"-${ARG_SHORT_SKIP_CONFIG}"|"-${ARG_SHORT_VERSION}"|"-${ARG_SHORT_FIPS}"|"-${ARG_SHORT_YES}"|"-${ARG_SHORT_UNINSTALL}"|"-${ARG_SHORT_PURGE}"|"-${ARG_SHORT_SKIP_TOKEN}"|"-${ARG_SHORT_DOWNLOAD}"|"-${ARG_SHORT_CONFIG_BRANCH}"|"-${ARG_SHORT_BINARY_BRANCH}"|"-${ARG_SHORT_BRANCH}"|"-${ARG_SHORT_KEEP_DOWNLOADS}"|"-${ARG_SHORT_TIMEOUT}"|"-${ARG_SHORT_INSTALL_HOSTMETRICS}"|"-${ARG_SHORT_REMOTELY_MANAGED}"|"-${ARG_SHORT_EPHEMERAL}")
+ "-${ARG_SHORT_TOKEN}"|"-${ARG_SHORT_HELP}"|"-${ARG_SHORT_API}"|"-${ARG_SHORT_OPAMP_API}"|"-${ARG_SHORT_TAG}"|"-${ARG_SHORT_VERSION}"|"-${ARG_SHORT_FIPS}"|"-${ARG_SHORT_YES}"|"-${ARG_SHORT_UNINSTALL}"|"-${ARG_SHORT_UPGRADE}"|"-${ARG_SHORT_PURGE}"|"-${ARG_SHORT_SKIP_TOKEN}"|"-${ARG_SHORT_DOWNLOAD}"|"-${ARG_SHORT_CONFIG_BRANCH}"|"-${ARG_SHORT_BINARY_BRANCH}"|"-${ARG_SHORT_BRANCH}"|"-${ARG_SHORT_KEEP_DOWNLOADS}"|"-${ARG_SHORT_TIMEOUT}"|"-${ARG_SHORT_INSTALL_HOSTMETRICS}"|"-${ARG_SHORT_REMOTELY_MANAGED}"|"-${ARG_SHORT_EPHEMERAL}")
set -- "$@" "${arg}"
;;
"--${ARG_LONG_INSTALL_HOSTMETRICS}")
@@ -270,7 +267,7 @@ function parse_options() {
while true; do
set +e
- getopts "${ARG_SHORT_HELP}${ARG_SHORT_TOKEN}:${ARG_SHORT_API}:${ARG_SHORT_OPAMP_API}:${ARG_SHORT_TAG}:${ARG_SHORT_VERSION}:${ARG_SHORT_FIPS}${ARG_SHORT_YES}${ARG_SHORT_UNINSTALL}${ARG_SHORT_PURGE}${ARG_SHORT_SKIP_TOKEN}${ARG_SHORT_SKIP_CONFIG}${ARG_SHORT_DOWNLOAD}${ARG_SHORT_KEEP_DOWNLOADS}${ARG_SHORT_CONFIG_BRANCH}:${ARG_SHORT_BINARY_BRANCH}:${ARG_SHORT_BRANCH}:${ARG_SHORT_EPHEMERAL}${ARG_SHORT_REMOTELY_MANAGED}${ARG_SHORT_INSTALL_HOSTMETRICS}${ARG_SHORT_TIMEOUT}:" opt
+ getopts "${ARG_SHORT_HELP}${ARG_SHORT_TOKEN}:${ARG_SHORT_API}:${ARG_SHORT_OPAMP_API}:${ARG_SHORT_TAG}:${ARG_SHORT_VERSION}:${ARG_SHORT_FIPS}${ARG_SHORT_YES}${ARG_SHORT_UPGRADE}${ARG_SHORT_UNINSTALL}${ARG_SHORT_PURGE}${ARG_SHORT_SKIP_TOKEN}${ARG_SHORT_DOWNLOAD}${ARG_SHORT_KEEP_DOWNLOADS}${ARG_SHORT_CONFIG_BRANCH}:${ARG_SHORT_BINARY_BRANCH}:${ARG_SHORT_BRANCH}:${ARG_SHORT_EPHEMERAL}${ARG_SHORT_REMOTELY_MANAGED}${ARG_SHORT_INSTALL_HOSTMETRICS}${ARG_SHORT_TIMEOUT}:" opt
set -e
# Invalid argument catched, print and exit
@@ -286,13 +283,12 @@ function parse_options() {
"${ARG_SHORT_TOKEN}") SUMOLOGIC_INSTALLATION_TOKEN="${OPTARG}" ;;
"${ARG_SHORT_API}") API_BASE_URL="${OPTARG}" ;;
"${ARG_SHORT_OPAMP_API}") OPAMP_API_URL="${OPTARG}" ;;
- "${ARG_SHORT_SKIP_CONFIG}") SKIP_CONFIG=true ;;
"${ARG_SHORT_VERSION}") VERSION="${OPTARG}" ;;
"${ARG_SHORT_FIPS}") FIPS=true ;;
"${ARG_SHORT_YES}") CONTINUE=true ;;
"${ARG_SHORT_UNINSTALL}") UNINSTALL=true ;;
+ "${ARG_SHORT_UPGRADE}") UPGRADE=true ;;
"${ARG_SHORT_PURGE}") PURGE=true ;;
- "${ARG_SHORT_SKIP_TOKEN}") SKIP_TOKEN=true ;;
"${ARG_SHORT_DOWNLOAD}") DOWNLOAD_ONLY=true ;;
"${ARG_SHORT_CONFIG_BRANCH}") CONFIG_BRANCH="${OPTARG}" ;;
"${ARG_SHORT_BINARY_BRANCH}") BINARY_BRANCH="${OPTARG}" ;;
@@ -318,11 +314,6 @@ function parse_options() {
done
}
-# Get github rate limit
-function github_rate_limit() {
- curl --retry 5 --connect-timeout 5 --max-time 30 --retry-delay 0 --retry-max-time 150 -X GET https://api.github.com/rate_limit -v 2>&1 | grep x-ratelimit-remaining | grep -oE "[0-9]+"
-}
-
# Ensure TMPDIR is set to a directory where we can safely store temporary files
function set_tmpdir() {
# generate a new tmpdir using mktemp
@@ -339,7 +330,7 @@ function check_dependencies() {
error=1
fi
- REQUIRED_COMMANDS=(echo sed curl head grep sort mv chmod getopts hostname touch xargs)
+ REQUIRED_COMMANDS=(echo sed curl head grep sort mv getopts hostname touch xargs)
if [[ -n "${BINARY_BRANCH}" ]]; then # unzip is only necessary for downloading from GHA artifacts
REQUIRED_COMMANDS+=(unzip)
fi
@@ -356,105 +347,11 @@ function check_dependencies() {
fi
}
-function get_latest_package_version() {
- local versions
- readonly versions="${1}"
-
- # get latest version directly from website if there is no versions from api
- if [[ -z "${versions}" ]]; then
- curl --retry 5 --connect-timeout 5 --max-time 30 --retry-delay 0 \
- --retry-max-time 150 -s \
- "https://github.com/${PACKAGE_GITHUB_ORG}/${PACKAGE_GITHUB_REPO}/releases" \
- | grep -oE '/'${PACKAGE_GITHUB_ORG}'/'${PACKAGE_GITHUB_REPO}'/releases/tag/(.*)"' \
- | head -n 1 \
- | sed 's%/'${PACKAGE_GITHUB_ORG}'/'${PACKAGE_GITHUB_REPO}'/releases/tag/v\([^"]*\)".*%\1%g'
- else
- # sed 's/ /\n/g' converts spaces to new lines
- echo "${versions}" | sed 's/ /\n/g' | head -n 1
- fi
-}
-
-function get_latest_version() {
- local versions
- readonly versions="${1}"
-
- # get latest version directly from website if there is no versions from api
- if [[ -z "${versions}" ]]; then
- curl --retry 5 --connect-timeout 5 --max-time 30 --retry-delay 5 --retry-max-time 150 -s https://github.com/SumoLogic/sumologic-otel-collector/releases \
- | grep -Eo '/SumoLogic/sumologic-otel-collector/releases/tag/v[0-9]+\.[0-9]+\.[0-9]+-sumo-[0-9]+[^-]' \
- | head -n 1 | sed 's%/SumoLogic/sumologic-otel-collector/releases/tag/v\([^"]*\)".*%\1%g'
- else
- # sed 's/ /\n/g' converts spaces to new lines
- echo "${versions}" | sed 's/ /\n/g' | head -n 1
- fi
-}
-
-# Get available versions of otelcol-sumo
-# skip prerelease and draft releases
-# sort it from last to first
-# remove v from beginning of version
-function get_versions() {
- # returns empty in case we exceeded github rate limit
- if [[ "$(github_rate_limit)" == "0" ]]; then
- return
- fi
-
- curl \
- --connect-timeout 5 \
- --max-time 30 \
- --retry 5 \
- --retry-delay 0 \
- --retry-max-time 150 \
- -sH "Accept: application/vnd.github.v3+json" \
- https://api.github.com/repos/SumoLogic/sumologic-otel-collector/releases \
- | grep -E '(tag_name|"(draft|prerelease)")' \
- | sed 'N;N;s/.*true.*//' \
- | grep -o 'v.*"' \
- | sort -rV \
- | sed 's/^v//;s/"$//'
-}
-
-function get_package_versions() {
- # returns empty in case we exceeded github rate limit. This can happen if we are running this script too many times in a short period.
- if [[ "$(github_rate_limit)" == "0" ]]; then
- return
- fi
-
- curl \
- --connect-timeout 5 \
- --max-time 30 \
- --retry 5 \
- --retry-delay 0 \
- --retry-max-time 150 \
- -sH "Accept: application/vnd.github.v3+json" \
- https://api.github.com/repos/${PACKAGE_GITHUB_ORG}/${PACKAGE_GITHUB_REPO}/releases \
- | grep -E '(tag_name|"(draft|prerelease)")' \
- | sed 'N;N;s/.*true.*//' \
- | grep -o 'v.*"' \
- | sort -rV \
- | sed 's/^v//;s/"$//'
-}
-
-# Get versions from provided one to the latest
-get_versions_from() {
- local versions
- readonly versions="${1}"
-
- local from
- readonly from="${2}"
-
- # Return if there is no installed version
- if [[ "${from}" == "" ]]; then
- return 0
- fi
-
- local line
- readonly line="$(( $(echo "${versions}" | sed 's/ /\n/g' | grep -n "${from}$" | sed 's/:.*//g') - 1 ))"
-
- if [[ "${line}" -gt "0" ]]; then
- echo "${versions}" | sed 's/ /\n/g' | head -n "${line}" | sort
- fi
- return 0
+# NB: this function is only for Darwin
+function get_latest_s3_package_version() {
+ curl --retry 5 --connect-timeout 5 --max-time 30 --retry-delay 0 \
+ --retry-max-time 150 -s \
+ "${S3_URI}/latest_version" | tr -d '\n'
}
# Get OS type (linux or darwin)
@@ -515,15 +412,6 @@ function verify_installation() {
echo -e "Installation succeded:\t$(${otel_command} --version)"
}
-# Get installed version of otelcol-sumo
-function get_installed_version() {
- if [[ -f "${SUMO_BINARY_PATH}" ]]; then
- set +o pipefail
- "${SUMO_BINARY_PATH}" --version | grep -o 'v[0-9].*$' | sed 's/v//'
- set -o pipefail
- fi
-}
-
# Ask to continue and abort if not
function ask_to_continue() {
if [[ "${CONTINUE}" == true ]]; then
@@ -533,7 +421,7 @@ function ask_to_continue() {
# Just fail if we're not running in uninteractive mode
# TODO: Figure out a way to reliably ask for confirmation with stdin redirected
- echo "Please use the --yes flag to continue"
+ echo "Please use the -y flag to continue"
exit 1
# local choice
@@ -548,47 +436,14 @@ function ask_to_continue() {
}
-# Print information about breaking changes
-function print_breaking_changes() {
- local versions
- readonly versions="${1}"
-
- local changelog
- changelog="$(echo -e "$(curl --retry 5 --connect-timeout 5 --max-time 30 --retry-delay 0 --retry-max-time 150 -sS https://raw.githubusercontent.com/SumoLogic/sumologic-otel-collector/main/CHANGELOG.md)")"
- declare -r changelog
-
- local is_breaking_change
- local message
- message=""
-
- for version in ${versions}; do
- # Print changelog for every version
- is_breaking_change=$(echo -e "${changelog}" | grep -E '^## |^### Breaking|breaking changes' | sed -e '/## \[v'"${version}"'/,/## \[v/!d' | grep -E 'Breaking|breaking' || echo "")
-
- if [[ -n "${is_breaking_change}" ]]; then
- if [[ -n "${message}" ]]; then
- message="${message}, "
- fi
- message="${message}v${version}"
- fi
- done
-
- if [[ -n "${message}" ]]; then
- echo "The following versions contain breaking changes: ${message}! Please make sure to read the linked Changelog file."
- fi
-}
-
# set up configuration
function setup_config() {
echo 'We are going to get and set up a default configuration for you'
- echo "Generating configuration and saving as ${CONFIG_PATH}"
+ echo "Generating configuration and saving it in ${CONFIG_DIRECTORY}"
if [[ "${REMOTELY_MANAGED}" == "true" ]]; then
echo "Warning: remote management is currently in beta."
- echo -e "Creating remote configurations directory (${REMOTE_CONFIG_DIRECTORY})"
- mkdir -p "${REMOTE_CONFIG_DIRECTORY}"
-
write_opamp_extension
if [[ -n "${SUMOLOGIC_INSTALLATION_TOKEN}" ]]; then
@@ -607,26 +462,24 @@ function setup_config() {
write_opamp_endpoint "${OPAMP_API_URL}"
fi
- write_tags "${FIELDS[@]}"
+ if [[ ${#FIELDS[@]} -gt 0 ]]; then
+ write_tags "${FIELDS[@]}"
+ fi
- # Return/stop function execution
+ # Return/stop function execution early as remaining logic only applies
+ # to locally-managed installations
return
fi
if [[ "${INSTALL_HOSTMETRICS}" == "true" ]]; then
echo -e "Installing ${OS_TYPE} hostmetrics configuration"
otelcol-config --enable-hostmetrics
- if [[ "${OS_TYPE}" == "linux" ]]; then
- echo -e "Setting the CAP_DAC_READ_SEARCH Linux capability on the collector binary to allow it to read host metrics from /proc directory: setcap 'cap_dac_read_search=ep' \"${SUMO_BINARY_PATH}\""
- echo -e "You can remove it with the following command: sudo setcap -r \"${SUMO_BINARY_PATH}\""
- echo -e "Without this capability, the collector will not be able to collect some of the host metrics."
- # TODO(echlebek): remove this when it's supported in packaging
- setcap 'cap_dac_read_search=ep' "${SUMO_BINARY_PATH}"
- fi
fi
## Check if there is anything to update in configuration
if [[ -n "${SUMOLOGIC_INSTALLATION_TOKEN}" || -n "${API_BASE_URL}" || ${#FIELDS[@]} -ne 0 || "${EPHEMERAL}" == "true" ]]; then
+ USER_TOKEN="$(get_user_token)"
+
if [[ -n "${SUMOLOGIC_INSTALLATION_TOKEN}" && -z "${USER_TOKEN}" ]]; then
write_installation_token "${SUMOLOGIC_INSTALLATION_TOKEN}"
fi
@@ -635,51 +488,54 @@ function setup_config() {
write_ephemeral_true
fi
- # fill in api base url
if [[ -n "${API_BASE_URL}" && -z "${USER_API_URL}" ]]; then
write_api_url "${API_BASE_URL}"
fi
- # fill in opamp url
- if [[ -n "${OPAMP_API_URL}" && -z "${USER_OPAMP_API_URL}" ]]; then
- write_opamp_extension
- write_opamp_endpoint "${OPAMP_API_URL}"
+ if [[ ${#FIELDS[@]} -gt 0 ]]; then
+ write_tags "${FIELDS[@]}"
fi
-
- write_tags "${FIELDS[@]}"
fi
}
function setup_config_darwin() {
+ echo 'We are going to get and set up a default configuration for you'
+
+ echo "Generating configuration and saving it in ${CONFIG_DIRECTORY}"
+ if [[ "${REMOTELY_MANAGED}" == "true" ]]; then
+ echo "Warning: remote management is currently in beta."
+
+ write_opamp_extension
+
+ if [[ -n "${OPAMP_API_URL}" ]]; then
+ write_opamp_endpoint "${OPAMP_API_URL}"
+ fi
+ fi
+
if [[ "${EPHEMERAL}" == "true" ]]; then
write_ephemeral_true
fi
- # fill in api base url
- if [[ -n "${API_BASE_URL}" ]]; then
+ if [[ -n "${API_BASE_URL}" ]]; then
write_api_url "${API_BASE_URL}"
+ elif [[ -n "${USER_API_URL}" ]]; then
+ write_api_url "${USER_API_URL}"
fi
- write_tags "${FIELDS[@]}"
+ if [[ ${#FIELDS[@]} -gt 0 ]]; then
+ write_tags "${FIELDS[@]}"
+ fi
+ # Return/stop function execution early as remaining logic only applies to
+ # locally-managed installations
if [[ "${REMOTELY_MANAGED}" == "true" ]]; then
- echo "Warning: remote management is currently in beta."
-
- echo -e "Creating remote configurations directory (${REMOTE_CONFIG_DIRECTORY})"
- # TODO(echlebek): remove this once packaging does it
- mkdir -p "${REMOTE_CONFIG_DIRECTORY}"
-
- write_opamp_extension
-
- write_remote_config_launchd "${LAUNCHD_CONFIG}"
-
- # Remote configuration directory must be writable
- chmod 750 "${REMOTE_CONFIG_DIRECTORY}"
-
- # Remote configuration directory must be owned by the mac pkg service user
- chown _otelcol-sumo:_otelcol-sumo "${REMOTE_CONFIG_DIRECTORY}"
+ return
fi
+ if [[ "${INSTALL_HOSTMETRICS}" == "true" ]]; then
+ echo -e "Installing ${OS_TYPE} hostmetrics configuration"
+ otelcol-config --enable-hostmetrics
+ fi
}
# uninstall otelcol-sumo
@@ -696,6 +552,29 @@ function uninstall() {
echo "Uninstallation completed"
}
+function upgrade() {
+ case "${OS_TYPE}" in
+ "linux") upgrade_linux ;;
+ *)
+ echo "upgrading is not supported by this script for OS: ${OS_TYPE}"
+ exit 1
+ ;;
+ esac
+
+}
+
+function upgrade_linux() {
+ case $(get_package_manager) in
+ yum | dnf)
+ yum update --quiet -y
+ ;;
+ apt-get)
+ apt-get update --quiet && apt-get upgrade --quiet -y
+ ;;
+ esac
+
+}
+
# uninstall otelcol-sumo on darwin
function uninstall_darwin() {
local UNINSTALL_SCRIPT_PATH
@@ -716,7 +595,7 @@ function uninstall_darwin() {
function uninstall_linux() {
case $(get_package_manager) in
yum | dnf)
- yum remove --quiet -y otelcol-sumo
+ yum remove --quiet -yes otelcol-sumo
;;
apt-get)
if [[ "${PURGE}" == "true" ]]; then
@@ -728,16 +607,6 @@ function uninstall_linux() {
esac
}
-function escape_sed() {
- local text
- readonly text="${1}"
-
- # replaces `\` with `\\` and `/` with `\/`
- echo "${text}" \
- | sed -e 's/\\/\\\\/g' \
- | sed -e 's|/|\\/|g'
-}
-
function get_user_env_config() {
local file
readonly file="${1}"
@@ -764,12 +633,37 @@ function get_user_env_config() {
|| echo ""
}
+function get_launchd_token() {
+ local file
+ readonly file="${1}"
+
+ if [[ "${OS_TYPE}" != "darwin" ]]; then
+ return
+ fi
+
+ if [[ ! -f "${file}" ]]; then
+ return
+ fi
+
+ plutil_extract_key "${file}" "${LAUNCHD_TOKEN_KEY}"
+}
+
function get_user_api_url() {
- otelcol-config --read-kv .extensions.sumologic.api_base_url
+ if command -v otelcol-config &> /dev/null; then
+ KV=$(otelcol-config --read-kv .extensions.sumologic.api_base_url)
+ if [[ "${KV}" != "null" ]]; then
+ echo "${KV}"
+ fi
+ fi
}
function get_user_opamp_endpoint() {
- otelcol-config --read-kv .extensions.opamp.endpoint
+ if command -v otelcol-config &> /dev/null; then
+ KV=$(otelcol-config --read-kv .extensions.opamp.endpoint)
+ if [[ "${KV}" != "null" ]]; then
+ echo "${KV}"
+ fi
+ fi
}
# write installation token to user configuration file
@@ -780,27 +674,6 @@ function write_installation_token() {
otelcol-config --set-installation-token "$token"
}
-# write ${ENV_TOKEN}" to systemd env configuration file
-function write_installation_token_env() {
- local token
- readonly token="${1}"
-
- local file
- readonly file="${2}"
-
- local token_name
- token_name="${ENV_TOKEN}"
- readonly token_name
-
- # ToDo: ensure we override only ${ENV_TOKEN}" env value
- if grep "${token_name}" "${file}" > /dev/null 2>&1; then
- # Do not expose token in sed command as it can be saw on processes list
- echo "s/${token_name}=.*$/${token_name}=$(escape_sed "${token}")/" | sed -i.bak -f - "${file}"
- else
- echo "${token_name}=${token}" > "${file}"
- fi
-}
-
# write ${ENV_TOKEN} to launchd configuration file
function write_installation_token_launchd() {
local token
@@ -824,33 +697,15 @@ function write_installation_token_launchd() {
plutil_replace_key "${file}" "${LAUNCHD_ENV_KEY}" "xml" ""
fi
- # Create SUMOLOGIC_INSTALLATION_TOKEN key if it does not exist
+ # Create SUMOLOGIC_INSTALLATION_TOKEN key if it does not exist otherwise
+ # replace the SUMOLOGIC_INSTALLATION_TOKEN key
if ! plutil_key_exists "${file}" "${LAUNCHD_TOKEN_KEY}"; then
- plutil_create_key "${file}" "${LAUNCHD_TOKEN_KEY}" "string" "${SUMOLOGIC_INSTALLATION_TOKEN}"
- fi
-
- # Replace SUMOLOGIC_INSTALLATION_TOKEN key if it has an incorrect type
- if ! plutil_key_is_type "${LAUNCHD_CONFIG}" "${LAUNCHD_TOKEN_KEY}" "string"; then
- plutil_replace_key "${LAUNCHD_CONFIG}" "${LAUNCHD_TOKEN_KEY}" "string" "${SUMOLOGIC_INSTALLATION_TOKEN}"
+ plutil_create_key "${file}" "${LAUNCHD_TOKEN_KEY}" "string" "${token}"
+ else
+ plutil_replace_key "${file}" "${LAUNCHD_TOKEN_KEY}" "string" "${token}"
fi
}
-function write_remote_config_launchd() {
- local file
- readonly file="${1}"
-
- if [[ ! -f "${file}" ]]; then
- echo "The LaunchDaemon configuration file is missing: ${file}"
- exit 1
- fi
-
- # Delete existing ProgramArguments
- plutil_delete_key "${file}" "ProgramArguments"
-
- # Create new ProgramArguments with --remote-config
- plutil_create_key "${file}" "ProgramArguments" "json" "[ \"/usr/local/bin/otelcol-sumo\", \"--remote-config\", \"opamp:${CONFIG_PATH}\" ]"
-}
-
# write sumologic ephemeral: true to user configuration file
function write_ephemeral_true() {
otelcol-config --enable-ephemeral
@@ -887,81 +742,6 @@ function write_opamp_extension() {
}
# NB: this function is only for Darwin
-function get_package_from_branch() {
- local branch
- readonly branch="${1}"
-
- local name
- readonly name="${2}"
-
- local actions_url actions_output artifacts_link artifact_id
- readonly actions_url="https://api.github.com/repos/${PACKAGE_GITHUB_ORG}/${PACKAGE_GITHUB_REPO}/actions/runs?status=success&branch=${branch}&event=push&per_page=1"
- echo -e "Getting artifacts from latest CI run for branch \"${branch}\":\t\t${actions_url}"
- actions_output="$(curl -f -sS \
- --connect-timeout 5 \
- --max-time 30 \
- --retry 5 \
- --retry-delay 0 \
- --retry-max-time 150 \
- -H "Accept: application/vnd.github+json" \
- -H "Authorization: token ${GITHUB_TOKEN}" \
- "${actions_url}")"
- readonly actions_output
-
- # get latest action run
- artifacts_link="$(echo "${actions_output}" | grep '"url"' | grep -oE '"https.*packaging/actions.*"' -m 1)"
-
- # strip first and last double-quote from $artifacts_link
- artifacts_link=${artifacts_link%\"}
- artifacts_link="${artifacts_link#\"}"
- artifacts_link="${artifacts_link}/artifacts"
- readonly artifacts_link
-
- echo -e "Getting artifact id for CI run:\t\t${artifacts_link}"
- artifact_id="$(curl -f -sS \
- --connect-timeout 5 \
- --max-time 30 \
- --retry 5 \
- --retry-delay 0 \
- --retry-max-time 150 \
- -H "Accept: application/vnd.github+json" \
- -H "Authorization: token ${GITHUB_TOKEN}" \
- "${artifacts_link}" \
- | grep -E '"(id|name)"' \
- | grep -B 1 "\"${name}\"" -m 1 \
- | grep -oE "[0-9]+" -m 1)"
- readonly artifact_id
-
- echo "Artifact ID: ${artifact_id}"
-
- local artifact_url download_path curl_args
- readonly artifact_url="https://api.github.com/repos/${PACKAGE_GITHUB_ORG}/${PACKAGE_GITHUB_REPO}/actions/artifacts/${artifact_id}/zip"
- readonly download_path="${DOWNLOAD_CACHE_DIR}/${artifact_id}.zip"
- echo -e "Downloading package from: ${artifact_url}"
- curl_args=(
- "-fL"
- "--connect-timeout" "5"
- "--max-time" "${CURL_MAX_TIME}"
- "--retry" "5"
- "--retry-delay" "0"
- "--retry-max-time" "150"
- "--output" "${download_path}"
- "--progress-bar"
- )
- if [ "${KEEP_DOWNLOADS}" == "true" ]; then
- curl_args+=("-z" "${download_path}")
- fi
- curl "${curl_args[@]}" \
- -H "Accept: application/vnd.github+json" \
- -H "Authorization: token ${GITHUB_TOKEN}" \
- "${artifact_url}"
-
- unzip -p "$download_path" > "${TMPDIR}/otelcol-sumo.pkg"
- if [ "${KEEP_DOWNLOADS}" == "false" ]; then
- rm -f "${download_path}"
- fi
-}
-
function get_package_from_url() {
local url download_filename download_path curl_args
readonly url="${1}"
@@ -1005,17 +785,6 @@ function plutil_create_key() {
fi
}
-function plutil_delete_key() {
- local file key
- readonly file="${1}"
- readonly key="${2}"
-
- if ! plutil -remove "${key}" "${file}"; then
- echo "plutil_delete_key error: key=${key}, file=${file}"
- exit 1
- fi
-}
-
function plutil_extract_key() {
local file key output
readonly file="${1}"
@@ -1072,24 +841,55 @@ function get_package_manager() {
}
function install_linux_package() {
- local package_with_version
- readonly package_with_version="${1}"
+ local package_name
+ readonly package_name="${1}"
+
+ if [[ "${PACKAGECLOUD_MASTER_TOKEN}" != "" ]]; then
+ base_url="https://${PACKAGECLOUD_MASTER_TOKEN}:@packages.sumologic.com"
+ else
+ base_url="https://packages.sumologic.com"
+ fi
+ base_url+="/install/repositories/${PACKAGECLOUD_ORG}/${PACKAGECLOUD_REPO}"
+
+ repo_id="${PACKAGECLOUD_ORG}_${PACKAGECLOUD_REPO}"
case $(get_package_manager) in
yum | dnf)
- curl -s https://packagecloud.io/install/repositories/sumologic/stable/script.rpm.sh | bash
- yum --quiet --disablerepo="*" --enablerepo="sumologic_stable" -y update
- yum install --quiet "${package_with_version}"
+ curl -s "${base_url}/script.rpm.sh" | bash
+
+ local package_str
+ package_str="${package_name}"
+ if [[ -n "${VERSION}" ]]; then
+ package_str="${package_str}-${VERSION}"
+ fi
+ echo "Installing ${package_str}"
+ yum install --quiet -y "${package_str}"
;;
apt-get)
- curl -s https://packagecloud.io/install/repositories/sumologic/stable/script.deb.sh | bash
- apt-get update --quiet -y -o Dir::Etc::sourcelist="sources.list.d/sumologic_stable"
- apt-get install --quiet "${package_with_version}"
+ curl -s "${base_url}/script.deb.sh" | bash
+ apt-get update --quiet -y -o Dir::Etc::sourcelist="sources.list.d/${repo_id}"
+
+ local package_str
+ package_str="${package_name}"
+ if [[ -n "${VERSION}" ]]; then
+ package_str="${package_str}=${VERSION}"
+ fi
+ echo "Installing ${package_str}"
+ apt-get install --quiet -y "${package_str}"
;;
esac
}
function check_deprecated_linux_flags() {
+ if [[ -n "${BINARY_BRANCH}" ]]; then
+ echo "warning: --binary-branch is deprecated"
+ exit 1
+ fi
+
+ if [[ -n "${CONFIG_BRANCH}" ]]; then
+ echo "warning: --config-branch is deprecated"
+ fi
+
if [[ "${OS_TYPE}" == "darwin" ]]; then
return
fi
@@ -1098,17 +898,114 @@ function check_deprecated_linux_flags() {
echo "--download-only is only supported on darwin, use 'install.sh --upgrade' to upgrade otelcol-sumo"
exit 1
fi
+}
- if [[ -n "${BINARY_BRANCH}" ]]; then
- echo "--binary-branch is only supported on darwin, use --version, --channel, and --channel-token on linux"
- exit 1
+function is_package_installed() {
+ case $(get_package_manager) in
+ yum | dnf)
+ # TODO: refine exact command
+ yum --cacheonly list --installed otelcol-sumo > /dev/null 2>&1
+ ;;
+ apt-get)
+ dpkg --status otelcol-sumo > /dev/null 2>&1
+ ;;
+ esac
+}
+
+# Try to infer if there is a binary, pre-packaging rework installation, the
+# kind of installation that was performed by downloading artifacts from Github,
+# before we moved to using distribution packages.
+function has_prepackaging_installation() {
+ if command -v otelcol-sumo > /dev/null 2>&1 && ! is_package_installed; then
+ true
+ else
+ false
fi
+}
- if [[ -n "${CONFIG_BRANCH}" ]]; then
- echo "warning: --config-branch is deprecated"
+function backup_prepackaging_configuration() {
+ cp -r "${CONFIG_DIRECTORY}" "${TMPDIR}/otelcol-sumo-configuration-backup"
+}
+
+function restore_prepackaging_configuration() {
+ echo "restore_prepackaging_configuration(): not implemented yet"
+}
+
+function uninstall_prepackaging_installation() {
+ # Stop the service and remove its unit file
+ SYSTEMD_SERVICE_PATH="/etc/systemd/system/otelcol-sumo.service"
+ if [[ -f "${SYSTEMD_SERVICE_PATH}" ]]; then
+ systemctl --quiet stop otelcol-sumo || true
+ systemctl --quiet disable otelcol-sumo || true
+ rm -f "${SYSTEMD_SERVICE_PATH}"
+ fi
+
+ # Remove the old binary
+ rm -f "${SUMO_BINARY_PATH}"
+
+ # Remove old configuration and data
+ FILE_STORAGE="/var/lib/otelcol-sumo/file_storage"
+ rm -rf "${CONFIG_DIRECTORY}" "${FILE_STORAGE}"
+
+ # Remove the otelcol-sumo user and group
+ SYSTEM_USER="otelcol-sumo"
+ userdel --remove --force "${SYSTEM_USER}" 2>/dev/null || true
+ groupdel "${SYSTEM_USER}" 2>/dev/null || true
+}
+
+function is_package_installed() {
+ case $(get_package_manager) in
+ yum | dnf)
+ # TODO: refine exact command
+ yum --cacheonly list --installed otelcol-sumo > /dev/null 2>&1
+ ;;
+ apt-get)
+ dpkg --status otelcol-sumo > /dev/null 2>&1
+ ;;
+ esac
+}
+
+# Try to infer if there is a binary, pre-packaging rework installation, the
+# kind of installation that was performed by downloading artifacts from Github,
+# before we moved to using distribution packages.
+function has_prepackaging_installation() {
+ if command -v otelcol-sumo > /dev/null 2>&1 && ! is_package_installed; then
+ true
+ else
+ false
fi
}
+function backup_prepackaging_configuration() {
+ cp -r "${CONFIG_DIRECTORY}" "${TMPDIR}/otelcol-sumo-configuration-backup"
+}
+
+function restore_prepackaging_configuration() {
+ echo "restore_prepackaging_configuration(): not implemented yet"
+}
+
+function uninstall_prepackaging_installation() {
+ # Stop the service and remove its unit file
+ SYSTEMD_SERVICE_PATH="/etc/systemd/system/otelcol-sumo.service"
+ if [[ -f "${SYSTEMD_SERVICE_PATH}" ]]; then
+ systemctl --quiet stop otelcol-sumo || true
+ systemctl --quiet disable otelcol-sumo || true
+ rm -f "${SYSTEMD_SERVICE_PATH}"
+ fi
+
+ # Remove the old binary
+ rm -f "${SUMO_BINARY_PATH}"
+
+ # Remove old configuration and data
+ FILE_STORAGE="/var/lib/otelcol-sumo/file_storage"
+ rm -rf "${CONFIG_DIRECTORY}" "${FILE_STORAGE}"
+
+ # Remove the otelcol-sumo user and group
+ SYSTEM_USER="otelcol-sumo"
+ userdel --remove --force "${SYSTEM_USER}" 2>/dev/null || true
+ groupdel "${SYSTEM_USER}" 2>/dev/null || true
+}
+
############################ Main code
OS_TYPE="$(get_os_type)"
@@ -1125,7 +1022,7 @@ check_dependencies
check_deprecated_linux_flags
readonly SUMOLOGIC_INSTALLATION_TOKEN API_BASE_URL OPAMP_API_URL FIELDS CONTINUE CONFIG_DIRECTORY UNINSTALL
-readonly USER_ENV_DIRECTORY CONFIG_DIRECTORY CONFIG_PATH COMMON_CONFIG_PATH
+readonly USER_ENV_DIRECTORY CONFIG_DIRECTORY COMMON_CONFIG_PATH
readonly INSTALL_HOSTMETRICS
readonly REMOTELY_MANAGED
readonly CURL_MAX_TIME
@@ -1135,49 +1032,67 @@ if [[ "${UNINSTALL}" == "true" ]]; then
uninstall
exit 0
fi
+if [[ "${UPGRADE}" == "true" ]]; then
+ upgrade
+ exit 0
+fi
+
+# get_installation_token returns the value of SUMOLOGIC_INSTALLATION_TOKEN
+# (set by a flag or environment variable) when it is not empty, otherwise it
+# will attempt to fetch the token from an existing installation and return it.
+function get_installation_token() {
+ local token=""
+
+ if [[ -z "${token}" ]]; then
+ token="${SUMOLOGIC_INSTALLATION_TOKEN}"
+ fi
+
+ if [[ -z "${token}" ]]; then
+ token="$(get_user_token)"
+ fi
+
+ echo "${token}"
+}
# Attempt to find a token from an existing installation
-if command -v otelcol-config &> /dev/null; then
- USER_TOKEN=$(otelcol-config --read-kv .extensions.sumologic.installation_token)
-fi
-if [[ -z "${USER_TOKEN}" ]]; then
- USER_TOKEN="$(get_user_env_config "${TOKEN_ENV_FILE}")"
-fi
-readonly USER_TOKEN
+function get_user_token() {
+ local token="${USER_TOKEN}"
-# Exit if installation token is not set and there is no user configuration
-if [[ -z "${SUMOLOGIC_INSTALLATION_TOKEN}" && "${SKIP_TOKEN}" != "true" && -z "${USER_TOKEN}" && -z "${DOWNLOAD_ONLY}" ]]; then
- echo "Installation token has not been provided. Please set the '${ENV_TOKEN}' environment variable."
- echo "You can ignore this requirement by adding '--${ARG_LONG_SKIP_TOKEN} argument."
- exit 1
-fi
+ # Attempt to find a token from an existing installation
+ # Check the systemd env file for a token
+ if [[ -f "${TOKEN_ENV_FILE}" && -z "${token}" ]]; then
+ token="$(get_user_env_config "${TOKEN_ENV_FILE}")"
+ fi
-# verify if passed arguments are the same like in user's configuration
-if [[ -z "${DOWNLOAD_ONLY}" ]]; then
- if [[ -n "${USER_TOKEN}" && -n "${SUMOLOGIC_INSTALLATION_TOKEN}" && "${USER_TOKEN}" != "${SUMOLOGIC_INSTALLATION_TOKEN}" ]]; then
- echo "You are trying to install with different token than in your configuration file!"
- exit 1
- fi
+ # Check the launchd config for a token
+ if [[ -f "${LAUNCHD_CONFIG}" && -z "${token}" ]]; then
+ token="$(get_launchd_token "${LAUNCHD_CONFIG}")"
+ fi
- USER_API_URL="$(get_user_api_url)"
- if [[ -n "${USER_API_URL}" && -n "${API_BASE_URL}" && "${USER_API_URL}" != "${API_BASE_URL}" ]]; then
- echo "You are trying to install with different api base url than in your configuration file!"
- exit 1
+ # Check yaml configuration for a token
+ if [[ -z "${token}" ]]; then
+ if command -v otelcol-config &> /dev/null; then
+ local output=""
+ output=$(otelcol-config --read-kv .extensions.sumologic.installation_token)
+ if [[ "${output}" != "null" ]]; then
+ token="${output}"
+ fi
fi
+ fi
- USER_OPAMP_API_URL="$(get_user_opamp_endpoint "${COMMON_CONFIG_PATH}")"
- if [[ -n "${USER_OPAMP_API_URL}" && -n "${OPAMP_API_URL}" && "${USER_OPAMP_API_URL}" != "${OPAMP_API_URL}" ]]; then
- echo "You are trying to install with different opamp endpoint than in your configuration file!"
- exit 1
- fi
-fi
+ echo "${token}"
+}
-set +u
-if [[ -n "${BINARY_BRANCH}" && -z "${GITHUB_TOKEN}" ]]; then
- echo "GITHUB_TOKEN env is required for '${ARG_LONG_BINARY_BRANCH}' option"
- exit 1
+# Load & cache user token
+USER_TOKEN="$(get_user_token)"
+
+# Exit if installation token is not set by flag, environment variable, or from
+# existing installation configuration. Skip this check when DOWNLOAD_ONLY is set
+# which is only possible on macOS.
+if [[ -z "$(get_installation_token)" && -z "${DOWNLOAD_ONLY}" ]]; then
+ echo "Installation token has not been provided. Please set the '${ENV_TOKEN}' environment variable."
+ exit 1
fi
-set -u
if [ "${FIPS}" == "true" ]; then
case "${OS_TYPE}" in
@@ -1195,6 +1110,27 @@ if [ "${FIPS}" == "true" ]; then
fi
if [[ "${OS_TYPE}" == "darwin" ]]; then
+ # verify if passed arguments are the same like in user's configuration
+ if [[ -z "${DOWNLOAD_ONLY}" ]]; then
+ USER_TOKEN="$(get_user_token)"
+ if [[ -n "${USER_TOKEN}" && -n "${SUMOLOGIC_INSTALLATION_TOKEN}" && "${USER_TOKEN}" != "${SUMOLOGIC_INSTALLATION_TOKEN}" ]]; then
+ echo "You are trying to install with different token than in your configuration file!"
+ exit 1
+ fi
+
+ USER_API_URL="$(get_user_api_url)"
+ if [[ -n "${USER_API_URL}" && -n "${API_BASE_URL}" && "${USER_API_URL}" != "${API_BASE_URL}" ]]; then
+ echo "You are trying to install with different api base url than in your configuration file! (${USER_API_URL} != ${API_BASE_URL})"
+ exit 1
+ fi
+
+ USER_OPAMP_API_URL="$(get_user_opamp_endpoint "${COMMON_CONFIG_PATH}")"
+ if [[ -n "${USER_OPAMP_API_URL}" && -n "${OPAMP_API_URL}" && "${USER_OPAMP_API_URL}" != "${OPAMP_API_URL}" ]]; then
+ echo "You are trying to install with different opamp endpoint than in your configuration file!"
+ exit 1
+ fi
+ fi
+
package_arch=""
case "${ARCH_TYPE}" in
"amd64") package_arch="intel" ;;
@@ -1206,88 +1142,43 @@ if [[ "${OS_TYPE}" == "darwin" ]]; then
esac
readonly package_arch
- if [[ "${SKIP_CONFIG}" == "true" ]]; then
- echo "SKIP_CONFIG is not supported on darwin"
- exit 1
- fi
-
- echo -e "Getting versions..."
- # Get versions, but ignore errors as we fallback to other methods later
- VERSIONS="$(get_package_versions || echo "")"
+ pkg_url=""
- # Use user's version if set, otherwise get latest version from API (or website)
- if [[ -z "${VERSION}" ]]; then
- VERSION="$(get_latest_package_version "${VERSIONS}")"
- fi
-
- readonly VERSIONS VERSION
+ if [[ -z "${DARWIN_PKG_URL}" ]]; then
+ # Use user's version if set, otherwise get latest version from API (or website)
+ if [[ -z "${VERSION}" ]]; then
+ echo -e "Getting latest version..."
+ VERSION="$(get_latest_s3_package_version)"
+ fi
- echo -e "Version to install:\t${VERSION}"
+ readonly VERSION
- package_suffix="${package_arch}.pkg"
+ echo -e "Version to install:\t${VERSION}"
- if [[ -n "${BINARY_BRANCH}" ]]; then
- artifact_name="otelcol-sumo_.*-${package_suffix}"
- get_package_from_branch "${BINARY_BRANCH}" "${artifact_name}"
- else
- artifact_name="otelcol-sumo_${VERSION}-${package_suffix}"
+ artifact_name="otelcol-sumo_${VERSION}-${package_arch}.pkg"
readonly artifact_name
- LINK="https://github.com/${PACKAGE_GITHUB_ORG}/${PACKAGE_GITHUB_REPO}/releases/download/v${VERSION}/${artifact_name}"
- readonly LINK
-
- get_package_from_url "${LINK}"
+ pkg_url="${S3_URI}/${VERSION}/${artifact_name}"
+ else
+ pkg_url="${DARWIN_PKG_URL}"
fi
+ get_package_from_url "${pkg_url}"
+
pkg="${TMPDIR}/otelcol-sumo.pkg"
- choices="${TMPDIR}/otelcol-sumo-choices.xml"
- readonly pkg choices
if [[ "${DOWNLOAD_ONLY}" == "true" ]]; then
echo "Package downloaded to: ${pkg}"
exit 0
fi
- # Extract choices xml from meta package, override the choices to enable
- # optional choices, and then install using the new choice selections
- installer -showChoiceChangesXML -pkg "${pkg}" -target / > "${choices}"
-
- # Determine how many installation choices exist
- choices_count=$(plutil -convert raw -o - "${choices}")
- readonly choices_count
-
- # Loop through each installation choice
- for (( i=0; i < "${choices_count}"; i++ )); do
- choice_id_key="${i}.choiceIdentifier"
- choice_attr_key="${i}.choiceAttribute"
- attr_setting_key="${i}.attributeSetting"
-
- # Skip if choiceAttribute does not equal selected
- choice_attr="$(plutil_extract_key "${choices}" "${choice_attr_key}")"
- if [ "$choice_attr" != "selected" ]; then
- continue
- fi
-
- # Get the choice identifier
- choice_id="$(plutil_extract_key "${choices}" "${choice_id_key}")"
-
- # Mark the choice as selected if the feature flag is true
- case "${choice_id}" in
- "otelcol-sumo-hostmetricsChoice")
- if [[ "${INSTALL_HOSTMETRICS}" == "true" ]]; then
- echo -e "Enabling ${OS_TYPE} hostmetrics install option"
- plutil_replace_key "${choices}" "${attr_setting_key}" "integer" 1
- fi
- ;;
- esac
- done
-
- installer -applyChoiceChangesXML "$choices" -pkg "$pkg" -target /
+ echo "Installing otelcol-sumo package"
+ installer -pkg "${pkg}" -target /
- if [[ -n "${SUMOLOGIC_INSTALLATION_TOKEN}" && -z "${USER_TOKEN}" && "${SKIP_TOKEN}" != "true" ]]; then
- echo "Writing installation token to launchd config"
- write_installation_token_launchd "${SUMOLOGIC_INSTALLATION_TOKEN}" "${LAUNCHD_CONFIG}"
- fi
+ # The token must be written to the launchd config on every install as
+ # upgrades replace the launchd config
+ echo "Writing installation token to launchd config"
+ write_installation_token_launchd "$(get_installation_token)" "${LAUNCHD_CONFIG}"
setup_config_darwin
@@ -1297,81 +1188,62 @@ if [[ "${OS_TYPE}" == "darwin" ]]; then
echo "Waiting for otelcol to start"
while ! launchctl print system/otelcol-sumo | grep -q "state = running"; do
- sleep 0.1
+ echo -n " otelcol service "
+ launchctl print system/otelcol-sumo | grep "state = "
+ sleep 1
done
OTEL_EXITED_WITH_ERROR=false
echo 'Checking otelcol status'
- for i in {1..15}; do
+ for _ in {1..15}; do
if launchctl print system/otelcol-sumo | grep -q "last exit code = 1"; then
OTEL_EXITED_WITH_ERROR=true
break;
fi
- sleep 1
+ sleep 0.4
done
if [[ "${OTEL_EXITED_WITH_ERROR}" == "true" ]]; then
echo "Failed to launch otelcol"
tail /var/log/otelcol-sumo/otelcol-sumo.log
exit 1
fi
+ echo "Successfully started otelcol"
exit 0
fi
-echo -e "Getting installed version..."
-INSTALLED_VERSION="$(get_installed_version)"
-echo -e "Installed version:\t${INSTALLED_VERSION:-none}"
-
-echo -e "Getting versions..."
-# Get versions, but ignore errors as we fallback to other methods later
-VERSIONS="$(get_versions || echo "")"
-
-# Use user's version if set, otherwise get latest version from API (or website)
-if [[ -z "${VERSION}" ]]; then
- VERSION="$(get_latest_version "${VERSIONS}")"
+package_name=""
+if [[ "${FIPS}" == "true" ]]; then
+ echo "Getting FIPS-compliant binary"
+ package_name=otelcol-sumo-fips
+else
+ package_name=otelcol-sumo
fi
-echo -e "Version to install:\t${VERSION}"
+if has_prepackaging_installation; then
+ # Display a warning and information message here?
+ echo 'Pre-packaging installation detected'
-# Check if otelcol is already in newest version
-if [[ "${INSTALLED_VERSION}" == "${VERSION}" ]]; then
- echo -e "OpenTelemetry collector is already in newest (${VERSION}) version"
-else
+ # Backup current configuration
+ backup_prepackaging_configuration
- # add newline before breaking changes and changelog
- echo ""
- if [[ -n "${INSTALLED_VERSION}" ]]; then
- # Take versions from installed up to the newest
- BETWEEN_VERSIONS="$(get_versions_from "${VERSIONS}" "${INSTALLED_VERSION}")"
- readonly BETWEEN_VERSIONS
- print_breaking_changes "${BETWEEN_VERSIONS}"
- fi
+ # Remove current installation
+ uninstall_prepackaging_installation
- echo -e "Changelog:\t\thttps://github.com/SumoLogic/sumologic-otel-collector/blob/main/CHANGELOG.md"
- # add newline after breaking changes and changelog
- echo ""
-
- package_with_version="${VERSION}"
- if [[ -n "${package_with_version}" ]]; then
- if [[ "${FIPS}" == "true" ]]; then
- echo "Getting FIPS-compliant binary"
- package_with_version=otelcol-sumo-fips
- else
- package_with_version=otelcol-sumo
- fi
- fi
-
- install_linux_package "${package_with_version}"
-
- verify_installation
+ # We can now proceed and install using the packages and attempt to restore
+ # the configuration later.
+ HAD_PREPACKAGING_INSTALLATION="true"
fi
-if [[ "${SKIP_CONFIG}" == "false" ]]; then
- setup_config
-fi
+install_linux_package "${package_name}"
+verify_installation
+setup_config
-if [[ -n "${SUMOLOGIC_INSTALLATION_TOKEN}" && -z "${USER_TOKEN}" ]]; then
- echo 'Writing installation token to env file'
- write_installation_token_env "${SUMOLOGIC_INSTALLATION_TOKEN}" "${TOKEN_ENV_FILE}"
+# If an old, pre-packaging rework installation was removed during this run,
+# attempt the restore the configuration that was backed up during that removal.
+set +u
+if [[ -n "${HAD_PREPACKAGING_INSTALLATION}" ]]; then
+ restore_prepackaging_configuration
fi
+set -u
echo 'Reloading systemd'
systemctl daemon-reload
@@ -1382,11 +1254,4 @@ systemctl enable otelcol-sumo
echo 'Starting otelcol-sumo service'
systemctl restart otelcol-sumo
-echo 'Waiting 10s before checking status'
-sleep 10
-if ! systemctl status otelcol-sumo --no-pager; then
- echo "Failed to launch otelcol"
- exit 1
-fi
-
exit 0
diff --git a/install-script/test/Makefile b/install-script/test/Makefile
index 85c2eed1..335c4041 100644
--- a/install-script/test/Makefile
+++ b/install-script/test/Makefile
@@ -3,18 +3,24 @@ ifeq ($(OS),Windows_NT)
endif
ifneq ($(OS),windows)
- GOTESTPREFIX ?= sudo env PATH="${PATH}" GH_CI_TOKEN="${GITHUB_TOKEN}"
+ GOTESTPREFIX ?= sudo env PATH="${PATH}" GH_CI_TOKEN="${GITHUB_TOKEN}" DARWIN_PKG_URL="${DARWIN_PKG_URL}" PACKAGECLOUD_MASTER_TOKEN="${PACKAGECLOUD_MASTER_TOKEN}" PACKAGECLOUD_REPO="${PACKAGECLOUD_REPO}" OTC_VERSION="${OTC_VERSION}" OTC_BUILD_NUMBER="${OTC_BUILD_NUMBER}"
endif
LINT=golangci-lint
GOTEST=go test
GOTESTBINARY=sumologic_scripts_tests.test
+GOTESTNAME ?= ""
+GOTESTRUN=
+
+ifneq ($(GOTESTNAME),"")
+ GOTESTRUN=-test.run $(GOTESTNAME)
+endif
# We build the test binary separately to avoid downloading modules as root
.PHONY: test
test:
$(GOTEST) -c
- $(GOTESTPREFIX) ./$(GOTESTBINARY) -test.v
+ $(GOTESTPREFIX) ./$(GOTESTBINARY) -test.v $(GOTESTRUN)
.PHONY: fmt
fmt:
diff --git a/install-script/test/check.go b/install-script/test/check.go
index a362d953..53dbc2a6 100644
--- a/install-script/test/check.go
+++ b/install-script/test/check.go
@@ -7,7 +7,7 @@ import (
"path/filepath"
"testing"
- "github.com/stretchr/testify/require"
+ "github.com/stretchr/testify/assert"
)
type check struct {
@@ -26,197 +26,234 @@ func checkSkipTest(c check) bool {
return false
}
-type checkFunc func(check)
+type checkFunc func(check) bool
-func checkBinaryCreated(c check) {
- require.FileExists(c.test, binaryPath, "binary has not been created")
+func checkBinaryCreated(c check) bool {
+ return assert.FileExists(c.test, binaryPath, "binary has not been created")
}
-func checkBinaryNotCreated(c check) {
- require.NoFileExists(c.test, binaryPath, "binary is already created")
+func checkBinaryNotCreated(c check) bool {
+ return assert.NoFileExists(c.test, binaryPath, "binary is already created")
}
-func checkBinaryIsRunning(c check) {
+func checkBinaryIsRunning(c check) bool {
cmd := exec.Command(binaryPath, "--version")
err := cmd.Start()
- require.NoError(c.test, err, "error while checking version")
+ if !assert.NoError(c.test, err, "error while checking version") {
+ return false
+ }
code, err := exitCode(cmd)
- require.NoError(c.test, err, "error while checking exit code")
- require.Equal(c.test, 0, code, "got error code while checking version")
+ assert.NoError(c.test, err, "error while checking exit code")
+ assert.Equal(c.test, 0, code, "got error code while checking version")
+ return true
}
-func checkRun(c check) {
- require.Equal(c.test, c.expectedInstallCode, c.code, "unexpected installation script error code")
+func checkRun(c check) bool {
+ return assert.Equal(c.test, c.expectedInstallCode, c.code, "unexpected installation script error code")
}
-func checkConfigCreated(c check) {
- require.FileExists(c.test, configPath, "configuration has not been created properly")
+func checkConfigCreated(c check) bool {
+ return assert.FileExists(c.test, configPath, "configuration has not been created properly")
}
-func checkConfigNotCreated(c check) {
- require.NoFileExists(c.test, configPath, "configuration has been created")
+func checkConfigNotCreated(c check) bool {
+ return assert.NoFileExists(c.test, configPath, "configuration has been created")
}
-func checkConfigOverrided(c check) {
+func checkConfigOverrided(c check) bool {
conf, err := getConfig(configPath)
- require.NoError(c.test, err)
+ if err != nil {
+ c.test.Error(err)
+ return false
+ }
- require.Condition(c.test, func() (success bool) {
- switch conf.Extensions.Sumologic.InstallationToken {
- case "${SUMOLOGIC_INSTALLATION_TOKEN}":
- return true
- default:
- return false
- }
- }, "invalid value for installation token")
+ if got, want := conf.Extensions.Sumologic.InstallationToken, "${SUMOLOGIC_INSTALLATION_TOKEN}"; got != want {
+ c.test.Errorf("bad installation token: got %q, want %q", got, want)
+ }
+ return true
}
-func checkUserConfigCreated(c check) {
- require.FileExists(c.test, userConfigPath, "user configuration has not been created properly")
+func checkUserConfigCreated(c check) bool {
+ return assert.FileExists(c.test, userConfigPath, "user configuration has not been created properly")
}
-func checkUserConfigNotCreated(c check) {
- require.NoFileExists(c.test, userConfigPath, "user configuration has been created")
+func checkUserConfigNotCreated(c check) bool {
+ return assert.NoFileExists(c.test, userConfigPath, "user configuration has been created")
}
-func checkHomeDirectoryCreated(c check) {
- require.DirExists(c.test, libPath, "home directory has not been created properly")
+func checkHomeDirectoryCreated(c check) bool {
+ return assert.DirExists(c.test, libPath, "home directory has not been created properly")
}
-func checkNoBakFilesPresent(c check) {
+func checkNoBakFilesPresent(c check) bool {
cwd, err := os.Getwd()
- require.NoError(c.test, err)
+ if !assert.NoError(c.test, err) {
+ return false
+ }
cwdGlob := filepath.Join(cwd, "*.bak")
etcPathGlob := filepath.Join(etcPath, "*.bak")
etcPathNestedGlob := filepath.Join(etcPath, "*", "*.bak")
for _, bakGlob := range []string{cwdGlob, etcPathGlob, etcPathNestedGlob} {
bakFiles, err := filepath.Glob(bakGlob)
- require.NoError(c.test, err)
- require.Empty(c.test, bakFiles)
+ if !assert.NoError(c.test, err) {
+ return false
+ }
+ if !assert.Empty(c.test, bakFiles) {
+ return false
+ }
}
+ return true
}
-func checkOpAmpEndpointSet(c check) {
- conf, err := getConfig(configPath)
- require.NoError(c.test, err, "error while reading configuration")
+func checkOpAmpEndpointSet(c check) bool {
+ conf, err := getConfig(sumoRemotePath)
+ if !assert.NoError(c.test, err, "error while reading configuration") {
+ return false
+ }
- require.Equal(c.test, conf.Extensions.OpAmp.Endpoint, "wss://example.com")
+ if !assert.Equal(c.test, conf.Extensions.OpAmp.Endpoint, "wss://example.com") {
+ return false
+ }
+ return true
}
-func checkHostmetricsConfigCreated(c check) {
- require.FileExists(c.test, hostmetricsConfigPath, "hostmetrics configuration has not been created properly")
+func checkHostmetricsConfigCreated(c check) bool {
+ return assert.FileExists(c.test, hostmetricsConfigPath, "hostmetrics configuration has not been created properly")
}
-func checkHostmetricsConfigNotCreated(c check) {
- require.NoFileExists(c.test, hostmetricsConfigPath, "hostmetrics configuration has been created")
+func checkHostmetricsConfigNotCreated(c check) bool {
+ return assert.NoFileExists(c.test, hostmetricsConfigPath, "hostmetrics configuration has been created")
}
-func checkRemoteConfigDirectoryCreated(c check) {
- require.DirExists(c.test, opampDPath, "remote configuration directory has not been created properly")
+func checkRemoteConfigDirectoryCreated(c check) bool {
+ return assert.DirExists(c.test, opampDPath, "remote configuration directory has not been created properly")
}
-func checkRemoteConfigDirectoryNotCreated(c check) {
- require.NoDirExists(c.test, opampDPath, "remote configuration directory has been created")
+func checkRemoteConfigDirectoryNotCreated(c check) bool {
+ return assert.NoDirExists(c.test, opampDPath, "remote configuration directory has been created")
}
-func checkTags(c check) {
+func checkTags(c check) bool {
conf, err := getConfig(userConfigPath)
- require.NoError(c.test, err, "error while reading configuration")
+ if !assert.NoError(c.test, err, "error while reading configuration") {
+ return false
+ }
+ errored := false
for k, v := range c.installOptions.tags {
- require.Equal(c.test, v, conf.Extensions.Sumologic.Tags[k], "tag is different than expected")
+ if !assert.Equal(c.test, v, conf.Extensions.Sumologic.Tags[k], "tag is different than expected") {
+ errored = true
+ }
}
+ return !errored
}
-func checkDifferentTags(c check) {
+func checkDifferentTags(c check) bool {
conf, err := getConfig(userConfigPath)
- require.NoError(c.test, err, "error while reading configuration")
+ if !assert.NoError(c.test, err, "error while reading configuration") {
+ return false
+ }
- require.Equal(c.test, "tag", conf.Extensions.Sumologic.Tags["some"], "tag is different than expected")
+ return assert.Equal(c.test, "tag", conf.Extensions.Sumologic.Tags["some"], "tag is different than expected")
}
-func checkAbortedDueToDifferentToken(c check) {
- require.Greater(c.test, len(c.output), 0)
- require.Contains(c.test, c.output[len(c.output)-1], "You are trying to install with different token than in your configuration file!")
+func checkAbortedDueToDifferentToken(c check) bool {
+ if !assert.Greater(c.test, len(c.output), 0) {
+ return false
+ }
+ return assert.Contains(c.test, c.output[len(c.output)-1], "You are trying to install with different token than in your configuration file!")
}
-func preActionWriteAPIBaseURLToUserConfig(c check) {
+func preActionWriteAPIBaseURLToUserConfig(c check) bool {
conf, err := getConfig(userConfigPath)
- require.NoError(c.test, err)
+ if !assert.NoError(c.test, err) {
+ return false
+ }
conf.Extensions.Sumologic.APIBaseURL = c.installOptions.apiBaseURL
err = saveConfig(userConfigPath, conf)
- require.NoError(c.test, err)
+ return assert.NoError(c.test, err)
}
-func preActionWriteDifferentAPIBaseURLToUserConfig(c check) {
+func preActionWriteDifferentAPIBaseURLToUserConfig(c check) bool {
conf, err := getConfig(userConfigPath)
- require.NoError(c.test, err)
+ if !assert.NoError(c.test, err) {
+ return false
+ }
conf.Extensions.Sumologic.APIBaseURL = "different" + c.installOptions.apiBaseURL
err = saveConfig(userConfigPath, conf)
- require.NoError(c.test, err)
+ return assert.NoError(c.test, err)
}
-func preActionWriteDifferentTagsToUserConfig(c check) {
+func preActionWriteDifferentTagsToUserConfig(c check) bool {
conf, err := getConfig(userConfigPath)
- require.NoError(c.test, err)
+ if !assert.NoError(c.test, err) {
+ return false
+ }
conf.Extensions.Sumologic.Tags = map[string]string{
"some": "tag",
}
err = saveConfig(userConfigPath, conf)
- require.NoError(c.test, err)
+ return assert.NoError(c.test, err)
}
-func preActionWriteEmptyUserConfig(c check) {
+func preActionWriteEmptyUserConfig(c check) bool {
conf, err := getConfig(userConfigPath)
- require.NoError(c.test, err)
+ if !assert.NoError(c.test, err) {
+ return false
+ }
err = saveConfig(userConfigPath, conf)
- require.NoError(c.test, err)
+ return assert.NoError(c.test, err)
}
-func preActionWriteTagsToUserConfig(c check) {
+func preActionWriteTagsToUserConfig(c check) bool {
conf, err := getConfig(userConfigPath)
- require.NoError(c.test, err)
+ if !assert.NoError(c.test, err) {
+ return false
+ }
conf.Extensions.Sumologic.Tags = c.installOptions.tags
err = saveConfig(userConfigPath, conf)
- require.NoError(c.test, err)
+ return assert.NoError(c.test, err)
}
-func checkAbortedDueToDifferentAPIBaseURL(c check) {
- require.Greater(c.test, len(c.output), 0)
- require.Contains(c.test, c.output[len(c.output)-1], "You are trying to install with different api base url than in your configuration file!")
+func checkAbortedDueToDifferentAPIBaseURL(c check) bool {
+ if !assert.Greater(c.test, len(c.output), 0) {
+ return false
+ }
+ return assert.Contains(c.test, c.output[len(c.output)-1], "You are trying to install with different api base url than in your configuration file!")
}
-func checkAPIBaseURLInConfig(c check) {
+func checkAPIBaseURLInConfig(c check) bool {
conf, err := getConfig(userConfigPath)
- require.NoError(c.test, err, "error while reading configuration")
-
- require.Equal(c.test, c.installOptions.apiBaseURL, conf.Extensions.Sumologic.APIBaseURL, "api base url is different than expected")
-}
+ if !assert.NoError(c.test, err, "error while reading configuration") {
+ return false
+ }
-func checkAbortedDueToDifferentTags(c check) {
- require.Greater(c.test, len(c.output), 0)
- require.Contains(c.test, c.output[len(c.output)-1], "You are trying to install with different tags than in your configuration file!")
+ return assert.Equal(c.test, c.installOptions.apiBaseURL, conf.Extensions.Sumologic.APIBaseURL, "api base url is different than expected")
}
-func PathHasPermissions(t *testing.T, path string, perms uint32) {
+func PathHasPermissions(t *testing.T, path string, perms uint32) bool {
info, err := os.Stat(path)
- require.NoError(t, err)
+ if !assert.NoError(t, err) {
+ return false
+ }
expected := fs.FileMode(perms)
got := info.Mode().Perm()
- require.Equal(t, expected, got, "%s should have %o permissions but has %o", path, expected, got)
+ return assert.Equal(t, expected, got, "%s should have %o permissions but has %o", path, expected, got)
}
-func PathHasUserACL(t *testing.T, path string, ownerName string, perms string) {
+func PathHasUserACL(t *testing.T, path string, ownerName string, perms string) bool {
cmd := exec.Command("/usr/bin/getfacl", path)
output, err := cmd.Output()
- require.NoError(t, err, "error while checking "+path+" acl")
- require.Contains(t, string(output), "user:"+ownerName+":"+perms)
+ if !assert.NoError(t, err, "error while checking "+path+" acl") {
+ return false
+ }
+ return assert.Contains(t, string(output), "user:"+ownerName+":"+perms)
}
diff --git a/install-script/test/check_darwin.go b/install-script/test/check_darwin.go
index d874f1cc..d59df2f1 100644
--- a/install-script/test/check_darwin.go
+++ b/install-script/test/check_darwin.go
@@ -3,16 +3,16 @@ package sumologic_scripts_tests
import (
"io/fs"
"os"
+ "path"
"path/filepath"
"regexp"
"strings"
"github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
)
-func checkConfigFilesOwnershipAndPermissions(ownerName string, ownerGroup string) func(c check) {
- return func(c check) {
+func checkConfigFilesOwnershipAndPermissions(ownerName string, ownerGroup string) func(c check) bool {
+ return func(c check) bool {
PathHasPermissions(c.test, etcPath, etcPathPermissions)
PathHasOwner(c.test, etcPath, ownerName, ownerGroup)
@@ -21,11 +21,15 @@ func checkConfigFilesOwnershipAndPermissions(ownerName string, ownerGroup string
for _, glob := range []string{etcPathGlob, etcPathNestedGlob} {
paths, err := filepath.Glob(glob)
- require.NoError(c.test, err)
+ if !assert.NoError(c.test, err) {
+ return false
+ }
for _, path := range paths {
var permissions uint32
info, err := os.Stat(path)
- require.NoError(c.test, err)
+ if !assert.NoError(c.test, err) {
+ return false
+ }
if info.IsDir() {
switch path {
case etcPath:
@@ -41,9 +45,6 @@ func checkConfigFilesOwnershipAndPermissions(ownerName string, ownerGroup string
case configPath:
// /etc/otelcol-sumo/sumologic.yaml
permissions = configPathFilePermissions
- case userConfigPath:
- // /etc/otelcol-sumo/conf.d/common.yaml
- permissions = commonConfigPathFilePermissions
default:
// /etc/otelcol-sumo/conf.d/*
permissions = confDPathFilePermissions
@@ -54,46 +55,57 @@ func checkConfigFilesOwnershipAndPermissions(ownerName string, ownerGroup string
}
}
PathHasPermissions(c.test, configPath, configPathFilePermissions)
+
+ return true
}
}
-func checkDifferentTokenInLaunchdConfig(c check) {
- require.NotEmpty(c.test, c.installOptions.installToken, "installation token has not been provided")
+func checkDifferentTokenInLaunchdConfig(c check) bool {
+ if !assert.NotEmpty(c.test, c.installOptions.installToken, "installation token has not been provided") {
+ return false
+ }
conf, err := getLaunchdConfig(launchdPath)
- require.NoError(c.test, err)
+ if !assert.NoError(c.test, err) {
+ return false
+ }
- require.Equal(c.test, "different"+c.installOptions.installToken, conf.EnvironmentVariables.InstallationToken, "installation token is different than expected")
+ return assert.Equal(c.test, "different"+c.installOptions.installToken, conf.EnvironmentVariables.InstallationToken, "installation token is different than expected")
}
-func checkGroupExists(c check) {
- exists := dsclKeyExistsForPath(c.test, "/Groups", systemGroup)
- require.True(c.test, exists, "group has not been created")
+func checkGroupExists(c check) bool {
+ exists, err := dsclKeyExistsForPath(c.test, "/Groups", systemGroup)
+ assert.NoError(c.test, err)
+ return assert.True(c.test, exists, "group has not been created")
}
-func checkGroupNotExists(c check) {
- exists := dsclKeyExistsForPath(c.test, "/Groups", systemGroup)
- require.False(c.test, exists, "group has been created")
+func checkGroupNotExists(c check) bool {
+ exists, err := dsclKeyExistsForPath(c.test, "/Groups", systemGroup)
+ assert.NoError(c.test, err)
+ return assert.False(c.test, exists, "group has been created")
}
-func checkHostmetricsOwnershipAndPermissions(ownerName string, ownerGroup string) func(c check) {
- return func(c check) {
+func checkHostmetricsOwnershipAndPermissions(ownerName string, ownerGroup string) func(c check) bool {
+ return func(c check) bool {
PathHasOwner(c.test, hostmetricsConfigPath, ownerName, ownerGroup)
PathHasPermissions(c.test, hostmetricsConfigPath, confDPathFilePermissions)
+ return true
}
}
-func checkLaunchdConfigCreated(c check) {
- require.FileExists(c.test, launchdPath, "launchd configuration has not been created properly")
+func checkLaunchdConfigCreated(c check) bool {
+ return assert.FileExists(c.test, launchdPath, "launchd configuration has not been created properly")
}
-func checkLaunchdConfigNotCreated(c check) {
- require.NoFileExists(c.test, launchdPath, "launchd configuration has been created")
+func checkLaunchdConfigNotCreated(c check) bool {
+ return assert.NoFileExists(c.test, launchdPath, "launchd configuration has been created")
}
-func checkPackageCreated(c check) {
+func checkPackageCreated(c check) bool {
re, err := regexp.Compile("Package downloaded to: .*/otelcol-sumo.pkg")
- require.NoError(c.test, err)
+ if !assert.NoError(c.test, err) {
+ return false
+ }
matchedLine := ""
for _, line := range c.output {
@@ -101,96 +113,100 @@ func checkPackageCreated(c check) {
matchedLine = line
}
}
- require.NotEmpty(c.test, matchedLine, "package path not in output")
+ if !assert.NotEmpty(c.test, matchedLine, "package path not in output") {
+ return false
+ }
packagePath := strings.TrimPrefix(matchedLine, "Package downloaded to: ")
- require.FileExists(c.test, packagePath, "package has not been created")
+ return assert.FileExists(c.test, packagePath, "package has not been created")
}
-func checkTokenInLaunchdConfig(c check) {
- require.NotEmpty(c.test, c.installOptions.installToken, "installation token has not been provided")
+func checkTokenInLaunchdConfig(c check) bool {
+ if !assert.NotEmpty(c.test, c.installOptions.installToken, "installation token has not been provided") {
+ return false
+ }
conf, err := getLaunchdConfig(launchdPath)
- require.NoError(c.test, err)
-
- require.Equal(c.test, c.installOptions.installToken, conf.EnvironmentVariables.InstallationToken, "installation token is different than expected")
-}
-
-func checkEphemeralInConfig(p string) func(c check) {
- return func(c check) {
- assert.True(c.test, c.installOptions.ephemeral, "ephemeral was not specified")
-
- conf, err := getConfig(p)
- require.NoError(c.test, err, "error while reading configuration")
-
- assert.True(c.test, conf.Extensions.Sumologic.Ephemeral, "ephemeral is not true")
+ if !assert.NoError(c.test, err) {
+ return false
}
-}
-
-func checkEphemeralNotInConfig(p string) func(c check) {
- return func(c check) {
- assert.False(c.test, c.installOptions.ephemeral, "ephemeral was specified")
- conf, err := getConfig(p)
- require.NoError(c.test, err, "error while reading configuration")
-
- assert.False(c.test, conf.Extensions.Sumologic.Ephemeral, "ephemeral is true")
- }
+ return assert.Equal(c.test, c.installOptions.installToken, conf.EnvironmentVariables.InstallationToken, "installation token is different than expected")
}
-func checkUserExists(c check) {
- exists := dsclKeyExistsForPath(c.test, "/Users", systemUser)
- require.True(c.test, exists, "user has not been created")
+func checkUserExists(c check) bool {
+ exists, err := dsclKeyExistsForPath(c.test, "/Users", systemUser)
+ assert.NoError(c.test, err)
+ return assert.True(c.test, exists, "user has not been created")
}
-func checkUserNotExists(c check) {
- exists := dsclKeyExistsForPath(c.test, "/Users", systemUser)
- require.False(c.test, exists, "user has been created")
+func checkUserNotExists(c check) bool {
+ exists, err := dsclKeyExistsForPath(c.test, "/Users", systemUser)
+ assert.NoError(c.test, err)
+ return assert.False(c.test, exists, "user has been created")
}
-func preActionInstallPackage(c check) {
+func preActionInstallPackage(c check) bool {
+ c.installOptions.installToken = installToken
+ c.installOptions.apiBaseURL = mockAPIBaseURL
c.code, c.output, c.errorOutput, c.err = runScript(c)
+ return assert.NoError(c.test, c.err)
}
-func preActionInstallPackageWithDifferentAPIBaseURL(c check) {
- c.installOptions.apiBaseURL = "different" + c.installOptions.apiBaseURL
+func preActionInstallPackageWithDifferentAPIBaseURL(c check) bool {
+ c.installOptions.installToken = installToken
+ c.installOptions.apiBaseURL = path.Join(c.installOptions.apiBaseURL, "different")
c.code, c.output, c.errorOutput, c.err = runScript(c)
+ return assert.NoError(c.test, c.err)
}
-func preActionInstallPackageWithDifferentTags(c check) {
+func preActionInstallPackageWithDifferentTags(c check) bool {
+ c.installOptions.installToken = installToken
c.installOptions.tags = map[string]string{
"some": "tag",
}
c.code, c.output, c.errorOutput, c.err = runScript(c)
+ return assert.NoError(c.test, c.err)
}
-func preActionInstallPackageWithNoAPIBaseURL(c check) {
- c.installOptions.apiBaseURL = ""
+func preActionInstallPackageWithNoAPIBaseURL(c check) bool {
+ c.installOptions.installToken = installToken
+ c.installOptions.apiBaseURL = emptyAPIBaseURL
c.code, c.output, c.errorOutput, c.err = runScript(c)
+ return assert.NoError(c.test, c.err)
}
-func preActionInstallPackageWithNoTags(c check) {
+func preActionInstallPackageWithNoTags(c check) bool {
+ c.installOptions.installToken = installToken
c.installOptions.tags = nil
c.code, c.output, c.errorOutput, c.err = runScript(c)
+ return assert.NoError(c.test, c.err)
}
-func preActionMockLaunchdConfig(c check) {
+func preActionMockLaunchdConfig(c check) bool {
f, err := os.Create(launchdPath)
- require.NoError(c.test, err)
+ if !assert.NoError(c.test, err) {
+ return false
+ }
err = f.Chmod(fs.FileMode(launchdPathFilePermissions))
- require.NoError(c.test, err)
+ if !assert.NoError(c.test, err) {
+ return false
+ }
conf := NewLaunchdConfig()
+ conf.EnvironmentVariables.InstallationToken = installToken
err = saveLaunchdConfig(launchdPath, conf)
- require.NoError(c.test, err)
+ return assert.NoError(c.test, err)
}
-func preActionWriteDifferentTokenToLaunchdConfig(c check) {
+func preActionWriteDifferentTokenToLaunchdConfig(c check) bool {
conf, err := getLaunchdConfig(launchdPath)
- require.NoError(c.test, err)
+ if !assert.NoError(c.test, err) {
+ return false
+ }
conf.EnvironmentVariables.InstallationToken = "different" + c.installOptions.installToken
err = saveLaunchdConfig(launchdPath, conf)
- require.NoError(c.test, err)
+ return assert.NoError(c.test, err)
}
diff --git a/install-script/test/check_linux.go b/install-script/test/check_linux.go
index 23e5cf28..03e9364f 100644
--- a/install-script/test/check_linux.go
+++ b/install-script/test/check_linux.go
@@ -6,264 +6,251 @@ import (
"os"
"os/exec"
"os/user"
- "path/filepath"
"strconv"
"strings"
"testing"
"github.com/joho/godotenv"
"github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
)
func checkACLAvailability(c check) bool {
return assert.FileExists(&testing.T{}, "/usr/bin/getfacl", "File ACLS is not supported")
}
-func checkConfigFilesOwnershipAndPermissions(ownerName string, ownerGroup string) func(c check) {
- return func(c check) {
- etcPathGlob := filepath.Join(etcPath, "*")
- etcPathNestedGlob := filepath.Join(etcPath, "*", "*")
-
- for _, glob := range []string{etcPathGlob, etcPathNestedGlob} {
- paths, err := filepath.Glob(glob)
- require.NoError(c.test, err)
- for _, path := range paths {
- var permissions uint32
- info, err := os.Stat(path)
- require.NoError(c.test, err)
- if info.IsDir() {
- if path == opampDPath {
- permissions = opampDPermissions
- } else {
- permissions = configPathDirPermissions
- }
- } else {
- permissions = configPathFilePermissions
- }
- PathHasPermissions(c.test, path, permissions)
- PathHasOwner(c.test, configPath, ownerName, ownerGroup)
- }
- }
- PathHasPermissions(c.test, configPath, configPathFilePermissions)
- }
-}
-
-func checkDifferentTokenInConfig(c check) {
+func checkDifferentTokenInConfig(c check) bool {
conf, err := getConfig(userConfigPath)
- require.NoError(c.test, err, "error while reading configuration")
+ if !assert.NoError(c.test, err, "error while reading configuration") {
+ return false
+ }
- require.Equal(c.test, "different"+c.installOptions.installToken, conf.Extensions.Sumologic.InstallationToken, "installation token is different than expected")
+ return assert.Equal(c.test, "different"+c.installOptions.installToken, conf.Extensions.Sumologic.InstallationToken, "installation token is different than expected")
}
-func checkDifferentTokenInEnvFile(c check) {
- require.NotEmpty(c.test, c.installOptions.installToken, "installation token has not been provided")
+func checkDifferentTokenInEnvFile(c check) bool {
+ if !assert.NotEmpty(c.test, c.installOptions.installToken, "installation token has not been provided") {
+ return false
+ }
envs, err := godotenv.Read(tokenEnvFilePath)
- require.NoError(c.test, err)
+ if !assert.NoError(c.test, err) {
+ return false
+ }
if _, ok := envs["SUMOLOGIC_INSTALL_TOKEN"]; ok {
- require.Equal(c.test, "different"+c.installOptions.installToken, envs["SUMOLOGIC_INSTALL_TOKEN"], "installation token is different than expected")
+ if !assert.Equal(c.test, "different"+c.installOptions.installToken, envs["SUMOLOGIC_INSTALL_TOKEN"], "installation token is different than expected") {
+ return false
+ }
} else {
- require.Equal(c.test, "different"+c.installOptions.installToken, envs["SUMOLOGIC_INSTALLATION_TOKEN"], "installation token is different than expected")
+ if !assert.Equal(c.test, "different"+c.installOptions.installToken, envs["SUMOLOGIC_INSTALLATION_TOKEN"], "installation token is different than expected") {
+ return false
+ }
}
+ return true
}
-func checkDownloadTimeout(c check) {
+func checkDownloadTimeout(c check) bool {
output := strings.Join(c.errorOutput, "\n")
count := strings.Count(output, "Operation timed out after")
- require.Equal(c.test, 6, count)
+ return assert.Equal(c.test, 6, count)
}
-func checkHostmetricsOwnershipAndPermissions(ownerName string, ownerGroup string) func(c check) {
- return func(c check) {
+func checkHostmetricsOwnershipAndPermissions(ownerName string, ownerGroup string) func(c check) bool {
+ return func(c check) bool {
PathHasOwner(c.test, hostmetricsConfigPath, ownerName, ownerGroup)
PathHasPermissions(c.test, hostmetricsConfigPath, configPathFilePermissions)
+ return true
}
}
-func checkOutputUserAddWarnings(c check) {
+func checkOutputUserAddWarnings(c check) bool {
output := strings.Join(c.output, "\n")
- require.NotContains(c.test, output, "useradd", "unexpected useradd output")
+ if !assert.NotContains(c.test, output, "useradd", "unexpected useradd output") {
+ return false
+ }
errOutput := strings.Join(c.errorOutput, "\n")
- require.NotContains(c.test, errOutput, "useradd", "unexpected useradd output")
-}
-
-func checkTokenEnvFileCreated(c check) {
- require.FileExists(c.test, tokenEnvFilePath, "env token file has not been created")
+ return assert.NotContains(c.test, errOutput, "useradd", "unexpected useradd output")
}
-func checkTokenEnvFileNotCreated(c check) {
- require.NoFileExists(c.test, tokenEnvFilePath, "env token file not been created")
+func checkTokenEnvFileCreated(c check) bool {
+ return assert.FileExists(c.test, tokenEnvFilePath, "env token file has not been created")
}
-func checkTokenInConfig(c check) {
- require.NotEmpty(c.test, c.installOptions.installToken, "installation token has not been provided")
-
- conf, err := getConfig(userConfigPath)
- require.NoError(c.test, err, "error while reading configuration")
-
- require.Equal(c.test, c.installOptions.installToken, conf.Extensions.Sumologic.InstallationToken, "installation token is different than expected")
-}
-
-func checkTokenInSumoConfig(c check) {
- require.NotEmpty(c.test, c.installOptions.installToken, "installation token has not been provided")
-
- conf, err := getConfig(configPath)
- require.NoError(c.test, err, "error while reading configuration")
-
- require.Equal(c.test, c.installOptions.installToken, conf.Extensions.Sumologic.InstallationToken, "installation token is different than expected")
+func checkTokenEnvFileNotCreated(c check) bool {
+ return assert.NoFileExists(c.test, tokenEnvFilePath, "env token file has been created")
}
-func checkTokenInEnvFile(c check) {
- require.NotEmpty(c.test, c.installOptions.installToken, "installation token has not been provided")
+func checkTokenInEnvFile(c check) bool {
+ if !assert.NotEmpty(c.test, c.installOptions.installToken, "installation token has not been provided") {
+ return false
+ }
envs, err := godotenv.Read(tokenEnvFilePath)
- require.NoError(c.test, err)
+ if !assert.NoError(c.test, err) {
+ return false
+ }
if _, ok := envs["SUMOLOGIC_INSTALL_TOKEN"]; ok {
- require.Equal(c.test, c.installOptions.installToken, envs["SUMOLOGIC_INSTALL_TOKEN"], "installation token is different than expected")
+ if !assert.Equal(c.test, c.installOptions.installToken, envs["SUMOLOGIC_INSTALL_TOKEN"], "installation token is different than expected") {
+ return false
+ }
} else {
- require.Equal(c.test, c.installOptions.installToken, envs["SUMOLOGIC_INSTALLATION_TOKEN"], "installation token is different than expected")
- }
-}
-
-func checkEphemeralInConfig(p string) func(c check) {
- return func(c check) {
- assert.True(c.test, c.installOptions.ephemeral, "ephemeral was not specified")
-
- conf, err := getConfig(p)
- require.NoError(c.test, err, "error while reading configuration")
-
- assert.True(c.test, conf.Extensions.Sumologic.Ephemeral, "ephemeral is not true")
+ if !assert.Equal(c.test, c.installOptions.installToken, envs["SUMOLOGIC_INSTALLATION_TOKEN"], "installation token is different than expected") {
+ return false
+ }
}
+ return true
}
-func checkEphemeralNotInConfig(p string) func(c check) {
- return func(c check) {
- assert.False(c.test, c.installOptions.ephemeral, "ephemeral was specified")
-
- conf, err := getConfig(p)
- require.NoError(c.test, err, "error while reading configuration")
-
- assert.False(c.test, conf.Extensions.Sumologic.Ephemeral, "ephemeral is true")
+func checkUninstallationOutput(c check) bool {
+ if !assert.Greater(c.test, len(c.output), 1) {
+ return false
}
+ return assert.Contains(c.test, c.output[len(c.output)-1], "Uninstallation completed")
}
-func checkUninstallationOutput(c check) {
- require.Greater(c.test, len(c.output), 1)
- require.Contains(c.test, c.output[len(c.output)-1], "Uninstallation completed")
-}
-
-func checkUserExists(c check) {
+func checkUserExists(c check) bool {
_, err := user.Lookup(systemUser)
- require.NoError(c.test, err, "user has not been created")
+ return assert.NoError(c.test, err, "user has not been created")
}
-func checkVarLogACL(c check) {
+func checkVarLogACL(c check) bool {
if !checkACLAvailability(c) {
- return
+ return true
}
PathHasUserACL(c.test, "/var/log", systemUser, "r-x")
+ return true
}
-func preActionCreateHomeDirectory(c check) {
+func preActionCreateHomeDirectory(c check) bool {
err := os.MkdirAll(libPath, fs.FileMode(etcPathPermissions))
- require.NoError(c.test, err)
+ return assert.NoError(c.test, err)
}
// preActionCreateUser creates the system user and then set it as owner of configPath
-func preActionCreateUser(c check) {
- preActionMockUserConfig(c)
+func preActionCreateUser(c check) bool {
+ if !preActionMockUserConfig(c) {
+ return false
+ }
cmd := exec.Command("useradd", systemUser)
_, err := cmd.CombinedOutput()
- require.NoError(c.test, err)
+ if !assert.NoError(c.test, err) {
+ return false
+ }
f, err := os.Open(configPath)
- require.NoError(c.test, err)
+ if !assert.NoError(c.test, err) {
+ return false
+ }
user, err := user.Lookup(systemUser)
- require.NoError(c.test, err)
+ if !assert.NoError(c.test, err) {
+ return false
+ }
uid, err := strconv.Atoi(user.Uid)
- require.NoError(c.test, err)
+ if !assert.NoError(c.test, err) {
+ return false
+ }
gid, err := strconv.Atoi(user.Gid)
- require.NoError(c.test, err)
+ if !assert.NoError(c.test, err) {
+ return false
+ }
err = f.Chown(uid, gid)
- require.NoError(c.test, err)
+ return assert.NoError(c.test, err)
}
-func preActionMockConfigs(c check) {
- preActionMockConfig(c)
- preActionMockUserConfig(c)
+func preActionMockConfigs(c check) bool {
+ if !preActionMockConfig(c) {
+ return false
+ }
+ return preActionMockUserConfig(c)
}
-func preActionMockEnvFiles(c check) {
+func preActionMockEnvFiles(c check) bool {
err := os.MkdirAll(envDirectoryPath, fs.FileMode(etcPathPermissions))
- require.NoError(c.test, err)
+ if !assert.NoError(c.test, err) {
+ return false
+ }
f, err := os.Create(configPath)
- require.NoError(c.test, err)
+ if !assert.NoError(c.test, err) {
+ return false
+ }
err = f.Chmod(fs.FileMode(configPathFilePermissions))
- require.NoError(c.test, err)
+ return assert.NoError(c.test, err)
}
-func preActionMockStructure(c check) {
- preActionMockConfigs(c)
+func preActionMockStructure(c check) bool {
+ if !preActionMockConfigs(c) {
+ return false
+ }
err := os.MkdirAll(fileStoragePath, os.ModePerm)
- require.NoError(c.test, err)
+ if !assert.NoError(c.test, err) {
+ return false
+ }
content := []byte("#!/bin/sh\necho hello world\n")
err = os.WriteFile(binaryPath, content, 0755)
- require.NoError(c.test, err)
+ return assert.NoError(c.test, err)
}
-func preActionWriteDefaultAPIBaseURLToUserConfig(c check) {
+func preActionWriteDefaultAPIBaseURLToUserConfig(c check) bool {
conf, err := getConfig(userConfigPath)
- require.NoError(c.test, err)
+ if !assert.NoError(c.test, err) {
+ return false
+ }
conf.Extensions.Sumologic.APIBaseURL = apiBaseURL
err = saveConfig(userConfigPath, conf)
- require.NoError(c.test, err)
+ return assert.NoError(c.test, err)
}
-func preActionWriteDifferentDeprecatedTokenToEnvFile(c check) {
- preActionMockEnvFiles(c)
+func preActionWriteDifferentDeprecatedTokenToEnvFile(c check) bool {
+ if !preActionMockEnvFiles(c) {
+ return false
+ }
content := fmt.Sprintf("SUMOLOGIC_INSTALL_TOKEN=different%s", c.installOptions.installToken)
err := os.WriteFile(tokenEnvFilePath, []byte(content), fs.FileMode(etcPathPermissions))
- require.NoError(c.test, err)
+ return assert.NoError(c.test, err)
}
-func preActionWriteDifferentTokenToEnvFile(c check) {
- preActionMockEnvFiles(c)
+func preActionWriteDifferentTokenToEnvFile(c check) bool {
+ if !preActionMockEnvFiles(c) {
+ return false
+ }
content := fmt.Sprintf("SUMOLOGIC_INSTALLATION_TOKEN=different%s", c.installOptions.installToken)
err := os.WriteFile(tokenEnvFilePath, []byte(content), fs.FileMode(etcPathPermissions))
- require.NoError(c.test, err)
+ return assert.NoError(c.test, err)
}
-func preActionWriteDifferentTokenToUserConfig(c check) {
+func preActionWriteDifferentTokenToUserConfig(c check) bool {
conf, err := getConfig(userConfigPath)
- require.NoError(c.test, err)
+ if !assert.NoError(c.test, err) {
+ return false
+ }
conf.Extensions.Sumologic.InstallationToken = "different" + c.installOptions.installToken
err = saveConfig(userConfigPath, conf)
- require.NoError(c.test, err)
+ return assert.NoError(c.test, err)
}
-func preActionWriteTokenToUserConfig(c check) {
+func preActionWriteTokenToUserConfig(c check) bool {
conf, err := getConfig(userConfigPath)
- require.NoError(c.test, err)
+ if !assert.NoError(c.test, err) {
+ return false
+ }
conf.Extensions.Sumologic.InstallationToken = c.installOptions.installToken
err = saveConfig(userConfigPath, conf)
- require.NoError(c.test, err)
+ return assert.NoError(c.test, err)
}
diff --git a/install-script/test/check_unix.go b/install-script/test/check_unix.go
index 71e3fad7..f1683b39 100644
--- a/install-script/test/check_unix.go
+++ b/install-script/test/check_unix.go
@@ -10,43 +10,116 @@ import (
"syscall"
"testing"
- "github.com/stretchr/testify/require"
+ "github.com/stretchr/testify/assert"
+ "gopkg.in/yaml.v3"
)
-func checkAbortedDueToNoToken(c check) {
- require.Greater(c.test, len(c.output), 1)
- require.Contains(c.test, c.output[len(c.output)-2], "Installation token has not been provided. Please set the 'SUMOLOGIC_INSTALLATION_TOKEN' environment variable.")
- require.Contains(c.test, c.output[len(c.output)-1], "You can ignore this requirement by adding '--skip-installation-token argument.")
+type configRoot struct {
+ Extensions *configExtensions `yaml:"extensions,omitempty"`
}
-func preActionMockConfig(c check) {
+type configExtensions struct {
+ Sumologic *sumologicExt `yaml:"sumologic,omitempty"`
+}
+
+type sumologicExt struct {
+ Ephemeral bool `yaml:"ephemeral,omitempty"`
+}
+
+func checkAbortedDueToNoToken(c check) bool {
+ if !assert.Greater(c.test, len(c.output), 1) {
+ return false
+ }
+ return assert.Contains(c.test, c.output, "Installation token has not been provided. Please set the 'SUMOLOGIC_INSTALLATION_TOKEN' environment variable.")
+}
+
+func checkEphemeralConfigFileCreated(p string) func(c check) bool {
+ return func(c check) bool {
+ return assert.FileExists(c.test, p, "ephemeral config file has not been created")
+ }
+}
+
+func checkEphemeralConfigFileNotCreated(p string) func(c check) bool {
+ return func(c check) bool {
+ return assert.NoFileExists(c.test, p, "ephemeral config file has been created")
+ }
+}
+
+func checkEphemeralEnabledInRemote(p string) func(c check) bool {
+ return func(c check) bool {
+ yamlFile, err := os.ReadFile(p)
+ if assert.NoError(c.test, err, "sumologic remote config file could not be read") {
+ return false
+ }
+
+ var config configRoot
+
+ if assert.NoError(c.test, yaml.Unmarshal(yamlFile, &config), "could not parse yaml") {
+ return false
+ }
+
+ return config.Extensions.Sumologic.Ephemeral
+ }
+}
+
+func checkEphemeralNotEnabledInRemote(p string) func(c check) bool {
+ return func(c check) bool {
+ yamlFile, err := os.ReadFile(p)
+ if err != nil {
+ // assume the error is due to the file not existing, which is valid
+ return true
+ }
+
+ var config configRoot
+
+ if assert.NoError(c.test, yaml.Unmarshal(yamlFile, &config), "could not parse yaml") {
+ return false
+ }
+
+ return !config.Extensions.Sumologic.Ephemeral
+ }
+}
+
+func preActionMockConfig(c check) bool {
err := os.MkdirAll(etcPath, fs.FileMode(etcPathPermissions))
- require.NoError(c.test, err)
+ if !assert.NoError(c.test, err) {
+ return false
+ }
f, err := os.Create(configPath)
- require.NoError(c.test, err)
+ if !assert.NoError(c.test, err) {
+ return false
+ }
err = f.Chmod(fs.FileMode(configPathFilePermissions))
- require.NoError(c.test, err)
+ return assert.NoError(c.test, err)
}
-func preActionMockUserConfig(c check) {
+func preActionMockUserConfig(c check) bool {
err := os.MkdirAll(etcPath, fs.FileMode(etcPathPermissions))
- require.NoError(c.test, err)
+ if !assert.NoError(c.test, err) {
+ return false
+ }
err = os.MkdirAll(confDPath, fs.FileMode(configPathDirPermissions))
- require.NoError(c.test, err)
+ if !assert.NoError(c.test, err) {
+ return false
+ }
f, err := os.Create(userConfigPath)
- require.NoError(c.test, err)
+ if !assert.NoError(c.test, err) {
+ return false
+ }
- err = f.Chmod(fs.FileMode(commonConfigPathFilePermissions))
- require.NoError(c.test, err)
+ err = f.Chmod(fs.FileMode(confDPathFilePermissions))
+ return assert.NoError(c.test, err)
}
-func PathHasOwner(t *testing.T, path string, ownerName string, groupName string) {
+func PathHasOwner(t *testing.T, path string, ownerName string, groupName string) bool {
info, err := os.Stat(path)
- require.NoError(t, err)
+ if !assert.NoError(t, err) {
+ return false
+ }
// get the owning user and group
stat := info.Sys().(*syscall.Stat_t)
@@ -54,11 +127,17 @@ func PathHasOwner(t *testing.T, path string, ownerName string, groupName string)
gid := strconv.FormatUint(uint64(stat.Gid), 10)
usr, err := user.LookupId(uid)
- require.NoError(t, err)
+ if !assert.NoError(t, err) {
+ return false
+ }
group, err := user.LookupGroupId(gid)
- require.NoError(t, err)
-
- require.Equal(t, ownerName, usr.Username, "%s should be owned by user '%s'", path, ownerName)
- require.Equal(t, groupName, group.Name, "%s should be owned by group '%s'", path, groupName)
+ if !assert.NoError(t, err) {
+ return false
+ }
+
+ if !assert.Equal(t, ownerName, usr.Username, "%s should be owned by user '%s'", path, ownerName) {
+ return false
+ }
+ return assert.Equal(t, groupName, group.Name, "%s should be owned by group '%s'", path, groupName)
}
diff --git a/install-script/test/check_windows.go b/install-script/test/check_windows.go
index 1a406db5..6b9246a3 100644
--- a/install-script/test/check_windows.go
+++ b/install-script/test/check_windows.go
@@ -12,7 +12,6 @@ import (
"unsafe"
"github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
"golang.org/x/sys/windows"
)
@@ -29,79 +28,109 @@ type ACLRecord struct {
AccessMode windows.ACCESS_MODE
}
-func checkAbortedDueToNoToken(c check) {
- require.Greater(c.test, len(c.output), 1)
- require.Greater(c.test, len(c.errorOutput), 1)
+func checkAbortedDueToNoToken(c check) bool {
+ if !assert.Greater(c.test, len(c.output), 1) {
+ return false
+ }
+ if !assert.Greater(c.test, len(c.errorOutput), 1) {
+ return false
+ }
// The exact formatting of the error message can be different depending on Powershell version
errorOutput := strings.Join(c.errorOutput, " ")
- require.Contains(c.test, errorOutput, "Installation token has not been provided.")
- require.Contains(c.test, errorOutput, "Please set the SUMOLOGIC_INSTALLATION_TOKEN environment variable.")
+ if !assert.Contains(c.test, errorOutput, "Installation token has not been provided.") {
+ return false
+ }
+ return assert.Contains(c.test, errorOutput, "Please set the SUMOLOGIC_INSTALLATION_TOKEN environment variable.")
}
-func checkBinaryFipsError(c check) {
+func checkBinaryFipsError(c check) bool {
cmd := exec.Command(binaryPath, "--version")
_, err := cmd.Output()
- require.Error(c.test, err, "running on a non-FIPS system must error")
+ if !assert.Error(c.test, err, "running on a non-FIPS system must error") {
+ return false
+ }
exitErr, ok := err.(*exec.ExitError)
- require.True(c.test, ok, "returned error must be of type ExitError")
+ if !assert.True(c.test, ok, "returned error must be of type ExitError") {
+ return false
+ }
- require.Equal(c.test, 2, exitErr.ExitCode(), "got error code while checking version")
- require.Contains(c.test, string(exitErr.Stderr), "not in FIPS mode")
+ if !assert.Equal(c.test, 2, exitErr.ExitCode(), "got error code while checking version") {
+ return false
+ }
+ return assert.Contains(c.test, string(exitErr.Stderr), "not in FIPS mode")
}
-func checkEphemeralNotInConfig(p string) func(c check) {
- return func(c check) {
+func checkEphemeralNotInConfig(p string) func(c check) bool {
+ return func(c check) bool {
assert.False(c.test, c.installOptions.ephemeral, "ephemeral was specified")
conf, err := getConfig(p)
- require.NoError(c.test, err, "error while reading configuration")
+ if !assert.NoError(c.test, err, "error while reading configuration") {
+ return false
+ }
assert.False(c.test, conf.Extensions.Sumologic.Ephemeral, "ephemeral is true")
+ return true
}
}
-func checkEphemeralInConfig(p string) func(c check) {
- return func(c check) {
+func checkEphemeralInConfig(p string) func(c check) bool {
+ return func(c check) bool {
assert.True(c.test, c.installOptions.ephemeral, "ephemeral was not specified")
conf, err := getConfig(p)
- require.NoError(c.test, err, "error while reading configuration")
+ if !assert.NoError(c.test, err, "error while reading configuration") {
+ return false
+ }
assert.True(c.test, conf.Extensions.Sumologic.Ephemeral, "ephemeral is not true")
+ return true
}
}
-func checkTokenInConfig(c check) {
- require.NotEmpty(c.test, c.installOptions.installToken, "installation token has not been provided")
+func checkTokenInConfig(c check) bool {
+ if !assert.NotEmpty(c.test, c.installOptions.installToken, "installation token has not been provided") {
+ return false
+ }
conf, err := getConfig(userConfigPath)
- require.NoError(c.test, err, "error while reading configuration")
+ if !assert.NoError(c.test, err, "error while reading configuration") {
+ return false
+ }
- require.Equal(c.test, c.installOptions.installToken, conf.Extensions.Sumologic.InstallationToken, "installation token is different than expected")
+ return assert.Equal(c.test, c.installOptions.installToken, conf.Extensions.Sumologic.InstallationToken, "installation token is different than expected")
}
-func checkTokenInSumoConfig(c check) {
- require.NotEmpty(c.test, c.installOptions.installToken, "installation token has not been provided")
+func checkTokenInSumoConfig(c check) bool {
+ if !assert.NotEmpty(c.test, c.installOptions.installToken, "installation token has not been provided") {
+ return false
+ }
conf, err := getConfig(configPath)
- require.NoError(c.test, err, "error while reading configuration")
+ if !assert.NoError(c.test, err, "error while reading configuration") {
+ return false
+ }
- require.Equal(c.test, c.installOptions.installToken, conf.Extensions.Sumologic.InstallationToken, "installation token is different than expected")
+ return assert.Equal(c.test, c.installOptions.installToken, conf.Extensions.Sumologic.InstallationToken, "installation token is different than expected")
}
-func checkConfigFilesOwnershipAndPermissions(ownerSid string) func(c check) {
- return func(c check) {
+func checkConfigFilesOwnershipAndPermissions(ownerSid string) func(c check) bool {
+ return func(c check) bool {
etcPathGlob := filepath.Join(etcPath, "*")
etcPathNestedGlob := filepath.Join(etcPath, "*", "*")
for _, glob := range []string{etcPathGlob, etcPathNestedGlob} {
paths, err := filepath.Glob(glob)
- require.NoError(c.test, err)
+ if !assert.NoError(c.test, err) {
+ return false
+ }
for _, path := range paths {
var aclRecords []ACLRecord
info, err := os.Stat(path)
- require.NoError(c.test, err)
+ if !assert.NoError(c.test, err) {
+ return false
+ }
if info.IsDir() {
if path == opampDPath {
aclRecords = opampDPermissions
@@ -115,38 +144,48 @@ func checkConfigFilesOwnershipAndPermissions(ownerSid string) func(c check) {
PathHasOwner(c.test, path, ownerSid)
}
}
+ return true
}
}
-func PathHasOwner(t *testing.T, path string, ownerSID string) {
+func PathHasOwner(t *testing.T, path string, ownerSID string) bool {
securityDescriptor, err := windows.GetNamedSecurityInfo(
path,
windows.SE_FILE_OBJECT,
windows.OWNER_SECURITY_INFORMATION,
)
- require.NoError(t, err)
+ if !assert.NoError(t, err) {
+ return false
+ }
// get the owning user
owner, _, err := securityDescriptor.Owner()
- require.NoError(t, err)
+ if !assert.NoError(t, err) {
+ return false
+ }
- require.Equal(t, ownerSID, owner.String(), "%s should be owned by user '%s'", path, ownerSID)
+ return assert.Equal(t, ownerSID, owner.String(), "%s should be owned by user '%s'", path, ownerSID)
}
-func PathHasWindowsACLs(t *testing.T, path string, expectedACLs []ACLRecord) {
+func PathHasWindowsACLs(t *testing.T, path string, expectedACLs []ACLRecord) bool {
securityDescriptor, err := windows.GetNamedSecurityInfo(
path,
windows.SE_FILE_OBJECT,
windows.DACL_SECURITY_INFORMATION,
)
- require.NoError(t, err)
+ if !assert.NoError(t, err) {
+ return false
+ }
// get the ACL entries
acl, _, err := securityDescriptor.DACL()
- require.NoError(t, err)
- require.NotNil(t, acl)
+ if !assert.NoError(t, err) || !assert.NotNil(t, acl) {
+ return false
+ }
entries, err := GetExplicitEntriesFromACL(acl)
- require.NoError(t, err)
+ if !assert.NoError(t, err) {
+ return false
+ }
aclRecords := []ACLRecord{}
for _, entry := range entries {
aclRecord := ExplicitEntryToACLRecord(entry)
@@ -155,6 +194,7 @@ func PathHasWindowsACLs(t *testing.T, path string, expectedACLs []ACLRecord) {
}
}
assert.Equal(t, expectedACLs, aclRecords, "invalid ACLs for %s", path)
+ return true
}
// GetExplicitEntriesFromACL gets a list of explicit entries from an ACL
diff --git a/install-script/test/command_unix.go b/install-script/test/command_unix.go
index 05d0c40a..3ac98f76 100644
--- a/install-script/test/command_unix.go
+++ b/install-script/test/command_unix.go
@@ -9,15 +9,12 @@ import (
"os"
"os/exec"
"strings"
-
- "github.com/stretchr/testify/require"
)
type installOptions struct {
installToken string
autoconfirm bool
tags map[string]string
- skipConfig bool
skipInstallToken bool
fips bool
envs map[string]string
@@ -30,6 +27,7 @@ type installOptions struct {
opampEndpoint string
downloadOnly bool
dontKeepDownloads bool
+ version string
}
func (io *installOptions) string() []string {
@@ -45,8 +43,8 @@ func (io *installOptions) string() []string {
opts = append(opts, "--fips")
}
- if io.skipConfig {
- opts = append(opts, "--skip-config")
+ if io.downloadOnly {
+ opts = append(opts, "--download-only")
}
if io.skipInstallToken {
@@ -76,8 +74,19 @@ func (io *installOptions) string() []string {
}
}
- if io.apiBaseURL != "" {
- opts = append(opts, "--api", io.apiBaseURL)
+ // 1. If the apiBaseURL is empty, replace it with the mock API's URL.
+ // 2. If the apiBaseURL is equal to the emptyAPIBaseURL constant, don't set
+ // the --api flag.
+ // 3. If none of the above are true, set the --api flag to the value of
+ // apiBaseURL.
+ apiBaseURL := ""
+ if io.apiBaseURL == "" {
+ apiBaseURL = mockAPIBaseURL
+ } else if io.apiBaseURL != emptyAPIBaseURL {
+ apiBaseURL = io.apiBaseURL
+ }
+ if apiBaseURL != "" {
+ opts = append(opts, "--api", apiBaseURL)
}
if io.timeout != 0 {
@@ -88,6 +97,15 @@ func (io *installOptions) string() []string {
opts = append(opts, "--opamp-api", io.opampEndpoint)
}
+ otc_version := os.Getenv("OTC_VERSION")
+ otc_build_number := os.Getenv("OTC_BUILD_NUMBER")
+
+ if io.version != "" {
+ opts = append(opts, "--version", io.version)
+ } else if otc_version != "" && otc_build_number != "" {
+ opts = append(opts, "--version", fmt.Sprintf("%s-%s", otc_version, otc_build_number))
+ }
+
return opts
}
@@ -124,22 +142,24 @@ func runScript(ch check) (int, []string, []string, error) {
cmd.Env = ch.installOptions.buildEnvs()
output := []string{}
+ ch.test.Logf("Running command: %s", strings.Join(ch.installOptions.string(), " "))
+
in, err := cmd.StdinPipe()
if err != nil {
- require.NoError(ch.test, err)
+ return 0, nil, nil, err
}
defer in.Close()
out, err := cmd.StdoutPipe()
if err != nil {
- require.NoError(ch.test, err)
+ return 0, nil, nil, err
}
defer out.Close()
errOut, err := cmd.StderrPipe()
if err != nil {
- require.NoError(ch.test, err)
+ return 0, nil, nil, err
}
defer errOut.Close()
@@ -148,7 +168,7 @@ func runScript(ch check) (int, []string, []string, error) {
// Start the process
if err = cmd.Start(); err != nil {
- require.NoError(ch.test, err)
+ return 0, nil, nil, err
}
// Read the results from the process
@@ -167,8 +187,9 @@ func runScript(ch check) (int, []string, []string, error) {
}
// otherwise ensure there is no error
- require.NoError(ch.test, err)
-
+ if err != nil {
+ return 0, nil, nil, err
+ }
}
// Handle stderr separately
diff --git a/install-script/test/command_windows.go b/install-script/test/command_windows.go
index 47ad5b86..cea52c45 100644
--- a/install-script/test/command_windows.go
+++ b/install-script/test/command_windows.go
@@ -7,8 +7,6 @@ import (
"os"
"os/exec"
"strings"
-
- "github.com/stretchr/testify/require"
)
type installOptions struct {
@@ -50,6 +48,8 @@ func (io *installOptions) string() []string {
if io.apiBaseURL != "" {
opts = append(opts, "-Api", io.apiBaseURL)
+ } else {
+ opts = append(opts, "-Api", mockAPIBaseURL)
}
return opts
@@ -90,20 +90,20 @@ func runScript(ch check) (int, []string, []string, error) {
in, err := cmd.StdinPipe()
if err != nil {
- require.NoError(ch.test, err)
+ return 0, nil, nil, err
}
defer in.Close()
out, err := cmd.StdoutPipe()
if err != nil {
- require.NoError(ch.test, err)
+ return 0, nil, nil, err
}
defer out.Close()
errOut, err := cmd.StderrPipe()
if err != nil {
- require.NoError(ch.test, err)
+ return 0, nil, nil, err
}
defer errOut.Close()
@@ -112,7 +112,7 @@ func runScript(ch check) (int, []string, []string, error) {
// Start the process
if err = cmd.Start(); err != nil {
- require.NoError(ch.test, err)
+ return 0, nil, nil, err
}
// Read the results from the process
@@ -131,8 +131,9 @@ func runScript(ch check) (int, []string, []string, error) {
}
// otherwise ensure there is no error
- require.NoError(ch.test, err)
-
+ if err != nil {
+ return 0, nil, nil, err
+ }
}
// Handle stderr separately
diff --git a/install-script/test/common.go b/install-script/test/common.go
index f82b3aa8..3af4b9c0 100644
--- a/install-script/test/common.go
+++ b/install-script/test/common.go
@@ -1,5 +1,12 @@
package sumologic_scripts_tests
+import (
+ "io"
+ "net"
+ "net/http"
+ "testing"
+)
+
type testSpec struct {
name string
options installOptions
@@ -9,3 +16,29 @@ type testSpec struct {
conditionalChecks []condCheckFunc
installCode int
}
+
+func startMockAPI(t *testing.T) (*http.Server, error) {
+ t.Log("Starting HTTP server")
+ mux := http.NewServeMux()
+ mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
+ if _, err := io.WriteString(w, "200 OK\n"); err != nil {
+ panic(err)
+ }
+ })
+
+ listener, err := net.Listen("tcp", ":3333")
+ if err != nil {
+ return nil, err
+ }
+
+ httpServer := &http.Server{
+ Handler: mux,
+ }
+ go func() {
+ err := httpServer.Serve(listener)
+ if err != nil && err != http.ErrServerClosed {
+ panic(err)
+ }
+ }()
+ return httpServer, nil
+}
diff --git a/install-script/test/common_darwin.go b/install-script/test/common_darwin.go
index a4f1311c..7197c49f 100644
--- a/install-script/test/common_darwin.go
+++ b/install-script/test/common_darwin.go
@@ -9,14 +9,16 @@ import (
"strings"
"testing"
- "github.com/stretchr/testify/require"
+ "github.com/stretchr/testify/assert"
)
-func dsclDeletePath(t *testing.T, path string) {
+func dsclDeletePath(t *testing.T, path string) bool {
cmd := exec.Command("dscl", ".", "-delete", path)
output, err := cmd.CombinedOutput()
- require.NoErrorf(t, err, "error while using dscl to delete path: %s, path: %s", output, path)
- require.Empty(t, string(output))
+ if !assert.NoErrorf(t, err, "error while using dscl to delete path: %s, path: %s", output, path) {
+ return false
+ }
+ return assert.Empty(t, string(output))
}
// The user.Lookup() and user.LookupGroup() functions do not appear to work
@@ -24,25 +26,25 @@ func dsclDeletePath(t *testing.T, path string) {
// has been deleted. There are several GitHub issues in github.com/golang/go
// that describe similar or related behaviour. To work around this issue we use
// the dscl command to determine if a user or group exists.
-func dsclKeyExistsForPath(t *testing.T, path, key string) bool {
+func dsclKeyExistsForPath(t *testing.T, path, key string) (bool, error) {
cmd := exec.Command("dscl", ".", "-list", path)
out, err := cmd.StdoutPipe()
if err != nil {
- require.NoError(t, err)
+ return false, err
}
defer out.Close()
bufOut := bufio.NewReader(out)
if err := cmd.Start(); err != nil {
- require.NoError(t, err)
+ return false, err
}
for {
line, _, err := bufOut.ReadLine()
if string(line) == key {
- return true
+ return true, nil
}
// exit if script finished
@@ -51,82 +53,131 @@ func dsclKeyExistsForPath(t *testing.T, path, key string) bool {
}
// otherwise ensure there is no error
- require.NoError(t, err)
+ if err != nil {
+ return false, err
+ }
}
- return false
+ return false, nil
}
-func forgetPackage(t *testing.T, name string) {
+func forgetPackage(t *testing.T, name string) error {
noReceiptMsg := fmt.Sprintf("No receipt for '%s' found at '/'.", name)
output, err := exec.Command("pkgutil", "--forget", name).CombinedOutput()
if err != nil && !strings.Contains(string(output), noReceiptMsg) {
- require.NoErrorf(t, err, "error forgetting package: %s", string(output))
+ return fmt.Errorf("error forgetting package: %s", string(output))
}
+ return nil
}
-func removeFileIfExists(t *testing.T, path string) {
+func removeFileIfExists(t *testing.T, path string) error {
if _, err := os.Stat(path); err != nil {
- return
+ if os.IsNotExist(err) {
+ return nil
+ }
+ return err
}
- require.NoErrorf(t, os.Remove(path), "error removing file: %s", path)
+ if err := os.Remove(path); err != nil {
+ return fmt.Errorf("error removing file: %s", path)
+ }
+ return nil
}
-func removeDirectoryIfExists(t *testing.T, path string) {
+func removeDirectoryIfExists(t *testing.T, path string) error {
info, err := os.Stat(path)
if err != nil {
- return
+ if os.IsNotExist(err) {
+ return nil
+ }
+ return err
}
- require.Truef(t, info.IsDir(), "path is not a directory: %s", path)
- require.NoErrorf(t, os.RemoveAll(path), "error removing directory: %s", path)
+ if !info.IsDir() {
+ return fmt.Errorf("path is not a directory: %s", path)
+ }
+ if err := os.RemoveAll(path); err != nil {
+ return fmt.Errorf("error removing directory: %s", path)
+ }
+ return nil
}
func tearDown(t *testing.T) {
// Stop service
- unloadLaunchdService(t)
+ if err := unloadLaunchdService(t); err != nil {
+ t.Log(err)
+ }
// Remove files
- removeFileIfExists(t, binaryPath)
- removeFileIfExists(t, launchdPath)
+ if err := removeFileIfExists(t, binaryPath); err != nil {
+ t.Log(err)
+ }
+ if err := removeFileIfExists(t, launchdPath); err != nil {
+ t.Log(err)
+ }
// Remove configuration & data
- removeDirectoryIfExists(t, etcPath)
- removeDirectoryIfExists(t, fileStoragePath)
- removeDirectoryIfExists(t, logDirPath)
- removeDirectoryIfExists(t, appSupportDirPath)
+ if err := removeDirectoryIfExists(t, etcPath); err != nil {
+ t.Log(err)
+ }
+ if err := removeDirectoryIfExists(t, fileStoragePath); err != nil {
+ t.Log(err)
+ }
+ if err := removeDirectoryIfExists(t, logDirPath); err != nil {
+ t.Log(err)
+ }
+ if err := removeDirectoryIfExists(t, appSupportDirPath); err != nil {
+ t.Log(err)
+ }
// Remove user & group
- if dsclKeyExistsForPath(t, "/Users", systemUser) {
+ if exists, err := dsclKeyExistsForPath(t, "/Users", systemUser); err != nil {
+ t.Log(err)
+ } else if exists {
dsclDeletePath(t, fmt.Sprintf("/Users/%s", systemUser))
}
- if dsclKeyExistsForPath(t, "/Groups", systemGroup) {
+ if exists, err := dsclKeyExistsForPath(t, "/Groups", systemGroup); err != nil {
+ t.Log(err)
+ } else if exists {
dsclDeletePath(t, fmt.Sprintf("/Groups/%s", systemGroup))
}
- if dsclKeyExistsForPath(t, "/Users", systemUser) {
+ if exists, err := dsclKeyExistsForPath(t, "/Users", systemUser); err != nil {
+ t.Log(err)
+ } else if exists {
panic(fmt.Sprintf("user exists after deletion: %s", systemUser))
}
- if dsclKeyExistsForPath(t, "/Groups", systemGroup) {
+
+ if exists, err := dsclKeyExistsForPath(t, "/Groups", systemGroup); err != nil {
+ t.Log(err)
+ } else if exists {
panic(fmt.Sprintf("group exists after deletion: %s", systemGroup))
}
// Remove packages
- forgetPackage(t, "com.sumologic.otelcol-sumo-hostmetrics")
- forgetPackage(t, "com.sumologic.otelcol-sumo")
+ if err := forgetPackage(t, "com.sumologic.otelcol-sumo"); err != nil {
+ t.Log(err)
+ }
}
-func unloadLaunchdService(t *testing.T) {
+func unloadLaunchdService(t *testing.T) error {
info, err := os.Stat(launchdPath)
if err != nil {
- return
+ if os.IsNotExist(err) {
+ return nil
+ }
+ return err
}
- require.Falsef(t, info.IsDir(), "launchd config is not a file: %s", launchdPath)
+ if info.IsDir() {
+ return fmt.Errorf("launchd config is a directory: %s", launchdPath)
+ }
output, err := exec.Command("launchctl", "unload", "-w", "otelcol-sumo").Output()
- require.NoErrorf(t, err, "error stopping service: %s", string(output))
+ if err != nil {
+ fmt.Errorf("error stopping service: %s", string(output))
+ }
+ return nil
}
diff --git a/install-script/test/common_linux.go b/install-script/test/common_linux.go
index 42ee014c..0c5731c2 100644
--- a/install-script/test/common_linux.go
+++ b/install-script/test/common_linux.go
@@ -4,8 +4,6 @@ package sumologic_scripts_tests
import (
"testing"
-
- "github.com/stretchr/testify/require"
)
func tearDown(t *testing.T) {
@@ -17,5 +15,8 @@ func tearDown(t *testing.T) {
}
_, _, _, err := runScript(ch)
- require.NoError(t, err)
+ if err != nil {
+ t.Log(err)
+ }
+ return
}
diff --git a/install-script/test/common_unix.go b/install-script/test/common_unix.go
index ffa012d3..960f0dbc 100644
--- a/install-script/test/common_unix.go
+++ b/install-script/test/common_unix.go
@@ -4,24 +4,19 @@ package sumologic_scripts_tests
import (
"context"
- "io"
- "net"
- "net/http"
+ "fmt"
"os"
"testing"
-
- "github.com/stretchr/testify/require"
)
// These checks always have to be true after a script execution
var commonPostChecks = []checkFunc{checkNoBakFilesPresent}
-func cleanCache(t *testing.T) {
- err := os.RemoveAll(cacheDirectory)
- require.NoError(t, err)
+func cleanCache(t *testing.T) error {
+ return os.RemoveAll(cacheDirectory)
}
-func runTest(t *testing.T, spec *testSpec) {
+func runTest(t *testing.T, spec *testSpec) (fErr error) {
ch := check{
test: t,
installOptions: spec.options,
@@ -37,56 +32,59 @@ func runTest(t *testing.T, spec *testSpec) {
defer tearDown(t)
- t.Log("Starting HTTP server")
- mux := http.NewServeMux()
- mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
- if _, err := io.WriteString(w, "200 OK\n"); err != nil {
- panic(err)
- }
- })
-
- listener, err := net.Listen("tcp", ":3333")
- require.NoError(t, err)
-
- httpServer := &http.Server{
- Handler: mux,
+ mockAPI, err := startMockAPI(t)
+ if err != nil {
+ return fmt.Errorf("Failed to start mock API: %s", err)
}
- go func() {
- err := httpServer.Serve(listener)
- if err != nil && err != http.ErrServerClosed {
- panic(err)
- }
- }()
+
defer func() {
- require.NoError(t, httpServer.Shutdown(context.Background()))
+ if err := mockAPI.Shutdown(context.Background()); err != nil {
+ fErr = fmt.Errorf("Failed to shutdown API: %s", err)
+ return
+ }
}()
t.Log("Running pre actions")
for _, a := range spec.preActions {
- a(ch)
+ if ok := a(ch); !ok {
+ return nil
+ }
}
t.Log("Running pre checks")
for _, c := range spec.preChecks {
- c(ch)
+ if ok := c(ch); !ok {
+ return nil
+ }
}
+ t.Log("Running script")
ch.code, ch.output, ch.errorOutput, ch.err = runScript(ch)
+ if ch.err != nil {
+ return ch.err
+ }
// Remove cache in case of curl issue
if ch.code == curlTimeoutErrorCode {
- cleanCache(t)
+ if err := cleanCache(t); err != nil {
+ return err
+ }
}
checkRun(ch)
t.Log("Running common post checks")
for _, c := range commonPostChecks {
- c(ch)
+ if ok := c(ch); !ok {
+ return nil
+ }
}
t.Log("Running post checks")
for _, c := range spec.postChecks {
- c(ch)
+ if ok := c(ch); !ok {
+ return nil
+ }
}
+ return nil
}
diff --git a/install-script/test/common_windows.go b/install-script/test/common_windows.go
index 58a5c585..a6ee0673 100644
--- a/install-script/test/common_windows.go
+++ b/install-script/test/common_windows.go
@@ -5,19 +5,14 @@ package sumologic_scripts_tests
import (
"context"
"fmt"
- "io"
- "net"
- "net/http"
"os/exec"
"testing"
-
- "github.com/stretchr/testify/require"
)
// These checks always have to be true after a script execution
var commonPostChecks = []checkFunc{checkNoBakFilesPresent}
-func runTest(t *testing.T, spec *testSpec) {
+func runTest(t *testing.T, spec *testSpec) (fErr error) {
ch := check{
test: t,
installOptions: spec.options,
@@ -33,52 +28,53 @@ func runTest(t *testing.T, spec *testSpec) {
defer tearDown(t)
- t.Log("Starting HTTP server")
- mux := http.NewServeMux()
- mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
- _, err := io.WriteString(w, "200 OK\n")
- require.NoError(t, err)
- })
-
- listener, err := net.Listen("tcp", ":3333")
- require.NoError(t, err)
-
- httpServer := &http.Server{
- Handler: mux,
+ mockAPI, err := startMockAPI(t)
+ if err != nil {
+ return fmt.Errorf("Failed to start mock API: %s", err)
}
- go func() {
- err := httpServer.Serve(listener)
- if err != nil && err != http.ErrServerClosed {
- require.NoError(t, err)
- }
- }()
+
defer func() {
- require.NoError(t, httpServer.Shutdown(context.Background()))
+ if err := mockAPI.Shutdown(context.Background()); err != nil {
+ fErr = fmt.Errorf("Failed to shutdown API: %s", err)
+ return
+ }
}()
t.Log("Running pre actions")
for _, a := range spec.preActions {
- a(ch)
+ if ok := a(ch); !ok {
+ return nil
+ }
}
t.Log("Running pre checks")
for _, c := range spec.preChecks {
- c(ch)
+ if ok := c(ch); !ok {
+ return nil
+ }
}
ch.code, ch.output, ch.errorOutput, ch.err = runScript(ch)
+ if err != nil {
+ return err
+ }
checkRun(ch)
t.Log("Running common post checks")
for _, c := range commonPostChecks {
- c(ch)
+ if ok := c(ch); !ok {
+ return nil
+ }
}
t.Log("Running post checks")
for _, c := range spec.postChecks {
- c(ch)
+ if ok := c(ch); !ok {
+ return nil
+ }
}
+ return nil
}
func tearDown(t *testing.T) {
diff --git a/install-script/test/config.go b/install-script/test/config.go
index 66abeb17..98a3b854 100644
--- a/install-script/test/config.go
+++ b/install-script/test/config.go
@@ -31,6 +31,9 @@ func getConfig(path string) (config, error) {
yamlFile, err := os.ReadFile(path)
if err != nil {
+ if err == os.ErrNotExist {
+ return config{}, nil
+ }
return config{}, err
}
diff --git a/install-script/test/consts_common.go b/install-script/test/consts_common.go
index ce994738..86c71a12 100644
--- a/install-script/test/consts_common.go
+++ b/install-script/test/consts_common.go
@@ -9,6 +9,9 @@ const (
GithubOrg = "SumoLogic"
GithubAppRepository = "sumologic-otel-collector"
GithubApiBaseUrl = "https://api.github.com"
+
+ mockAPIBaseURL = "http://127.0.0.1:3333"
+ emptyAPIBaseURL = "empty"
)
func authenticateGithub() string {
diff --git a/install-script/test/consts_darwin.go b/install-script/test/consts_darwin.go
index 5594a88e..296fb9bd 100644
--- a/install-script/test/consts_darwin.go
+++ b/install-script/test/consts_darwin.go
@@ -4,18 +4,9 @@ const (
appSupportDirPath string = "/Library/Application Support/otelcol-sumo"
packageName string = "otelcol-sumo.pkg"
launchdPath string = "/Library/LaunchDaemons/com.sumologic.otelcol-sumo.plist"
- launchdPathFilePermissions uint32 = 0640
+ launchdPathFilePermissions uint32 = 0600
uninstallScriptPath string = appSupportDirPath + "/uninstall.sh"
- // TODO: fix mismatch between darwin permissions & linux binary install permissions
- // 00-otelcol-config-settings.yaml must be writable as the install scripts mutate it
- commonConfigPathFilePermissions uint32 = 0660
- configPathDirPermissions uint32 = 0770
- configPathFilePermissions uint32 = 0440
- confDPathFilePermissions uint32 = 0644
- etcPathPermissions uint32 = 0751
- opampDPermissions uint32 = 0750
-
rootGroup string = "wheel"
rootUser string = "root"
systemGroup string = "_otelcol-sumo"
diff --git a/install-script/test/consts_linux.go b/install-script/test/consts_linux.go
index 0221221b..450818f4 100644
--- a/install-script/test/consts_linux.go
+++ b/install-script/test/consts_linux.go
@@ -4,14 +4,6 @@ const (
envDirectoryPath string = etcPath + "/env"
tokenEnvFilePath string = envDirectoryPath + "/token.env"
- // TODO: fix mismatch between package permissions & expected permissions
- commonConfigPathFilePermissions uint32 = 0550
- configPathDirPermissions uint32 = 0550
- configPathFilePermissions uint32 = 0440
- confDPathFilePermissions uint32 = 0644
- etcPathPermissions uint32 = 0551
- opampDPermissions uint32 = 0750
-
rootGroup string = "root"
rootUser string = "root"
systemGroup string = "otelcol-sumo"
diff --git a/install-script/test/consts_unix.go b/install-script/test/consts_unix.go
index 9b21fb18..9cd65ddf 100644
--- a/install-script/test/consts_unix.go
+++ b/install-script/test/consts_unix.go
@@ -3,22 +3,31 @@
package sumologic_scripts_tests
const (
- binaryPath string = "/usr/local/bin/otelcol-sumo"
- libPath string = "/var/lib/otelcol-sumo"
- fileStoragePath string = libPath + "/file_storage"
- etcPath string = "/etc/otelcol-sumo"
- scriptPath string = "../install.sh"
- configPath string = etcPath + "/sumologic.yaml"
- confDPath string = etcPath + "/conf.d"
- opampDPath string = etcPath + "/opamp.d"
- userConfigPath string = confDPath + "/00-otelcol-config-settings.yaml"
- hostmetricsConfigPath string = confDPath + "/hostmetrics.yaml"
- cacheDirectory string = "/var/cache/otelcol-sumo/"
- logDirPath string = "/var/log/otelcol-sumo"
+ binaryPath = "/usr/local/bin/otelcol-sumo"
+ libPath = "/var/lib/otelcol-sumo"
+ fileStoragePath = libPath + "/file_storage"
+ etcPath = "/etc/otelcol-sumo"
+ scriptPath = "../install.sh"
+ configPath = etcPath + "/sumologic.yaml"
+ confDPath = etcPath + "/conf.d"
+ confDAvailablePath = etcPath + "/conf.d-available"
+ opampDPath = etcPath + "/opamp.d"
+ userConfigPath = confDPath + "/00-otelcol-config-settings.yaml"
+ hostmetricsConfigPath = confDPath + "/hostmetrics.yaml"
+ cacheDirectory = "/var/cache/otelcol-sumo/"
+ logDirPath = "/var/log/otelcol-sumo"
+ sumoRemotePath = "/etc/otelcol-sumo/sumologic-remote.yaml"
- installToken string = "token"
- installTokenEnv string = "SUMOLOGIC_INSTALLATION_TOKEN"
- apiBaseURL string = "https://open-collectors.sumologic.com"
+ installToken = "token"
+ installTokenEnv = "SUMOLOGIC_INSTALLATION_TOKEN"
+ apiBaseURL = "https://open-collectors.sumologic.com"
+ ephemeralConfigPath = confDPath + "/ephemeral.yaml"
- curlTimeoutErrorCode int = 28
+ curlTimeoutErrorCode = 28
+
+ configPathDirPermissions uint32 = 0770
+ configPathFilePermissions uint32 = 0660
+ confDPathFilePermissions uint32 = 0660
+ etcPathPermissions uint32 = 0771
+ opampDPermissions uint32 = 0770
)
diff --git a/install-script/test/consts_windows.go b/install-script/test/consts_windows.go
index 6257288a..1253414c 100644
--- a/install-script/test/consts_windows.go
+++ b/install-script/test/consts_windows.go
@@ -20,6 +20,7 @@ const (
opampDPath = etcPath + `\opamp.d`
userConfigPath = confDPath + `\common.yaml`
hostmetricsConfigPath = confDPath + `\hostmetrics.yaml`
+ sumoRemotePath = etcPath + `\sumologic-remote.yaml`
installToken string = "token"
installTokenEnv string = "SUMOLOGIC_INSTALLATION_TOKEN"
diff --git a/install-script/test/install_darwin_test.go b/install-script/test/install_darwin_test.go
index 89bc973f..af765c0e 100644
--- a/install-script/test/install_darwin_test.go
+++ b/install-script/test/install_darwin_test.go
@@ -22,7 +22,7 @@ func TestInstallScriptDarwin(t *testing.T) {
options: installOptions{},
preChecks: notInstalledChecks,
postChecks: append(notInstalledChecks, checkAbortedDueToNoToken),
- installCode: 2,
+ installCode: 1,
},
{
name: "download only",
@@ -56,33 +56,14 @@ func TestInstallScriptDarwin(t *testing.T) {
installCode: 1,
},
{
- // Skip config is not supported on Darwin
- name: "skip config",
+ name: "skip installation token",
options: installOptions{
- skipConfig: true,
skipInstallToken: true,
},
preChecks: notInstalledChecks,
postChecks: notInstalledChecks,
installCode: 1,
},
- {
- name: "skip installation token",
- options: installOptions{
- skipInstallToken: true,
- },
- preChecks: notInstalledChecks,
- postChecks: []checkFunc{
- checkBinaryCreated,
- checkBinaryIsRunning,
- checkConfigCreated,
- checkConfigFilesOwnershipAndPermissions(systemUser, systemGroup),
- checkUserConfigCreated,
- checkLaunchdConfigCreated,
- checkHomeDirectoryCreated,
- },
- installCode: 1, // because of invalid installation token
- },
{
name: "installation token only",
options: installOptions{
@@ -95,7 +76,8 @@ func TestInstallScriptDarwin(t *testing.T) {
checkConfigCreated,
checkConfigFilesOwnershipAndPermissions(systemUser, systemGroup),
checkUserConfigCreated,
- checkEphemeralNotInConfig(userConfigPath),
+ checkEphemeralConfigFileNotCreated(ephemeralConfigPath),
+ checkEphemeralNotEnabledInRemote(sumoRemotePath),
checkLaunchdConfigCreated,
checkTokenInLaunchdConfig,
checkUserExists,
@@ -103,7 +85,6 @@ func TestInstallScriptDarwin(t *testing.T) {
checkHostmetricsConfigNotCreated,
checkHomeDirectoryCreated,
},
- installCode: 1, // because of invalid installation token
},
{
name: "installation token and ephemeral",
@@ -118,7 +99,8 @@ func TestInstallScriptDarwin(t *testing.T) {
checkConfigCreated,
checkConfigFilesOwnershipAndPermissions(systemUser, systemGroup),
checkUserConfigCreated,
- checkEphemeralInConfig(userConfigPath),
+ checkEphemeralConfigFileCreated(ephemeralConfigPath),
+ checkEphemeralNotEnabledInRemote(sumoRemotePath),
checkLaunchdConfigCreated,
checkTokenInLaunchdConfig,
checkUserExists,
@@ -126,13 +108,12 @@ func TestInstallScriptDarwin(t *testing.T) {
checkHostmetricsConfigNotCreated,
checkHomeDirectoryCreated,
},
- installCode: 1, // because of invalid installation token
},
{
name: "override default config",
options: installOptions{
- skipInstallToken: true,
- autoconfirm: true,
+ autoconfirm: true,
+ installToken: installToken,
},
preActions: []checkFunc{preActionMockConfig},
preChecks: []checkFunc{
@@ -149,7 +130,7 @@ func TestInstallScriptDarwin(t *testing.T) {
checkUserConfigCreated,
checkLaunchdConfigCreated,
},
- installCode: 1, // because of invalid installation token
+ installCode: 0,
},
{
name: "installation token and hostmetrics",
@@ -172,7 +153,7 @@ func TestInstallScriptDarwin(t *testing.T) {
checkHostmetricsOwnershipAndPermissions(systemUser, systemGroup),
checkHomeDirectoryCreated,
},
- installCode: 1, // because of invalid installation token
+ installCode: 0,
},
{
name: "installation token and remotely-managed",
@@ -187,15 +168,18 @@ func TestInstallScriptDarwin(t *testing.T) {
checkConfigCreated,
checkRemoteConfigDirectoryCreated,
checkConfigFilesOwnershipAndPermissions(systemUser, systemGroup),
- checkUserConfigCreated,
- checkEphemeralNotInConfig(configPath),
+ checkUserConfigNotCreated,
+ checkEphemeralConfigFileNotCreated(ephemeralConfigPath),
+ checkEphemeralNotEnabledInRemote(sumoRemotePath),
checkLaunchdConfigCreated,
checkTokenInLaunchdConfig,
checkUserExists,
checkGroupExists,
checkHomeDirectoryCreated,
},
- installCode: 1, // because of invalid installation token
+ // TODO(JK): this succeeds when testing locally but fails in CI,
+ // I need to determine why this is the case
+ installCode: 1,
},
{
name: "installation token, remotely-managed, and ephemeral",
@@ -211,38 +195,18 @@ func TestInstallScriptDarwin(t *testing.T) {
checkConfigCreated,
checkRemoteConfigDirectoryCreated,
checkConfigFilesOwnershipAndPermissions(systemUser, systemGroup),
- checkUserConfigCreated,
- checkEphemeralInConfig(configPath),
- checkLaunchdConfigCreated,
- checkTokenInLaunchdConfig,
- checkUserExists,
- checkGroupExists,
- checkHomeDirectoryCreated,
- },
- installCode: 1, // because of invalid installation token
- },
- {
- name: "installation token only, binary not in PATH",
- options: installOptions{
- installToken: installToken,
- envs: map[string]string{
- "PATH": "/sbin:/bin:/usr/sbin:/usr/bin",
- },
- },
- preChecks: notInstalledChecks,
- postChecks: []checkFunc{
- checkBinaryCreated,
- checkBinaryIsRunning,
- checkConfigCreated,
- checkConfigFilesOwnershipAndPermissions(systemUser, systemGroup),
- checkUserConfigCreated,
+ checkUserConfigNotCreated,
+ checkEphemeralConfigFileNotCreated(ephemeralConfigPath),
+ checkEphemeralEnabledInRemote(sumoRemotePath),
checkLaunchdConfigCreated,
checkTokenInLaunchdConfig,
checkUserExists,
checkGroupExists,
checkHomeDirectoryCreated,
},
- installCode: 1, // because of invalid installation token
+ // TODO(JK): this succeeds when testing locally but fails in CI,
+ // I need to determine why this is the case
+ installCode: 1,
},
{
name: "same installation token in launchd config",
@@ -267,7 +231,7 @@ func TestInstallScriptDarwin(t *testing.T) {
checkTokenInLaunchdConfig,
checkHomeDirectoryCreated,
},
- installCode: 1, // because of invalid installation token
+ installCode: 0,
},
{
name: "different installation token in launchd config",
@@ -301,8 +265,7 @@ func TestInstallScriptDarwin(t *testing.T) {
{
name: "same api base url",
options: installOptions{
- apiBaseURL: apiBaseURL,
- skipInstallToken: true,
+ apiBaseURL: mockAPIBaseURL,
},
preActions: []checkFunc{
preActionInstallPackage,
@@ -320,13 +283,12 @@ func TestInstallScriptDarwin(t *testing.T) {
checkUserConfigCreated,
checkAPIBaseURLInConfig,
},
- installCode: 1, // because of invalid installation token
+ installCode: 0,
},
{
name: "different api base url",
options: installOptions{
- apiBaseURL: apiBaseURL,
- skipInstallToken: true,
+ apiBaseURL: apiBaseURL,
},
preActions: []checkFunc{
preActionInstallPackageWithDifferentAPIBaseURL,
@@ -349,37 +311,16 @@ func TestInstallScriptDarwin(t *testing.T) {
{
name: "adding api base url",
options: installOptions{
- apiBaseURL: apiBaseURL,
- skipInstallToken: true,
+ apiBaseURL: mockAPIBaseURL,
},
preActions: []checkFunc{preActionInstallPackageWithNoAPIBaseURL},
preChecks: []checkFunc{
checkBinaryCreated,
checkConfigCreated,
- checkUserConfigCreated,
- checkUserExists,
- },
- postChecks: []checkFunc{
- checkBinaryCreated,
- checkConfigCreated,
- checkUserConfigCreated,
- checkAPIBaseURLInConfig,
- },
- installCode: 1, // because of invalid installation token
- },
- {
- name: "editing api base url",
- options: installOptions{
- apiBaseURL: apiBaseURL,
- skipInstallToken: true,
- },
- preActions: []checkFunc{
- preActionInstallPackageWithNoAPIBaseURL,
- },
- preChecks: []checkFunc{
- checkBinaryCreated,
- checkConfigCreated,
- checkUserConfigCreated,
+ // The user config file will only exist if non-default values
+ // are used for otelcol-config managed settings such as the
+ // API URL or tags
+ checkUserConfigNotCreated,
checkUserExists,
},
postChecks: []checkFunc{
@@ -388,12 +329,12 @@ func TestInstallScriptDarwin(t *testing.T) {
checkUserConfigCreated,
checkAPIBaseURLInConfig,
},
- installCode: 1, // because of invalid installation token
+ installCode: 0,
},
{
name: "configuration with tags",
options: installOptions{
- skipInstallToken: true,
+ installToken: installToken,
tags: map[string]string{
"lorem": "ipsum",
"foo": "bar",
@@ -411,12 +352,11 @@ func TestInstallScriptDarwin(t *testing.T) {
checkTags,
checkLaunchdConfigCreated,
},
- installCode: 1, // because of invalid installation token
+ installCode: 0,
},
{
name: "same tags",
options: installOptions{
- skipInstallToken: true,
tags: map[string]string{
"lorem": "ipsum",
"foo": "bar",
@@ -442,43 +382,11 @@ func TestInstallScriptDarwin(t *testing.T) {
checkTags,
checkLaunchdConfigCreated,
},
- installCode: 1, // because of invalid installation token
- },
- {
- name: "different tags",
- options: installOptions{
- skipInstallToken: true,
- tags: map[string]string{
- "lorem": "ipsum",
- "foo": "bar",
- "escape_me": "'\\/",
- "slash": "a/b",
- "numeric": "1_024",
- },
- },
- preActions: []checkFunc{
- preActionInstallPackageWithDifferentTags,
- },
- preChecks: []checkFunc{
- checkBinaryCreated,
- checkConfigCreated,
- checkUserConfigCreated,
- checkUserExists,
- },
- postChecks: []checkFunc{
- checkBinaryCreated,
- checkConfigCreated,
- checkUserConfigCreated,
- checkDifferentTags,
- checkLaunchdConfigCreated,
- checkAbortedDueToDifferentTags,
- },
- installCode: 1,
+ installCode: 0,
},
{
name: "editing tags",
options: installOptions{
- skipInstallToken: true,
tags: map[string]string{
"lorem": "ipsum",
"foo": "bar",
@@ -503,11 +411,13 @@ func TestInstallScriptDarwin(t *testing.T) {
checkTags,
checkLaunchdConfigCreated,
},
- installCode: 1, // because of invalid installation token
+ installCode: 0,
},
} {
t.Run(spec.name, func(t *testing.T) {
- runTest(t, &spec)
+ if err := runTest(t, &spec); err != nil {
+ t.Error(err)
+ }
})
}
}
diff --git a/install-script/test/install_unix_test.go b/install-script/test/install_unix_test.go
index 13bd0b82..5b2565b3 100644
--- a/install-script/test/install_unix_test.go
+++ b/install-script/test/install_unix_test.go
@@ -7,62 +7,42 @@ import (
)
func TestInstallScript(t *testing.T) {
+ notInstalledChecks := []checkFunc{
+ checkBinaryNotCreated,
+ checkConfigNotCreated,
+ checkUserConfigNotCreated,
+ }
+
for _, spec := range []testSpec{
{
name: "no arguments",
options: installOptions{},
- preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigNotCreated},
- postChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigNotCreated},
- installCode: 2,
- },
- {
- name: "skip config",
- options: installOptions{
- skipConfig: true,
- skipInstallToken: true,
- },
- preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigNotCreated},
- postChecks: []checkFunc{checkBinaryCreated, checkConfigNotCreated, checkUserConfigNotCreated},
+ preChecks: notInstalledChecks,
+ postChecks: notInstalledChecks,
+ installCode: 1,
},
{
name: "skip installation token",
options: installOptions{
skipInstallToken: true,
},
- preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigNotCreated},
- postChecks: []checkFunc{
- checkBinaryCreated,
- checkBinaryIsRunning,
- checkConfigCreated,
- checkConfigFilesOwnershipAndPermissions(rootUser, rootGroup),
- checkUserConfigNotCreated,
- },
- },
- {
- name: "override default config",
- options: installOptions{
- skipInstallToken: true,
- },
- preActions: []checkFunc{preActionMockConfig},
- preChecks: []checkFunc{checkBinaryNotCreated, checkConfigCreated, checkUserConfigNotCreated},
- postChecks: []checkFunc{checkBinaryCreated, checkBinaryIsRunning, checkConfigCreated, checkConfigOverrided, checkUserConfigNotCreated},
+ preChecks: notInstalledChecks,
+ postChecks: notInstalledChecks,
+ installCode: 1,
},
{
name: "installation token only",
options: installOptions{
installToken: installToken,
},
- preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigNotCreated},
+ preChecks: notInstalledChecks,
postChecks: []checkFunc{
checkBinaryCreated,
checkBinaryIsRunning,
checkConfigCreated,
- checkConfigFilesOwnershipAndPermissions(rootUser, rootGroup),
- checkUserConfigCreated,
- checkEphemeralNotInConfig(userConfigPath),
- checkTokenInConfig,
+ checkEphemeralConfigFileNotCreated(ephemeralConfigPath),
checkHostmetricsConfigNotCreated,
- checkTokenEnvFileNotCreated,
+ checkTokenEnvFileCreated,
},
},
{
@@ -71,17 +51,15 @@ func TestInstallScript(t *testing.T) {
installToken: installToken,
ephemeral: true,
},
- preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigNotCreated},
+ preChecks: notInstalledChecks,
postChecks: []checkFunc{
checkBinaryCreated,
checkBinaryIsRunning,
checkConfigCreated,
- checkConfigFilesOwnershipAndPermissions(rootUser, rootGroup),
- checkUserConfigCreated,
- checkTokenInConfig,
- checkEphemeralInConfig(userConfigPath),
+ checkEphemeralConfigFileCreated(ephemeralConfigPath),
+ checkEphemeralNotEnabledInRemote(sumoRemotePath),
checkHostmetricsConfigNotCreated,
- checkTokenEnvFileNotCreated,
+ checkTokenEnvFileCreated,
},
},
{
@@ -90,17 +68,14 @@ func TestInstallScript(t *testing.T) {
installToken: installToken,
installHostmetrics: true,
},
- preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigNotCreated},
+ preChecks: notInstalledChecks,
postChecks: []checkFunc{
checkBinaryCreated,
checkBinaryIsRunning,
checkConfigCreated,
- checkRemoteConfigDirectoryNotCreated,
- checkConfigFilesOwnershipAndPermissions(rootUser, rootGroup),
- checkUserConfigCreated,
- checkTokenInConfig,
+ checkRemoteConfigDirectoryCreated,
checkHostmetricsConfigCreated,
- checkHostmetricsOwnershipAndPermissions(rootUser, rootGroup),
+ checkHostmetricsOwnershipAndPermissions(systemUser, systemGroup),
},
},
{
@@ -109,15 +84,14 @@ func TestInstallScript(t *testing.T) {
installToken: installToken,
remotelyManaged: true,
},
- preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigNotCreated},
+ preChecks: notInstalledChecks,
postChecks: []checkFunc{
checkBinaryCreated,
checkBinaryIsRunning,
checkConfigCreated,
checkRemoteConfigDirectoryCreated,
- checkConfigFilesOwnershipAndPermissions(rootUser, rootGroup),
- checkTokenInSumoConfig,
- checkEphemeralNotInConfig(configPath),
+ checkEphemeralConfigFileNotCreated(ephemeralConfigPath),
+ checkEphemeralNotEnabledInRemote(sumoRemotePath),
},
},
{
@@ -127,15 +101,14 @@ func TestInstallScript(t *testing.T) {
remotelyManaged: true,
ephemeral: true,
},
- preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigNotCreated},
+ preChecks: notInstalledChecks,
postChecks: []checkFunc{
checkBinaryCreated,
checkBinaryIsRunning,
checkConfigCreated,
checkRemoteConfigDirectoryCreated,
- checkConfigFilesOwnershipAndPermissions(rootUser, rootGroup),
- checkTokenInSumoConfig,
- checkEphemeralInConfig(configPath),
+ checkEphemeralConfigFileNotCreated(ephemeralConfigPath),
+ checkEphemeralEnabledInRemote(sumoRemotePath),
},
},
{
@@ -145,126 +118,21 @@ func TestInstallScript(t *testing.T) {
remotelyManaged: true,
opampEndpoint: "wss://example.com",
},
- preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigNotCreated},
+ preChecks: notInstalledChecks,
postChecks: []checkFunc{
checkBinaryCreated,
checkBinaryIsRunning,
checkConfigCreated,
checkRemoteConfigDirectoryCreated,
- checkConfigFilesOwnershipAndPermissions(rootUser, rootGroup),
- checkTokenInSumoConfig,
- checkEphemeralNotInConfig(configPath),
+ checkEphemeralConfigFileNotCreated(ephemeralConfigPath),
+ checkEphemeralNotEnabledInRemote(sumoRemotePath),
checkOpAmpEndpointSet,
},
},
- {
- name: "installation token only, binary not in PATH",
- options: installOptions{
- installToken: installToken,
- envs: map[string]string{
- "PATH": "/sbin:/bin:/usr/sbin:/usr/bin",
- },
- },
- preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigNotCreated},
- postChecks: []checkFunc{
- checkBinaryCreated,
- checkBinaryIsRunning,
- checkConfigCreated,
- checkConfigFilesOwnershipAndPermissions(rootUser, rootGroup),
- checkUserConfigCreated,
- checkTokenInConfig,
- },
- },
- {
- name: "same installation token",
- options: installOptions{
- installToken: installToken,
- },
- preActions: []checkFunc{preActionMockUserConfig, preActionWriteTokenToUserConfig},
- preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigCreated},
- postChecks: []checkFunc{checkBinaryCreated, checkBinaryIsRunning, checkConfigCreated, checkUserConfigCreated, checkTokenInConfig},
- },
- {
- name: "different installation token",
- options: installOptions{
- installToken: installToken,
- },
- preActions: []checkFunc{preActionMockUserConfig, preActionWriteDifferentTokenToUserConfig},
- preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigCreated},
- postChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigCreated, checkAbortedDueToDifferentToken},
- installCode: 1,
- },
- {
- name: "adding installation token",
- options: installOptions{
- installToken: installToken,
- },
- preActions: []checkFunc{preActionMockUserConfig},
- preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigCreated},
- postChecks: []checkFunc{checkBinaryCreated, checkConfigCreated, checkUserConfigCreated, checkTokenInConfig},
- },
- {
- name: "editing installation token",
- options: installOptions{
- apiBaseURL: apiBaseURL,
- installToken: installToken,
- },
- preActions: []checkFunc{preActionMockUserConfig, preActionWriteEmptyUserConfig},
- preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigCreated},
- postChecks: []checkFunc{checkBinaryCreated, checkConfigCreated, checkUserConfigCreated, checkTokenInConfig},
- },
- {
- name: "same api base url",
- options: installOptions{
- apiBaseURL: apiBaseURL,
- skipInstallToken: true,
- },
- preActions: []checkFunc{preActionMockUserConfig, preActionWriteAPIBaseURLToUserConfig},
- preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigCreated},
- postChecks: []checkFunc{checkBinaryCreated, checkBinaryIsRunning, checkConfigCreated, checkUserConfigCreated, checkAPIBaseURLInConfig},
- },
- {
- name: "different api base url",
- options: installOptions{
- apiBaseURL: apiBaseURL,
- skipInstallToken: true,
- },
- preActions: []checkFunc{preActionMockUserConfig, preActionWriteDifferentAPIBaseURLToUserConfig},
- preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigCreated},
- postChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigCreated,
- checkAbortedDueToDifferentAPIBaseURL},
- installCode: 1,
- },
- {
- name: "adding api base url",
- options: installOptions{
- apiBaseURL: apiBaseURL,
- skipInstallToken: true,
- },
- preActions: []checkFunc{preActionMockUserConfig},
- preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigCreated},
- postChecks: []checkFunc{checkBinaryCreated, checkConfigCreated, checkUserConfigCreated, checkAPIBaseURLInConfig},
- },
- {
- name: "editing api base url",
- options: installOptions{
- apiBaseURL: apiBaseURL,
- skipInstallToken: true,
- },
- preActions: []checkFunc{preActionMockUserConfig, preActionWriteEmptyUserConfig},
- preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigCreated},
- postChecks: []checkFunc{checkBinaryCreated, checkConfigCreated, checkUserConfigCreated, checkAPIBaseURLInConfig},
- },
- {
- name: "empty installation token",
- preActions: []checkFunc{preActionMockUserConfig, preActionWriteDifferentTokenToUserConfig},
- preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigCreated},
- postChecks: []checkFunc{checkBinaryCreated, checkConfigCreated, checkUserConfigCreated, checkDifferentTokenInConfig},
- },
{
name: "configuration with tags",
options: installOptions{
- skipInstallToken: true,
+ installToken: installToken,
tags: map[string]string{
"lorem": "ipsum",
"foo": "bar",
@@ -273,68 +141,19 @@ func TestInstallScript(t *testing.T) {
"numeric": "1_024",
},
},
- preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigNotCreated},
+ preChecks: notInstalledChecks,
postChecks: []checkFunc{
checkBinaryCreated,
checkBinaryIsRunning,
checkConfigCreated,
- checkConfigFilesOwnershipAndPermissions(rootUser, rootGroup),
checkTags,
},
},
- {
- name: "same tags",
- options: installOptions{
- skipInstallToken: true,
- tags: map[string]string{
- "lorem": "ipsum",
- "foo": "bar",
- "escape_me": "'\\/",
- "slash": "a/b",
- "numeric": "1_024",
- },
- },
- preActions: []checkFunc{preActionMockUserConfig, preActionWriteTagsToUserConfig},
- preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigCreated},
- postChecks: []checkFunc{checkBinaryCreated, checkBinaryIsRunning, checkConfigCreated, checkUserConfigCreated, checkTags},
- },
- {
- name: "different tags",
- options: installOptions{
- skipInstallToken: true,
- tags: map[string]string{
- "lorem": "ipsum",
- "foo": "bar",
- "escape_me": "'\\/",
- "slash": "a/b",
- "numeric": "1_024",
- },
- },
- preActions: []checkFunc{preActionMockUserConfig, preActionWriteDifferentTagsToUserConfig},
- preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigCreated},
- postChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigCreated, checkDifferentTags,
- checkAbortedDueToDifferentTags},
- installCode: 1,
- },
- {
- name: "editing tags",
- options: installOptions{
- skipInstallToken: true,
- tags: map[string]string{
- "lorem": "ipsum",
- "foo": "bar",
- "escape_me": "'\\/",
- "slash": "a/b",
- "numeric": "1_024",
- },
- },
- preActions: []checkFunc{preActionMockUserConfig, preActionWriteEmptyUserConfig},
- preChecks: []checkFunc{checkBinaryNotCreated, checkConfigNotCreated, checkUserConfigCreated},
- postChecks: []checkFunc{checkBinaryCreated, checkBinaryIsRunning, checkConfigCreated, checkTags},
- },
} {
t.Run(spec.name, func(t *testing.T) {
- runTest(t, &spec)
+ if err := runTest(t, &spec); err != nil {
+ t.Error(err)
+ }
})
}
}
diff --git a/install-script/test/install_windows_test.go b/install-script/test/install_windows_test.go
index d94df1cb..67d9ff44 100644
--- a/install-script/test/install_windows_test.go
+++ b/install-script/test/install_windows_test.go
@@ -147,7 +147,9 @@ func TestInstallScript(t *testing.T) {
},
} {
t.Run(spec.name, func(t *testing.T) {
- runTest(t, &spec)
+ if err := runTest(t, &spec); err != nil {
+ t.Error(err)
+ }
})
}
}
diff --git a/packages.cmake b/packages.cmake
index 65f091ad..4a25ec0e 100644
--- a/packages.cmake
+++ b/packages.cmake
@@ -125,6 +125,9 @@ macro(build_cpack_config)
# Build CPackConfig
include(CPack)
+ # Create components
+ create_otc_components()
+
# Add a target for each packagecloud distro the package should be published to
set(_pc_user "sumologic")
set(_pc_repo "ci-builds")
@@ -132,25 +135,72 @@ macro(build_cpack_config)
create_packagecloud_publish_target(${_pc_user} ${_pc_repo} ${_pc_distro} ${_package_output})
endforeach()
+ # Add a target for uploading the package to Amazon S3
+ set(_s3_channel "ci-builds")
+ set(_version "${OTC_VERSION}-${BUILD_NUMBER}")
+ set(_s3_bucket "sumologic-osc-${_s3_channel}")
+ set(_s3_path "${_version}/")
+ create_s3_cp_target(${_s3_bucket} ${_s3_path} ${_package_output})
+
# Add a publish-package target to publish the package built above
get_property(_all_publish_targets GLOBAL PROPERTY _all_publish_targets)
add_custom_target(publish-package
DEPENDS ${_all_publish_targets})
+
+ # Add a wait-for-packagecloud-indexing target to wait for Packagecloud to finish indexing
+ create_wait_for_packagecloud_indexing_target(${_pc_user} ${_pc_repo} ${_package_output})
endmacro()
# Create a Packagecloud publish target for uploading a package to a specific
# repository for a specific distribution.
-function(create_packagecloud_publish_target _pc_user _pc_repo _pc_distro _pkg_name)
- set(_pc_output "${_pkg_name}-${_pc_repo}/${_pc_distro}")
- separate_arguments(_packagecloud_push_cmd UNIX_COMMAND "packagecloud push --skip-exists ${_pc_user}/${_pc_repo}/${_pc_distro} ${_pkg_name}")
+function(create_packagecloud_publish_target _pc_user _pc_repo _pc_distro _pkg_path)
+ set(_pc_output "${_pkg_path}-${_pc_repo}/${_pc_distro}")
+ separate_arguments(_packagecloud_push_cmd
+ UNIX_COMMAND "packagecloud push --skip-exists ${_pc_user}/${_pc_repo}/${_pc_distro} ${_pkg_path}")
add_custom_command(OUTPUT ${_pc_output}
COMMAND ${_packagecloud_push_cmd}
- DEPENDS ${_pkg_name}
+ DEPENDS ${_pkg_path}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
VERBATIM)
append_to_publish_targets(${_pc_output})
endfunction()
+# Create a Packagecloud wait for indexing target that will block until
+# Packagecloud has finished indexing packages with the given package name.
+function(create_wait_for_packagecloud_indexing_target _pc_user _pc_repo _pkg_path)
+ set(_pc_output "${_pkg_path}-${_pc_repo}-wait-for-indexing")
+ cmake_path(GET _pkg_path FILENAME _pkg_name)
+ set(_repo_id "${_pc_user}/${_pc_repo}")
+ set(_base_cmd "packagecloud search")
+ set(_query_arg "--query ${_pkg_name}")
+ set(_wait_args "--wait-for-indexing --wait-seconds 30 --wait-max-retries 12")
+ set(_cmd "${_base_cmd} ${_repo_id} ${_query_arg} ${_wait_args}")
+ separate_arguments(_packagecloud_search_cmd UNIX_COMMAND "${_cmd}")
+
+ message(STATUS "wait for indexing command: ${_cmd}")
+
+ add_custom_command(OUTPUT ${_pc_output}
+ COMMAND ${_packagecloud_search_cmd}
+ DEPENDS ${_pkg_name}
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+ VERBATIM)
+
+ add_custom_target(wait-for-packagecloud-indexing
+ DEPENDS ${_pc_output})
+endfunction()
+
+# Create an Amazon S3 publish target for uploading a package to an S3 bucket.
+function(create_s3_cp_target _s3_bucket _s3_path _pkg_path)
+ set(_s3_output "${_pkg_path}-s3-${_s3_bucket}")
+ separate_arguments(_s3_cp_cmd UNIX_COMMAND "aws s3 cp ${_pkg_path} s3://${_s3_bucket}/${_s3_path}")
+ add_custom_command(OUTPUT ${_s3_output}
+ COMMAND ${_s3_cp_cmd}
+ DEPENDS ${_pkg_path}
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+ VERBATIM)
+ append_to_publish_targets(${_s3_output})
+endfunction()
+
# Sets a GitHub output parameter by appending a statement to the file defined by
# the GITHUB_OUTPUT environment variable. It enables the passing of data from
# this CMake project to GitHub Actions.
diff --git a/settings/otc.cmake b/settings/otc.cmake
index 348cac56..1d19c215 100644
--- a/settings/otc.cmake
+++ b/settings/otc.cmake
@@ -22,8 +22,11 @@ macro(set_otc_settings)
# File names
set(OTC_BINARY "otelcol-sumo")
set(OTC_CONFIG_BINARY "otelcol-config")
+ set(OTC_LAUNCHD_CONFIG "com.sumologic.otelcol-sumo.plist")
+ set(OTC_SERVICE_SCRIPT "otelcol-sumo.sh")
set(OTC_SUMOLOGIC_CONFIG "sumologic.yaml")
set(OTC_SYSTEMD_CONFIG "otelcol-sumo.service")
+ set(DOT_KEEP_FILE ".keep")
# Directories
set(OTC_BIN_DIR "usr/local/bin")
@@ -31,11 +34,16 @@ macro(set_otc_settings)
set(OTC_CONFIG_FRAGMENTS_DIR "${OTC_CONFIG_DIR}/conf.d")
set(OTC_CONFIG_FRAGMENTS_AVAILABLE_DIR "${OTC_CONFIG_DIR}/conf.d-available")
set(OTC_USER_ENV_DIR "${OTC_CONFIG_DIR}/env")
+ set(OTC_OPAMPD_DIR "${OTC_CONFIG_DIR}/opamp.d")
set(OTC_STATE_DIR "var/lib/otelcol-sumo")
set(OTC_FILESTORAGE_STATE_DIR "${OTC_STATE_DIR}/file_storage")
set(OTC_LAUNCHD_DIR "Library/LaunchDaemons")
set(OTC_SYSTEMD_DIR "lib/systemd/system")
set(OTC_LOG_DIR "var/log/otelcol-sumo")
+ set(OTC_SHARE_DIR "usr/share/otelcol-sumo")
+ if("${goos}" STREQUAL "darwin")
+ set(OTC_SHARE_DIR "usr/local/share/otelcol-sumo")
+ endif()
# File paths
set(OTC_BIN_PATH "${OTC_BIN_DIR}/${OTC_BINARY}")
@@ -74,6 +82,7 @@ macro(set_otc_settings)
set(GH_ARTIFACT_OTC_BINARY_PATH "${GH_ARTIFACTS_DIR}/${GH_OUTPUT_OTC_BIN}")
set(GH_ARTIFACT_OTC_CONFIG_BINARY_PATH "${GH_ARTIFACTS_DIR}/${GH_OUTPUT_OTC_CONFIG_BIN}")
set(ACL_LOG_FILE_PATHS "/var/log")
+ set(DOT_KEEP_PATH "${ASSETS_DIR}/${DOT_KEEP_FILE}")
##
# Other