diff --git a/gosuper/build.sh b/gosuper/build.sh deleted file mode 100644 index e57739b8..00000000 --- a/gosuper/build.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/bash - -set -o errexit - -./test_formatting.sh -go test -v ./gosuper - -case "$ARCH" in -'amd64') - export GOARCH=amd64 -;; -'i386') - export GOARCH=386 -;; -'i386-nlp') - export GOARCH=386 -;; -'rpi') - export GOARCH=arm - export GOARM=6 -;; -'armv7hf') - export GOARCH=arm - export GOARM=7 -;; -'armel') - export GOARCH=arm - export GOARM=5 -;; -'aarch64') - export GOARCH=arm64 -;; -esac - -go install -a -v ./gosuper \ - && cd /go/bin \ - && find -type f -name gosuper -exec mv {} /go/bin/gosuper \; \ - && upx --best /go/bin/gosuper diff --git a/gosuper/glide.lock b/gosuper/glide.lock deleted file mode 100644 index 0337efdb..00000000 --- a/gosuper/glide.lock +++ /dev/null @@ -1,15 +0,0 @@ -hash: cb4cc5df2d5f540e768cb8d1033c61d5f082edce93a756840e1bc23b08ca3770 -updated: 2017-06-08T15:34:29.722957717-07:00 -imports: -- name: github.com/coreos/go-systemd - version: 48702e0da86bd25e76cfef347e2adeb434a0d0a6 - subpackages: - - dbus - - login1 -- name: github.com/godbus/dbus - version: 012f3c27dcbdbe5d1285634e604e4ef869d83f7d -- name: github.com/gorilla/context - version: 08b5f424b9271eedf6f9f0ce86cb9396ed337a42 -- name: github.com/gorilla/mux - version: bcd8bc72b08df0f70df986b97f95590779502d31 -testImports: [] diff --git a/gosuper/glide.yaml b/gosuper/glide.yaml deleted file mode 100644 index 471a11e2..00000000 --- a/gosuper/glide.yaml +++ /dev/null @@ -1,9 +0,0 @@ -package: resin-supervisor/gosuper -import: -- package: github.com/coreos/go-systemd - version: ^14.0.0 - subpackages: - - dbus - - login1 -- package: github.com/gorilla/mux - version: ^1.4.0 diff --git a/gosuper/go-1.8.3-patches/0001-dont-fail-when-no-mmx.patch b/gosuper/go-1.8.3-patches/0001-dont-fail-when-no-mmx.patch deleted file mode 100644 index f171c867..00000000 --- a/gosuper/go-1.8.3-patches/0001-dont-fail-when-no-mmx.patch +++ /dev/null @@ -1,78 +0,0 @@ -commit 6a0e489a556d753161ce75d85a3114654c031853 -Author: Pablo Carranza Velez -Date: Fri Jun 9 14:57:23 2017 -0700 - - Do not fail when there's no MMX support - - Adapted from https://github.com/resin-io/resin-supervisor/blob/c7a7ba93fb46775006f0739ced41fc0a2059b426/gosuper/go-1.6.3-patches/0001-Revert-runtime-check-and-fail-early-with-a-message-i.patch - Original author: Petros Angelatos - - Signed-off-by: Pablo Carranza Velez - -diff --git a/src/runtime/asm_386.s b/src/runtime/asm_386.s -index 3d0b74c..f4e51ce 100644 ---- a/src/runtime/asm_386.s -+++ b/src/runtime/asm_386.s -@@ -26,32 +26,6 @@ TEXT runtime·rt0_go(SB),NOSPLIT,$0 - MOVL SP, (g_stack+stack_hi)(BP) - - // find out information about the processor we're on --#ifdef GOOS_nacl // NaCl doesn't like PUSHFL/POPFL -- JMP has_cpuid --#else -- // first see if CPUID instruction is supported. -- PUSHFL -- PUSHFL -- XORL $(1<<21), 0(SP) // flip ID bit -- POPFL -- PUSHFL -- POPL AX -- XORL 0(SP), AX -- POPFL // restore EFLAGS -- TESTL $(1<<21), AX -- JNE has_cpuid --#endif -- --bad_proc: // show that the program requires MMX. -- MOVL $2, 0(SP) -- MOVL $bad_proc_msg<>(SB), 4(SP) -- MOVL $0x3d, 8(SP) -- CALL runtime·write(SB) -- MOVL $1, 0(SP) -- CALL runtime·exit(SB) -- INT $3 -- --has_cpuid: - MOVL $0, AX - CPUID - MOVL AX, SI -@@ -76,11 +50,6 @@ notintel: - MOVL CX, AX // Move to global variable clobbers CX when generating PIC - MOVL AX, runtime·cpuid_ecx(SB) - MOVL DX, runtime·cpuid_edx(SB) -- -- // Check for MMX support -- TESTL $(1<<23), DX // MMX -- JZ bad_proc -- - // Load EAX=7/ECX=0 cpuid flags - CMPL SI, $7 - JLT nocpuinfo -@@ -170,17 +139,6 @@ ok: - INT $3 - RET - --DATA bad_proc_msg<>+0x00(SB)/8, $"This pro" --DATA bad_proc_msg<>+0x08(SB)/8, $"gram can" --DATA bad_proc_msg<>+0x10(SB)/8, $" only be" --DATA bad_proc_msg<>+0x18(SB)/8, $" run on " --DATA bad_proc_msg<>+0x20(SB)/8, $"processo" --DATA bad_proc_msg<>+0x28(SB)/8, $"rs with " --DATA bad_proc_msg<>+0x30(SB)/8, $"MMX supp" --DATA bad_proc_msg<>+0x38(SB)/4, $"ort." --DATA bad_proc_msg<>+0x3c(SB)/1, $0xa --GLOBL bad_proc_msg<>(SB), RODATA, $0x3d -- - DATA runtime·mainPC+0(SB)/4,$runtime·main(SB) - GLOBL runtime·mainPC(SB),RODATA,$4 - diff --git a/gosuper/go-1.8.3-patches/0002-implement-atomic-quadword-ops-with-FILD-FISTP.patch b/gosuper/go-1.8.3-patches/0002-implement-atomic-quadword-ops-with-FILD-FISTP.patch deleted file mode 100644 index 76009fcc..00000000 --- a/gosuper/go-1.8.3-patches/0002-implement-atomic-quadword-ops-with-FILD-FISTP.patch +++ /dev/null @@ -1,88 +0,0 @@ -commit 03def348bdd766df0c508ee8cbf6ceba00e8d78c -Author: Pablo Carranza Velez -Date: Fri Jun 9 15:07:55 2017 -0700 - - Implement atomic quadword ops with FILD/FISTP - - Adapted from https://github.com/resin-io/resin-supervisor/blob/c7a7ba93fb46775006f0739ced41fc0a2059b426/gosuper/go-1.6.3-patches/0002-implement-atomic-quadword-ops-with-FILD-FISTP.patch - Original author: Petros Angelatos - - Signed-off-by: Pablo Carranza Velez - -diff --git a/src/runtime/internal/atomic/asm_386.s b/src/runtime/internal/atomic/asm_386.s -index 882906e..d37c675 100644 ---- a/src/runtime/internal/atomic/asm_386.s -+++ b/src/runtime/internal/atomic/asm_386.s -@@ -124,12 +124,10 @@ TEXT runtime∕internal∕atomic·Load64(SB), NOSPLIT, $0-12 - JZ 2(PC) - MOVL 0, AX // crash with nil ptr deref - LEAL ret_lo+4(FP), BX -- // MOVQ (%EAX), %MM0 -- BYTE $0x0f; BYTE $0x6f; BYTE $0x00 -- // MOVQ %MM0, 0(%EBX) -- BYTE $0x0f; BYTE $0x7f; BYTE $0x03 -- // EMMS -- BYTE $0x0F; BYTE $0x77 -+ // FILDQ (%EAX) -+ BYTE $0xdf; BYTE $0x28 -+ // FISTPQ (%EBX) -+ BYTE $0xdf; BYTE $0x3b - RET - - // void runtime∕internal∕atomic·Store64(uint64 volatile* addr, uint64 v); -@@ -138,13 +136,10 @@ TEXT runtime∕internal∕atomic·Store64(SB), NOSPLIT, $0-12 - TESTL $7, AX - JZ 2(PC) - MOVL 0, AX // crash with nil ptr deref -- // MOVQ and EMMS were introduced on the Pentium MMX. -- // MOVQ 0x8(%ESP), %MM0 -- BYTE $0x0f; BYTE $0x6f; BYTE $0x44; BYTE $0x24; BYTE $0x08 -- // MOVQ %MM0, (%EAX) -- BYTE $0x0f; BYTE $0x7f; BYTE $0x00 -- // EMMS -- BYTE $0x0F; BYTE $0x77 -+ // FILDQ 0x8(%ESP) -+ BYTE $0xdf; BYTE $0x6c; BYTE $0x24; BYTE $0x08 -+ // FISTPQ (%EAX) -+ BYTE $0xdf; BYTE $0x38 - // This is essentially a no-op, but it provides required memory fencing. - // It can be replaced with MFENCE, but MFENCE was introduced only on the Pentium4 (SSE2). - MOVL $0, AX -diff --git a/src/sync/atomic/asm_386.s b/src/sync/atomic/asm_386.s -index f2a13da..c7787a4 100644 ---- a/src/sync/atomic/asm_386.s -+++ b/src/sync/atomic/asm_386.s -@@ -157,12 +157,10 @@ TEXT ·LoadUint64(SB),NOSPLIT,$0-12 - TESTL $7, AX - JZ 2(PC) - MOVL 0, AX // crash with nil ptr deref -- // MOVQ and EMMS were introduced on the Pentium MMX. -- // MOVQ (%EAX), %MM0 -- BYTE $0x0f; BYTE $0x6f; BYTE $0x00 -- // MOVQ %MM0, 0x8(%ESP) -- BYTE $0x0f; BYTE $0x7f; BYTE $0x44; BYTE $0x24; BYTE $0x08 -- EMMS -+ // FILDQ (%EAX) -+ BYTE $0xdf; BYTE $0x28 -+ // FISTPQ 0x8(%ESP) -+ BYTE $0xdf; BYTE $0x7c; BYTE $0x24; BYTE $0x08 - RET - - TEXT ·LoadUintptr(SB),NOSPLIT,$0-8 -@@ -188,12 +186,10 @@ TEXT ·StoreUint64(SB),NOSPLIT,$0-12 - TESTL $7, AX - JZ 2(PC) - MOVL 0, AX // crash with nil ptr deref -- // MOVQ and EMMS were introduced on the Pentium MMX. -- // MOVQ 0x8(%ESP), %MM0 -- BYTE $0x0f; BYTE $0x6f; BYTE $0x44; BYTE $0x24; BYTE $0x08 -- // MOVQ %MM0, (%EAX) -- BYTE $0x0f; BYTE $0x7f; BYTE $0x00 -- EMMS -+ // FILDQ 0x8(%ESP) -+ BYTE $0xdf; BYTE $0x6c; BYTE $0x24; BYTE $0x08 -+ // FISTPQ (%EAX) -+ BYTE $0xdf; BYTE $0x38 - // This is essentially a no-op, but it provides required memory fencing. - // It can be replaced with MFENCE, but MFENCE was introduced only on the Pentium4 (SSE2). - XORL AX, AX diff --git a/gosuper/gosuper/api.go b/gosuper/gosuper/api.go deleted file mode 100644 index 03f17b3d..00000000 --- a/gosuper/gosuper/api.go +++ /dev/null @@ -1,265 +0,0 @@ -package main - -import ( - "encoding/json" - "fmt" - "log" - "net/http" - "time" - - "resin-supervisor/gosuper/systemd" -) - -// APIResponse The api response sent from go supervisor -type APIResponse struct { - Data interface{} - Error string -} - -// VPNBody interface for post request received by VPN control end point -type VPNBody struct { - Enable bool -} - -type LogToDisplayBody struct { - Enable bool -} - -type RestartServiceBody struct { - Name string -} - -func jsonResponse(writer http.ResponseWriter, response interface{}, status int) { - jsonBody, err := json.Marshal(response) - if err != nil { - log.Printf("Could not marshal JSON for %+v\n", response) - } - writer.Header().Set("Content-Type", "application/json") - writer.WriteHeader(status) - writer.Write(jsonBody) -} - -func parseJSONBody(destination interface{}, request *http.Request) error { - decoder := json.NewDecoder(request.Body) - return decoder.Decode(&destination) -} - -func responseSenders(writer http.ResponseWriter) (sendResponse func(interface{}, string, int), sendError func(error)) { - sendResponse = func(data interface{}, errorMsg string, statusCode int) { - jsonResponse(writer, APIResponse{data, errorMsg}, statusCode) - } - sendError = func(err error) { - sendResponse("Error", err.Error(), http.StatusInternalServerError) - } - return -} - -func inASecond(theFunc func()) { - time.Sleep(time.Duration(time.Second)) - theFunc() -} - -//RebootHandler Reboots the device using Systemd -func RebootHandler(writer http.ResponseWriter, request *http.Request) { - log.Println("Rebooting") - - sendResponse, sendError := responseSenders(writer) - if systemd.Logind == nil { - sendError(fmt.Errorf("Logind unavailable, cannot reboot.")) - return - } - sendResponse("OK", "", http.StatusAccepted) - go inASecond(func() { systemd.Logind.Reboot(false) }) -} - -//ShutdownHandler Shuts down the device using Systemd -func ShutdownHandler(writer http.ResponseWriter, request *http.Request) { - log.Println("Shutting down") - - sendResponse, sendError := responseSenders(writer) - if systemd.Logind == nil { - sendError(fmt.Errorf("Logind unavailable, cannot shut down.")) - return - } - sendResponse("OK", "", http.StatusAccepted) - go inASecond(func() { systemd.Logind.PowerOff(false) }) -} - -//VPNControl is used to control VPN service status with dbus -func VPNControl(writer http.ResponseWriter, request *http.Request) { - sendResponse, sendError := responseSenders(writer) - var body VPNBody - if err := parseJSONBody(&body, request); err != nil { - log.Println(err) - sendResponse("Error", err.Error(), http.StatusBadRequest) - return - } - - if systemd.Dbus == nil { - sendError(fmt.Errorf("Systemd dbus unavailable, cannot set VPN state.")) - return - } - - action := systemd.Dbus.StopUnit - actionDescr := "VPN Disable" - if body.Enable { - action = systemd.Dbus.StartUnit - actionDescr = "VPN Enable" - } - if _, err := action("openvpn-resin.service", "fail", nil); err != nil { - log.Printf("%s: %s\n", actionDescr, err) - sendError(err) - return - } - log.Printf("%sd\n", actionDescr) - sendResponse("OK", "", http.StatusAccepted) -} - -func getUnitStatus(unitName string) (state bool, err error) { - if systemd.Dbus == nil { - err = fmt.Errorf("Systemd dbus unavailable, cannot get unit status.") - return - } - if activeState, e := systemd.Dbus.GetUnitProperty(unitName, "ActiveState"); e != nil { - err = fmt.Errorf("Unable to get unit status: %v", e) - return - } else { - activeStateStr := activeState.Value.String() - state = activeStateStr != `"inactive"` && activeStateStr != `"deactivating"` - return - } -} - -func unitStatusHandler(serviceName string, writer http.ResponseWriter, request *http.Request) { - sendResponse, sendError := responseSenders(writer) - if status, err := getUnitStatus(serviceName); err != nil { - sendError(fmt.Errorf("Unable to get VPN status: %v", err)) - } else { - sendResponse(status, "", http.StatusOK) - } -} - -func VPNStatus(writer http.ResponseWriter, request *http.Request) { - unitStatusHandler("openvpn-resin.service", writer, request) -} - -func logToDisplayServiceName() (serviceName string, err error) { - serviceName = "resin-info@tty1.service" - serviceNameOld := "tty-replacement.service" - if systemd.Dbus == nil { - err = fmt.Errorf("Systemd dbus unavailable, cannot get log to display service.") - return - } - if loaded, e := systemd.Dbus.GetUnitProperty(serviceName, "LoadState"); e != nil { - err = fmt.Errorf("Unable to get log to display load status: %v", e) - return - } else if loaded.Value.String() == `"not-found"` { - // If the resin-info service is not found, we're on an older OS - // which uses a different service name - serviceName = serviceNameOld - } - if loaded, e := systemd.Dbus.GetUnitProperty(serviceName, "LoadState"); e != nil { - err = fmt.Errorf("Unable to get log to display load status: %v", e) - return - } else if loaded.Value.String() == `"not-found"` { - // We might be in a different OS that just doesn't have the service - serviceName = "" - return - } - return -} - -func LogToDisplayStatus(writer http.ResponseWriter, request *http.Request) { - sendResponse, sendError := responseSenders(writer) - serviceName, err := logToDisplayServiceName() - if err != nil { - sendError(err) - return - } else if serviceName == "" { - sendResponse("Error", "Not found", http.StatusNotFound) - return - } - unitStatusHandler(serviceName, writer, request) -} - -//LogToDisplayControl is used to control tty-replacement service status with dbus -func LogToDisplayControl(writer http.ResponseWriter, request *http.Request) { - sendResponse, sendError := responseSenders(writer) - var body LogToDisplayBody - if err := parseJSONBody(&body, request); err != nil { - log.Println(err) - sendResponse("Error", err.Error(), http.StatusBadRequest) - return - } - - if systemd.Dbus == nil { - sendError(fmt.Errorf("Systemd dbus unavailable, cannot set log to display state.")) - return - } - - serviceName, err := logToDisplayServiceName() - if err != nil { - sendError(err) - return - } else if serviceName == "" { - sendResponse("Error", "Not found", http.StatusNotFound) - return - } - - if status, err := getUnitStatus(serviceName); err != nil { - sendError(fmt.Errorf("Unable to get log to display status: %v", err)) - return - } else { - enable := body.Enable - if status == enable { - // Nothing to do, return Data = false to signal nothing was changed - sendResponse(false, "", http.StatusOK) - return - } else if enable { - if _, err := systemd.Dbus.StartUnit(serviceName, "fail", nil); err != nil { - sendError(fmt.Errorf("Unable to start service: %v", err)) - return - } - if _, _, err = systemd.Dbus.EnableUnitFiles([]string{serviceName}, false, false); err != nil { - sendError(fmt.Errorf("Unable to enable service: %v", err)) - return - } - } else { - if _, err := systemd.Dbus.StopUnit(serviceName, "fail", nil); err != nil { - sendError(fmt.Errorf("Unable to stop service: %v", err)) - return - } - if _, err = systemd.Dbus.DisableUnitFiles([]string{serviceName}, false); err != nil { - sendError(fmt.Errorf("Unable to disable service: %v", err)) - return - } - } - sendResponse(true, "", http.StatusOK) - } -} - -//RestartService is used to restart a systemd service by name -func RestartService(writer http.ResponseWriter, request *http.Request) { - sendResponse, sendError := responseSenders(writer) - var body RestartServiceBody - if err := parseJSONBody(&body, request); err != nil { - log.Println(err) - sendResponse("Error", err.Error(), http.StatusBadRequest) - return - } - - if systemd.Dbus == nil { - sendError(fmt.Errorf("Systemd dbus unavailable, cannot restart service.")) - return - } - - actionDescr := "Service Restart" - - if _, err := systemd.Dbus.RestartUnit(body.Name+".service", "fail", nil); err != nil { - log.Printf("%s: %s\n", actionDescr, err) - sendError(err) - return - } - log.Printf("%sd\n", actionDescr) - sendResponse("OK", "", http.StatusOK) -} diff --git a/gosuper/gosuper/main.go b/gosuper/gosuper/main.go deleted file mode 100644 index 25d3b2f9..00000000 --- a/gosuper/gosuper/main.go +++ /dev/null @@ -1,46 +0,0 @@ -package main - -import ( - "fmt" - "log" - "net" - "net/http" - "os" - - "github.com/gorilla/mux" -) - -func setupApi(router *mux.Router) { - router.HandleFunc("/ping", func(writer http.ResponseWriter, request *http.Request) { - fmt.Fprintln(writer, "OK") - }) - - apiv1 := router.PathPrefix("/v1").Subrouter() - apiv1.HandleFunc("/reboot", RebootHandler).Methods("POST") - apiv1.HandleFunc("/shutdown", ShutdownHandler).Methods("POST") - apiv1.HandleFunc("/vpncontrol", VPNControl).Methods("POST") - apiv1.HandleFunc("/vpncontrol", VPNStatus).Methods("GET") - apiv1.HandleFunc("/log-to-display", LogToDisplayControl).Methods("POST") - apiv1.HandleFunc("/log-to-display", LogToDisplayStatus).Methods("GET") - apiv1.HandleFunc("/restart-service", RestartService).Methods("POST") -} - -func startApi(listenAddress string, router *mux.Router) { - if listener, err := net.Listen("unix", listenAddress); err != nil { - log.Fatalf("Could not listen on %s: %v", listenAddress, err) - } else { - log.Printf("Starting HTTP server on %s\n", listenAddress) - if err = http.Serve(listener, router); err != nil { - log.Fatalf("Could not start HTTP server: %v", err) - } - } -} - -func main() { - log.SetFlags(log.Lshortfile | log.LstdFlags) - log.Println("Resin Go Supervisor starting") - listenAddress := os.Getenv("GOSUPER_SOCKET") - router := mux.NewRouter() - setupApi(router) - startApi(listenAddress, router) -} diff --git a/gosuper/systemd/systemd.go b/gosuper/systemd/systemd.go deleted file mode 100644 index 725065b7..00000000 --- a/gosuper/systemd/systemd.go +++ /dev/null @@ -1,25 +0,0 @@ -package systemd - -import ( - "log" - - "github.com/coreos/go-systemd/dbus" - "github.com/coreos/go-systemd/login1" -) - -var ( - // Logind Systemd Login1 connection - Logind *login1.Conn - // Dbus Systems Dbus connection - Dbus *dbus.Conn -) - -func init() { - var err error - if Logind, err = login1.New(); err != nil { - log.Printf("Failed to connect to host system bus: %s", err) - } - if Dbus, err = dbus.New(); err != nil { - log.Printf("Failed to connect to host DBUS: %s", err) - } -} diff --git a/gosuper/test_formatting.sh b/gosuper/test_formatting.sh deleted file mode 100755 index a6967ba6..00000000 --- a/gosuper/test_formatting.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash - -for dir in $(find ./* -path ./vendor -prune -or -type d -print); do - errormessage=$(gofmt -l $dir) - if [ -n "$errormessage" ]; then - echo "$errormessage" - failed=1 - fi -done - -if [ -n "$failed" ]; then - echo "Bad formatting, run make format-gosuper to fix above errors." - exit 1 -fi diff --git a/gosuper/vendor/github.com/coreos/go-systemd/.travis.yml b/gosuper/vendor/github.com/coreos/go-systemd/.travis.yml deleted file mode 100644 index aa346efd..00000000 --- a/gosuper/vendor/github.com/coreos/go-systemd/.travis.yml +++ /dev/null @@ -1,27 +0,0 @@ -sudo: required - -services: - - docker - -env: - global: - - GOPATH=/opt - - BUILD_DIR=/opt/src/github.com/coreos/go-systemd - matrix: - - DOCKER_BASE=ubuntu:16.04 - - DOCKER_BASE=debian:stretch - -before_install: - - docker pull ${DOCKER_BASE} - - docker run --privileged -e GOPATH=${GOPATH} --cidfile=/tmp/cidfile ${DOCKER_BASE} /bin/bash -c "apt-get update && apt-get install -y build-essential git golang dbus libsystemd-dev libpam-systemd && go get github.com/coreos/pkg/dlopen && go get github.com/godbus/dbus" - - docker commit `cat /tmp/cidfile` go-systemd/container-tests - - rm -f /tmp/cidfile - -install: - - docker run -d --cidfile=/tmp/cidfile --privileged -e GOPATH=${GOPATH} -v ${PWD}:${BUILD_DIR} go-systemd/container-tests /bin/systemd --system - -script: - - docker exec `cat /tmp/cidfile` /bin/bash -c "cd ${BUILD_DIR} && ./test" - -after_script: - - docker kill `cat /tmp/cidfile` diff --git a/gosuper/vendor/github.com/coreos/go-systemd/CONTRIBUTING.md b/gosuper/vendor/github.com/coreos/go-systemd/CONTRIBUTING.md deleted file mode 100644 index 0551ed53..00000000 --- a/gosuper/vendor/github.com/coreos/go-systemd/CONTRIBUTING.md +++ /dev/null @@ -1,77 +0,0 @@ -# How to Contribute - -CoreOS projects are [Apache 2.0 licensed](LICENSE) and accept contributions via -GitHub pull requests. This document outlines some of the conventions on -development workflow, commit message formatting, contact points and other -resources to make it easier to get your contribution accepted. - -# Certificate of Origin - -By contributing to this project you agree to the Developer Certificate of -Origin (DCO). This document was created by the Linux Kernel community and is a -simple statement that you, as a contributor, have the legal right to make the -contribution. See the [DCO](DCO) file for details. - -# Email and Chat - -The project currently uses the general CoreOS email list and IRC channel: -- Email: [coreos-dev](https://groups.google.com/forum/#!forum/coreos-dev) -- IRC: #[coreos](irc://irc.freenode.org:6667/#coreos) IRC channel on freenode.org - -Please avoid emailing maintainers found in the MAINTAINERS file directly. They -are very busy and read the mailing lists. - -## Getting Started - -- Fork the repository on GitHub -- Read the [README](README.md) for build and test instructions -- Play with the project, submit bugs, submit patches! - -## Contribution Flow - -This is a rough outline of what a contributor's workflow looks like: - -- Create a topic branch from where you want to base your work (usually master). -- Make commits of logical units. -- Make sure your commit messages are in the proper format (see below). -- Push your changes to a topic branch in your fork of the repository. -- Make sure the tests pass, and add any new tests as appropriate. -- Submit a pull request to the original repository. - -Thanks for your contributions! - -### Coding Style - -CoreOS projects written in Go follow a set of style guidelines that we've documented -[here](https://github.com/coreos/docs/tree/master/golang). Please follow them when -working on your contributions. - -### Format of the Commit Message - -We follow a rough convention for commit messages that is designed to answer two -questions: what changed and why. The subject line should feature the what and -the body of the commit should describe the why. - -``` -scripts: add the test-cluster command - -this uses tmux to setup a test cluster that you can easily kill and -start for debugging. - -Fixes #38 -``` - -The format can be described more formally as follows: - -``` -: - - - -