Configurability, to permit running a development instance that doesn't touch prod.

This commit is contained in:
Tony Garnock-Jones 2015-01-12 14:51:20 -05:00
parent 0df0c2d06b
commit b36882fa63
9 changed files with 145 additions and 19 deletions

View File

@ -6,6 +6,53 @@ You will need to install the following Racket packages:
raco pkg install reloadable
## Configuration
See the directory `configs/` for example configuration files. To
select a configuration file, set the environment variable `CONFIG` to
its base filename. For example, to select `configs/live.rkt`, set
`CONFIG` to `live`. A good place to do this is in the `run-prelude`
file; see the description of `run-prelude` below.
If `CONFIG` is not set, it defaults to the short hostname of the
machine (`hostname -s`).
Within a configuration file, configuration details are to be given as
a hashtable to `main`.
Keys useful for deployment:
- *port*: number; default the value of the `SITE_PORT` environment
variable, if defined; otherwise, 8443.
- *ssl?*: boolean; default `#t`.
- *reloadable?*: boolean; `#t` if the `SITE_RELOADABLE` environment
variable is defined; otherwise, `#f`.
- *recent-seconds*: number, in seconds; default 172800. Packages
modified fewer than this many seconds ago are considered "recent",
and displayed as such in the UI.
Keys useful for development:
- *package-index-url*: string; default
`http://pkgs.racket-lang.org/pkgs-all.json.gz`.
- *package-fetch-interval*; number, in seconds; default 300.
- *session-lifetime*: number, in seconds; default 604800.
- *static-cached-directory*: string; names a directory relative to
`src/` within which generated static HTML files are to be placed.
Must be writable by the user running the server.
- *static-cached-urlprefix*: string; absolute or relative URL,
prepended to relative URLs referring to generated static HTML files
placed in `static-cached-directory`.
- *disable-cache?*: boolean; default `#f`.
- *backend-baseurl*: string; default `https://pkgd.racket-lang.org`.
Must point to the backend package server API root, such that (for
example) `/jsonp/authenticate`, when appended to it, resolves to
the authentication call.
- *pkg-build-baseurl*: string; default
`http://pkg-build.racket-lang.org/`. Used to build URLs relative to
the package build host, for such as documentation links and build
reports.
## Local testing
You will need some dummy SSL keys. Run `make keys` to produce some.
@ -19,8 +66,8 @@ compiles the code and starts the server.
### Automatic code reloading
If you would like to enable the automatic code-reloading feature, set
the environment variable `SITE_RELOADABLE` to a non-empty string. (A
good place to do that is in a `run-prelude` script; see below.)
the environment variable `SITE_RELOADABLE` to a non-empty string or
set the `reloadable?` configuration variable to `#t`.
You must also delete any compiled code `.zo` files. Otherwise, the
system will not be able to correctly replace modules while running.
@ -44,7 +91,8 @@ logging of stdout/stderr.
If the file `run-prelude` exists in the same directory as `run`, it
will be dotted in before racket is invoked. I use this to update my
`PATH` to include my locally-built racket `bin` directory, necessary
because I don't have a system-wide racket.
because I don't have a system-wide racket, and to select an
appropriate `CONFIG` setting.
On Debian, daemontools can be installed with `apt-get install
daemontools daemontools-run`, and the services directory is
@ -61,6 +109,17 @@ You can send signals to the running service by creating files in
- creating `.restart-required` causes it to exit, to be restarted by
daemontools.
- creating `.reload` causes an explicit code reload. Useful when
automatic code reloading is disabled.
- creating `.fetchindex` causes an immediate refetch of the package
index from the backend server.
- creating `.rerender` causes an immediate rerendering of all
generated static HTML files.
See `src/signals.rkt` for details of the available signals.
So long as `sudo chmod 0777 /etc/service/webservice/signals`, these
are useful for non-root administrators to control the running service.

4
configs/live.rkt Normal file
View File

@ -0,0 +1,4 @@
#lang racket/base
;; Default configuration; should be suitable for live deployment.
(require "../src/main.rkt")
(main)

6
configs/tonyg.rkt Normal file
View File

@ -0,0 +1,6 @@
#lang racket/base
;; Configuration for tonyg's development setup.
(require "../src/main.rkt")
(main (hash 'port 8444
'reloadable? #t
))

16
run
View File

@ -1,7 +1,19 @@
#!/bin/sh
if [ -f ./run-prelude ]; then . ./run-prelude; fi
cd src
if [ -z "$CONFIG" ]; then
CONFIG=$(hostname -s)
echo 'Environment variable CONFIG not defined; defaulting to "'"${CONFIG}"'"'
fi
if [ ! -f configs/${CONFIG}.rkt ]; then
echo "Config ${CONFIG} not found: config/${CONFIG}.rkt not readable"
exit 1
fi
PLTSTDERR=info
export PLTSTDERR
echo '============================================='
exec racket main.rkt 2>&1
cd src
exec racket ../configs/${CONFIG}.rkt 2>&1

