Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support consul service meta data #595

Closed
wants to merge 45 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
21269c5
add uid and gid options for running commands
frederikbosch Oct 24, 2019
f9260e5
fix integration tests
gbmeuk Nov 4, 2019
e1379f3
convert to GOMODULES, remove glide, bump consul
teutat3s Feb 3, 2020
c454f3d
add consul checksum for download verification
teutat3s Feb 3, 2020
7aab61d
more integration test fixes
teutat3s Feb 3, 2020
06dab1c
Bump go version 1.14
teutat3s May 25, 2020
f9f11c7
Bump consul version to 1.7.3
teutat3s May 25, 2020
829a790
First drone yaml
teutat3s May 25, 2020
610fee1
Add consul to drone test via bash script
teutat3s May 25, 2020
8ca6175
Fix coprocess integration test
teutat3s May 25, 2020
e1d05a0
Add integration tests to drone CI
teutat3s May 25, 2020
6ef7e30
Fix integration tests with drone CI
teutat3s May 25, 2020
94497a2
Two drone pipelines
teutat3s May 25, 2020
64cd4b4
Add GitHub release steps to drone
teutat3s May 25, 2020
9107a9c
Fix GitHub release step
teutat3s May 25, 2020
91ed15c
Fix GitHub release step again
teutat3s May 25, 2020
c28eece
Add our build status badge
teutat3s May 25, 2020
1529184
Fix release step
teutat3s May 25, 2020
feb426e
Add github base URL
teutat3s May 25, 2020
bd162c6
Update go dependencies, prometheus.UninstrumentedHandler ->
teutat3s Apr 13, 2022
bfe76f4
Bump go, node, consul, consul-template, alpine versions
teutat3s Apr 13, 2022
ac8df40
Fix lint target for go modules
teutat3s Apr 13, 2022
f257dd7
Update CI, publish to greenbaum/containerpilot
teutat3s Apr 13, 2022
02c046a
Fix test scripts on NixOS, correctly escape double quotes in tests
teutat3s Apr 13, 2022
0eb1281
Add shell.nix
teutat3s Apr 13, 2022
85a1669
lint: staticcheck S1009 should omit nil check
teutat3s Apr 13, 2022
38bc053
lint: staticcheck S1034 assigning the result of
teutat3s Apr 13, 2022
314174d
lint: staticcheck S1023 redundant return / break
teutat3s Apr 13, 2022
bc48806
lint: staticcheck S1039 unnecessary use of
teutat3s Apr 13, 2022
1579be5
lint: staticcheck unnecessary guard around call to
teutat3s Apr 13, 2022
4c50e2c
lint: go vet, literal copies lock value from
teutat3s Apr 13, 2022
3ca312d
lint: staticcheck S1025 should use String()
teutat3s Apr 13, 2022
d666335
lint: go vet, events.Event composite literal uses unkeyed fields
teutat3s Apr 14, 2022
182ea2c
lint: golint is deprecated, replace with staticcheck
teutat3s Apr 14, 2022
9237c89
lint: staticcheck U1000 field / func is unused
teutat3s Apr 14, 2022
5396438
lint: staticcheck ST1005 error strings should not
teutat3s Apr 14, 2022
bd0e51d
lint: staticcheck SA1012 do not pass a nil Context
teutat3s Apr 14, 2022
13075f6
lint: staticcheck SA4006 this value of ip is never
teutat3s Apr 14, 2022
e90eeac
Apply gofmt
teutat3s Apr 14, 2022
154f090
Use correct order of makefile targets for linting
teutat3s Apr 14, 2022
694b9b7
Merge remote-tracking branch 'upstream/master'
teutat3s Apr 14, 2022
5038214
Add nix flake: devshell
teutat3s Oct 25, 2022
ea436c7
Bump min. go version to 1.18, 1.17 is EOL
teutat3s Oct 25, 2022
9b31d52
Support service meta data
teutat3s Oct 25, 2022
8c5e115
Fix linter errors
teutat3s Oct 25, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions .drone.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
kind: pipeline
type: exec
name: exec-runner

