Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Experiment Creation (WIP) #8

Draft
wants to merge 67 commits into
base: expapitemp
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
ead8831
cue/parser: embed the template into parser package as exported variable
Apr 29, 2020
714cce8
experiments: modfiy the Parser function to use cue not json
Apr 29, 2020
92d9d75
cmd/labctl/command: add dry run for debug purposes
Apr 29, 2020
1dc0c6e
labd/routers/experimentrouter: commit current state
Apr 29, 2020
4bcdabb
labd/routers/experimentrouter: commit the panic code
Apr 29, 2020
cf58c94
labd/routers/experimentrouter: something works?
Apr 29, 2020
91691b4
labd/routers/experimentrouter: fix panic
Apr 30, 2020
1aa007d
labd/routers/experimentrouter: continue making some minor modifications
Apr 30, 2020
9b975ed
cue/cue.mod: add some fixes to labels
Apr 30, 2020
ee184a9
labd/routers/experimentrouter: switch to use errgorup instead of wait
Apr 30, 2020
150de93
labd/routers: add a helper package to be reused by multiple routers
Apr 30, 2020
0922764
labd/routers: use the helper functions
Apr 30, 2020
c8b0f77
labd/routers/helpers: remove usage of logutil
Apr 30, 2020
1aaa9bc
labd/routers/experimentrouter: remove nil assign
Apr 30, 2020
0f855d4
labd/routers/helpers: set default peer def if peer def is empty
Apr 30, 2020
72fead1
labd/routers/experimentrouter: check in current code
Apr 30, 2020
853ec43
metadata: add a ToJSONIndent helper for experiment definitions
May 4, 2020
79e7cbf
cue/cue.mod: fix labels accordingly
May 4, 2020
078017d
transformers/oci: add default case to return unhandled media type
May 4, 2020
57931ee
cue/cue.mod: fix incorrect function name
May 4, 2020
80f6dcb
cmd/labctl/command: use indent json marshal for dry.run
May 4, 2020
bdd4c0c
transformers/oci: add an error log
May 4, 2020
a324555
labd/routers/experimentrouter: make sure to retrieve nodes
May 4, 2020
440ae08
labd/routers/experimentrouter: use lset
May 4, 2020
e60abe5
labd/routers/experimentrouter: fix seed issues
May 4, 2020
9285c96
labagent/supervisor: log context error, dont sigterm if nil
May 4, 2020
25193d5
labd/routers/experimentrouter: make sure to cleanup cluster
May 4, 2020
8e4721b
labd/routers/experimentrouter: make sure to update benchmark
May 4, 2020
63532d3
labd/routers/experimentrouter: temporarily get single benchmark working
May 4, 2020
9378097
labd/routers/experimentrouter: temporarily log the report
May 4, 2020
cfcdcac
labd/routers/experimentrouter: write report via json
May 4, 2020
4a53b28
labd/controlapi: use json indent helper
May 4, 2020
3ecf563
cue/cue.mod: comment out a test that is being problematic??
May 4, 2020
327a3ec
metadata: add reports to the experiment struct
May 4, 2020
7902abb
labd/routers/experimentrouter: write json after all benchmarks are ran
May 5, 2020
d111b4e
labd/routers/experimentrouter: use derived context to help cleanups
May 5, 2020
135203b
metadata: add helper functions to experiment
May 5, 2020
4858dec
cmd/labapp/command: temporarily override the logger we use
May 5, 2020
f715544
cmd/labapp/command: close the file handler when context is cancelled
May 5, 2020
26207ce
labagent: redirect agent log to disk
May 5, 2020
4ff7fa0
labagent: set to debug log level
May 5, 2020
b9dc57a
cmd/labapp/command: revert the logger changes
May 5, 2020
c522c0b
labd/routers/experimentrouter: us xid
May 5, 2020
1ce20c7
labd/routers/experimentrouter: fix daemon not writing properly
May 6, 2020
8939bc7
labd/routers/experimentrouter: fix bad assign
May 6, 2020
56cbee4
labd/routers/experimentrouter: remove early exit
May 6, 2020
e8acbf7
labd/routers/experimentrouter: remove useless print
May 6, 2020
44530a5
labagent/supervisor: does this fix it?
May 6, 2020
be65c58
labagent/supervisor: remove no longer needed logs
May 6, 2020
bb67694
labd/routers/experimentrouter: add more logs for debugging purposes
May 8, 2020
79cb1be
labd/routers/experimentrouter: add another log
May 8, 2020
7f1efea
labagent/supervisor: comment our kill to demonstrate bug
May 8, 2020
2ca8314
labagent/supervisor: remove the kill cancel out
May 8, 2020
23ccb60
labd/routeres/experimentrouter: use xid to generate name
May 8, 2020
5a8a4d7
providers/inmemory: add a port helper
May 8, 2020
a87dcf8
providers/inmemory: log free ports
May 8, 2020
5ac5d6c
providers/inmemory: return ports when not in use
May 8, 2020
38c4381
labd/routers/experimentrouter: remove comment add log
May 8, 2020
3d48906
providers/inmemory: temporarily force provider ot log to disk
May 8, 2020
daa1bd4
providers/inmemory: log if an error is encountered while closing ano …
May 8, 2020
b93d6e6
pkg/digestconv: prevent empty digest from causing a panic
May 8, 2020
506333f
labagent: add latest changes
May 11, 2020
2d68c78
Fix experiment router race conditions and implementation problems
hinshun May 14, 2020
ede4745
Merge pull request #9 from hinshun/experiment-api
bonedaddy May 14, 2020
63e3fc7
cue: remove unused comments, change peer from optional to specify....
May 15, 2020
e9a9078
labd/routers/helpers: comment out handling which is now done by cue
May 15, 2020
1515eaf
nodes: I fixed the session bug???
May 21, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions cmd/labapp/command/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ func appAction(c *cli.Context) error {
if err != nil {
return err
}

ctx := cliutil.CommandContext(c)
ctx, tracer, closer := traceutil.New(ctx, "labapp", nil)
defer closer.Close()
Expand All @@ -125,7 +124,6 @@ func appAction(c *cli.Context) error {
ctx = opentracing.ContextWithSpan(ctx, span)
}
}

