refactor(server): Change setup to create new storage backends

This commit is contained in:
Vincent Ambo 2019-10-27 18:33:57 +01:00 committed by Vincent Ambo
parent d134461721
commit a7f14a64af
5 changed files with 44 additions and 15 deletions

View File

@ -27,7 +27,6 @@ import (
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"net/http"
"os" "os"
"os/exec" "os/exec"
"sort" "sort"
@ -45,9 +44,6 @@ import (
// use up is set at a lower point. // use up is set at a lower point.
const LayerBudget int = 94 const LayerBudget int = 94
// HTTP client to use for direct calls to APIs that are not part of the SDK
var client = &http.Client{}
// State holds the runtime state that is carried around in Nixery and // State holds the runtime state that is carried around in Nixery and
// passed to builder functions. // passed to builder functions.
type State struct { type State struct {

View File

@ -125,7 +125,7 @@ func manifestFromCache(ctx context.Context, s *State, key string) (json.RawMessa
log.WithError(err).WithFields(log.Fields{ log.WithError(err).WithFields(log.Fields{
"manifest": key, "manifest": key,
"backend": s.Storage.Name(), "backend": s.Storage.Name(),
}) }).Error("failed to fetch manifest from cache")
return nil, false return nil, false
} }

View File

@ -37,6 +37,13 @@ func getConfig(key, desc, def string) string {
return value return value
} }
// Backend represents the possible storage backend types
type Backend int
const (
GCS = iota
)
// Config holds the Nixery configuration options. // Config holds the Nixery configuration options.
type Config struct { type Config struct {
Port string // Port on which to launch HTTP server Port string // Port on which to launch HTTP server
@ -44,6 +51,7 @@ type Config struct {
Timeout string // Timeout for a single Nix builder (seconds) Timeout string // Timeout for a single Nix builder (seconds)
WebDir string // Directory with static web assets WebDir string // Directory with static web assets
PopUrl string // URL to the Nix package popularity count PopUrl string // URL to the Nix package popularity count
Backend Backend // Storage backend to use for Nixery
} }
func FromEnv() (Config, error) { func FromEnv() (Config, error) {
@ -52,11 +60,22 @@ func FromEnv() (Config, error) {
return Config{}, err return Config{}, err
} }
var b Backend
switch os.Getenv("NIXERY_STORAGE_BACKEND") {
case "gcs":
b = GCS
default:
log.WithField("values", []string{
"gcs",
}).Fatal("NIXERY_STORAGE_BUCKET must be set to a supported value")
}
return Config{ return Config{
Port: getConfig("PORT", "HTTP port", ""), Port: getConfig("PORT", "HTTP port", ""),
Pkgs: pkgs, Pkgs: pkgs,
Timeout: getConfig("NIX_TIMEOUT", "Nix builder timeout", "60"), Timeout: getConfig("NIX_TIMEOUT", "Nix builder timeout", "60"),
WebDir: getConfig("WEB_DIR", "Static web file dir", ""), WebDir: getConfig("WEB_DIR", "Static web file dir", ""),
PopUrl: os.Getenv("NIX_POPULARITY_URL"), PopUrl: os.Getenv("NIX_POPULARITY_URL"),
Backend: b,
}, nil }, nil
} }

View File

@ -36,6 +36,7 @@ import (
"github.com/google/nixery/server/builder" "github.com/google/nixery/server/builder"
"github.com/google/nixery/server/config" "github.com/google/nixery/server/config"
"github.com/google/nixery/server/layers" "github.com/google/nixery/server/layers"
"github.com/google/nixery/server/storage"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
) )
@ -196,6 +197,18 @@ func main() {
log.WithError(err).Fatal("failed to load configuration") log.WithError(err).Fatal("failed to load configuration")
} }
var s storage.Backend
switch cfg.Backend {
case config.GCS:
s, err = storage.NewGCSBackend()
}
if err != nil {
log.WithError(err).Fatal("failed to initialise storage backend")
}
log.WithField("backend", s.Name()).Info("initialised storage backend")
ctx := context.Background() ctx := context.Background()
cache, err := builder.NewCache() cache, err := builder.NewCache()
if err != nil { if err != nil {
@ -215,6 +228,7 @@ func main() {
Cache: &cache, Cache: &cache,
Cfg: cfg, Cfg: cfg,
Pop: pop, Pop: pop,
Storage: s,
} }
log.WithFields(log.Fields{ log.WithFields(log.Fields{

View File

@ -30,10 +30,10 @@ type GCSBackend struct {
// Constructs a new GCS bucket backend based on the configured // Constructs a new GCS bucket backend based on the configured
// environment variables. // environment variables.
func New() (GCSBackend, error) { func NewGCSBackend() (*GCSBackend, error) {
bucket := os.Getenv("GCS_BUCKET") bucket := os.Getenv("GCS_BUCKET")
if bucket == "" { if bucket == "" {
return GCSBackend{}, fmt.Errorf("GCS_BUCKET must be configured for GCS usage") return nil, fmt.Errorf("GCS_BUCKET must be configured for GCS usage")
} }
ctx := context.Background() ctx := context.Background()
@ -46,16 +46,16 @@ func New() (GCSBackend, error) {
if _, err := handle.Attrs(ctx); err != nil { if _, err := handle.Attrs(ctx); err != nil {
log.WithError(err).WithField("bucket", bucket).Error("could not access configured bucket") log.WithError(err).WithField("bucket", bucket).Error("could not access configured bucket")
return GCSBackend{}, err return nil, err
} }
signing, err := signingOptsFromEnv() signing, err := signingOptsFromEnv()
if err != nil { if err != nil {
log.WithError(err).Error("failed to configure GCS bucket signing") log.WithError(err).Error("failed to configure GCS bucket signing")
return GCSBackend{}, err return nil, err
} }
return GCSBackend{ return &GCSBackend{
bucket: bucket, bucket: bucket,
handle: handle, handle: handle,
signing: signing, signing: signing,
@ -66,7 +66,7 @@ func (b *GCSBackend) Name() string {
return "Google Cloud Storage (" + b.bucket + ")" return "Google Cloud Storage (" + b.bucket + ")"
} }
func (b *GCSBackend) Persist(path string, f func(io.Writer) (string, int, error)) (string, int, error) { func (b *GCSBackend) Persist(path string, f func(io.Writer) (string, int64, error)) (string, int64, error) {
ctx := context.Background() ctx := context.Background()
obj := b.handle.Object(path) obj := b.handle.Object(path)
w := obj.NewWriter(ctx) w := obj.NewWriter(ctx)
@ -139,7 +139,7 @@ func (b *GCSBackend) Move(old, new string) error {
return nil return nil
} }
func (b *GCSBackend) Serve(digest string, w http.ResponseWriter) error { func (b *GCSBackend) ServeLayer(digest string, w http.ResponseWriter) error {
url, err := b.constructLayerUrl(digest) url, err := b.constructLayerUrl(digest)
if err != nil { if err != nil {
log.WithError(err).WithFields(log.Fields{ log.WithError(err).WithFields(log.Fields{