9
src/config.rkt Normal file
View File

@ -0,0 +1,9 @@
#lang racket/base
(provide config)
(require reloadable)
(define *config* (make-persistent-state '*config* (lambda () config)))
(define (config) (*config*))

View File

@ -1,11 +1,18 @@
#lang racket/base
(module+ main
(require "entrypoint.rkt")
(provide main)
(require reloadable)
(require "entrypoint.rkt")
(define (main [config (hash)])
(make-persistent-state '*config* (lambda () config))
(void (make-reloadable-entry-point 'refresh-packages! "packages.rkt"))
(void (make-reloadable-entry-point 'rerender-all! "site.rkt"))
(start-service #:reloadable? (getenv "SITE_RELOADABLE")
#:port (let ((port-str (getenv "SITE_PORT")))
(if port-str (string->number port-str) 8443))
(start-service #:port (hash-ref config 'port (lambda ()
(let ((port-str (getenv "SITE_PORT")))
(if port-str (string->number port-str) 8443))))
#:ssl? (hash-ref config 'ssl? (lambda () #t))
#:reloadable? (hash-ref config 'reloadable? (lambda () (getenv "SITE_RELOADABLE")))
(make-reloadable-entry-point 'request-handler "site.rkt")
(make-reloadable-entry-point 'on-continuation-expiry "site.rkt")))

View File

@ -27,6 +27,7 @@
(require web-server/private/gzip)
(require net/url)
(require reloadable)
(require "config.rkt")
(require "daemon.rkt")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -41,8 +42,15 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define package-index-url "http://pkgs.racket-lang.org/pkgs-all.json.gz")
(define package-fetch-interval (* 300 1000)) ;; 300 seconds = 300,000 milliseconds = 5 minutes
(define package-index-url
(or (@ (config) package-index-url)
"http://pkgs.racket-lang.org/pkgs-all.json.gz"))
(define package-fetch-interval
(* (or (@ (config) package-fetch-interval)
300) ;; 300 seconds = 5 minutes
1000)) ;; convert to milliseconds
(define base-bogus-timeout (* 5 1000)) ;; 5 seconds
(struct package-manager-state (local-packages

View File

@ -10,10 +10,14 @@
lookup-session)
(require "randomness.rkt")
(require "config.rkt")
(require reloadable)
(define current-session (make-parameter #f))
(define session-lifetime (make-parameter (* 7 24 60 60 1000))) ;; one week in milliseconds
(define session-lifetime
(* (or (hash-ref (config) 'session-lifetime-seconds #f)
(* 7 24 60 60)) ;; one week in seconds
1000)) ;; convert to milliseconds
(struct session (key expiry email password) #:prefab)

View File

@ -22,11 +22,19 @@
(require "jsonp-client.rkt")
(require reloadable)
(require "daemon.rkt")
(require "config.rkt")
(define static-cached-directory "../static/cached")
(define static-cached-urlprefix "/cached")
(define static-cached-directory
(or (@ (config) static-cached-directory)
"../static/cached"))
(define disable-cache? #f)
(define static-cached-urlprefix
(or (@ (config) static-cached-urlprefix)
"/cached"))
(define disable-cache?
(or (@ (config) disable-cache?)
#f))
(define nav-index "Package Index")
(define nav-search "Search")
@ -44,11 +52,20 @@
;; "http://download.racket-lang.org/")
))
(define backend-baseurl "https://pkgd.racket-lang.org")
(define backend-baseurl
(or (@ (config) backend-baseurl)
"https://pkgd.racket-lang.org"))
(define default-empty-source-url "git://github.com//")
(define COOKIE "pltsession")
(define recent-seconds (* 2 24 60 60)) ;; two days
(define recent-seconds
(or (@ (config) recent-seconds)
(* 2 24 60 60))) ;; two days
(define pkg-build-baseurl
(or (@ (config) pkg-build-baseurl)
"http://pkg-build.racket-lang.org/"))
(struct draft-package (old-name name description authors tags versions) #:prefab)
@ -435,7 +452,7 @@
(define (buildhost-link #:attributes [attributes '()] url-suffix label)
`(a (,@attributes
(href ,(format "http://pkg-build.racket-lang.org/~a" url-suffix))) ,label))
(href ,(format "~a~a" pkg-build-baseurl url-suffix))) ,label))
(define (authors-list authors #:gravatars? [gravatars? #f])
`(ul ((class "authors")) ,@(for/list ((author authors))