platform:
os: linux
arch: amd64

steps:
- name: integration-tests
environment:
commands:
- make clean
- make build lint
- make test
- make integration
when:
event:
- pull_request
- push

---
kind: pipeline
type: docker
name: docker-runner

platform:
os: linux
arch: amd64

steps:
- name: prepare-release
image: golang:1.18
commands:
- |
go build \
-o build/containerpilot \
-ldflags \
"-X github.com/greenbaum/containerpilot/version.GitHash=$(git rev-parse --short HEAD) \
-X github.com/greenbaum/containerpilot/version.Version=${DRONE_TAG}"
- mkdir release && cd build && tar -czf ../release/containerpilot-${DRONE_TAG}.tar.gz containerpilot
- cd ../release && sha1sum containerpilot-${DRONE_TAG}.tar.gz > containerpilot-${DRONE_TAG}.sha1.txt
when:
event:
- tag

- name: publish-release
image: plugins/github-release
settings:
api_key:
from_secret: github_api-key
files:
- release/containerpilot-${DRONE_TAG}.tar.gz
- release/containerpilot-${DRONE_TAG}.sha1.txt
title: "New release: version ${DRONE_TAG}"
base_url: greenbaum/containerpilot
when:
event:
- tag
depends_on:
- prepare-release

---
kind: secret
name: github_api-key
get:
path: secret/data/drone/github
name: api-key

13 changes: 13 additions & 0 deletions .envrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/usr/bin/env bash
# ^ added for shellcheck and file-type detection

# Watch & reload direnv on change
cd devshell || exit
watch_file devshell.toml

if [[ $(type -t use_flake) != function ]]; then
echo "ERROR: use_flake function missing."
echo "Please update direnv to v2.30.0 or later."
exit 1
fi
use flake
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,6 @@ cover.html
# IDE files
.idea
*.iml

# Nix files
.direnv
23 changes: 14 additions & 9 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
FROM golang:1.9
FROM golang:1.19

ENV CONSUL_VERSION=1.0.0
ENV GLIDE_VERSION=0.12.3
ENV CONSUL_VERSION=1.13.3

RUN apt-get update \
&& apt-get install -y unzip \
&& go get github.com/golang/lint/golint \
&& curl -Lo /tmp/glide.tgz "https://github.com/Masterminds/glide/releases/download/v${GLIDE_VERSION}/glide-v${GLIDE_VERSION}-linux-amd64.tar.gz" \
&& tar -C /usr/bin -xzf /tmp/glide.tgz --strip=1 linux-amd64/glide \
&& curl --fail -Lso consul.zip "https://releases.hashicorp.com/consul/${CONSUL_VERSION}/consul_${CONSUL_VERSION}_linux_amd64.zip" \
&& unzip consul.zip -d /usr/bin
&& go install honnef.co/go/tools/cmd/staticcheck@latest


RUN export CONSUL_CHECKSUM=5370b0b5bf765530e28cb80f90dcb47bd7d6ba78176c1ab2430f56e460ed279c \
&& export archive=consul_${CONSUL_VERSION}_linux_amd64.zip \
&& curl -Lso /tmp/${archive} https://releases.hashicorp.com/consul/${CONSUL_VERSION}/${archive} \
&& echo "${CONSUL_CHECKSUM} /tmp/${archive}" | sha256sum -c \
&& cd /bin \
&& unzip /tmp/${archive} \
&& chmod +x /bin/consul \
&& rm /tmp/${archive}

ENV CGO_ENABLED 0
ENV GOPATH /go:/cp
ENV GOPATH /go
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

*An init system for cloud-native distributed applications that automates the process of service discovery, configuration, and lifecycle management inside the container, so you can focus on your apps.*

