mirror of
https://github.com/genuinetools/reg.git
synced 2024-05-09 16:28:32 -04:00
move server under main command closes #106
Signed-off-by: Jess Frazelle <acidburn@microsoft.com>
This commit is contained in:
parent
f99f1ce934
commit
298ecf1510
|
@ -6,6 +6,5 @@ linux/arm
|
|||
linux/arm64
|
||||
linux/amd64
|
||||
linux/386
|
||||
solaris/amd64
|
||||
windows/amd64
|
||||
windows/386
|
||||
|
|
|
@ -43,9 +43,6 @@ jobs:
|
|||
- cross/reg-linux-386
|
||||
- cross/reg-linux-386.md5
|
||||
- cross/reg-linux-386.sha256
|
||||
- cross/reg-solaris-amd64
|
||||
- cross/reg-solaris-amd64.md5
|
||||
- cross/reg-solaris-amd64.sha256
|
||||
- cross/reg-windows-amd64
|
||||
- cross/reg-windows-amd64.md5
|
||||
- cross/reg-windows-amd64.sha256
|
||||
|
|
|
@ -28,5 +28,10 @@ FROM scratch
|
|||
COPY --from=builder /usr/bin/reg /usr/bin/reg
|
||||
COPY --from=builder /etc/ssl/certs/ /etc/ssl/certs
|
||||
|
||||
COPY server/static /src/static
|
||||
COPY server/templates /src/templates
|
||||
|
||||
WORKDIR /src
|
||||
|
||||
ENTRYPOINT [ "reg" ]
|
||||
CMD [ "--help" ]
|
||||
|
|
16
Makefile
16
Makefile
|
@ -43,7 +43,7 @@ static: ## Builds a static executable
|
|||
-tags "$(BUILDTAGS) static_build" \
|
||||
${GO_LDFLAGS_STATIC} -o $(NAME) .
|
||||
|
||||
all: clean build fmt lint test staticcheck vet install build-server ## Runs a clean, build, fmt, lint, test, staticcheck, vet and install
|
||||
all: clean build fmt lint test staticcheck vet install ## Runs a clean, build, fmt, lint, test, staticcheck, vet and install
|
||||
|
||||
.PHONY: fmt
|
||||
fmt: ## Verifies all files have been `gofmt`ed
|
||||
|
@ -207,20 +207,6 @@ snakeoil: ## Update snakeoil certs for testing
|
|||
mv $(CURDIR)/key.pem $(CURDIR)/testutils/snakeoil/key.pem
|
||||
mv $(CURDIR)/cert.pem $(CURDIR)/testutils/snakeoil/cert.pem
|
||||
|
||||
.PHONY: build-server
|
||||
build-server: $(NAME)-server ## Builds a dynamic executable for reg-server
|
||||
|
||||
$(NAME)-server: $(wildcard */*.go) VERSION.txt
|
||||
@echo "+ $@"
|
||||
$(GO) build -tags "$(BUILDTAGS)" ${GO_LDFLAGS} -o $(NAME)-server ./server/...
|
||||
|
||||
.PHONY: static-server
|
||||
static-server: ## Builds a static reg-server executable
|
||||
@echo "+ $@"
|
||||
CGO_ENABLED=0 $(GO) build \
|
||||
-tags "$(BUILDTAGS) static_build" \
|
||||
${GO_LDFLAGS_STATIC} -o $(NAME)-server ./server
|
||||
|
||||
.PHONY: help
|
||||
help:
|
||||
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
|
||||
|
|
|
@ -3,11 +3,13 @@ package main
|
|||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/genuinetools/reg/clair"
|
||||
|
@ -19,6 +21,8 @@ import (
|
|||
type registryController struct {
|
||||
reg *registry.Registry
|
||||
cl *clair.Clair
|
||||
l sync.Mutex
|
||||
tmpl *template.Template
|
||||
}
|
||||
|
||||
type v1Compatibility struct {
|
||||
|
@ -44,7 +48,9 @@ type AnalysisResult struct {
|
|||
}
|
||||
|
||||
func (rc *registryController) repositories(staticDir string) error {
|
||||
updating = true
|
||||
rc.l.Lock()
|
||||
defer rc.l.Unlock()
|
||||
|
||||
logrus.Info("fetching catalog")
|
||||
|
||||
result := AnalysisResult{
|
||||
|
@ -52,7 +58,7 @@ func (rc *registryController) repositories(staticDir string) error {
|
|||
LastUpdated: time.Now().Local().Format(time.RFC1123),
|
||||
}
|
||||
|
||||
repoList, err := r.Catalog("")
|
||||
repoList, err := rc.reg.Catalog("")
|
||||
if err != nil {
|
||||
return fmt.Errorf("getting catalog failed: %v", err)
|
||||
}
|
||||
|
@ -67,7 +73,7 @@ func (rc *registryController) repositories(staticDir string) error {
|
|||
result.Repositories = append(result.Repositories, r)
|
||||
}
|
||||
|
||||
// parse & execute the template
|
||||
// Parse & execute the template.
|
||||
logrus.Info("executing the template repositories")
|
||||
|
||||
path := filepath.Join(staticDir, "index.html")
|
||||
|
@ -81,12 +87,11 @@ func (rc *registryController) repositories(staticDir string) error {
|
|||
}
|
||||
defer f.Close()
|
||||
|
||||
if err := tmpl.ExecuteTemplate(f, "repositories", result); err != nil {
|
||||
if err := rc.tmpl.ExecuteTemplate(f, "repositories", result); err != nil {
|
||||
f.Close()
|
||||
return fmt.Errorf("execute template repositories failed: %v", err)
|
||||
}
|
||||
|
||||
updating = false
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -179,7 +184,7 @@ func (rc *registryController) tagsHandler(w http.ResponseWriter, r *http.Request
|
|||
result.Repositories = append(result.Repositories, rp)
|
||||
}
|
||||
|
||||
if err := tmpl.ExecuteTemplate(w, "tags", result); err != nil {
|
||||
if err := rc.tmpl.ExecuteTemplate(w, "tags", result); err != nil {
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"func": "tags",
|
||||
"URL": r.URL,
|
||||
|
@ -245,7 +250,7 @@ func (rc *registryController) vulnerabilitiesHandler(w http.ResponseWriter, r *h
|
|||
return
|
||||
}
|
||||
|
||||
if err := tmpl.ExecuteTemplate(w, "vulns", result); err != nil {
|
||||
if err := rc.tmpl.ExecuteTemplate(w, "vulns", result); err != nil {
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"func": "vulnerabilities",
|
||||
"URL": r.URL,
|
18
main.go
18
main.go
|
@ -4,7 +4,10 @@ import (
|
|||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/genuinetools/pkg/cli"
|
||||
|
@ -43,6 +46,7 @@ func main() {
|
|||
&listCommand{},
|
||||
&manifestCommand{},
|
||||
&removeCommand{},
|
||||
&serverCommand{},
|
||||
&tagsCommand{},
|
||||
&vulnsCommand{},
|
||||
}
|
||||
|
@ -69,6 +73,20 @@ func main() {
|
|||
|
||||
// Set the before function.
|
||||
p.Before = func(ctx context.Context) error {
|
||||
// On ^C, or SIGTERM handle exit.
|
||||
signals := make(chan os.Signal, 0)
|
||||
signal.Notify(signals, os.Interrupt)
|
||||
signal.Notify(signals, syscall.SIGTERM)
|
||||
var cancel context.CancelFunc
|
||||
ctx, cancel = context.WithCancel(ctx)
|
||||
go func() {
|
||||
for sig := range signals {
|
||||
cancel()
|
||||
logrus.Infof("Received %s, exiting.", sig.String())
|
||||
os.Exit(0)
|
||||
}
|
||||
}()
|
||||
|
||||
// Set the log level.
|
||||
if debug {
|
||||
logrus.SetLevel(logrus.DebugLevel)
|
||||
|
|
176
server.go
Normal file
176
server.go
Normal file
|
@ -0,0 +1,176 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/genuinetools/reg/clair"
|
||||
"github.com/gorilla/mux"
|
||||
wordwrap "github.com/mitchellh/go-wordwrap"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const serverHelp = `Run a static UI server for a registry.`
|
||||
|
||||
func (cmd *serverCommand) Name() string { return "server" }
|
||||
func (cmd *serverCommand) Args() string { return "[OPTIONS]" }
|
||||
func (cmd *serverCommand) ShortHelp() string { return serverHelp }
|
||||
func (cmd *serverCommand) LongHelp() string { return serverHelp }
|
||||
func (cmd *serverCommand) Hidden() bool { return false }
|
||||
|
||||
func (cmd *serverCommand) Register(fs *flag.FlagSet) {
|
||||
fs.DurationVar(&cmd.interval, "interval", time.Hour, "interval to generate new index.html's at")
|
||||
|
||||
fs.StringVar(&cmd.registryServer, "registry", "", "URL to the private registry (ex. r.j3ss.co)")
|
||||
fs.StringVar(&cmd.registryServer, "r", "", "URL to the private registry (ex. r.j3ss.co)")
|
||||
|
||||
fs.StringVar(&cmd.clairServer, "clair", "", "url to clair instance")
|
||||
|
||||
fs.StringVar(&cmd.cert, "cert", "", "path to ssl cert")
|
||||
fs.StringVar(&cmd.key, "key", "", "path to ssl key")
|
||||
fs.StringVar(&cmd.port, "port", "8080", "port for server to run on")
|
||||
|
||||
fs.BoolVar(&cmd.once, "once", false, "generate an output once and then exit")
|
||||
}
|
||||
|
||||
type serverCommand struct {
|
||||
interval time.Duration
|
||||
registryServer string
|
||||
clairServer string
|
||||
|
||||
once bool
|
||||
|
||||
cert string
|
||||
key string
|
||||
port string
|
||||
}
|
||||
|
||||
func (cmd *serverCommand) Run(ctx context.Context, args []string) error {
|
||||
// Create the registry client.
|
||||
r, err := createRegistryClient(cmd.registryServer)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Create the registry controller for the handlers.
|
||||
rc := registryController{
|
||||
reg: r,
|
||||
}
|
||||
|
||||
// Create a clair client if the user passed in a server address.
|
||||
if len(cmd.clairServer) < 1 {
|
||||
rc.cl, err = clair.New(cmd.clairServer, clair.Opt{
|
||||
Insecure: insecure,
|
||||
Debug: debug,
|
||||
Timeout: timeout,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("creation of clair client at %s failed: %v", cmd.clairServer, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Get the path to the static directory.
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
staticDir := filepath.Join(wd, "static")
|
||||
templateDir := filepath.Join(staticDir, "../templates")
|
||||
|
||||
// Make sure all the paths exist.
|
||||
tmplPaths := []string{
|
||||
staticDir,
|
||||
filepath.Join(templateDir, "vulns.html"),
|
||||
filepath.Join(templateDir, "repositories.html"),
|
||||
filepath.Join(templateDir, "tags.html"),
|
||||
}
|
||||
for _, path := range tmplPaths {
|
||||
if _, err := os.Stat(path); os.IsNotExist(err) {
|
||||
return fmt.Errorf("template %s not found", path)
|
||||
}
|
||||
}
|
||||
|
||||
funcMap := template.FuncMap{
|
||||
"trim": func(s string) string {
|
||||
return wordwrap.WrapString(s, 80)
|
||||
},
|
||||
"color": func(s string) string {
|
||||
switch s = strings.ToLower(s); s {
|
||||
case "high":
|
||||
return "danger"
|
||||
case "critical":
|
||||
return "danger"
|
||||
case "defcon1":
|
||||
return "danger"
|
||||
case "medium":
|
||||
return "warning"
|
||||
case "low":
|
||||
return "info"
|
||||
case "negligible":
|
||||
return "info"
|
||||
case "unknown":
|
||||
return "default"
|
||||
default:
|
||||
return "default"
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
rc.tmpl = template.Must(template.New("").Funcs(funcMap).ParseGlob(templateDir + "/*.html"))
|
||||
|
||||
// Create the initial index.
|
||||
logrus.Info("creating initial static index")
|
||||
if err := rc.repositories(staticDir); err != nil {
|
||||
return fmt.Errorf("creating index failed: %v", err)
|
||||
}
|
||||
|
||||
if cmd.once {
|
||||
logrus.Info("output generated, exiting...")
|
||||
return nil
|
||||
}
|
||||
|
||||
ticker := time.NewTicker(cmd.interval)
|
||||
go func() {
|
||||
// Create more indexes every X minutes based off interval.
|
||||
for range ticker.C {
|
||||
logrus.Info("creating timer based static index")
|
||||
if err := rc.repositories(staticDir); err != nil {
|
||||
logrus.Warnf("creating static index failed: %v", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// Create mux server.
|
||||
mux := mux.NewRouter()
|
||||
mux.UseEncodedPath()
|
||||
|
||||
// Static files handler.
|
||||
staticHandler := http.FileServer(http.Dir(staticDir))
|
||||
mux.HandleFunc("/repo/{repo}/tags", rc.tagsHandler)
|
||||
mux.HandleFunc("/repo/{repo}/tags/", rc.tagsHandler)
|
||||
mux.HandleFunc("/repo/{repo}/tag/{tag}", rc.vulnerabilitiesHandler)
|
||||
mux.HandleFunc("/repo/{repo}/tag/{tag}/", rc.vulnerabilitiesHandler)
|
||||
mux.HandleFunc("/repo/{repo}/tag/{tag}/vulns", rc.vulnerabilitiesHandler)
|
||||
mux.HandleFunc("/repo/{repo}/tag/{tag}/vulns/", rc.vulnerabilitiesHandler)
|
||||
mux.HandleFunc("/repo/{repo}/tag/{tag}/vulns.json", rc.vulnerabilitiesHandler)
|
||||
mux.PathPrefix("/static/").Handler(http.StripPrefix("/static/", staticHandler))
|
||||
mux.Handle("/", staticHandler)
|
||||
|
||||
// Set up the server.
|
||||
server := &http.Server{
|
||||
Addr: ":" + cmd.port,
|
||||
Handler: mux,
|
||||
}
|
||||
logrus.Infof("Starting server on port %q", cmd.port)
|
||||
if len(cmd.cert) > 0 && len(cmd.key) > 0 {
|
||||
return server.ListenAndServeTLS(cmd.cert, cmd.key)
|
||||
}
|
||||
return server.ListenAndServe()
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
FROM golang:alpine as builder
|
||||
MAINTAINER Jessica Frazelle <jess@linux.com>
|
||||
|
||||
ENV PATH /go/bin:/usr/local/go/bin:$PATH
|
||||
ENV GOPATH /go
|
||||
|
||||
RUN apk add --no-cache \
|
||||
ca-certificates
|
||||
|
||||
RUN set -x \
|
||||
&& apk add --no-cache --virtual .build-deps \
|
||||
git \
|
||||
gcc \
|
||||
libc-dev \
|
||||
libgcc \
|
||||
&& go get -v github.com/genuinetools/reg \
|
||||
&& cd /go/src/github.com/genuinetools/reg \
|
||||
&& CGO_ENABLED=0 go build -a -tags netgo -ldflags '-extldflags "-static"' -o /usr/bin/reg-server ./server \
|
||||
&& apk del .build-deps \
|
||||
&& rm -rf /go \
|
||||
&& echo "Build complete."
|
||||
|
||||
FROM scratch
|
||||
|
||||
COPY --from=builder /usr/bin/reg-server /usr/bin/reg-server
|
||||
COPY --from=builder /etc/ssl/certs/ /etc/ssl/certs
|
||||
|
||||
COPY static /src/static
|
||||
COPY templates /src/templates
|
||||
|
||||
WORKDIR /src
|
||||
|
||||
ENTRYPOINT [ "reg-server" ]
|
||||
CMD [ "--help" ]
|
250
server/server.go
250
server/server.go
|
@ -1,250 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"flag"
|
||||
"html/template"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/genuinetools/pkg/cli"
|
||||
"github.com/genuinetools/reg/clair"
|
||||
"github.com/genuinetools/reg/registry"
|
||||
"github.com/genuinetools/reg/repoutils"
|
||||
"github.com/genuinetools/reg/version"
|
||||
"github.com/gorilla/mux"
|
||||
wordwrap "github.com/mitchellh/go-wordwrap"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
var (
|
||||
insecure bool
|
||||
forceNonSSL bool
|
||||
skipPing bool
|
||||
|
||||
interval time.Duration
|
||||
timeout time.Duration
|
||||
|
||||
username string
|
||||
password string
|
||||
registryServer string
|
||||
clairServer string
|
||||
|
||||
once bool
|
||||
|
||||
cert string
|
||||
key string
|
||||
port string
|
||||
|
||||
debug bool
|
||||
|
||||
updating bool
|
||||
r *registry.Registry
|
||||
cl *clair.Clair
|
||||
tmpl *template.Template
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Create a new cli program.
|
||||
p := cli.NewProgram()
|
||||
p.Name = "reg-server"
|
||||
p.Description = "Docker registry v2 static UI server"
|
||||
|
||||
// Set the GitCommit and Version.
|
||||
p.GitCommit = version.GITCOMMIT
|
||||
p.Version = version.VERSION
|
||||
|
||||
// Setup the global flags.
|
||||
p.FlagSet = flag.NewFlagSet("global", flag.ExitOnError)
|
||||
p.FlagSet.BoolVar(&insecure, "insecure", false, "do not verify tls certificates")
|
||||
p.FlagSet.BoolVar(&insecure, "k", false, "do not verify tls certificates")
|
||||
|
||||
p.FlagSet.BoolVar(&forceNonSSL, "force-non-ssl", false, "force allow use of non-ssl")
|
||||
p.FlagSet.BoolVar(&forceNonSSL, "f", false, "force allow use of non-ssl")
|
||||
|
||||
p.FlagSet.BoolVar(&skipPing, "skip-ping", false, "skip pinging the registry while establishing connection")
|
||||
|
||||
p.FlagSet.DurationVar(&interval, "interval", time.Hour, "interval to generate new index.html's at")
|
||||
p.FlagSet.DurationVar(&timeout, "timeout", time.Minute, "timeout for HTTP requests")
|
||||
|
||||
p.FlagSet.StringVar(&username, "username", "", "username for the registry")
|
||||
p.FlagSet.StringVar(&username, "u", "", "username for the registry")
|
||||
|
||||
p.FlagSet.StringVar(&password, "password", "", "password for the registry")
|
||||
p.FlagSet.StringVar(&password, "p", "", "password for the registry")
|
||||
|
||||
p.FlagSet.StringVar(®istryServer, "registry", "", "URL to the private registry (ex. r.j3ss.co)")
|
||||
p.FlagSet.StringVar(®istryServer, "r", "", "URL to the private registry (ex. r.j3ss.co)")
|
||||
|
||||
p.FlagSet.StringVar(&clairServer, "clair", "", "url to clair instance")
|
||||
|
||||
p.FlagSet.StringVar(&cert, "cert", "", "path to ssl cert")
|
||||
p.FlagSet.StringVar(&key, "key", "", "path to ssl key")
|
||||
p.FlagSet.StringVar(&port, "port", "8080", "port for server to run on")
|
||||
|
||||
p.FlagSet.BoolVar(&once, "once", false, "generate an output once and then exit")
|
||||
|
||||
p.FlagSet.BoolVar(&debug, "d", false, "enable debug logging")
|
||||
|
||||
// Set the before function.
|
||||
p.Before = func(ctx context.Context) error {
|
||||
// Set the log level.
|
||||
if debug {
|
||||
logrus.SetLevel(logrus.DebugLevel)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Set the main program action.
|
||||
p.Action = func(ctx context.Context) error {
|
||||
auth, err := repoutils.GetAuthConfig(username, password, registryServer)
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
|
||||
// Create the registry client.
|
||||
r, err = registry.New(auth, registry.Opt{
|
||||
Insecure: insecure,
|
||||
Debug: debug,
|
||||
SkipPing: skipPing,
|
||||
Timeout: timeout,
|
||||
})
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
|
||||
// create a clair instance if needed
|
||||
if len(clairServer) < 1 {
|
||||
cl, err = clair.New(clairServer, clair.Opt{
|
||||
Insecure: insecure,
|
||||
Debug: debug,
|
||||
Timeout: timeout,
|
||||
})
|
||||
if err != nil {
|
||||
logrus.Warnf("creation of clair failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// get the path to the static directory
|
||||
wd, err := os.Getwd()
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
staticDir := filepath.Join(wd, "static")
|
||||
|
||||
// create the template
|
||||
templateDir := filepath.Join(staticDir, "../templates")
|
||||
|
||||
// make sure all the templates exist
|
||||
vulns := filepath.Join(templateDir, "vulns.html")
|
||||
if _, err := os.Stat(vulns); os.IsNotExist(err) {
|
||||
logrus.Fatalf("Template %s not found", vulns)
|
||||
}
|
||||
layout := filepath.Join(templateDir, "repositories.html")
|
||||
if _, err := os.Stat(layout); os.IsNotExist(err) {
|
||||
logrus.Fatalf("Template %s not found", layout)
|
||||
}
|
||||
tags := filepath.Join(templateDir, "tags.html")
|
||||
if _, err := os.Stat(tags); os.IsNotExist(err) {
|
||||
logrus.Fatalf("Template %s not found", tags)
|
||||
}
|
||||
|
||||
funcMap := template.FuncMap{
|
||||
"trim": func(s string) string {
|
||||
return wordwrap.WrapString(s, 80)
|
||||
},
|
||||
"color": func(s string) string {
|
||||
switch s = strings.ToLower(s); s {
|
||||
case "high":
|
||||
return "danger"
|
||||
case "critical":
|
||||
return "danger"
|
||||
case "defcon1":
|
||||
return "danger"
|
||||
case "medium":
|
||||
return "warning"
|
||||
case "low":
|
||||
return "info"
|
||||
case "negligible":
|
||||
return "info"
|
||||
case "unknown":
|
||||
return "default"
|
||||
default:
|
||||
return "default"
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
tmpl = template.Must(template.New("").Funcs(funcMap).ParseGlob(templateDir + "/*.html"))
|
||||
|
||||
rc := registryController{
|
||||
reg: r,
|
||||
cl: cl,
|
||||
}
|
||||
|
||||
// create the initial index
|
||||
logrus.Info("creating initial static index")
|
||||
if err := rc.repositories(staticDir); err != nil {
|
||||
logrus.Fatalf("Error creating index: %v", err)
|
||||
}
|
||||
|
||||
if once {
|
||||
logrus.Info("Output generated")
|
||||
return nil
|
||||
}
|
||||
|
||||
ticker := time.NewTicker(interval)
|
||||
|
||||
go func() {
|
||||
// create more indexes every X minutes based off interval
|
||||
for range ticker.C {
|
||||
if !updating {
|
||||
logrus.Info("creating timer based static index")
|
||||
if err := rc.repositories(staticDir); err != nil {
|
||||
logrus.Warnf("creating static index failed: %v", err)
|
||||
updating = false
|
||||
}
|
||||
} else {
|
||||
logrus.Warnf("skipping timer based static index update for %s", interval.String())
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// create mux server
|
||||
mux := mux.NewRouter()
|
||||
mux.UseEncodedPath()
|
||||
|
||||
// static files handler
|
||||
staticHandler := http.FileServer(http.Dir(staticDir))
|
||||
mux.HandleFunc("/repo/{repo}/tags", rc.tagsHandler)
|
||||
mux.HandleFunc("/repo/{repo}/tags/", rc.tagsHandler)
|
||||
mux.HandleFunc("/repo/{repo}/tag/{tag}", rc.vulnerabilitiesHandler)
|
||||
mux.HandleFunc("/repo/{repo}/tag/{tag}/", rc.vulnerabilitiesHandler)
|
||||
mux.HandleFunc("/repo/{repo}/tag/{tag}/vulns", rc.vulnerabilitiesHandler)
|
||||
mux.HandleFunc("/repo/{repo}/tag/{tag}/vulns/", rc.vulnerabilitiesHandler)
|
||||
mux.HandleFunc("/repo/{repo}/tag/{tag}/vulns.json", rc.vulnerabilitiesHandler)
|
||||
mux.PathPrefix("/static/").Handler(http.StripPrefix("/static/", staticHandler))
|
||||
mux.Handle("/", staticHandler)
|
||||
|
||||
// set up the server
|
||||
server := &http.Server{
|
||||
Addr: ":" + port,
|
||||
Handler: mux,
|
||||
}
|
||||
logrus.Infof("Starting server on port %q", port)
|
||||
if len(cert) > 0 && len(key) > 0 {
|
||||
logrus.Fatal(server.ListenAndServeTLS(cert, key))
|
||||
} else {
|
||||
logrus.Fatal(server.ListenAndServe())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Run our program.
|
||||
p.Run()
|
||||
}
|
Loading…
Reference in a new issue