Skip to content

Commit

Permalink
Updated main function to allow Collector to be run as a Windows Servi…
Browse files Browse the repository at this point in the history
…ce & added build step for generating Windows MSI (#408)
  • Loading branch information
james-bebbington committed Jul 8, 2020
1 parent 86c8ef5 commit b34888b
Show file tree
Hide file tree
Showing 11 changed files with 260 additions and 19 deletions.
36 changes: 34 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
version: 2.1

parameters:
run-build-publish:
type: boolean
Expand All @@ -10,6 +11,9 @@ parameters:
type: string
default: ""

orbs:
win: circleci/[email protected]

executors:
golang:
docker:
Expand Down Expand Up @@ -150,12 +154,19 @@ workflows:
filters:
tags:
only: /.*/
- windows-msi:
requires:
- cross-compile
filters:
tags:
only: /.*/
- publish-stable:
requires:
- lint
- unit-tests
- integration-tests
- cross-compile
- cross-compile
- windows-msi
filters:
branches:
ignore: /.*/
Expand All @@ -166,7 +177,7 @@ workflows:
- lint
- unit-tests
- integration-tests
- cross-compile
- cross-compile
filters:
branches:
only: /master|release\/.+/
Expand Down Expand Up @@ -244,6 +255,27 @@ jobs:
- store_test_results:
path: testbed/tests/results/junit

windows-msi:
executor:
name: win/default
shell: powershell.exe
steps:
- attach_to_workspace
- run:
name: Install Wix Toolset
command: .\internal\buildscripts\packaging\msi\make.ps1 Install-Tools
- run:
name: Build MSI
command: |
$Version = if ($env:CIRCLE_TAG -match '^v(\d+\.\d+\.\d+)') { $Matches[1] } else { "0.0.1" }
.\internal\buildscripts\packaging\msi\make.ps1 New-MSI -Version $Version
- run:
name: Validate MSI
command: .\internal\buildscripts\packaging\msi\make.ps1 Confirm-MSI
- persist_to_workspace:
root: ~/
paths: project/bin

publish-stable:
docker:
- image: cimg/go:1.14
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,7 @@ coverage.txt
integration-coverage.txt
coverage.html
integration-coverage.html

# Wix
*.wixobj
*.wixpdb
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ docker-otelcontribcol:

.PHONY: otelcontribcol
otelcontribcol:
GO111MODULE=on CGO_ENABLED=0 go build -o ./bin/otelcontribcol_$(GOOS)_$(GOARCH) $(BUILD_INFO) ./cmd/otelcontribcol
GO111MODULE=on CGO_ENABLED=0 go build -o ./bin/otelcontribcol_$(GOOS)_$(GOARCH)$(EXTENSION) $(BUILD_INFO) ./cmd/otelcontribcol


.PHONY: otelcontribcol-all-sys
Expand All @@ -143,7 +143,7 @@ otelcontribcol-linux_arm64:

.PHONY: otelcontribcol-windows_amd64
otelcontribcol-windows_amd64:
GOOS=windows GOARCH=amd64 $(MAKE) otelcontribcol
GOOS=windows GOARCH=amd64 EXTENSION=.exe $(MAKE) otelcontribcol

.PHONY: update-dep
update-dep:
Expand Down
36 changes: 23 additions & 13 deletions cmd/otelcontribcol/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.

// Program otelcontribcol is the Omnition Telemetry Service built on top of
// OpenTelemetry Service.
// Program otelcontribcol is an extension to the OpenTelemetry Collector
// that includes additional components, some vendor-specific, contributed
// from the wider community.
package main

import (
"fmt"
"log"

"go.opentelemetry.io/collector/service"
Expand All @@ -25,14 +27,10 @@ import (
)

func main() {
handleErr := func(message string, err error) {
if err != nil {
log.Fatalf("%s: %v", message, err)
}
}

factories, err := components()
handleErr("Failed to build components", err)
if err != nil {
log.Fatalf("failed to build components: %v", err)
}

info := service.ApplicationStartInfo{
ExeName: "otelcontribcol",
Expand All @@ -41,9 +39,21 @@ func main() {
GitHash: version.GitHash,
}

svc, err := service.New(service.Parameters{Factories: factories, ApplicationStartInfo: info})
handleErr("Failed to construct the application", err)
if err := run(service.Parameters{ApplicationStartInfo: info, Factories: factories}); err != nil {
log.Fatal(err)
}
}

func runInteractive(params service.Parameters) error {
app, err := service.New(params)
if err != nil {
return fmt.Errorf("failed to construct the application: %w", err)
}

err = app.Start()
if err != nil {
return fmt.Errorf("application run finished with error: %w", err)
}

err = svc.Start()
handleErr("Application run finished with error", err)
return nil
}
23 changes: 23 additions & 0 deletions cmd/otelcontribcol/main_others.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http:https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// +build !windows

package main

import "go.opentelemetry.io/collector/service"

func run(params service.Parameters) error {
return runInteractive(params)
}
46 changes: 46 additions & 0 deletions cmd/otelcontribcol/main_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http:https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// +build windows

package main

import (
"fmt"

"go.opentelemetry.io/collector/service"
"golang.org/x/sys/windows/svc"
)

func run(params service.Parameters) error {
isInteractive, err := svc.IsAnInteractiveSession()
if err != nil {
return fmt.Errorf("failed to determine if we are running in an interactive session: %w", err)
}

if isInteractive {
return runInteractive(params)
} else {
return runService(params)
}
}

func runService(params service.Parameters) error {
// do not need to supply service name when startup is invoked through Service Control Manager directly
if err := svc.Run("", service.NewWindowsService(params)); err != nil {
return fmt.Errorf("failed to start service: %w", err)
}

return nil
}
6 changes: 4 additions & 2 deletions examples/tracing/otel-collector-config.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
receivers:
otlp:
endpoint: 0.0.0.0:55680
protocols:
grpc:
endpoint: 0.0.0.0:55680
zipkin:
endpoint: 0.0.0.0:9411

exporters:
logging:

zipkin:
url: "http:https://zipkin:9411/api/v2/spans"
endpoint: "http:https://zipkin:9411/api/v2/spans"
format: proto

jaeger_thrift:
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ require (
github.com/stretchr/testify v1.6.1
github.com/tcnksm/ghr v0.13.0
go.opentelemetry.io/collector v0.5.1-0.20200708003418-541edde63b3a
golang.org/x/sys v0.0.0-20200413165638-669c56c373c4
honnef.co/go/tools v0.0.1-2020.1.4
)

Expand Down
67 changes: 67 additions & 0 deletions internal/buildscripts/packaging/msi/make.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Copyright The OpenTelemetry Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http:https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

<#
.SYNOPSIS
Makefile like build commands for the Collector on Windows.
Usage: .\make.ps1 <Command> [-<Param> <Value> ...]
Example: .\make.ps1 New-MSI -Config "./my-config.yaml"
.PARAMETER Target
Build target to run (Install-Tools, New-MSI)
#>
Param(
[Parameter(Mandatory=$true, ValueFromRemainingArguments=$true)][string]$Target
)

$ErrorActionPreference = "Stop"

function Install-Tools {
choco install wixtoolset -y
setx /m PATH "%PATH%;C:\Program Files (x86)\WiX Toolset v3.11\bin"
refreshenv
}

function New-MSI(
[string]$Version="0.0.1",
[string]$Config="./examples/tracing/otel-collector-config.yml"
) {
candle -arch x64 -dVersion="$Version" -dConfig="$Config" internal/buildscripts/packaging/msi/opentelemetry-contrib-collector.wxs
light opentelemetry-contrib-collector.wixobj
Move-Item -Force opentelemetry-contrib-collector.msi bin/opentelemetry-contrib-collector.msi
}

function Confirm-MSI {
# ensure system32 is in Path so we can use executables like msiexec & sc
$env:Path += ";C:\Windows\System32"

# install msi, validate service is installed & running
Start-Process -Wait msiexec "/i `"$pwd\bin\opentelemetry-contrib-collector.msi`" /qn"
sc.exe query state=all | findstr "otelcontribcol" | Out-Null
if ($LASTEXITCODE -ne 0) { Throw "otelcontribcol service failed to install" }

# stop service
Stop-Service otelcontribcol

# start service
Start-Service otelcontribcol

# uninstall msi, validate service is uninstalled
Start-Process -Wait msiexec "/x `"$pwd\bin\opentelemetry-contrib-collector.msi`" /qn"
sc.exe query state=all | findstr "otelcontribcol" | Out-Null
if ($LASTEXITCODE -ne 1) { Throw "otelcontribcol service failed to uninstall" }
}

$sb = [scriptblock]::create("$Target")
Invoke-Command -ScriptBlock $sb
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<Wix xmlns="http:https://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" UpgradeCode="2B747F3C-BA1A-47DB-8617-E6BE77832F7E" Name="OpenTelemetry Collector Contrib" Version="$(var.Version)" Manufacturer="OpenTelemetry" Language="1033">
<Package InstallerVersion="200" Compressed="yes" Comments="Windows Installer Package"/>
<Media Id="1" Cabinet="product.cab" EmbedCab="yes"/>
<Icon Id="ProductIcon" SourceFile="./internal/buildscripts/packaging/msi/opentelemetry.ico"/>
<Property Id="ARPPRODUCTICON" Value="ProductIcon"/>
<Property Id="ARPHELPLINK" Value="https://opentelemetry.io/"/>
<Property Id="ARPURLINFOABOUT" Value="https://opentelemetry.io/"/>
<Property Id="ARPNOREPAIR" Value="1"/>
<Property Id="ARPNOMODIFY" Value="1"/>

<Feature Id="Feature" Level="1">
<ComponentRef Id="ApplicationComponent"/>
</Feature>

<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFiles64Folder">
<Directory Id="INSTALLDIR" Name="OpenTelemetry Collector Contrib">
<Component Id="ApplicationComponent" Guid="03F8DA4A-B41A-4AC1-8B18-5E3AF5D7A548">
<!-- Files to include -->
<File Id="ExecutableFile" Name="otelcontribcol.exe" KeyPath="yes" Source="./bin/otelcontribcol_windows_amd64.exe"/>
<File Id="DefaultConfigFile" Name="config.yaml" Source="$(var.Config)" />
<!-- Since we may have overwritten the config file (see below), we need to explicitly remove it on uninstall -->
<RemoveFile Id="RemoveConfigFile" Name="config.yaml" On="uninstall" />

<ServiceInstall
Id="Sevice"
Name="otelcontribcol"
DisplayName="OpenTelemetry Collector Contrib"
Description="Collects, processes, and exports telemetry from various configurable sources."
Type="ownProcess"
Vital="yes"
Start="auto"
Account="LocalSystem"
ErrorControl="normal"
Arguments=" --config=&quot;[INSTALLDIR]config.yaml&quot;"
Interactive="no" />
<ServiceControl
Id="StartStopRemoveService"
Name="otelcontribcol"
Start="install"
Stop="both"
Remove="uninstall"
Wait="yes" />
</Component>
</Directory>
</Directory>
</Directory>

<!-- If CONFIG is supplied as a custom argument when installing, overwrite config.yaml with the specified file -->
<CustomAction Id="CopyConfig" ExeCommand="xcopy /y &quot;[CONFIG]&quot; &quot;[INSTALLDIR]config.yaml*&quot;" Directory="INSTALLDIR" Impersonate="no" Execute="deferred" Return="check" />
<InstallExecuteSequence>
<Custom Action="CopyConfig" After="InstallFiles">CONFIG AND NOT Installed</Custom>
</InstallExecuteSequence>
</Product>
</Wix>
Binary file not shown.

0 comments on commit b34888b

Please sign in to comment.