[![Build Status](https://travis-ci.org/joyent/containerpilot.svg)](https://travis-ci.org/joyent/containerpilot)
[![Build Status](https://drone.greenbaum.cloud/api/badges/greenbaum.cloud/containerpilot/status.svg)](https://drone.greenbaum.cloud/greenbaum.cloud/containerpilot)
[![MPL licensed](https://img.shields.io/badge/license-MPL_2.0-blue.svg)](https://github.com/joyent/containerpilot/blob/master/LICENSE)
[![GoDoc](https://godoc.org/github.com/joyent/containerpilot?status.svg)](https://godoc.org/github.com/joyent/containerpilot)

Expand Down
3 changes: 2 additions & 1 deletion client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import (
// requests out to a ContainerPilot process's control socket.
type HTTPClient struct {
http.Client
socketPath string
// staticcheck U1000 field is unused
//socketPath string
}

var socketType = "unix"
Expand Down
27 changes: 21 additions & 6 deletions commands/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ type Command struct {
logger log.Entry
lock *sync.Mutex
fields log.Fields
UID int
GID int
}

// NewCommand parses JSON config into a Command
Expand Down Expand Up @@ -101,7 +103,20 @@ func (c *Command) Run(pctx context.Context, bus *events.EventBus) {
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
}

cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
if os.Getuid() == 0 {
if c.UID != 0 && c.GID != 0 {
cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(c.UID), Gid: uint32(c.GID)}
} else if c.UID != 0 {
cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(c.UID)}
} else if c.GID != 0 {
cmd.SysProcAttr.Credential = &syscall.Credential{Gid: uint32(c.GID)}
}
} else {
log.Debugf("%s.Skipping uid and gid (ContainerPilot is not running as root)", c.Name)
}

c.Cmd = cmd
ctx, cancel := getContext(pctx, c.Timeout)

Expand All @@ -126,8 +141,8 @@ func (c *Command) Run(pctx context.Context, bus *events.EventBus) {
defer log.Debugf("%s.Run end", c.Name)
if err := c.Cmd.Start(); err != nil {
log.Errorf("unable to start %s: %v", c.Name, err)
bus.Publish(events.Event{events.ExitFailed, c.Name})
bus.Publish(events.Event{events.Error, err.Error()})
bus.Publish(events.Event{Code: events.ExitFailed, Source: c.Name})
bus.Publish(events.Event{Code: events.Error, Source: err.Error()})
return
}

Expand All @@ -150,12 +165,12 @@ func (c *Command) Run(pctx context.Context, bus *events.EventBus) {
// we'll return from Wait() and publish events
if err := c.Cmd.Wait(); err != nil {
log.Errorf("%s exited with error: %v", c.Name, err)
bus.Publish(events.Event{events.ExitFailed, c.Name})
bus.Publish(events.Event{events.Error,
fmt.Errorf("%s: %s", c.Name, err).Error()})
bus.Publish(events.Event{Code: events.ExitFailed, Source: c.Name})
bus.Publish(events.Event{Code: events.Error,
Source: fmt.Errorf("%s: %s", c.Name, err).Error()})
} else {
log.Debugf("%s exited without error", c.Name)
bus.Publish(events.Event{events.ExitSuccess, c.Name})
bus.Publish(events.Event{Code: events.ExitSuccess, Source: c.Name})
}
}()
}
Expand Down
24 changes: 12 additions & 12 deletions commands/commands_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
func TestCommandRunWithTimeoutZero(t *testing.T) {
cmd, _ := NewCommand("sleep 2", time.Duration(0), nil)
got := runtestCommandRun(cmd)
timedout := events.Event{events.ExitFailed, "sleep"}
timedout := events.Event{Code: events.ExitFailed, Source: "sleep"}
if got[timedout] != 1 {
t.Fatalf("stopped command prior to test timeout, got events %v", got)
}
Expand All @@ -25,9 +25,9 @@ func TestCommandRunWithTimeoutKilled(t *testing.T) {
cmd, _ := NewCommand("sleep 2", time.Duration(100*time.Millisecond), nil)
cmd.Name = t.Name()
got := runtestCommandRun(cmd)
testTimeout := events.Event{events.TimerExpired, "DebugSubscriberTimeout"}
expired := events.Event{events.ExitFailed, t.Name()}
errMsg := events.Event{events.Error, fmt.Sprintf("%s: signal: killed", cmd.Name)}
testTimeout := events.Event{Code: events.TimerExpired, Source: "DebugSubscriberTimeout"}
expired := events.Event{Code: events.ExitFailed, Source: t.Name()}
errMsg := events.Event{Code: events.Error, Source: fmt.Sprintf("%s: signal: killed", cmd.Name)}
if got[testTimeout] > 0 || got[expired] != 1 || got[errMsg] != 1 {
t.Fatalf("expected:\n%v\n%v\ngot events:\n%v", expired, errMsg, got)
}
Expand All @@ -38,9 +38,9 @@ func TestCommandRunChildrenKilled(t *testing.T) {
time.Duration(100*time.Millisecond), nil)
cmd.Name = t.Name()
got := runtestCommandRun(cmd)
testTimeout := events.Event{events.TimerExpired, "DebugSubscriberTimeout"}
expired := events.Event{events.ExitFailed, t.Name()}
errMsg := events.Event{events.Error, fmt.Sprintf("%s: signal: killed", cmd.Name)}
testTimeout := events.Event{Code: events.TimerExpired, Source: "DebugSubscriberTimeout"}
expired := events.Event{Code: events.ExitFailed, Source: t.Name()}
errMsg := events.Event{Code: events.Error, Source: fmt.Sprintf("%s: signal: killed", cmd.Name)}
if got[testTimeout] > 0 || got[expired] != 1 || got[errMsg] != 1 {
t.Fatalf("expected:\n%v\n%v\ngot events:\n%v", expired, errMsg, got)
}
Expand All @@ -49,8 +49,8 @@ func TestCommandRunChildrenKilled(t *testing.T) {
func TestCommandRunExecFailed(t *testing.T) {
cmd, _ := NewCommand("./testdata/test.sh failStuff --debug", time.Duration(0), nil)
got := runtestCommandRun(cmd)
failed := events.Event{events.ExitFailed, "./testdata/test.sh"}
errMsg := events.Event{events.Error, "./testdata/test.sh: exit status 255"}
failed := events.Event{Code: events.ExitFailed, Source: "./testdata/test.sh"}
errMsg := events.Event{Code: events.Error, Source: "./testdata/test.sh: exit status 255"}
if got[failed] != 1 || got[errMsg] != 1 {
t.Fatalf("expected:\n%v\n%v\ngot events:\n%v", failed, errMsg, got)
}
Expand All @@ -59,9 +59,9 @@ func TestCommandRunExecFailed(t *testing.T) {
func TestCommandRunExecInvalid(t *testing.T) {
cmd, _ := NewCommand("./testdata/invalidCommand", time.Duration(0), nil)
got := runtestCommandRun(cmd)
failed := events.Event{events.ExitFailed, "./testdata/invalidCommand"}
errMsg := events.Event{events.Error,
"fork/exec ./testdata/invalidCommand: no such file or directory"}
failed := events.Event{Code: events.ExitFailed, Source: "./testdata/invalidCommand"}
errMsg := events.Event{Code: events.Error,
Source: "fork/exec ./testdata/invalidCommand: no such file or directory"}
if got[failed] != 1 || got[errMsg] != 1 {
t.Fatalf("expected:\n%v\n%v\ngot events:\n%v", failed, errMsg, got)
}
Expand Down
2 changes: 1 addition & 1 deletion commands/testdata/test.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash

trap 'exit 2' SIGTERM

Expand Down
6 changes: 3 additions & 3 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"bytes"
"errors"
"fmt"
"io/ioutil"
"os"
"strings"

"github.com/flynn/json5"
Expand Down Expand Up @@ -79,7 +79,7 @@ func RenderConfig(configFlag, renderFlag string) error {
fmt.Printf("%s", renderedConfig)
} else {
var err error
if err = ioutil.WriteFile(renderFlag, renderedConfig, 0644); err != nil {
if err = os.WriteFile(renderFlag, renderedConfig, 0644); err != nil {
return fmt.Errorf("could not write config file: %s", err)
}
}
Expand Down Expand Up @@ -108,7 +108,7 @@ func loadConfigFile(configFlag string) ([]byte, error) {
if configFlag == "" {
return nil, errors.New("-config flag is required")
}
data, err := ioutil.ReadFile(configFlag)
data, err := os.ReadFile(configFlag)
if err != nil {
return nil, fmt.Errorf("could not read config file: %s", err)
}
Expand Down
6 changes: 3 additions & 3 deletions config/config_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package config

import (
"io/ioutil"
"os"
"path/filepath"
"testing"
Expand Down Expand Up @@ -33,6 +32,7 @@ func TestValidConfigJobs(t *testing.T) {
assert.Equal(job0.Port, 8080, "config for job0.Port")
assert.Equal(job0.Exec, "/bin/serviceA", "config for job0.Exec")
assert.Equal(job0.Tags, []string{"tag1", "tag2"}, "config for job0.Tags")
assert.Equal(job0.Meta, map[string]string{"keyA": "A"}, "config for job0.Meta")
assert.Equal(job0.Restarts, nil, "config for job1.Restarts")

job1 := cfg.Jobs[1]
Expand Down Expand Up @@ -184,8 +184,8 @@ func TestRenderConfigFileStdout(t *testing.T) {
temp.Close()
os.Stdout = old

renderedOut, _ := ioutil.ReadFile(fname)
renderedFile, _ := ioutil.ReadFile("testJSON.json")
renderedOut, _ := os.ReadFile(fname)
renderedFile, _ := os.ReadFile("testJSON.json")
if string(renderedOut) != string(renderedFile) {
t.Fatalf("expected the rendered file and stdout to be identical")
}
Expand Down
2 changes: 1 addition & 1 deletion config/decode/decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func interfaceToString(raw interface{}) string {
}

func interfaceToStringArray(rawArray []interface{}) []string {
if rawArray == nil || len(rawArray) == 0 {
if len(rawArray) == 0 {
return nil
}
var stringArray []string
Expand Down
8 changes: 4 additions & 4 deletions config/logger/logging.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func (l *Config) Init() error {
}
level, err := logrus.ParseLevel(strings.ToLower(l.Level))
if err != nil {
return fmt.Errorf("Unknown log level '%s': %s", l.Level, err)
return fmt.Errorf("unknown log level '%s': %s", l.Level, err)
}
var formatter logrus.Formatter
var output io.Writer
Expand All @@ -65,19 +65,19 @@ func (l *Config) Init() error {
TimestampFormat: time.RFC3339Nano,
}
default:
return fmt.Errorf("Unknown log format '%s'", l.Format)
return fmt.Errorf("unknown log format '%s'", l.Format)
}
switch strings.ToLower(l.Output) {
case "stderr":
output = os.Stderr
case "stdout":
output = os.Stdout
case "":
return fmt.Errorf("Unknown output type '%s'", l.Output)
return fmt.Errorf("unknown output type '%s'", l.Output)
default:
f, err := reopen.NewFileWriter(l.Output)
if err != nil {
return fmt.Errorf("Error initializing log file '%s': %s", l.Output, err)
return fmt.Errorf("error initializing log file '%s': %s", l.Output, err)
}
initializeSignal(f)
output = f
Expand Down
3 changes: 1 addition & 2 deletions config/logger/logging_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package logger

import (
"io/ioutil"
"os"
"reflect"
"strings"
Expand Down Expand Up @@ -84,7 +83,7 @@ func TestFileLogger(t *testing.T) {
// write a log message
logMsg := "this is a test"
logrus.Info(logMsg)
content, err := ioutil.ReadFile(filename)
content, err := os.ReadFile(filename)
if err != nil {
t.Errorf("Did not expect error: %v", err)
}
Expand Down
Loading