app, err := labapp.New(ctx, root, c.GlobalString("address"), c.GlobalInt("libp2p-port"), zerolog.Ctx(ctx), metadata.PeerDefinition{
Transports: c.GlobalStringSlice("libp2p-transports"),
Muxers: c.GlobalStringSlice("libp2p-muxers"),
Expand Down
54 changes: 54 additions & 0 deletions cmd/labctl/command/debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@ import (
"errors"
"fmt"

"github.com/Netflix/p2plab"
"github.com/Netflix/p2plab/metadata"
"github.com/Netflix/p2plab/nodes"
"github.com/Netflix/p2plab/pkg/cliutil"
"github.com/Netflix/p2plab/query"
"github.com/urfave/cli"
)

Expand Down Expand Up @@ -58,6 +61,19 @@ var debugCommand = cli.Command{
},
},
},
{
Name: "connect",
Aliases: []string{"c"},
Usage: "Connects a cluster together",
ArgsUsage: "<cluster>",
Action: connectAction,
Flags: []cli.Flag{
cli.StringFlag{
Name: "query,q",
Usage: "Runs a query to filter the listed nodes.",
},
},
},
},
}

Expand Down Expand Up @@ -103,3 +119,41 @@ func runTaskAction(c *cli.Context) error {

return nil
}

func connectAction(c *cli.Context) error {
if c.NArg() != 1 {
return errors.New("cluster id must be provided")
}

control, err := ResolveControl(c)
if err != nil {
return err
}

var opts []p2plab.ListOption
ctx := cliutil.CommandContext(c)
if c.IsSet("query") {
q, err := query.Parse(ctx, c.String("query"))
if err != nil {
return err
}

opts = append(opts, p2plab.WithQuery(q.String()))
}

cluster := c.Args().First()
ns, err := control.Node().List(ctx, cluster)
if err != nil {
return err
}
if len(ns) == 0 {
return fmt.Errorf("No nodes found for %q", cluster)
}

err = nodes.WaitHealthy(ctx, ns)
if err != nil {
return err
}

return nodes.Connect(ctx, ns)
}
25 changes: 22 additions & 3 deletions cmd/labctl/command/experiment.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package command

