#!/usr/bin/perl use strict; use FindBin qw($Bin); use Getopt::Long; require "$Bin/misc/devlib.pl"; require "$Bin/misc/get_closure.pl"; sub usage { die "Usage: dev-server [OPTS] [] -- [other_blobserver_opts]\n\nWhere OPTS include:\n [--wipe] [--mongo|--mysql|--postgres] [--tls] [--fullclosure] " . "[--all] [--nobuild] [--staticres] [--KBps=] " . "[--latency_ms=] [--slow] [--verbose] [--hostname=]\n"; } chdir $Bin or die; my $opt_slow; # add latency my $opt_KBps = 150; # if non-zero, kBps to throttle connections my $opt_latency_ms = 90; # added latency in millisecond my $opt_fast; # (no longer does anything) my $opt_all; # listen on all interfaces my $opt_hostname; # hostname to advertise, else `hostname` is used my $opt_nobuild; my $opt_fullclosure; # make all of closure available my $opt_staticres; # use static resources, not those on disk my $opt_tls; my $opt_wipe; my $opt_verbose; # keep indexes in memory only. often used with --wipe, but not # necessarily. if --wipe isn't used, all blobs are re-indexed # on start-up. my $opt_memory; my $opt_mongo; my $opt_postgres; my $opt_mysql; GetOptions("wipe" => \$opt_wipe, "tls" => \$opt_tls, "all" => \$opt_all, "nobuild" => \$opt_nobuild, "memory" => \$opt_memory, "mongo" => \$opt_mongo, "postgres" => \$opt_postgres, "mysql" => \$opt_mysql, "staticres" => \$opt_staticres, "KBps=i" => \$opt_KBps, "latency_ms=i" => \$opt_latency_ms, "fast" => \$opt_fast, "slow" => \$opt_slow, "verbose" => \$opt_verbose, "hostname=s" => \$opt_hostname, "fullclosure" => \$opt_fullclosure, ) or usage(); $opt_memory = 1 unless $opt_memory || $opt_mongo || $opt_postgres || $opt_mysql; my $port = shift; $port = "3179" unless defined($port); usage() unless $port =~ /^\d+$/; if ($opt_fast) { warn "# Btw, --fast is now the default. Use --slow if you want to simulate slowness.\n"; } if ($opt_slow) { $ENV{DEV_THROTTLE_KBPS} = $opt_KBps; $ENV{DEV_THROTTLE_LATENCY_MS} = $opt_latency_ms; } $ENV{CAMLI_HTTP_DEBUG} = 1 if $opt_verbose; my $camlistored; my $camtool; # closure to return path if ($opt_nobuild) { $camlistored = find_bin("./server/camlistored"); $camtool = sub { scalar find_bin("./cmd/camtool") }; } else { $camlistored = build_bin("./server/camlistored"); $camtool = sub { scalar build_bin("./cmd/camtool") }; } my $root = "/tmp/camliroot-$ENV{USER}/port$port/"; if ($opt_wipe && -d $root) { print "Wiping $root\n"; system("rm", "-rf", $root) and die "Failed to wipe $root.\n"; } my $suffixdir = sub { my $suffix = shift; my $root = "$root/$suffix"; unless (-d $root) { system("mkdir", "-p", $root) and die "Failed to create $root.\n"; } return $root; }; my $DBNAME = "devcamli$ENV{USER}"; my @opts; if ($opt_wipe) { push @opts, "-wipe"; } else { push @opts, "-ignoreexists"; } $ENV{"CAMLI_MYSQL_ENABLED"} = "false"; $ENV{"CAMLI_MONGO_ENABLED"} = "false"; $ENV{"CAMLI_POSTGRES_ENABLED"} = "false"; if ($opt_memory) { $ENV{"CAMLI_INDEXER_PATH"} = "/index-mem/"; } elsif ($opt_mongo) { $ENV{"CAMLI_MONGO_ENABLED"} = "true"; $ENV{"CAMLI_INDEXER_PATH"} = "/index-mongo/"; if ($opt_wipe) { $ENV{"CAMLI_MONGO_WIPE"} = "true"; } else { $ENV{"CAMLI_MONGO_WIPE"} = "false"; } } elsif ($opt_postgres) { $ENV{"CAMLI_POSTGRES_ENABLED"} = "true"; $ENV{"CAMLI_INDEXER_PATH"} = "/index-postgres/"; system($camtool->(), "dbinit", "-dbtype=postgres", "-user=postgres", "-password=postgres", "-host=localhost", "-dbname=$DBNAME", @opts) and die "Failed to run camtool dbinit.\n"; } else { $ENV{"CAMLI_MYSQL_ENABLED"} = "true"; $ENV{"CAMLI_INDEXER_PATH"} = "/index-mysql/"; system($camtool->(), "dbinit", "-user=root", "-password=root", "-host=localhost", "-dbname=$DBNAME", @opts) and die "Failed to run camtool dbinit.\n"; } my $base = "http://localhost:$port"; my $listen = "127.0.0.1:$port"; if ($opt_all) { $listen = "0.0.0.0:$port"; my $host = $opt_hostname || `hostname`; chomp $host; $base = "http://$host:$port"; } if ($opt_tls) { $base =~ s/^http/https/; } $ENV{CAMLI_TLS} = "false"; if ($opt_tls) { $ENV{CAMLI_TLS} = "true"; } $ENV{CAMLI_DEV_CAMLI_ROOT} = $Bin; $ENV{CAMLI_BASEURL} = $base; $ENV{CAMLI_AUTH} = "userpass:camlistore:pass$port:+localhost"; $ENV{CAMLI_ADVERTISED_PASSWORD} = "pass$port"; # public password $ENV{CAMLI_ROOT} = $suffixdir->("bs"); $ENV{CAMLI_ROOT_SHARD1} = $suffixdir->("s1"); $ENV{CAMLI_ROOT_SHARD2} = $suffixdir->("s2"); $ENV{CAMLI_ROOT_REPLICA1} = $suffixdir->("r1"); $ENV{CAMLI_ROOT_REPLICA2} = $suffixdir->("r2"); $ENV{CAMLI_ROOT_REPLICA3} = $suffixdir->("r3"); $ENV{CAMLI_ROOT_CACHE} = $suffixdir->("cache"); $ENV{CAMLI_ROOT_ENCMETA} = $suffixdir->("encmeta"); $ENV{CAMLI_ROOT_ENCBLOB} = $suffixdir->("encblob"); $ENV{CAMLI_PORT} = $port; $ENV{CAMLI_SECRET_RING} = "$Bin/pkg/jsonsign/testdata/test-secring.gpg"; $ENV{CAMLI_DBNAME} = $DBNAME; my $templatedir = "$Bin/dev-server-template"; if ($opt_wipe && -d $templatedir) { my $blobs = "$ENV{CAMLI_ROOT}/sha1"; system("cp", "-a", $templatedir, $blobs) and die "Failed to cp template blobs.\n"; } # To use resources from disk, instead of the copies linked into the # binary: if ($opt_fullclosure) { if (-e "$Bin/tmp/closure-lib/.svn") { system("rm", "-rf", "$Bin/tmp/closure-lib") and die "Failed to remove the svn checkout of the closure-lib.\n"; } get_closure_lib(); get_closure_compiler(); chdir $Bin or die; $ENV{CAMLI_DEV_CLOSURE_DIR} = "$Bin/tmp/closure-lib/closure"; } print "Starting dev server on $base/ui/ with password \"pass$port\"\n"; exec("$camlistored", "-configfile=$Bin/config/dev-server-config.json", "-listen=$listen", @ARGV); die "exec failure: $!\n";