Skip to content

Commit

Permalink
Merge pull request #6 from redcraft-org/feature/go-modules
Browse files Browse the repository at this point in the history
Use go modules instead of hacky tricks
  • Loading branch information
lululombard authored Oct 24, 2020
2 parents 5156367 + 3c82016 commit e46c26b
Show file tree
Hide file tree
Showing 26 changed files with 811 additions and 316 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ jobs:

- uses: actions/setup-go@v2
with:
go-version: '^1.13.8'
go-version: '^1.14'

- name: Install dependencies
run: go install

- name: Build binary
run: scripts/build.sh
Expand Down
21 changes: 21 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Test project

on: [push]

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@master

- uses: actions/setup-go@v2
with:
go-version: '^1.14'

- name: Install dependencies
run: go install

- name: Check compilation
run: echo "Reported rcsm version `DUMP_VERSION_AND_EXIT=1 scripts/test.sh`"
4 changes: 0 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,5 @@ bin/*
.idea/
.vscode/
pkg/
src/github.com/
src/golang.org/
src/go.opentelemetry.io/
src/gopkg.in/

.env
9 changes: 4 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,13 @@ rcsm requires tmux to be installed and in the PATH to work.

## Development

### Disclaimer
### Installation

We're not golang experts and I'm pretty sure we're doing stuff wrong in this project because it will set the `GOPATH` to `src`, and we use some scripts to install deps.

Feel free to contribute to fix this if that's not how we're supposed to do it.
Run `go install`, it should install all the dependencies from `go.mod`.

### Start the project

rcsm requires tmux, golang 1.13.8 or later to develop for, and that's pretty much it!
rcsm requires tmux, golang 1.14 or later to develop for, and that's pretty much it!

You can start the dev server by running `scripts/test.sh` and compile the project using `scripts/build.sh`.

Expand Down Expand Up @@ -112,6 +110,7 @@ Make sure to add a webhook integration on the desired Discord channel and set th

Here's how the formatting looks:

<!-- Please do not fix this linter warning, it's for high DPI displays -->
<img width="393" alt="Discord webhooks" src="https://user-images.githubusercontent.com/2182934/92288579-55071f00-eedb-11ea-9ed2-0650a29593d7.png">

### Redis
Expand Down
31 changes: 31 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
module github.com/redcraft-org/redcraft_server_management

go 1.15

require (
github.com/acroca/go-symbols v0.1.1
github.com/aws/aws-sdk-go v1.35.14
github.com/blang/semver v3.5.1+incompatible
github.com/cweill/gotests v1.5.3
github.com/davidrjenni/reftools v0.0.0-20191222082827-65925cf01315
github.com/fatih/gomodifytags v1.11.0
github.com/go-delve/delve v1.5.0
github.com/go-redis/redis v6.15.9+incompatible
github.com/go-redis/redis/v8 v8.3.2
github.com/godoctor/godoctor v0.0.0-20200702010311-8433dcb3dc61
github.com/google/go-querystring v1.0.0
github.com/haya14busa/goplay v1.0.0
github.com/joho/godotenv v1.3.0
github.com/josharian/impl v1.0.0
github.com/mdempsky/gocode v0.0.0-20200405233807-4acdcbdea79d
github.com/ramya-rao-a/go-outline v0.0.0-20200117021646-2a048b4510eb
github.com/rhysd/go-github-selfupdate v1.2.2
github.com/rogpeppe/godef v1.1.2
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966
github.com/stamblerre/gocode v1.0.0
github.com/uudashr/gopkgs/v2 v2.1.2
golang.org/x/lint v0.0.0-20200302205851-738671d3881b
golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6
gopkg.in/bufio.v1 v1.0.0-20140618132640-567b2bfa514e // indirect
gopkg.in/redis.v2 v2.3.2
)
234 changes: 234 additions & 0 deletions go.sum

Large diffs are not rendered by default.

60 changes: 60 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package main

import (
"fmt"
"os"
"os/signal"
"syscall"

"github.com/redcraft-org/redcraft_server_management/rcsm"
)

func main() {
initialize()
waitForQuitSignal()
stop()
}

func initialize() {
if rcsm.ReadEnvBool("DUMP_VERSION_AND_EXIT", false) {
fmt.Print(rcsm.Version)
os.Exit(0)
}

rcsm.ReadConfig()

rcsm.TriggerLogEvent("info", "rcsm", fmt.Sprintf("Starting rcsm (RedCraft Server Manager) v%s", rcsm.Version))

if rcsm.RedisEnabled {
rcsm.RedisConnect()
}

rcsm.CreateMissingServers()
rcsm.DiscoverServers()

if rcsm.AutoStartOnBoot {
rcsm.StartAllServers()
}

if rcsm.AutoRestartCrashEnabled {
rcsm.StartHealthCheck()
}

if rcsm.AutoUpdateEnabled {
rcsm.StartUpdateChecks()
}
}

func stop() {
rcsm.TriggerLogEvent("info", "rcsm", fmt.Sprintf("Stopping rcsm (RedCraft Server Manager) v%s", rcsm.Version))

if rcsm.AutoStopOnClose {
rcsm.StopAllServers()
}
}

func waitForQuitSignal() {
exitSignal := make(chan os.Signal)
signal.Notify(exitSignal, syscall.SIGINT, syscall.SIGTERM)
<-exitSignal
}
156 changes: 156 additions & 0 deletions rcsm/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
package rcsm

import (
"os"
"strconv"
"strings"

"github.com/joho/godotenv"
)

var (
// Version is the current version of rcsm
Version string = "0.1.0"
// EnvFile is the path to the .env file config
EnvFile string = ".env"

// InstanceName is used for event reporting on Redis and Webhooks, useful if you have multiple rcsm instances
InstanceName string = "server"

// RedisEnabled specifies if Redis communication should be enabled
RedisEnabled bool = false
// RedisHost specifies the Redis server to use
RedisHost string = "localhost:6379"
// RedisPassword is the plaintext password of the server
RedisPassword string = ""
// RedisDatabase is the database ID used for Redis
RedisDatabase int64 = 0
// RedisPubSubChannel is the channel used for Redis pub/sub notifications
RedisPubSubChannel string = "rcsm"

// S3Enabled specifies wether or not S3 is enabled to update the server from templates
S3Enabled bool = false
// S3Endpoint specifies the S3 endpoint if you use something else than AWS
S3Endpoint string = ""
// S3Region specifies the region to use for the S3 bucket
S3Region string = ""
// S3Bucket specifies the bucket name for server templates
S3Bucket string = ""
// AWSAccessKeyID is the key ID for S3 authentication
AWSAccessKeyID string = ""
// AWSSecretAccessKey is the secret key for S3 authentication
AWSSecretAccessKey string = ""

// MinecraftServersDirectory is the directory where server directories are stored
MinecraftServersDirectory string = "/opt/minecraft"
// MinecraftServersToCreate is the servers you want to deploy if a template exists on S3
MinecraftServersToCreate string = ""
// MinecraftTmuxSessionPrefix is the prefix to use for tmux session names
MinecraftTmuxSessionPrefix string = "rcsm_"

// AutoStartOnBoot specifies if Minecraft servers should start when rcsm starts
AutoStartOnBoot bool = true
// AutoStopOnClose specifies if Minecraft servers should stopped when rcsm closes
AutoStopOnClose bool = false
// AutoRestartCrashEnabled specifies if rcsm should attempt to restart servers on crash
AutoRestartCrashEnabled bool = true
// AutoRestartCrashMaxTries specifies how many tries rcsm should attempt to get a server running for more than 5 minutes
AutoRestartCrashMaxTries int64 = 3
// AutoRestartCrashTimeoutSec specifies for how long rcsm will wait to kill the server if not responding
AutoRestartCrashTimeoutSec int64 = 60

// WebhooksEnabled specifies if Webhooks (using Discord format) are enabled for alerts
WebhooksEnabled bool = false
// WebhooksEndpoint is the endpoint to use to send notifications to
WebhooksEndpoint string = ""

// AutoUpdateEnabled specifies if the auto update system should check for new versions of rcsm and install them
AutoUpdateEnabled bool = true
// AutoUpdateIntervalMinutes specifies how often updates should be checked
AutoUpdateIntervalMinutes int64 = 60
// AutoUpdateRepo specifies where to download updates for the last rcsm release
AutoUpdateRepo string = "redcraft-org/redcraft_server_management"
// ExitOnAutoUpdate specifies if rcsm should quit itself once updated. This is very useful when wrapped with systemd
ExitOnAutoUpdate bool = false
)

// ReadConfig reads the config from the env file
func ReadConfig() {
EnvFile = ReadEnvString("RCSM_ENV_FILE", ".env")

godotenv.Load(EnvFile)

InstanceName = ReadEnvString("INSTANCE_NAME", InstanceName)

RedisEnabled = ReadEnvBool("REDIS_ENABLED", RedisEnabled)
RedisHost = ReadEnvString("REDIS_HOST", RedisHost)
RedisPassword = ReadEnvString("REDIS_PASSWORD", RedisPassword)
RedisDatabase = ReadEnvInt("REDIS_DATABASE", RedisDatabase)
RedisPubSubChannel = ReadEnvString("REDIS_PUB_SUB_CHANNEL", RedisPubSubChannel)

S3Enabled = ReadEnvBool("S3_ENABLED", S3Enabled)
S3Endpoint = ReadEnvString("S3_ENDPOINT", S3Endpoint)
S3Region = ReadEnvString("S3_REGION", S3Region)
S3Bucket = ReadEnvString("S3_BUCKET", S3Bucket)
AWSAccessKeyID = ReadEnvString("AWS_ACCESS_KEY_ID", AWSAccessKeyID)
AWSSecretAccessKey = ReadEnvString("AWS_SECRET_ACCESS_KEY", AWSSecretAccessKey)

MinecraftServersDirectory = ReadEnvString("MINECRAFT_SERVERS_DIRECTORY", MinecraftServersDirectory)
MinecraftServersToCreate = ReadEnvString("MINECRAFT_SERVERS_TO_CREATE", MinecraftServersToCreate)
MinecraftTmuxSessionPrefix = ReadEnvString("MINECRAFT_TMUX_SESSION_PREFIX", MinecraftTmuxSessionPrefix)

AutoStartOnBoot = ReadEnvBool("AUTO_START_ON_BOOT", AutoStartOnBoot)
AutoStopOnClose = ReadEnvBool("AUTO_STOP_ON_CLOSE", AutoStopOnClose)
AutoRestartCrashEnabled = ReadEnvBool("AUTO_RESTART_CRASH_ENABLED", AutoRestartCrashEnabled)
AutoRestartCrashMaxTries = ReadEnvInt("AUTO_RESTART_CRASH_MAX_TRIES", AutoRestartCrashMaxTries)
AutoRestartCrashTimeoutSec = ReadEnvInt("AUTO_RESTART_CRASH_TIMEOUT_SEC", AutoRestartCrashTimeoutSec)

WebhooksEnabled = ReadEnvBool("WEBHOOKS_ENABLED", WebhooksEnabled)
WebhooksEndpoint = ReadEnvString("WEBHOOKS_ENDPOINT", WebhooksEndpoint)

AutoUpdateEnabled = ReadEnvBool("AUTO_UPDATE_ENABLED", AutoUpdateEnabled)
AutoUpdateIntervalMinutes = ReadEnvInt("AUTO_UPDATE_INTERVAL_MINUTES", AutoUpdateIntervalMinutes)
AutoUpdateRepo = ReadEnvString("AUTO_UPDATE_REPO", AutoUpdateRepo)
ExitOnAutoUpdate = ReadEnvBool("EXIT_ON_AUTO_UPDATE", ExitOnAutoUpdate)
}

// ReadEnvString reads a string from the env variables
func ReadEnvString(envName string, defaultValue string) string {
envVar := os.Getenv(envName)
if envVar == "" {
return defaultValue
}
return envVar
}

// ReadEnvInt reads an integer from the env variables
func ReadEnvInt(envName string, defaultValue int64) int64 {
envVarRaw := os.Getenv(envName)
if envVarRaw == "" {
return defaultValue
}
envVar, err := strconv.ParseInt(envVarRaw, 10, 64)
if err != nil {
return defaultValue
}
return envVar
}

// ReadEnvBool reads a boolean from the env variables
func ReadEnvBool(envName string, defaultValue bool) bool {
envVarRaw := os.Getenv(envName)
if envVarRaw == "" {
return defaultValue
}
envVar := strings.ToLower(envVarRaw)

switch envVar {
case
"true",
"yes",
"on",
"1":
return true
}
return false
}
7 changes: 3 additions & 4 deletions src/events/discord.go → rcsm/discord.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package events
package rcsm

import (
"bytes"
"config"
"encoding/json"
"fmt"
"io/ioutil"
Expand Down Expand Up @@ -38,7 +37,7 @@ func SendDiscordWebhook(level string, service string, message string) error {
}
instanceField := DiscordField{
Name: "Instance",
Value: config.InstanceName,
Value: InstanceName,
Inline: true,
}
serviceField := DiscordField{
Expand Down Expand Up @@ -67,7 +66,7 @@ func SendDiscordWebhook(level string, service string, message string) error {
return err
}

request, err := http.NewRequest("POST", config.WebhooksEndpoint, bytes.NewBuffer(jsonRequest))
request, err := http.NewRequest("POST", WebhooksEndpoint, bytes.NewBuffer(jsonRequest))
if err != nil {
return err
}
Expand Down
7 changes: 3 additions & 4 deletions src/events/events.go → rcsm/events.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package events
package rcsm

import (
"config"
"log"
"strings"
)
Expand All @@ -10,9 +9,9 @@ import (
func TriggerLogEvent(level string, service string, message string) {
level = strings.ToUpper(level)

log.Printf("[%s][%s][%s] %s", config.InstanceName, level, service, message)
log.Printf("[%s][%s][%s] %s", InstanceName, level, service, message)

if config.WebhooksEnabled && strings.ToLower(level) != "debug" {
if WebhooksEnabled && strings.ToLower(level) != "debug" {
err := SendDiscordWebhook(level, service, message)
if err != nil {
log.Printf("Error while sending webhook: %s", err)
Expand Down
Loading

0 comments on commit e46c26b

Please sign in to comment.