Use intrinsics in place of predefineds
This change leverages intrinsics in place of the predefined types. It remains to be seen if we can reach 100% on this, however I am hopeful. It's also nice that the system will be built "out of itself" with this approach; in other words, each of the types is simply a Mufile that can use conditional targeting as appropriate for the given cloud providers. If we find that this isn't enough, we can always bring back the concept.
This commit is contained in:
parent
4f92a12d30
commit
a28f02ce68
5
lib/mu/autoscaler/Mu.yaml
Normal file
5
lib/mu/autoscaler/Mu.yaml
Normal file
|
@ -0,0 +1,5 @@
|
|||
name: mu/autoscaler
|
||||
description: A service that can automatically scale other services based on policy.
|
||||
intrinsic: true
|
||||
properties:
|
||||
|
5
lib/mu/container/Mu.yaml
Normal file
5
lib/mu/container/Mu.yaml
Normal file
|
@ -0,0 +1,5 @@
|
|||
name: mu/container
|
||||
description: A Docker/LXC/Windows container.
|
||||
intrinsic: true
|
||||
properties:
|
||||
|
5
lib/mu/event/Mu.yaml
Normal file
5
lib/mu/event/Mu.yaml
Normal file
|
@ -0,0 +1,5 @@
|
|||
name: mu/event
|
||||
description: An event that may be used to trigger execution of another service.
|
||||
intrinsic: true
|
||||
properties:
|
||||
|
5
lib/mu/func/Mu.yaml
Normal file
5
lib/mu/func/Mu.yaml
Normal file
|
@ -0,0 +1,5 @@
|
|||
name: mu/func
|
||||
description: A single standalone function for serverless scenarios.
|
||||
intrinsic: true
|
||||
properties:
|
||||
|
5
lib/mu/gateway/Mu.yaml
Normal file
5
lib/mu/gateway/Mu.yaml
Normal file
|
@ -0,0 +1,5 @@
|
|||
name: mu/gateway
|
||||
description: An API gateway and load balancer, multiplexing requests over services.
|
||||
intrinsic: true
|
||||
properties:
|
||||
|
5
lib/mu/volume/Mu.yaml
Normal file
5
lib/mu/volume/Mu.yaml
Normal file
|
@ -0,0 +1,5 @@
|
|||
name: mu/container
|
||||
description: A Docker container.
|
||||
intrinsic: true
|
||||
properties:
|
||||
|
|
@ -11,7 +11,6 @@ import (
|
|||
"github.com/marapongo/mu/pkg/ast"
|
||||
"github.com/marapongo/mu/pkg/compiler/backends/clouds"
|
||||
"github.com/marapongo/mu/pkg/compiler/core"
|
||||
"github.com/marapongo/mu/pkg/compiler/predef"
|
||||
"github.com/marapongo/mu/pkg/diag"
|
||||
"github.com/marapongo/mu/pkg/encoding"
|
||||
"github.com/marapongo/mu/pkg/errors"
|
||||
|
@ -201,71 +200,14 @@ func (c *awsCloud) genStackServiceTemplates(comp core.Compiland, stack *ast.Stac
|
|||
|
||||
// genServiceTemplate creates a CloudFormation resource for a single service.
|
||||
func (c *awsCloud) genServiceTemplate(comp core.Compiland, stack *ast.Stack, svc *ast.Service) cfResources {
|
||||
util.Assert(svc.BoundType != nil)
|
||||
glog.V(4).Infof("Generating service templates: svc=%v type=%v", svc.Name, svc.BoundType.Name)
|
||||
|
||||
// Code-generation differs greatly for the various service types. There are three categories:
|
||||
// 1) A Mu primitive: these have very specific manifestations to accomplish the desired Mu semantics.
|
||||
// 2) An AWS-specific extension type: these largely just pass-through CloudFormation goo that we will emit.
|
||||
// 3) A reference to another Stack: these just instantiate those Stacks and reference their outputs.
|
||||
switch svc.BoundType {
|
||||
case predef.Container:
|
||||
return c.genMuContainerServiceTemplate(comp, stack, svc)
|
||||
case predef.Gateway:
|
||||
return c.genMuGatewayServiceTemplate(comp, stack, svc)
|
||||
case predef.Func:
|
||||
return c.genMuFuncServiceTemplate(comp, stack, svc)
|
||||
case predef.Event:
|
||||
return c.genMuEventServiceTemplate(comp, stack, svc)
|
||||
case predef.Volume:
|
||||
return c.genMuVolumeServiceTemplate(comp, stack, svc)
|
||||
case predef.Autoscaler:
|
||||
return c.genMuAutoscalerServiceTemplate(comp, stack, svc)
|
||||
default:
|
||||
return c.genOtherServiceTemplate(comp, stack, svc)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *awsCloud) genMuContainerServiceTemplate(comp core.Compiland, stack *ast.Stack, svc *ast.Service) cfResources {
|
||||
util.FailMF("%v service types are not yet supported (svc: %v)\n", svc.BoundType.Name, svc.Name)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *awsCloud) genMuGatewayServiceTemplate(comp core.Compiland, stack *ast.Stack, svc *ast.Service) cfResources {
|
||||
util.FailMF("%v service types are not yet supported (svc: %v)\n", svc.BoundType.Name, svc.Name)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *awsCloud) genMuFuncServiceTemplate(comp core.Compiland, stack *ast.Stack, svc *ast.Service) cfResources {
|
||||
util.FailMF("%v service types are not yet supported (svc: %v)\n", svc.BoundType.Name, svc.Name)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *awsCloud) genMuEventServiceTemplate(comp core.Compiland, stack *ast.Stack, svc *ast.Service) cfResources {
|
||||
util.FailMF("%v service types are not yet supported (svc: %v)\n", svc.BoundType.Name, svc.Name)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *awsCloud) genMuVolumeServiceTemplate(comp core.Compiland, stack *ast.Stack, svc *ast.Service) cfResources {
|
||||
util.FailMF("%v service types are not yet supported (svc: %v)\n", svc.BoundType.Name, svc.Name)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *awsCloud) genMuAutoscalerServiceTemplate(comp core.Compiland, stack *ast.Stack, svc *ast.Service) cfResources {
|
||||
util.FailMF("%v service types are not yet supported (svc: %v)\n", svc.BoundType.Name, svc.Name)
|
||||
return nil
|
||||
}
|
||||
|
||||
// genOtherServiceTemplate generates code for a general-purpose Stack service reference.
|
||||
func (c *awsCloud) genOtherServiceTemplate(comp core.Compiland, stack *ast.Stack, svc *ast.Service) cfResources {
|
||||
// Instantiate and textually include the BoundStack into our current template.
|
||||
// Instantiate and textually include the stack into our current template.
|
||||
// TODO: consider an option where a Stack can become a distinct CloudFormation Stack, and then reference it by
|
||||
// name. This would be a terrible default, because we'd end up with dozens of CloudFormation Stacks for even
|
||||
// the simplest of Mu Stacks. Especially because many Mu Stacks are single-Service. Perhaps we could come
|
||||
// up with some clever default, like multi-Service Mu Stacks map to CloudFormation Stacks, and single-Service
|
||||
// ones don't, however I'm not yet convinced this is the right path. So, for now, we keep it simple.
|
||||
util.Assert(svc.BoundType != nil)
|
||||
glog.V(4).Infof("Generating \"other\" service template: svc=%v type=%v", svc.Name, svc.BoundType.Name)
|
||||
glog.V(4).Infof("Generating service template: svc=%v type=%v", svc.Name, svc.BoundType.Name)
|
||||
|
||||
if svc.BoundType.Intrinsic {
|
||||
// For intrinsics, generate code for those that we understand; for all others, issue an error.
|
||||
|
|
|
@ -10,7 +10,6 @@ import (
|
|||
|
||||
"github.com/marapongo/mu/pkg/ast"
|
||||
"github.com/marapongo/mu/pkg/compiler/core"
|
||||
"github.com/marapongo/mu/pkg/compiler/predef"
|
||||
"github.com/marapongo/mu/pkg/diag"
|
||||
"github.com/marapongo/mu/pkg/encoding"
|
||||
"github.com/marapongo/mu/pkg/errors"
|
||||
|
@ -35,14 +34,6 @@ func NewBinder(c Compiler) Binder {
|
|||
// Create a new binder and a new scope with an empty symbol table.
|
||||
b := &binder{c: c}
|
||||
b.PushScope()
|
||||
|
||||
// And now populate that symbol table with all known predefined Stack types before returning it.
|
||||
for nm, stack := range predef.Stacks {
|
||||
sym := NewStackSymbol(nm, stack)
|
||||
ok := b.RegisterSymbol(sym)
|
||||
util.AssertMF(ok, "Unexpected Symbol collision when registering predef Stack type %v", nm)
|
||||
}
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
|
|
|
@ -6,57 +6,13 @@ import (
|
|||
"github.com/marapongo/mu/pkg/ast"
|
||||
)
|
||||
|
||||
// Stacks contains all of the built-in primitive types known to the Mu compiler.
|
||||
var Stacks = map[ast.Name]*ast.Stack{
|
||||
Container.Name: Container,
|
||||
Gateway.Name: Gateway,
|
||||
Func.Name: Func,
|
||||
Event.Name: Event,
|
||||
Volume.Name: Volume,
|
||||
Autoscaler.Name: Autoscaler,
|
||||
}
|
||||
const namespace = "mu"
|
||||
|
||||
const Namespace = "mu"
|
||||
|
||||
func muName(nm string) ast.Name {
|
||||
return ast.Name(Namespace + ast.NameDelimiter + nm)
|
||||
}
|
||||
|
||||
var (
|
||||
Container = &ast.Stack{
|
||||
Name: muName("container"),
|
||||
Intrinsic: true,
|
||||
Description: "An LXC or Windows container.",
|
||||
Properties: ast.Properties{},
|
||||
}
|
||||
Gateway = &ast.Stack{
|
||||
Name: muName("gateway"),
|
||||
Intrinsic: true,
|
||||
Description: "An API gateway and load balancer, multiplexing requests over services.",
|
||||
Properties: ast.Properties{},
|
||||
}
|
||||
Func = &ast.Stack{
|
||||
Name: muName("func"),
|
||||
Intrinsic: true,
|
||||
Description: "A single standalone function for serverless scenarios.",
|
||||
Properties: ast.Properties{},
|
||||
}
|
||||
Event = &ast.Stack{
|
||||
Name: muName("event"),
|
||||
Intrinsic: true,
|
||||
Description: "An event that may be used to trigger execution of another service.",
|
||||
Properties: ast.Properties{},
|
||||
}
|
||||
Volume = &ast.Stack{
|
||||
Name: muName("volume"),
|
||||
Intrinsic: true,
|
||||
Description: "A volume that stores data and can be mounted by other services.",
|
||||
Properties: ast.Properties{},
|
||||
}
|
||||
Autoscaler = &ast.Stack{
|
||||
Name: muName("autoscaler"),
|
||||
Intrinsic: true,
|
||||
Description: "A service that can automatically scale other services based on policy.",
|
||||
Properties: ast.Properties{},
|
||||
}
|
||||
const (
|
||||
Autoscaler = namespace + ast.NameDelimiter + "autoscaler"
|
||||
Container = namespace + ast.NameDelimiter + "container"
|
||||
Gateway = namespace + ast.NameDelimiter + "gateway"
|
||||
Func = namespace + ast.NameDelimiter + "func"
|
||||
Event = namespace + ast.NameDelimiter + "event"
|
||||
Volume = namespace + ast.NameDelimiter + "volume"
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue