diff --git a/Dockerfile b/Dockerfile index ac347bf..1b0991e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -16,18 +16,24 @@ RUN go mod download COPY ./cmd ./cmd COPY ./pkg ./pkg WORKDIR /go/metahub/cmd/boltdb -# static build +# static build of boltdb backend +ENV CGO_ENABLED=0 GOOS=linux +RUN go build -a -ldflags '-extldflags "-static"' . +WORKDIR /go/metahub/cmd/static +# static build of static backend ENV CGO_ENABLED=0 GOOS=linux RUN go build -a -ldflags '-extldflags "-static"' . EXPOSE 8080 + # Go binary serves the ui web content FROM scratch +ARG MH_BACKEND=boltdb ENV PORT=80 COPY --from=go /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ COPY --from=ui /go/metahub/static /srv/html/static COPY --from=ui /go/metahub/templates/gen/index.html /srv/html/ -COPY --from=go /go/metahub/cmd/boltdb/boltdb /usr/bin/ +COPY --from=go /go/metahub/cmd/${MH_BACKEND}/${MH_BACKEND} /usr/bin/metahub VOLUME /data/ WORKDIR /data/ -ENTRYPOINT ["/usr/bin/boltdb"] +ENTRYPOINT ["/usr/bin/metahub"] diff --git a/cmd/static/main.go b/cmd/static/main.go new file mode 100644 index 0000000..ea2dd99 --- /dev/null +++ b/cmd/static/main.go @@ -0,0 +1,36 @@ +package main + +import ( + "fmt" + "log" + "metahub/pkg/daemon" + registry "metahub/pkg/registry/http/client" + "metahub/pkg/storage/static" + "net/http" + "os" + + "metahub/cmd" +) + +// Log allows to make http interactions visible +func Log(handler http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + log.Printf("%s %s %s", r.RemoteAddr, r.Method, r.URL) + handler.ServeHTTP(w, r) + }) +} + +func main() { + port := os.Getenv("PORT") + if port == "" { + port = "8080" + } + + storageService := static.NewService() + registryService := registry.NewService() + daemonService := daemon.NewService(storageService, registryService) + + router := cmd.RegisterRoutes(daemonService) + + log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), Log(router))) +} diff --git a/pkg/storage/boltdb/dummies.go b/pkg/storage/boltdb/dummies.go deleted file mode 100644 index 98e0eca..0000000 --- a/pkg/storage/boltdb/dummies.go +++ /dev/null @@ -1,41 +0,0 @@ -package boltdb - -import "metahub/pkg/storage" - -// Consts for protoype -const ( - user = "qnib" - accountName = user -) - -// Dummy MachineTypes -var ( - mType1 = storage.MachineType{ - ID : 1, - DisplayName : "type1", - Features : []string{"cpu:broadwell"}, - Login : user+"-type1", - Password : user+"-type1", - } - mType2 = storage.MachineType{ - ID : 2, - DisplayName : "type2", - Features : []string{"cpu:skylake"}, - Login : user+"-type2", - Password : user+"-type2", - } - mType3 = storage.MachineType{ - ID : 3, - DisplayName : "type3", - Features : []string{"cpu:coffelake"}, - Login : user+"-type3", - Password : user+"-type3", - } - mType4 = storage.MachineType{ - ID : 4, - DisplayName : "type4", - Features : []string{"cpu:broadwell","nvcap:5.2"}, - Login : user+"-type4", - Password : user+"-type4", - } -) diff --git a/pkg/storage/boltdb/machinetype_service.go b/pkg/storage/boltdb/machinetype_service.go index cfbf438..86c9389 100644 --- a/pkg/storage/boltdb/machinetype_service.go +++ b/pkg/storage/boltdb/machinetype_service.go @@ -6,12 +6,12 @@ import ( "fmt" "log" "metahub/pkg/storage" + "github.com/boltdb/bolt" - "os" ) type machineTypeService struct { - ctx context.Context + ctx context.Context } func formatLogin(accountName string, login string) { @@ -19,21 +19,6 @@ func formatLogin(accountName string, login string) { } func (s *machineTypeService) GetByID(accountName string, id int64) (mt *storage.MachineType, err error) { - log.Printf("GetByID(%s, %d)\n", accountName, id) - if _, b := os.LookupEnv("STATIC_MACHINES");b { - log.Println("Environment STATIC_MACHINES is set: Hardcoded types are served") - switch id { - case 1: - mt = &mType1 - case 2: - mt = &mType2 - case 3: - mt = &mType3 - case 4: - mt = &mType4 - } - return mt, nil - } var foundID bool db.View(func(tx *bolt.Tx) error { // Assume bucket exists and has keys @@ -53,37 +38,17 @@ func (s *machineTypeService) GetByID(accountName string, id int64) (mt *storage. } return err }) - if !foundID { - err = fmt.Errorf("Could not find MachineType with ID: %i", id) + if !foundID { + err = fmt.Errorf("Could not find MachineType with ID: %d", id) } return mt, err } func (s *machineTypeService) GetByUsername(username string) (mt *storage.MachineType, err error) { - log.Printf("GetByUsername(%s)\n", username) - if _, b := os.LookupEnv("STATIC_MACHINES");b { - log.Println("Environment STATIC_MACHINES is set: Serve static machine type") - switch username { - case user+"-type1": - return &mType1, nil - case user+"-type2": - return &mType2, nil - case user+"-type3": - return &mType3, nil - case user+"-type4": - return &mType4, nil - default: - panic(fmt.Errorf("Could not find username: %s", username)) - } - } return mt, nil } func (s *machineTypeService) Add(accountName string, mt *storage.MachineType) (err error) { - if _, b := os.LookupEnv("STATIC_MACHINES");b { - log.Println("Environment STATIC_MACHINES is set: Skip Add()") - return err - } dbSync.Lock() defer dbSync.Unlock() err = db.Update(func(tx *bolt.Tx) error { @@ -106,15 +71,6 @@ func (s *machineTypeService) Delete(accountName string, id int64) error { func (s *machineTypeService) List(accountName string) ([]storage.MachineType, error) { result := []storage.MachineType{} - if _, b := os.LookupEnv("STATIC_MACHINES");b { - log.Println("Environment STATIC_MACHINES is set: Serve static machine type") - return []storage.MachineType{ - mType1, - mType2, - mType3, - mType4, - },nil - } db.View(func(tx *bolt.Tx) error { // Assume bucket exists and has keys b := tx.Bucket([]byte("TYPES")) @@ -122,7 +78,7 @@ func (s *machineTypeService) List(accountName string) ([]storage.MachineType, er c := b.Cursor() var mt storage.MachineType for k, v := c.First(); k != nil; k, v = c.Next() { - if err := json.Unmarshal(v, &mt); err != nil { + if err := json.Unmarshal(v, &mt); err != nil { panic(err) } result = append(result, mt) @@ -133,10 +89,6 @@ func (s *machineTypeService) List(accountName string) ([]storage.MachineType, er } func (s *machineTypeService) Update(accountName string, mt storage.MachineType) (err error) { - if _, b := os.LookupEnv("STATIC_MACHINES");b { - log.Println("Environment STATIC_MACHINES is set: Serve static machine type") - return - } dbSync.Lock() defer dbSync.Unlock() err = db.Update(func(tx *bolt.Tx) error { diff --git a/pkg/storage/static/accesstoken_model.go b/pkg/storage/static/accesstoken_model.go new file mode 100644 index 0000000..0e9cc44 --- /dev/null +++ b/pkg/storage/static/accesstoken_model.go @@ -0,0 +1,12 @@ +package static + +import ( + "time" +) + +var accessTokenEntityKind = "access_token" + +type accessToken struct { + AccountName string `datastore:"account,noindex"` + Expiry time.Time `datastore:"expiry,omitempty"` +} diff --git a/pkg/storage/static/accesstoken_service.go b/pkg/storage/static/accesstoken_service.go new file mode 100644 index 0000000..a99a9be --- /dev/null +++ b/pkg/storage/static/accesstoken_service.go @@ -0,0 +1,23 @@ +package static + +import ( + "context" + "metahub/pkg/storage" + "time" +) + +type accessTokenService struct { + ctx context.Context +} + +func (s *accessTokenService) Get(token string) (*storage.AccessToken, error) { + //TODO: check at.Expiry? + return &storage.AccessToken{ + AccountName: token, + Expiry: time.Time{}, + }, nil +} + +func (s *accessTokenService) Put(token string, at storage.AccessToken) error { + return nil +} diff --git a/pkg/storage/static/account_model.go b/pkg/storage/static/account_model.go new file mode 100644 index 0000000..cc4083b --- /dev/null +++ b/pkg/storage/static/account_model.go @@ -0,0 +1,7 @@ +package static + +var accountEntityKind = "account" + +type account struct { + DisplayName string `datastore:"name,noindex"` +} diff --git a/pkg/storage/static/account_service.go b/pkg/storage/static/account_service.go new file mode 100644 index 0000000..afd539e --- /dev/null +++ b/pkg/storage/static/account_service.go @@ -0,0 +1,20 @@ +package static + +import ( + "context" + "metahub/pkg/storage" +) + +type accountService struct { + ctx context.Context +} + +func (s *accountService) Upsert(name string, a storage.Account) error { + return nil +} + +func (s *accountService) Get(name string) (*storage.Account, error) { + return &storage.Account{ + DisplayName: name, + }, nil +} diff --git a/pkg/storage/static/dummies.go b/pkg/storage/static/dummies.go new file mode 100644 index 0000000..fb8d402 --- /dev/null +++ b/pkg/storage/static/dummies.go @@ -0,0 +1,48 @@ +package static + +import "metahub/pkg/storage" + +// Consts for protoype +const ( + user = "qnib" + accountName = user +) + +// Dummy MachineTypes +var ( + mType1 = storage.MachineType{ + ID: 1, + DisplayName: "type1", + Features: []string{"cpu:broadwell"}, + Login: user + "-type1", + Password: user + "-type1", + } + mType2 = storage.MachineType{ + ID: 2, + DisplayName: "type2", + Features: []string{"cpu:skylake"}, + Login: user + "-type2", + Password: user + "-type2", + } + mType3 = storage.MachineType{ + ID: 3, + DisplayName: "type3", + Features: []string{"cpu:coffelake"}, + Login: user + "-type3", + Password: user + "-type3", + } + mType4 = storage.MachineType{ + ID: 4, + DisplayName: "type4", + Features: []string{"cpu:broadwell", "nvcap:5.2"}, + Login: user + "-type4", + Password: user + "-type4", + } +) + +func getMachineTypes() []storage.MachineType { + return []storage.MachineType{ + mType1, mType2, mType3, mType4, + } + +} diff --git a/pkg/storage/static/machinetype_model.go b/pkg/storage/static/machinetype_model.go new file mode 100644 index 0000000..95da954 --- /dev/null +++ b/pkg/storage/static/machinetype_model.go @@ -0,0 +1,10 @@ +package static + +var machineTypeEntityKind = "MachineType" + +type machineTypeModel struct { + DisplayName string `datastore:"name,noindex"` + Features []string `datastore:"features,noindex"` + Login string `datastore:"login"` + Password string `datastore:"password,noindex"` +} diff --git a/pkg/storage/static/machinetype_service.go b/pkg/storage/static/machinetype_service.go new file mode 100644 index 0000000..f83a79f --- /dev/null +++ b/pkg/storage/static/machinetype_service.go @@ -0,0 +1,67 @@ +package static + +import ( + "context" + "fmt" + "log" + "metahub/pkg/storage" +) + +type machineTypeService struct { + ctx context.Context +} + +func formatLogin(accountName string, login string) { + +} + +func (s *machineTypeService) GetByID(accountName string, id int64) (mt *storage.MachineType, err error) { + log.Printf("GetByID(%s, %d)\n", accountName, id) + switch id { + case 1: + mt = &mType1 + case 2: + mt = &mType2 + case 3: + mt = &mType3 + case 4: + mt = &mType4 + } + return mt, nil + +} + +func (s *machineTypeService) GetByUsername(username string) (mt *storage.MachineType, err error) { + log.Printf("GetByUsername(%s)\n", username) + switch username { + case user + "-type1": + return &mType1, nil + case user + "-type2": + return &mType2, nil + case user + "-type3": + return &mType3, nil + case user + "-type4": + return &mType4, nil + default: + panic(fmt.Errorf("Could not find username: %s", username)) + } +} + +func (s *machineTypeService) Add(accountName string, mt *storage.MachineType) (err error) { + log.Println("Environment STATIC_MACHINES is set: Skip Add()") + return err +} + +func (s *machineTypeService) Delete(accountName string, id int64) error { + log.Println("Environment STATIC_MACHINES is set: Skip Delete()") + return nil +} + +func (s *machineTypeService) List(accountName string) ([]storage.MachineType, error) { + return mTypes, nil +} + +func (s *machineTypeService) Update(accountName string, mt storage.MachineType) (err error) { + log.Println("Environment STATIC_MACHINES is set: Serve static machine type") + return +} diff --git a/pkg/storage/static/service.go b/pkg/storage/static/service.go new file mode 100644 index 0000000..92826d1 --- /dev/null +++ b/pkg/storage/static/service.go @@ -0,0 +1,50 @@ +package static + +import ( + "context" + "fmt" + "metahub/pkg/storage" + "sync" + + "github.com/boltdb/bolt" +) + +var db *bolt.DB +var dbSync sync.Mutex +var mTypes []storage.MachineType + +func init() { + mTypes = getMachineTypes() + setupData() +} + +// NewService returns a new storage.Service for boltdb +func NewService() storage.Service { + return &service{} +} + +type service struct { +} + +func (s *service) MachineTypeService(ctx context.Context) (storage.MachineTypeService, error) { + return &machineTypeService{ + ctx: ctx, + }, nil +} + +func (s *service) AccessTokenService(ctx context.Context) (storage.AccessTokenService, error) { + return &accessTokenService{ + ctx: ctx, + }, nil +} + +func (s *service) AccountService(ctx context.Context) (storage.AccountService, error) { + return &accountService{ + ctx: ctx, + }, nil +} + +func setupData() error { + fmt.Println("Data Setup Done") + return nil +}