Merge "playground: add light solarized theme based on Vanadium style"
diff --git a/client/browser/api/index.js b/client/browser/api/index.js
index 09daa8a..c13a196 100644
--- a/client/browser/api/index.js
+++ b/client/browser/api/index.js
@@ -19,7 +19,7 @@
timeout: 5 * 60 * 1000,
// Temporarily default to the staging load balancer until bundle lists are
// available from the API.
- url: 'https://playground-api.v.io',
+ url: 'https://playground-api.staging.v.io',
debug: false
};
@@ -106,10 +106,10 @@
// TODO(jasoncampbell): remove this list once a list API endpoint is
// available.
var ids = [
- '_051039d58946cfbe3a603fd7ed3149b0501b8f1e13ee0778e9c30e08d8a94d3',
- '_9999dc7e35426090058fb0240a8a2c1b128ea958e092b0d53ac5f2a5ca4c54a',
- '_eee960846ba210e4d9b6b01463625a2e5bf15b9dab61d76b4fc38ae04317bbd',
- '_5f199e7f67cc6b60efddf2d37cdf2c0d1aeec488007981e972c1e0a43f91c3e'
+ '_cadcfa075a6ac6d1939d12a64ac6e57bc7256c0422fb5d0690b3d8618779565',
+ '_be43fb9b2d03087dfd7c84437fd37dac7f6977d8cac330b9fce6aad94414558',
+ '_5385edd72b550c57bee83b100731338c70349ac7354dc4353665a1998fa7c8c',
+ '_46f8b66f0e80be00adc6222ac0235b1f8e70183daa64ec5924b14267dc6f0fd'
];
var workers = ids.map(createWorker);
diff --git a/go/src/v.io/x/playground/.gitignore b/go/src/v.io/x/playground/.gitignore
index 17618d0..a5f062c 100644
--- a/go/src/v.io/x/playground/.gitignore
+++ b/go/src/v.io/x/playground/.gitignore
@@ -1,3 +1,4 @@
netrc
config/*.json
!config/db-*-example.json
+!config/db-*-default.json
diff --git a/go/src/v.io/x/playground/Dockerfile b/go/src/v.io/x/playground/Dockerfile
index c70158d..cb701f6 100644
--- a/go/src/v.io/x/playground/Dockerfile
+++ b/go/src/v.io/x/playground/Dockerfile
@@ -35,6 +35,7 @@
RUN npm install --production $V23_ROOT/release/javascript/core
# Install Vanadium libraries and playground binaries.
+RUN v23 go install -a -tags wspr -v v.io/x/ref/services/wspr/...
RUN v23 go install -v v.io/...
# Uncomment the following lines to install a version of the builder tool using
diff --git a/go/src/v.io/x/playground/Makefile b/go/src/v.io/x/playground/Makefile
index 77c430a..55a266a 100644
--- a/go/src/v.io/x/playground/Makefile
+++ b/go/src/v.io/x/playground/Makefile
@@ -34,8 +34,19 @@
--sqlconf=$< \
--listen-timeout=0 \
--address=$(host):$(port) \
+ --origin='*' \
--use-docker=false
+.PHONY: pgadmin
+pgadmin:
+ v23 go install v.io/x/playground/pgadmin
+
+.PHONY: updatedb
+updatedb: config/db.json pgadmin
+ pgadmin \
+ --sqlconf=$< \
+ migrate up
+
config/db.json:
@echo "You are missing config/db.json, create this file based"
@echo "on the appropriate examples in the config directory."
diff --git a/go/src/v.io/x/playground/README.md b/go/src/v.io/x/playground/README.md
index 19cf776..88f6550 100644
--- a/go/src/v.io/x/playground/README.md
+++ b/go/src/v.io/x/playground/README.md
@@ -54,11 +54,11 @@
Run the compiler binary:
- $ $V23_ROOT/release/projects/playground/go/bin/compilerd --listen-timeout=0 --address=localhost:8181
+ $ $V23_ROOT/release/projects/playground/go/bin/compilerd --listen-timeout=0 --address=localhost:8181 --origin='*'
Or, run it without Docker (for faster iterations during development):
- $ PATH=$V23_ROOT/release/go/bin:$V23_ROOT/release/projects/playground/go/bin:$PATH compilerd --listen-timeout=0 --address=localhost:8181 --use-docker=false
+ $ PATH=$V23_ROOT/release/go/bin:$V23_ROOT/release/projects/playground/go/bin:$PATH compilerd --listen-timeout=0 --address=localhost:8181 --origin='*' --use-docker=false
The server should now be running at http://localhost:8181 and responding to
compile requests at http://localhost:8181/compile.
@@ -82,19 +82,17 @@
Create playground databases:
- MariaDB [(none)]> CREATE DATABASE IF NOT EXISTS playground;
+ MariaDB [(none)]> CREATE DATABASE IF NOT EXISTS pg_moria;
Create a playground user who has access to the playground database:
- MariaDB [(none)]> GRANT ALL PRIVILEGES ON playground.* TO 'playground'@'localhost';
+ MariaDB [(none)]> GRANT ALL PRIVILEGES ON pg_moria.* TO 'pg_gandalf'@'localhost' IDENTIFIED BY 'mellon';
-Create config/db.json from example:
+Create `config/db.json` from default:
- $ cp config/db-local-example.json config/db.json
+ $ cp config/db-local-default.json config/db.json
-Edit config/db.json and set username, password, and database.
-
-TODO(ivanpi): Describe cloud storage.
+Alternatively, make your own from example.
# Running tests
@@ -119,30 +117,28 @@
## Running migrations
-Build the `sql-migrate` tool:
+Migrations use the `github.com/rubenv/sql-migrate` library, wrapped in a tool
+`pgadmin` to allow TLS connections.
- $ v23 go install github.com/rubenv/sql-migrate/sql-migrate
+Create the database and `config/db.json` file following instructions above.
-Edit config/migrate.yml. Find or define whatever environment you plan to
-migrate, and make sure the datasource is correct.
+To migrate up, first run with -n (dry run):
-To see the current migration status, run:
+ $ $V23_ROOT/release/projects/playground/go/bin/pgadmin -sqlconf=./config/db.json migrate up -n
- $ $V23_ROOT/third_party/go/bin/sql-migrate status -config=./config/migrate.yml -env=<environment>
+If everything looks good, run the same command without -n; alternatively, run:
-To migrate up, first run with -dryrun:
-
- $ $V23_ROOT/third_party/go/bin/sql-migrate up -config=./config/migrate.yml -env=<environment> -dryrun
-
-If everything looks good, run the tool without -dryrun:
-
- $ $V23_ROOT/third_party/go/bin/sql-migrate up -config=./config/migrate.yml -env=<environment>
+ $ make updatedb
You can undo the last migration with:
- $ $V23_ROOT/third_party/go/bin/sql-migrate down -limit=1 -config=./config/migrate.yml -env=<environment>
+ $ $V23_ROOT/release/projects/playground/go/bin/pgadmin -sqlconf=./config/db.json migrate down -limit=1
-For more options and infomation, see https://github.com/rubenv/sql-migrate#usage
+For more options and infomation, run:
+
+ $ $V23_ROOT/release/projects/playground/go/bin/pgadmin help
+
+and see https://github.com/rubenv/sql-migrate
## Writing migrations
diff --git a/go/src/v.io/x/playground/compilerd/main.go b/go/src/v.io/x/playground/compilerd/main.go
index fc9ce91..88c01e9 100644
--- a/go/src/v.io/x/playground/compilerd/main.go
+++ b/go/src/v.io/x/playground/compilerd/main.go
@@ -42,6 +42,8 @@
address = flag.String("address", ":8181", "Address to listen on.")
+ origin = flag.String("origin", "https://playground.v.io", "The origin where the playground client is hosted. This will be used in CORS headers to allow XHRs to the playground API. Use '*' to allow all origins.")
+
// compilerd exits cleanly on SIGTERM or after a random amount of time,
// between listenTimeout/2 and listenTimeout.
listenTimeout = flag.Duration("listen-timeout", 60*time.Minute, "Maximum amount of time to listen for before exiting. A value of 0 disables the timeout.")
@@ -194,9 +196,7 @@
// Returns false iff response processing should not continue.
func handleCORS(w http.ResponseWriter, r *http.Request) bool {
// CORS headers.
- // TODO(nlacasse): Fill the origin header in with actual playground origin
- // before going to production.
- w.Header().Set("Access-Control-Allow-Origin", "*")
+ w.Header().Set("Access-Control-Allow-Origin", *origin)
w.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding")
diff --git a/go/src/v.io/x/playground/config/db-local-default.json b/go/src/v.io/x/playground/config/db-local-default.json
new file mode 100644
index 0000000..3fdbcd9
--- /dev/null
+++ b/go/src/v.io/x/playground/config/db-local-default.json
@@ -0,0 +1,4 @@
+{
+ "dataSourceName": "pg_gandalf:mellon@tcp(localhost:3306)/pg_moria",
+ "tlsDisable": true
+}
diff --git a/go/src/v.io/x/playground/config/migrate.yml b/go/src/v.io/x/playground/config/migrate.yml
deleted file mode 100644
index 84dc6e8..0000000
--- a/go/src/v.io/x/playground/config/migrate.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-development:
- dialect: mysql
- datasource: playground:@tcp(localhost:3306)/playground?parseTime=true
- dir: ./migrations
- table: migrations
-
-production:
- dialect: mysql
- datasource: <username>:<password>@tcp(<ip_address>:3306)/<database>
- dir: ./migrations
- table: migrations
-
diff --git a/go/src/v.io/x/playground/pgadmin/main.go b/go/src/v.io/x/playground/pgadmin/main.go
new file mode 100644
index 0000000..cbbdaf2
--- /dev/null
+++ b/go/src/v.io/x/playground/pgadmin/main.go
@@ -0,0 +1,37 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Admin tool for managing playground database and default bundles.
+
+package main
+
+import (
+ "flag"
+ "os"
+
+ "v.io/x/lib/cmdline"
+ "v.io/x/lib/dbutil"
+)
+
+func main() {
+ os.Exit(cmdPGAdmin.Main())
+}
+
+var cmdPGAdmin = &cmdline.Command{
+ Name: "pgadmin",
+ Short: "Playground database management tool",
+ Long: `
+Tool for managing the playground database and default bundles.
+Supports database schema migration.
+TODO(ivanpi): bundle bootstrap
+`,
+ Children: []*cmdline.Command{cmdMigrate},
+}
+
+var (
+ flagDryRun = flag.Bool("n", false, "Show what commands will run, but do not execute them.")
+
+ // Path to SQL configuration file, as described in v.io/x/lib/dbutil/mysql.go. Required parameter for most commands.
+ flagSQLConf = flag.String("sqlconf", "", "Path to SQL configuration file. "+dbutil.SqlConfigFileDescription)
+)
diff --git a/go/src/v.io/x/playground/pgadmin/migrate.go b/go/src/v.io/x/playground/pgadmin/migrate.go
new file mode 100644
index 0000000..fcb2b25
--- /dev/null
+++ b/go/src/v.io/x/playground/pgadmin/migrate.go
@@ -0,0 +1,147 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Wrapper around rubenv/sql-migrate to allow MySQL SSL connections using
+// dbutil (uses dbutil sqlconf files and flags with playground-specific
+// defaults instead of rubenv/sql-migrate YAML config).
+//
+// WARNING: MySQL doesn't support rolling back DDL transactions, so any failure
+// after migrations have started requires restoring from backup or manually
+// repairing database state!
+
+package main
+
+import (
+ "database/sql"
+ "fmt"
+ "os"
+
+ "github.com/rubenv/sql-migrate"
+
+ "v.io/x/lib/cmdline"
+ "v.io/x/lib/dbutil"
+)
+
+const mysqlWarning = `
+WARNING: MySQL doesn't support rolling back DDL transactions, so any failure
+after migrations have started requires restoring from backup or manually
+repairing database state!
+`
+
+// TODO(ivanpi): Add status command and sanity checks (e.g. "skipped" migrations are incorrectly applied by rubenv/sql-migrate).
+// TODO(ivanpi): Guard against version skew corrupting data (e.g. add version check to client).
+
+var cmdMigrate = &cmdline.Command{
+ Name: "migrate",
+ Short: "Database schema migrations",
+ Long: `
+See github.com/rubenv/sql-migrate
+` + mysqlWarning,
+ Children: []*cmdline.Command{cmdMigrateUp, cmdMigrateDown},
+}
+
+var cmdMigrateUp = &cmdline.Command{
+ Run: runWithDBConn(runMigrate(migrate.Up)),
+ Name: "up",
+ Short: "Apply new database schema migrations",
+ Long: `
+See github.com/rubenv/sql-migrate
+` + mysqlWarning,
+}
+
+var cmdMigrateDown = &cmdline.Command{
+ Run: runWithDBConn(runMigrate(migrate.Down)),
+ Name: "down",
+ Short: "Roll back database schema migrations",
+ Long: `
+See github.com/rubenv/sql-migrate
+` + mysqlWarning,
+}
+
+const (
+ migrationsTable = "migrations"
+ sqlDialect = "mysql"
+ pgMigrationsDir = "${V23_ROOT}/release/projects/playground/go/src/v.io/x/playground/migrations"
+)
+
+var (
+ flagMigrationsDir string
+ flagMigrationsLimit int
+)
+
+func init() {
+ cmdMigrate.Flags.StringVar(&flagMigrationsDir, "dir", pgMigrationsDir, "Path to directory containing migrations.")
+ cmdMigrateUp.Flags.IntVar(&flagMigrationsLimit, "limit", 0, "Maximum number of up migrations to apply. 0 for unlimited.")
+ cmdMigrateDown.Flags.IntVar(&flagMigrationsLimit, "limit", 1, "Maximum number of down migrations to apply. 0 for unlimited.")
+}
+
+// Returns a DBCommand for applying migrations in the provided direction.
+func runMigrate(direction migrate.MigrationDirection) DBCommand {
+ return func(db *sql.DB, cmd *cmdline.Command, args []string) error {
+ migrate.SetTable(migrationsTable)
+
+ source := migrate.FileMigrationSource{
+ Dir: os.ExpandEnv(flagMigrationsDir),
+ }
+
+ if *flagDryRun {
+ planned, _, err := migrate.PlanMigration(db, sqlDialect, source, direction, flagMigrationsLimit)
+ if err != nil {
+ return fmt.Errorf("Failed getting migrations to apply: %v", err)
+ }
+ for i, m := range planned {
+ fmt.Fprintf(cmd.Stdout(), "#%d: %q\n", i, m.Migration.Id)
+ for _, q := range m.Queries {
+ fmt.Fprint(cmd.Stdout(), q)
+ }
+ }
+ return nil
+ } else {
+ amount, err := migrate.ExecMax(db, sqlDialect, source, direction, flagMigrationsLimit)
+ if err != nil {
+ return fmt.Errorf("Migration FAILED (applied %d migrations): %v", amount, err)
+ }
+ fmt.Fprintf(cmd.Stdout(), "Successfully applied %d migrations\n", amount)
+ return nil
+ }
+ }
+}
+
+// Command to be wrapped with runWithDBConn().
+type DBCommand func(db *sql.DB, cmd *cmdline.Command, args []string) error
+
+// runWithDBConn is a wrapper method that handles opening and closing the
+// database connection.
+func runWithDBConn(fx DBCommand) cmdline.Runner {
+ return func(cmd *cmdline.Command, args []string) (rerr error) {
+ if *flagSQLConf == "" {
+ return cmd.UsageErrorf("SQL configuration file (-sqlconf) must be provided")
+ }
+
+ // Open database connection from config,
+ db, err := dbutil.NewSqlDBConnFromFile(*flagSQLConf, "SERIALIZABLE")
+ if err != nil {
+ return fmt.Errorf("Error opening database connection: %v", err)
+ }
+ // Best effort close.
+ defer func() {
+ if cerr := db.Close(); cerr != nil {
+ cerr = fmt.Errorf("Failed closing database connection: %v", cerr)
+ // Merge errors.
+ if rerr == nil {
+ rerr = cerr
+ } else {
+ rerr = fmt.Errorf("%v\n%v", rerr, cerr)
+ }
+ }
+ }()
+ // Ping database to check connection.
+ if err := db.Ping(); err != nil {
+ return fmt.Errorf("Error connecting to database: %v", err)
+ }
+
+ // Run wrapped function.
+ return fx(db, cmd, args)
+ }
+}