Skip to content
Permalink
Browse files

Preparing for caching in database, improving configuration file

  • Loading branch information...
Depado committed Feb 17, 2016
1 parent 327c302 commit 5c9b56f8f9f638596b94c612bd9402f7d2269bed
Showing with 108 additions and 48 deletions.
  1. +85 −15 configuration/configuration.go
  2. +9 −30 main.go
  3. +14 −3 models/service.go
@@ -1,35 +1,105 @@
package configuration

import (
"fmt"
"io/ioutil"
"strings"
"time"

"github.com/Depado/gomonit/models"

"gopkg.in/yaml.v2"
)

type configuration struct {
Port int `yaml:"port"`
Services []struct {
RepoURL string `yaml:"repo_url"`
BuildAPI string `yaml:"build_api"`
BuildURL string `yaml:"build_url"`
Name string `yaml:"name"`
URL string `yaml:"url"`
Host string `yaml:"host"`
ShortURL string `yaml:"short_url"`
Icon string `yaml:"icon"`
}
// Configuration is the type representing the configuration of the service
type Configuration struct {
Listen string
Debug bool
CIURL string
UpdateInterval time.Duration
Services []service
}

type service struct {
Name string `yaml:"name"`
Host string `yaml:"host"`
RepoType string `yaml:"repo_type"`
CIType string `yaml:"ci_type"`
Repo string `yaml:"repo"`
URL string `yaml:"url"`
Icon string `yaml:"icon"`
}

type unparsed struct {
Listen string `yaml:"listen"`
Debug bool `yaml:"debug"`
CIURL string `yaml:"ci_url"`
UpdateInterval string `yaml:"update_interval"`
Services []service
}

// C is the main configuration that is exported
var C configuration
var C Configuration

// Load loads the given fp (file path) to the C global configuration variable.
func Load(fp string) error {
var err error
var u unparsed
var d time.Duration
conf, err := ioutil.ReadFile(fp)
if err != nil {
return err
}
err = yaml.Unmarshal(conf, &C)
return err
if err = yaml.Unmarshal(conf, &u); err != nil {
return err
}
if d, err = time.ParseDuration(u.UpdateInterval); err != nil {
return err
}
C = Configuration{
Listen: u.Listen,
Debug: u.Debug,
CIURL: u.CIURL,
UpdateInterval: d,
Services: u.Services,
}
return nil
}

// Parse parses the configuration and returns the appropriate Services
func (c Configuration) Parse() (models.Services, error) {
services := make(models.Services, len(c.Services))
c.CIURL = strings.TrimSuffix(c.CIURL, "/")
for i, s := range c.Services {
if s.CIType != "" && s.CIType != "drone" {
return nil, fmt.Errorf("Unable to use %s as CI, currently only drone is supported.", s.CIType)
}
if s.RepoType != "" && s.RepoType != "github" {
return nil, fmt.Errorf("Unable to use %s as repository, currently only github is supported.", s.RepoType)
}
repoURL := ""
if s.Repo != "" {
repoURL = fmt.Sprintf("https://github.com/%s", s.Repo)
}
buildAPI := ""
buildURL := ""
if s.CIType != "" {
buildAPI = fmt.Sprintf("%s/api/repos/%s/builds", c.CIURL, s.Repo)
buildURL = fmt.Sprintf("%s/%s", c.CIURL, s.Repo)
}
short := strings.TrimPrefix(s.URL, "http://")
short = strings.TrimPrefix(short, "https://")
services[i] = &models.Service{
Name: s.Name,
URL: s.URL,
ShortURL: short,
Host: s.Host,
BuildAPI: buildAPI,
BuildURL: buildURL,
RepoURL: repoURL,
Up: s.URL == "",
Icon: "/static/custom/" + s.Icon,
}
}
return services, nil
}
39 main.go
@@ -1,10 +1,8 @@
package main

import (
"fmt"
"log"
"net/http"
"time"

"github.com/gin-gonic/gin"

@@ -16,44 +14,25 @@ import (

var all models.Services

func periodicHostUpdate() {
tc := time.NewTicker(30 * time.Minute)
for {
for _, host := range all {
go host.Check()
}
<-tc.C
}
}

func index(c *gin.Context) {
c.HTML(http.StatusOK, "index.tmpl", gin.H{
"all": all,
})
}

func main() {
if err := configuration.Load("conf.yml"); err != nil {
var err error
if err = configuration.Load("conf.yml"); err != nil {
log.Fatal(err)
}
cnf := configuration.C
all = make(models.Services, len(cnf.Services))
for i, s := range cnf.Services {
up := s.URL == ""
all[i] = &models.Service{
Name: s.Name,
URL: s.URL,
ShortURL: s.ShortURL,
Host: s.Host,
BuildAPI: s.BuildAPI,
BuildURL: s.BuildURL,
RepoURL: s.RepoURL,
Up: up,
Icon: "/static/custom/" + s.Icon,
}
if all, err = cnf.Parse(); err != nil {
log.Fatal(err)
}
go all.Monitor(cnf.UpdateInterval)
if !cnf.Debug {
gin.SetMode(gin.ReleaseMode)
}
go periodicHostUpdate()
// gin.SetMode(gin.ReleaseMode)
r := gin.Default()
r.LoadHTMLGlob("templates/*")
r.Static("/static", "./assets")
@@ -70,5 +49,5 @@ func main() {
ar.GET("/hosts/new", admin.NewHost)
ar.POST("/hosts/new", admin.PostNewHost)
}
r.Run(fmt.Sprintf("127.0.0.1:%d", cnf.Port))
r.Run(cnf.Listen)
}
@@ -103,18 +103,18 @@ func (s *Service) FetchCommits(client *http.Client) {
url := fmt.Sprintf("https://api.github.com/repos/%s/%s/commits", u[len(u)-2], u[len(u)-1])
req, err := http.NewRequest("GET", url, nil)
if err != nil {
log.Printf("[%s][ERROR] While building request for commits : %v\n", s.Name, err)
log.Printf("[%s][ERROR][COMMITS] While building request : %v\n", s.Name, err)
return
}
resp, err := client.Do(req)
if err != nil {
log.Printf("[%s][ERROR] While requesting commits : %v\n", s.Name, err)
log.Printf("[%s][ERROR][COMMITS] While requesting : %v\n", s.Name, err)
return
}
defer resp.Body.Close()
var all Commits
if err = json.NewDecoder(resp.Body).Decode(&all); err != nil {
log.Printf("[%s][ERROR] Couldn't decode response : %v\n", s.Name, err)
log.Printf("[%s][ERROR][COMMITS] Couldn't decode response : %v\n", s.Name, err)
return
}
s.LastCommits = all
@@ -123,6 +123,17 @@ func (s *Service) FetchCommits(client *http.Client) {
// Services represents a list of services
type Services []*Service

// Monitor allows to monitor Services every interval delay
func (ss Services) Monitor(interval time.Duration) {
tc := time.NewTicker(interval)
for {
for _, s := range ss {
go s.Check()
}
<-tc.C
}
}

// ServiceForm is the struct representing a Service (to add, or modify)
type ServiceForm struct {
Name string `form:"name" binding:"required"`

0 comments on commit 5c9b56f

Please sign in to comment.
You can’t perform that action at this time.