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

feat: Docker build #102

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
coverage.out
build/
.idea/
4 changes: 4 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
issues:
skip-dirs:
- vendor/*
- migration/*
9 changes: 3 additions & 6 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ sudo: required
language: go

go:
- "1.20.x"
- "1.22.x"

env:
- DEPLOY_DOCS="$(if [[ $TRAVIS_BRANCH == 'master' && $TRAVIS_PULL_REQUEST == 'false' ]]; then echo -n 'true' ; else echo -n 'false' ; fi)"
Expand All @@ -14,10 +14,8 @@ services:

install:
- docker pull mysql:8.0
- go install golang.org/x/lint/golint@latest
- go install github.com/kisielk/errcheck@latest
- go get github.com/spf13/[email protected]
- go get github.com/fsnotify/[email protected]
- curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.61.0

# With the "docker" tag enabled on go test invocation (-tags docker)
# the mysql:5.6 docker container will be started
Expand All @@ -26,10 +24,9 @@ install:
script:
- sudo service mysql stop
- diff -u <(echo -n) <(gofmt -d `find . -name '*.go' | grep -Ev '/vendor/|/migration'`)
- go list ./... | grep -Ev '/vendor/|/migration' | xargs -L1 golint
- go vet `go list ./... | grep -v /vendor/`
- errcheck -ignore 'io:Close' -ignoretests `go list ./... | grep -v /vendor/`
- go test -v ./...
- make clean test build lint

after_success:
- ./update-docs.sh
27 changes: 27 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
FROM golang:1.22-alpine3.20 as builder

RUN apk update && apk add git make bash build-base gcc bc

RUN mkdir -p /go/src/github.com/Netflix/chaosmonkey
WORKDIR /go/src/github.com/Netflix/chaosmonkey
ADD ./ /go/src/github.com/Netflix/chaosmonkey


RUN make all

FROM ubuntu:24.04

COPY --from=builder /go/src/github.com/Netflix/chaosmonkey/build/chaosmonkey /opt/chaosmonkey/bin/chaosmonkey

ADD ./docs/chaosmonkey.toml /etc/chaosmonkey.toml
ADD ./docs/chaosmonkey-terminate.sh /opt/chaosmonkey/bin/chaosmonkey-terminate.sh
ADD ./docs/chaosmonkey-schedule.sh /opt/chaosmonkey/bin/chaosmonkey-schedule.sh



RUN apt-get update
RUN apt-get install -y cron

ADD ./docs/chaosmonkey-cron /etc/cron.d/chaosmonkey-cron

ENTRYPOINT ["cron", "-f"]
45 changes: 35 additions & 10 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,25 +1,50 @@
.PHONY: check fmt lint errcheck test build
BINARY=chaosmonkey
GOARCH=amd64

SHELL:=/bin/bash
COMMIT=$(shell git rev-parse HEAD)
BRANCH=$(shell git rev-parse --abbrev-ref HEAD)
REPO=$(shell basename $(shell git rev-parse --show-toplevel))
PKGS := $(shell go list ./... | grep -v -e /integration -e /vendor)
INTEGRATION_PKGS := $(shell go list ./... | grep /integration)

BUILD_DIR=$(shell pwd)/build
CURRENT_DIR=$(shell pwd)

LDFLAGS = -ldflags "-X main.COMMIT=${COMMIT} -X main.BRANCH=${BRANCH}"
GOFLAGS='-mod=vendor'
GOOS=linux
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Linux)
LDFLAGS = -ldflags "-X main.COMMIT=${COMMIT} -X main.BRANCH=${BRANCH} -linkmode external -extldflags -static -s -w"
endif

all: clean test build

docker:
docker build . -t netflix/chaosmonkey:${COMMIT}

clean:
rm -rf ${BUILD_DIR}
go clean

build: check
go build github.com/Netflix/chaosmonkey/cmd/chaosmonkey
go build ${LDFLAGS} -o ${BUILD_DIR}/${BINARY} ./cmd/${BINARY}/main.go

check: fmt lint errcheck
check: fmt

gofmt: fmt

fmt:
diff -u <(echo -n) <(gofmt -d `find . -name '*.go' | grep -Ev '/vendor/|/migration'`)
go fmt $$(go list ./... | grep -v /vendor/) ;

lint:
go list ./... | grep -Ev '/vendor/|/migration' | xargs -L1 golint
lint: $(GOLINT)
golangci-lint run

errcheck:
errcheck -ignore 'io:Close' -ignoretests `go list ./... | grep -v /vendor/`
#errcheck:
#errcheck -ignore 'io:Close' -ignoretests `go list ./... | grep -v -e '/vendor/' -e '/migration'`

test:
go test -v ./...
go test -v ./...


# Coverage testing
Expand Down
4 changes: 2 additions & 2 deletions command/chaosmonkey.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ var (

// Usage prints usage
func Usage() {
usage := `
const usage = `
Chaos Monkey

Usage:
Expand Down Expand Up @@ -168,7 +168,7 @@ Example:

chaosmonkey regions chaosguineapig test
`
fmt.Printf(usage)
fmt.Printf("%s", usage)
}

func init() {
Expand Down
7 changes: 3 additions & 4 deletions command/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import (
"fmt"
"github.com/Netflix/chaosmonkey/v2/config"
"github.com/Netflix/chaosmonkey/v2/mysql"
"io/ioutil"
"log"
"os"
)
Expand Down Expand Up @@ -82,7 +81,7 @@ func setupCron(cfg *config.Monkey, executablePath string) error {
return err
}

err = ioutil.WriteFile(cfg.SchedulePath(), content, scriptPerms)
err = os.WriteFile(cfg.SchedulePath(), content, scriptPerms)
if err != nil {
return err
}
Expand All @@ -95,7 +94,7 @@ func setupCron(cfg *config.Monkey, executablePath string) error {
crontab := fmt.Sprintf("%s %s %s\n", cronExpr, cfg.TermAccount(), cfg.SchedulePath())
var cronPerms os.FileMode = 0644 // -rw-r--r-- : cron config file shouldn't have write perm
log.Printf("Creating %s\n", cfg.ScheduleCronPath())
err = ioutil.WriteFile(cfg.ScheduleCronPath(), []byte(crontab), cronPerms)
err = os.WriteFile(cfg.ScheduleCronPath(), []byte(crontab), cronPerms)
return err
}

Expand All @@ -113,7 +112,7 @@ func setupTerminationScript(cfg *config.Monkey, executablePath string) error {
return err
}

err = ioutil.WriteFile(cfg.TermPath(), content, perms)
err = os.WriteFile(cfg.TermPath(), content, perms)
return err
}

Expand Down
4 changes: 2 additions & 2 deletions command/install_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ import (
"github.com/Netflix/chaosmonkey/v2/config/param"
"github.com/Netflix/chaosmonkey/v2/mock"
"github.com/pkg/errors"
"io/ioutil"
"os"
"testing"
)

func assertHasSameContent(fileName string, expectedContent string) error {

cronContent, err := ioutil.ReadFile(fileName)
cronContent, err := os.ReadFile(fileName)
if err != nil {
return err
}
Expand Down
3 changes: 1 addition & 2 deletions command/schedule.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ package command

import (
"fmt"
"io/ioutil"
"log"
"os"
"time"
Expand Down Expand Up @@ -102,6 +101,6 @@ func registerWithCron(s *schedule.Schedule, cfg *config.Monkey) error {
crontab := s.Crontab(cfg.TermPath(), cfg.TermAccount())
var perms os.FileMode = 0644 // -rw-r--r--
log.Printf("Writing %s\n", cfg.CronPath())
err := ioutil.WriteFile(cfg.CronPath(), crontab, perms)
err := os.WriteFile(cfg.CronPath(), crontab, perms)
return err
}
4 changes: 2 additions & 2 deletions command/schedule_int_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ package command

import (
"bytes"
"io/ioutil"
"os"
"testing"
"time"

Expand Down Expand Up @@ -61,7 +61,7 @@ func TestScheduleCommand(t *testing.T) {
// Assertions
expectedCount := 4

cronFileContents, err := ioutil.ReadFile(cronFile)
cronFileContents, err := os.ReadFile(cronFile)
if err != nil {
t.Fatal(err)
}
Expand Down
6 changes: 3 additions & 3 deletions command/schedule_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
package command

import (
"io/ioutil"
"os"
"testing"
"time"

Expand Down Expand Up @@ -74,7 +74,7 @@ func TestRegisterWithCron(t *testing.T) {
}

// assertions
dat, err := ioutil.ReadFile(fname)
dat, err := os.ReadFile(fname)
if err != nil {
t.Error(err.Error())
return
Expand Down Expand Up @@ -123,7 +123,7 @@ func TestCronOutputInSortedOrder(t *testing.T) {
}

// assertions
dat, err := ioutil.ReadFile(fname)
dat, err := os.ReadFile(fname)
if err != nil {
t.Error(err.Error())
return
Expand Down
4 changes: 4 additions & 0 deletions config/monkey.go
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,7 @@ type RemoteProvider viper.RemoteProvider
type RemoteConfigFactory interface {
Get(rp RemoteProvider) (io.Reader, error)
Watch(rp RemoteProvider) (io.Reader, error)
WatchChannel(rp RemoteProvider) (<-chan *viper.RemoteResponse, chan bool)
}

type proxy struct {
Expand All @@ -439,6 +440,9 @@ func (p proxy) Get(rp viper.RemoteProvider) (io.Reader, error) {
func (p proxy) Watch(rp viper.RemoteProvider) (io.Reader, error) {
return p.factory.Watch(rp)
}
func (p proxy) WatchChannel(rp viper.RemoteProvider) (<-chan *viper.RemoteResponse, chan bool) {
return p.factory.WatchChannel(rp)
}

// SetRemoteProvider sets viper's remote provider
func SetRemoteProvider(name string, factory RemoteConfigFactory) {
Expand Down
9 changes: 9 additions & 0 deletions docs/chaosmonkey-cron
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Run the Chaos Monkey scheduler at 5AM PDT (4AM PST) every weekday
# This corresponds to: 12:00 UTC
# Because system clock runs UTC, time change affects when job runs

# The scheduler must run as root because it needs root permissions to write
# to the file /etc/cron.d/chaosmonkey-daily-terminations

# min hour dom month day user command
0 12 * * 1-5 root /apps/chaosmonkey/chaosmonkey-schedule.sh
3 changes: 3 additions & 0 deletions docs/chaosmonkey-schedule.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash
#Docker, so we just log to sysout
/apps/chaosmonkey/chaosmonkey schedule
3 changes: 3 additions & 0 deletions docs/chaosmonkey-terminate.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash
# Log to sysout by default
/opt/chaosmonkey/bin/chaosmonkey terminate "$@"
53 changes: 53 additions & 0 deletions docs/chaosmonkey.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
[chaosmonkey]
enabled = false # if false, won't terminate instances when invoked
leashed = true # if true, terminations are only simulated (logged only)
schedule_enabled = false # if true, will generate schedule of terminations each weekday
accounts = [] # list of Spinnaker accounts with chaos monkey enabled, e.g.: ["prod", "test"]

start_hour = 9 # time during day when starts terminating
end_hour = 15 # time during day when stops terminating

# tzdata format, see TZ column in https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
# Other allowed values: "UTC", "Local"
time_zone = "America/Los_Angeles" # time zone used by start.hour and end.hour

term_account = "root" # account used to run the term_path command

max_apps = 2147483647 # max number of apps Chaos Monkey will schedule terminations for

# location of command Chaos Monkey uses for doing terminations
term_path = "/opt/chaosmonkey/bin/chaosmonkey-terminate.sh"

# cron file that Chaos Monkey writes to each day for scheduling kills
cron_path = "/etc/cron.d/chaosmonkey-daily-terminations"

# decryption system for encrypted_password fields for spinnaker and database
decryptor = ""

# event tracking systems that records chaos monkey terminations
trackers = []

# metric collection systems that track errors for monitoring/alerting
error_counter = ""

# outage checking system that tells chaos monkey if there is an ongoing outage
outage_checker = ""

[database]
host = "" # database host
port = 3306 # tcp port that the database is lstening on
user = "" # database user
encrypted_password = "" # password for database auth, encrypted by decryptor
name = "" # name of database that contains chaos monkey data

[spinnaker]
endpoint = "" # spinnaker api url
certificate = "" # path to p12 file when using client-side tls certs
encrypted_password = "" # password used for p12 certificate, encrypted by decryptor
user = "" # user associated with terminations, sent in API call to terminate

# For dynamic configuration options, see viper docs
[dynamic]
provider = "" # options: "etcd", "consul"
endpoint = "" # url for dynamic provider
path = "" # path for dynamic provider
7 changes: 0 additions & 7 deletions eligible/eligible.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,13 +175,6 @@ func contains(region string, regions []deploy.RegionName) bool {
return false
}

const whiteListErrorMessage = "whitelist is not supported"

// isWhiteList returns true if an error is related to a whitelist
func isWhitelist(err error) bool {
return err.Error() == whiteListErrorMessage
}

// Instances returns instances eligible for termination
func Instances(group grp.InstanceGroup, exs []chaosmonkey.Exception, dep deploy.Deployment) ([]chaosmonkey.Instance, error) {
cloudProvider, err := dep.CloudProvider(group.Account())
Expand Down
Loading