import (
"errors"
"fmt"

"github.com/Netflix/p2plab"
"github.com/Netflix/p2plab/experiments"
Expand All @@ -33,7 +34,7 @@ var experimentCommand = cli.Command{
Subcommands: []cli.Command{
{
Name: "create",
Aliases: []string{"s"},
Aliases: []string{"c"},
Usage: "Creates an experiment from a definition file",
ArgsUsage: "<filename>",
Action: createExperimentAction,
Expand All @@ -42,6 +43,10 @@ var experimentCommand = cli.Command{
Name: "name",
Usage: "Name of the experiment, by default takes the name of the experiment definition.",
},
&cli.BoolFlag{
Name: "dry-run",
Usage: "dry run the epxeriment creation, parsing the cue file and printing it to stdout",
},
},
},
{
Expand Down Expand Up @@ -96,7 +101,7 @@ func createExperimentAction(c *cli.Context) error {
return errors.New("experiment definition must be provided")
}

p, err := CommandPrinter(c, printer.OutputID)
p, err := CommandPrinter(c, printer.OutputJSON)
if err != nil {
return err
}
Expand All @@ -112,18 +117,32 @@ func createExperimentAction(c *cli.Context) error {
return err
}

if c.Bool("dry-run") {
dt, err := edef.ToJSON()
if err != nil {
return err
}
fmt.Println(string(dt))
return nil
}

control, err := ResolveControl(c)
if err != nil {
return err
}

ctx := cliutil.CommandContext(c)
experiment, err := control.Experiment().Create(ctx, name, edef)
id, err := control.Experiment().Create(ctx, name, edef)
if err != nil {
return err
}

experiment, err := control.Experiment().Get(ctx, id)
if err != nil {
return err
}
zerolog.Ctx(ctx).Info().Msgf("Completed experiment %q", experiment.Metadata().ID)

return p.Print(experiment.Metadata())
}

Expand Down
2 changes: 1 addition & 1 deletion cue/cue.mod/Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
.PHONY: build
build:
cue export p2plab_example.cue p2plab.cue
cue export p2plab_example1.cue p2plab.cue
11 changes: 11 additions & 0 deletions cue/cue.mod/p2plab.cue
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,17 @@ Group :: {
region: string
// labels is an optional field
labels?: [...string]
// although not optional if left unspecified
// then we use the default values of Peer
peer: Peer | *Peer
}

Peer :: {
gitReference: string | *"HEAD"
transports: [...string] | *["tcp"]
muxers: [...string] | *["mplex"]
securityTransports: [...string] | *["secio"]
routing: string | *"nil"
}

// a cluster is a collection of 1 or more groups of nodes
Expand Down
10 changes: 4 additions & 6 deletions cue/cue.mod/p2plab_example1.cue
Original file line number Diff line number Diff line change
Expand Up @@ -34,18 +34,17 @@ scen1:: Scenario & {
"neighbors": "golang"
}
benchmark: {
"(not neighbors)": "golang"
"(not 'neighbors')": "golang"
}
}

scen2:: Scenario & {
objects: [ items ]
seed: {
"neighbors": "golang"
"neighbors": "mysql"
}
benchmark: {
"(neighbors)": "golang"
"(not neighbors)": "mysql"
"(not 'neighbors')": "mysql"
}
}

Expand All @@ -60,5 +59,4 @@ experiment: Experiment & {
scenario: scen2
}
]
// trials: [[clust1,scen1],[clust1,scen2]]
}
}
5 changes: 3 additions & 2 deletions cue/cue.mod/p2plab_example2.cue
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@ experiment: Experiment & {
"neighbors": "image"
}
benchmark: {
"(not neighbors)": "image"
"(not 'neighbors')": "image"
}
}
} for o in objects
]
}

objects :: [
[{
image: {
Expand All @@ -40,4 +41,4 @@ objects :: [
source: "docker.io/library/mysql:latest"
}
}],
]
]
2 changes: 1 addition & 1 deletion cue/parser/p2plab_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func (p *P2PLabInstance) ToExperimentDefinition() (metadata.ExperimentDefinition
return metadata.ExperimentDefinition{}, err
}
return metadata.ExperimentDefinition{
TrialDefinition: trials,
Trials: trials,
}, nil
}

