Skip to content

Commit

Permalink
add: service file, workflow
Browse files Browse the repository at this point in the history
  • Loading branch information
Zyian committed Mar 16, 2022
1 parent 65ddea6 commit 6daec1d
Show file tree
Hide file tree
Showing 8 changed files with 194 additions and 32 deletions.
33 changes: 33 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: goreleaser

on:
push:
tags:
- 'v*'

permissions:
contents: write

jobs:
goreleaser:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Fetch all tags
run: git fetch --force --tags
- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: 1.18
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v2
if: startsWith(github.ref, 'refs/tags/')
with:
distribution: goreleaser
version: latest
args: release --rm-dist
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@

# Dependency directories (remove the comment below to include it)
# vendor/
.idea/
.idea/
dist/
35 changes: 35 additions & 0 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# This is an example .goreleaser.yml file with some sensible defaults.
# Make sure to check the documentation at https://goreleaser.com
before:
hooks:
# You may remove this if you don't use go modules.
- go mod tidy
builds:
- env:
- CGO_ENABLED=0
main: ./cmd/arcmon
binary: arcmon
goos:
- linux
- windows
- darwin
archives:
- replacements:
darwin: Darwin
linux: Linux
windows: Windows
386: i386
amd64: x86_64
files:
- src: systemd/arcmon.service
strip_parent: true
checksum:
name_template: 'checksums.txt'
snapshot:
name_template: "{{ incpatch .Version }}-next"
changelog:
sort: asc
filters:
exclude:
- '^docs:'
- '^test:'
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# ArcDPS Monitor
# ArcDPS Monitor [![Go](https://github.com/mythwright/arc-monitor/actions/workflows/build.yml/badge.svg?branch=main)](https://github.com/mythwright/arc-monitor/actions/workflows/build.yml)
A very simple daemon to notifiy a Discord Webhook whenever ArcDPS gets updated (within a set interval)
114 changes: 89 additions & 25 deletions cmd/arcmon/main.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package arcmon
package main

