Implement core functionality of AWS integration

This commit is contained in:
Maximilian Paß
2022-01-20 20:47:29 +01:00
parent dd41e0d5c4
commit 6123d20525
17 changed files with 360 additions and 157 deletions

View File

@ -16,7 +16,11 @@ func (n *AbstractManager) SetNextHandler(next ManagerHandler) {
}
func (n *AbstractManager) NextHandler() ManagerHandler {
return n.nextHandler
if n.nextHandler != nil {
return n.nextHandler
} else {
return &AbstractManager{}
}
}
func (n *AbstractManager) List(_ bool) ([]runner.ExecutionEnvironment, error) {
@ -24,7 +28,7 @@ func (n *AbstractManager) List(_ bool) ([]runner.ExecutionEnvironment, error) {
}
func (n *AbstractManager) Get(_ dto.EnvironmentID, _ bool) (runner.ExecutionEnvironment, error) {
return nil, runner.ErrNullObject
return nil, runner.ErrRunnerNotFound
}
func (n *AbstractManager) CreateOrUpdate(_ dto.EnvironmentID, _ dto.ExecutionEnvironmentRequest) (bool, error) {

View File

@ -1,12 +1,15 @@
package environment
import (
"encoding/json"
"fmt"
"github.com/openHPI/poseidon/internal/runner"
"github.com/openHPI/poseidon/pkg/dto"
)
type AWSEnvironment struct {
id dto.EnvironmentID
id dto.EnvironmentID
awsEndpoint string
}
func NewAWSEnvironment() *AWSEnvironment {
@ -14,7 +17,14 @@ func NewAWSEnvironment() *AWSEnvironment {
}
func (a *AWSEnvironment) MarshalJSON() ([]byte, error) {
panic("implement me")
res, err := json.Marshal(dto.ExecutionEnvironmentData{
ID: int(a.ID()),
ExecutionEnvironmentRequest: dto.ExecutionEnvironmentRequest{Image: a.Image()},
})
if err != nil {
return res, fmt.Errorf("couldn't marshal aws execution environment: %w", err)
}
return res, nil
}
func (a *AWSEnvironment) ID() dto.EnvironmentID {
@ -26,24 +36,21 @@ func (a *AWSEnvironment) SetID(id dto.EnvironmentID) {
}
func (a *AWSEnvironment) PrewarmingPoolSize() uint {
panic("implement me")
return 0
}
func (a *AWSEnvironment) SetPrewarmingPoolSize(_ uint) {
panic("implement me")
}
func (a *AWSEnvironment) SetPrewarmingPoolSize(_ uint) {}
func (a *AWSEnvironment) ApplyPrewarmingPoolSize() error {
panic("implement me")
return nil
}
func (a *AWSEnvironment) CPULimit() uint {
panic("implement me")
return 0
}
func (a *AWSEnvironment) SetCPULimit(_ uint) {
panic("implement me")
}
// SetCPULimit is disabled as one can only set the memory limit with AWS Lambda.
func (a *AWSEnvironment) SetCPULimit(_ uint) {}
func (a *AWSEnvironment) MemoryLimit() uint {
panic("implement me")
@ -53,12 +60,13 @@ func (a *AWSEnvironment) SetMemoryLimit(_ uint) {
panic("implement me")
}
// Image is used to specify the AWS Endpoint Poseidon is connecting to.
func (a *AWSEnvironment) Image() string {
panic("implement me")
return a.awsEndpoint
}
func (a *AWSEnvironment) SetImage(_ string) {
panic("implement me")
func (a *AWSEnvironment) SetImage(awsEndpoint string) {
a.awsEndpoint = awsEndpoint
}
func (a *AWSEnvironment) NetworkAccess() (enabled bool, mappedPorts []uint16) {
@ -82,7 +90,11 @@ func (a *AWSEnvironment) Delete() error {
}
func (a *AWSEnvironment) Sample() (r runner.Runner, ok bool) {
panic("implement me")
workload, err := runner.NewAWSFunctionWorkload(a, nil)
if err != nil {
return nil, false
}
return workload, true
}
func (a *AWSEnvironment) AddRunner(_ runner.Runner) {

View File

@ -10,48 +10,80 @@ import (
// IMPROVE: Create Lambda functions dynamically.
type AWSEnvironmentManager struct {
*AbstractManager
runnerManager runner.Accessor
runnerManager runner.Manager
}
func NewAWSEnvironmentManager(runnerManager runner.Accessor) *AWSEnvironmentManager {
func NewAWSEnvironmentManager(runnerManager runner.Manager) *AWSEnvironmentManager {
m := &AWSEnvironmentManager{&AbstractManager{nil}, runnerManager}
runnerManager.Load()
m.Load()
return m
}
func (a *AWSEnvironmentManager) List(fetch bool) ([]runner.ExecutionEnvironment, error) {
list, err := a.NextHandler().List(fetch)
if err != nil {
return nil, fmt.Errorf("aws wraped: %w", err)
return nil, fmt.Errorf("aws wrapped: %w", err)
}
return list, nil
return append(list, a.runnerManager.ListEnvironments()...), nil
}
func (a *AWSEnvironmentManager) Get(id dto.EnvironmentID, fetch bool) (runner.ExecutionEnvironment, error) {
e, err := a.NextHandler().Get(id, fetch)
if err != nil {
return nil, fmt.Errorf("aws wraped: %w", err)
e, ok := a.runnerManager.GetEnvironment(id)
if ok {
return e, nil
} else {
e, err := a.NextHandler().Get(id, fetch)
if err != nil {
return nil, fmt.Errorf("aws wrapped: %w", err)
}
return e, nil
}
return e, nil
}
func (a *AWSEnvironmentManager) CreateOrUpdate(
id dto.EnvironmentID, request dto.ExecutionEnvironmentRequest) (bool, error) {
isCreated, err := a.NextHandler().CreateOrUpdate(id, request)
if err != nil {
return false, fmt.Errorf("aws wraped: %w", err)
if id != runner.AwsJavaEnvironmentID {
isCreated, err := a.NextHandler().CreateOrUpdate(id, request)
if err != nil {
return false, fmt.Errorf("aws wrapped: %w", err)
}
return isCreated, nil
}
return isCreated, nil
_, ok := a.runnerManager.GetEnvironment(id)
e := NewAWSEnvironment()
e.SetID(id)
e.SetImage(request.Image)
a.runnerManager.StoreEnvironment(e)
return !ok, nil
}
func (a *AWSEnvironmentManager) Delete(id dto.EnvironmentID) (bool, error) {
isFound, err := a.NextHandler().Delete(id)
if err != nil {
return false, fmt.Errorf("aws wraped: %w", err)
e, ok := a.runnerManager.GetEnvironment(id)
if !ok {
isFound, err := a.NextHandler().Delete(id)
if err != nil {
return false, fmt.Errorf("aws wrapped: %w", err)
}
return isFound, nil
}
return isFound, nil
a.runnerManager.DeleteEnvironment(id)
if err := e.Delete(); err != nil {
return true, fmt.Errorf("could not delete environment: %w", err)
}
return true, nil
}
func (a *AWSEnvironmentManager) Statistics() map[dto.EnvironmentID]*dto.StatisticalExecutionEnvironmentData {
return a.NextHandler().Statistics()
}
// Load fetches all remote environments in the local storage. ToDo: Fetch dynamically.
func (a *AWSEnvironmentManager) Load() {
_, err := a.CreateOrUpdate(runner.AwsJavaEnvironmentID, dto.ExecutionEnvironmentRequest{Image: "java11Exec"})
if err != nil {
log.WithError(err).Warn("Could not load aws environment.")
}
}

View File

@ -252,7 +252,7 @@ func (n *NomadEnvironment) IdleRunnerCount() int {
}
// MarshalJSON implements the json.Marshaler interface.
// This converts the NomadEnvironment into the expected schema for dto.ExecutionEnvironmentData.
// This converts the AWSEnvironment into the expected schema for dto.ExecutionEnvironmentData.
func (n *NomadEnvironment) MarshalJSON() (res []byte, err error) {
networkAccess, exposedPorts := n.NetworkAccess()