Expand Down
59 changes: 59 additions & 0 deletions cue/parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,65 @@ import (
"cuelang.org/go/cue"
)

var (
// CueTemplate contains the bare cue source template used to generate
// cue files
CueTemplate = `
// defines a set of nodes of size 1 or higher
// a "node" is simply an EC2 instance provisioned of the given type
// and there may be more than 1 node in a group, however there must always be 1
Group :: {
// must be greater than or equal to 1
// default value of this field is 1
size: >=1 | *1
instanceType: string
region: string
// labels is an optional field
labels?: [...string]
// although not optional if left unspecified
// then we use the default values of Peer
peer: Peer | *Peer
}

Peer :: {
gitReference: string | *"HEAD"
transports: [...string] | *["tcp"]
muxers: [...string] | *["mplex"]
securityTransports: [...string] | *["secio"]
routing: string | *"nil"
}

// a cluster is a collection of 1 or more groups of nodes
// that will be participating in a given benchmark
Cluster :: {
groups: [...Group]
}

// an object is a particular data format to be used in benchmarking
// typically these are container images
object :: [Name=_]: {
type: string
source: string
}

Scenario :: {
objects: [...object]
seed: { ... }
// enable any fields for benchmark
benchmark: { ... }
}

Trial :: {
cluster: Cluster
scenario: Scenario
}

Experiment :: {
trials: [...Trial]
}
`
)

// Parser bundles the cue runtime with helper functions
// to enable parsing of cue source files
type Parser struct {
Expand Down
2 changes: 1 addition & 1 deletion experiment.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import (
// ExperimentAPI is an unimplemented layer to run experiments, a collection
// of benchmarks while varying some aspect.
type ExperimentAPI interface {
Create(ctx context.Context, id string, edef metadata.ExperimentDefinition) (Experiment, error)
Create(ctx context.Context, name string, edef metadata.ExperimentDefinition) (id string, err error)

Get(ctx context.Context, id string) (Experiment, error)

Expand Down
19 changes: 11 additions & 8 deletions experiments/definition.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,26 @@
package experiments

import (
"encoding/json"
"io/ioutil"

"github.com/Netflix/p2plab/cue/parser"
"github.com/Netflix/p2plab/metadata"
)

// Parse reads the cue source file at filename and converts it to a
// metadata.ExperimentDefinition type
func Parse(filename string) (metadata.ExperimentDefinition, error) {
var edef metadata.ExperimentDefinition
content, err := ioutil.ReadFile(filename)
if err != nil {
return edef, err
return metadata.ExperimentDefinition{}, err
}

err = json.Unmarshal(content, &edef)
psr := parser.NewParser([]string{parser.CueTemplate})
inst, err := psr.Compile(
"p2plab_experiment",
string(content),
)
if err != nil {
return edef, err
return metadata.ExperimentDefinition{}, err
}

return edef, nil
return inst.ToExperimentDefinition()
}
14 changes: 1 addition & 13 deletions experiments/experiments_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@ package experiments

import (
"context"
"io/ioutil"
"os"
"strings"
"testing"

parser "github.com/Netflix/p2plab/cue/parser"
"github.com/Netflix/p2plab/metadata"
"github.com/google/uuid"
"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -85,17 +83,7 @@ func TestExperimentDefinition(t *testing.T) {
}

func newTestExperiment(t *testing.T, sourceFile, name string) metadata.Experiment {
data, err := ioutil.ReadFile("../cue/cue.mod/p2plab.cue")
require.NoError(t, err)
sourceData, err := ioutil.ReadFile(sourceFile)
require.NoError(t, err)
psr := parser.NewParser([]string{string(data)})
inst, err := psr.Compile(
name,
string(sourceData),
)
require.NoError(t, err)
edef, err := inst.ToExperimentDefinition()
edef, err := Parse(sourceFile)
require.NoError(t, err)
return metadata.Experiment{
ID: uuid.New().String(),
Expand Down
Loading