import (
"bytes"
Expand All @@ -8,8 +8,11 @@ import (
"net"
"net/http"
"os"
"os/signal"
"path/filepath"
"strings"
"sync"
"syscall"
"time"

"github.com/sirupsen/logrus"
Expand All @@ -24,38 +27,52 @@ const (
)

type ArcDPSVersion struct {
Timestamp time.Time `yaml:"timestamp"`
CheckSum string `yaml:"check_sum"`
Timestamp time.Time `yaml:"timestamp"`
CheckSum string `yaml:"check_sum"`
sync.RWMutex `yaml:"-"`
}

func main() {
f, err := os.Open(filepath.Dir(os.TempDir() + "/arcdps.yaml"))
if os.Getenv("DISCORD_WEBHOOK") == "" {
logrus.Fatalf("missing DISCORD_WEBHOOK env variable")
}

f, err := os.OpenFile(filepath.Join(".", "arcdps.yml"), os.O_RDWR|os.O_CREATE, 0755)
if err != nil {
if err != os.ErrNotExist {
logrus.Fatalf("err opening temp file: %v\n", err)
}
f, err = os.CreateTemp("", "/arcdps.yml")
if err != nil {
logrus.Fatalf("temp file not exists and unable to create new one: %v\n", err)
if !strings.Contains(err.Error(), "no such") {
logrus.Fatalf("err opening tracking file: %v\n", err)
}
}

logrus.Infof("using: %s", f.Name())

arcdps := &ArcDPSVersion{}
if err := yaml.NewDecoder(f).Decode(&arcdps); err != nil {
if err := yaml.NewDecoder(f).Decode(&arcdps); err != nil && err != io.EOF {
logrus.Fatalf("unable to decode arcdps.yml: %v", err)
}

s := NewServer()
s.Tick()

s := NewServer(arcdps)
ctx, cncl := context.WithCancel(context.Background())
go s.Tick(ctx)
sig := make(chan os.Signal, 1)
signal.Notify(sig, syscall.SIGTERM, syscall.SIGKILL, os.Interrupt)
<-sig
cncl()
logrus.Infof("shutting down")
f.Seek(0, 0) //rewind file descriptor
if err := yaml.NewEncoder(f).Encode(arcdps); err != nil {
logrus.Fatalf("unable to save file: (%v)", err)
}
f.Close()
}

type Server struct {
http *http.Client
webhookURL string
arcdps *ArcDPSVersion
}

func NewServer() *Server {
func NewServer(arcdps *ArcDPSVersion) *Server {
return &Server{
http: &http.Client{
Transport: &http.Transport{
Expand All @@ -64,11 +81,48 @@ func NewServer() *Server {
Timeout: 5 * time.Second,
},
webhookURL: os.Getenv("DISCORD_WEBHOOK"),
arcdps: arcdps,
}
}

func (s *Server) Tick() {

func (s *Server) Tick(ctx context.Context) {
ticker := time.NewTicker(DefaultTickDuration)
logrus.Infof("Starting Check Ticker")
for {
select {
case <-ticker.C:
check, err := s.GetChecksum(ctx)
if err != nil {
logrus.Errorf("Failed getting checksum: (%v)", err)
continue
}
version, err := s.GetVersion(ctx)
if err != nil {
logrus.Errorf("Failed getting version: (%v)", err)
continue
}
if s.arcdps.CheckSum == "" {
logrus.Infof("Setting initial version")
s.arcdps.CheckSum = check
s.arcdps.Timestamp = version
continue
}
if s.arcdps.CheckSum != check {
// new version
if err := s.SendWebHook(ctx,
fmt.Sprintf("`%s`", check),
fmt.Sprintf("`%s`", version.String()),
); err != nil {
logrus.Errorf("unable to send webhook: (%v)\n", err)
}
s.arcdps.CheckSum = check
s.arcdps.Timestamp = version
}
case <-ctx.Done():
ticker.Stop()
return
}
}
}

func (s *Server) GetChecksum(ctx context.Context) (string, error) {
Expand Down Expand Up @@ -128,35 +182,42 @@ func (s *Server) GetVersion(ctx context.Context) (time.Time, error) {
}

func (s *Server) SendWebHook(ctx context.Context, checksum, time string) error {
payload := bytes.NewBufferString(fmt.Sprintf(PayloadJSON, checksum, time))
payload := bytes.NewBufferString(fmt.Sprintf(PayloadJSON, checksum, time, DefaultTickDuration.String()))
req, err := http.NewRequestWithContext(ctx, "POST", s.webhookURL, payload)
if err != nil {
return err
}

req.Header.Set("Content-Type", "application/json")

resp, err := s.http.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()

if resp.StatusCode > 299 {
return fmt.Errorf("bad response from Discord: %d", resp.StatusCode)
body, err := io.ReadAll(resp.Body)
if err != nil {
return err
}
return fmt.Errorf("bad response from Discord: %d (%s)", resp.StatusCode, string(body))
}
return nil
}

var (
PayloadJSON = `
{
"content": null,
"embeds": [
{
"title": "ArcDPS has updated!",
"color": 12124160,
"fields": [
{
"name": "CheckSum",
"value": "%s"
"name": "Checksum",
"value": "%s",
"inline": true
},
{
"name": "Timestamp Version",
Expand All @@ -165,12 +226,15 @@ var (
},
{
"name": "Direct Download Link",
"value": "https://www.deltaconnected.com/arcdps/x64/d3d9.dll",
"inline": true
"value": "https://www.deltaconnected.com/arcdps/x64/d3d9.dll"
}
],
"author": {
"name": "ArcDPS Monitor",
"icon_url": "https://wiki.guildwars2.com/images/0/03/Specter_icon_(highres).png"
},
"footer": {
"text": "ArcDPS Monitor"
"text": "This bot checks every %s"
}
}
]
Expand Down
9 changes: 5 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
module github.com/mythwright/arc-monitor

go 1.17
go 1.18

require (
github.com/sirupsen/logrus v1.8.1 // indirect
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
github.com/sirupsen/logrus v1.8.1
gopkg.in/yaml.v2 v2.4.0
)

require golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86 // indirect
7 changes: 6 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86 h1:A9i04dxx7Cribqbs8jf3FQLogkL/CV2YN7hj9KWJCkc=
golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
23 changes: 23 additions & 0 deletions systemd/arcmon.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[Unit]
Description=ArcMon Daemon

Wants=network.target
After=network.target

[Service]
User=arcmon
Group=arcmon
Restart=on-failure

ProtectHome=true
ProtectSystem=full
PrivateDevices=true
NoNewPrivileges=true
PrivateTmp=true
InaccessibleDirectories=/root /sys /srv -/opt /media -/lost+found
ReadWriteDirectories=/var/arcmon
WorkingDirectory=/var/arcmon
ExecStart=arcmon

[Install]
WantedBy=multi-user.target

0 comments on commit 6daec1d

Please sign in to comment.