Skip to content
This repository was archived by the owner on May 16, 2023. It is now read-only.

Commit ca1217d

Browse files
committed
Phabricator-based Web UI
Summary: To try this UI, follow https://github.com/facebook/bistro/blob/master/web_ui/docker_toy/README.md
1 parent 66b80fd commit ca1217d

File tree

94 files changed

+8170
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

94 files changed

+8170
-0
lines changed

web_ui/docker_toy/.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
docker_build.log
2+
web_ui.tgz
+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<VirtualHost *>
2+
ServerName phabdocker.example.com
3+
4+
DocumentRoot /home/phabricator/webroot
5+
6+
RewriteEngine on
7+
RewriteRule ^/rsrc/(.*) - [L,QSA]
8+
RewriteRule ^/favicon.ico - [L,QSA]
9+
RewriteRule ^(.*)$ /index.php?__path__=$1 [B,L,QSA]
10+
</VirtualHost>
11+
12+
<Directory "/home/phabricator/webroot">
13+
Require all granted
14+
</Directory>

web_ui/docker_toy/Dockerfile

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
FROM ubuntu:14.04
2+
SHELL ["/bin/bash", "-c"]
3+
4+
RUN \
5+
apt-get update && apt-get install -yq \
6+
git joe apache2 mysql-server php5 php5-dev php5-curl php-apc php5-mcrypt \
7+
php5-mysql php5-gd && \
8+
a2enmod rewrite && \
9+
php5enmod mcrypt
10+
11+
COPY 001-phabricator.conf /etc/apache2/sites-available/
12+
13+
WORKDIR '/home'
14+
15+
RUN git clone https://github.com/phacility/libphutil.git && \
16+
cd libphutil && \
17+
git checkout 0cd92b1ff5c4e3cabfe691c8a1794b23e1f3f720 && \
18+
cd .. && \
19+
git clone https://github.com/phacility/arcanist.git && \
20+
cd arcanist && \
21+
git checkout d9cb5b18fbc1a22630eeaa16da7d291b206fba21 && \
22+
cd .. && \
23+
git clone https://github.com/phacility/phabricator.git && \
24+
cd phabricator && \
25+
git checkout 577d4980339f68826d534110107687f33b176e88 && \
26+
cd ..
27+
28+
ADD web_ui.tgz /home/bistro/
29+
30+
# IMPORTANT: Setting an empty `bistro.get-state-hostname-suffix` below
31+
# disables a security precaution built into the Bistro UI for the sake of
32+
# letting you test with minimal hostname configuration. Do NOT do this on
33+
# production deployments!
34+
RUN \
35+
php -i && \
36+
ln -s ../sites-available/001-phabricator.conf /etc/apache2/sites-enabled/ &&\
37+
rm /etc/apache2/sites-enabled/000-default.conf && \
38+
service mysql start && \
39+
/home/phabricator/bin/storage upgrade --force && \
40+
/home/bistro/plug_bistro_into_phabricator.sh /home && \
41+
/home/phabricator/bin/config set bistro.get-state-hostname-suffix '' && \
42+
service mysql stop

web_ui/docker_toy/README.md

+111
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
# Test-driving the Bistro UI
2+
3+
4+
## Security: words to the wise
5+
6+
**IMPORTANT:** The "test-drive" Docker-based scripts provided for the UI and
7+
for the back-end are emphatically **NOT** appropriate for production use.
8+
9+
I am paranoid, but If I were you, I would run them in a VM with highly
10+
restricted access to the Internet:
11+
12+
- No inbound connections,
13+
- Allow outgoing connections only to Github, to the Docker repo hosing the
14+
Ubuntu image, and to the Ubuntu package-management servers.
15+
16+
Upon completing the setup below, you would fire up a browser inside the VM
17+
to play with the UI.
18+
19+
Some specific security issues with these demos include:
20+
21+
- Everything runs as `root` -- don't kid yourself, Linux kernel isolation
22+
used by Docker is not perfect, so this is `root` on the host VM too.
23+
- Docker's security model -- more in `build/fbcode_builder/README.docker`.
24+
- Lack of code hash / signature verification on the Github code.
25+
- Lack of production hardening on the Phabricator set-up.
26+
- Lack of production hardening on the Bistro back-end setup.
27+
- Default MySQL password in containers.
28+
- `bistro.get-state-hostname-suffix` is set to '', instead of a safe value.
29+
30+
The above list is definitely not complete.
31+
32+
33+
## Start the backend first
34+
35+
First, you'll want a running back-end. The quickest way to get one is:
36+
- Use `build/fbcode_builder/README.md` to quickly build the binaries,
37+
- Follow `bistro/scripts/docker_toy/README.md` to start a toy deployment.
38+
39+
Once that's ready, let's bring up a second Docker image with a web server
40+
hosting the Bistro UI on port 80.
41+
42+
43+
## Docker build
44+
45+
Run this
46+
47+
./docker_build.sh &> docker_build.log ; tail docker_build.log
48+
49+
50+
## Start the Bistro UI in a Docker container
51+
52+
Start an interactive session in the UI image you just built:
53+
54+
docker run --rm -it --expose 80 $(docker images -q | head -n1) /bin/bash
55+
service mysql start
56+
service apache2 start
57+
58+
59+
## Connect to the Bistro UI from outside the container
60+
61+
To connect, your browser will need to send a request to the container's IP
62+
address with `phabdocker.example.com` in the `Host` header. The easiest way
63+
is to add an appropriate line to `/etc/hosts` via the command below. If you
64+
already have a browser extension that lets you set the `Host` header for
65+
IPs, use that instead.
66+
67+
sudo apt-get install jq # If not already installed.
68+
(
69+
echo "# Phabricator docker image virtual host"
70+
echo "$(docker inspect $(docker ps -q | head -n1) |
71+
jq -r .[0].NetworkSettings.IPAddress) phabdocker.example.com"
72+
) | sudo tee -a /etc/hosts
73+
74+
*Reminder:* clean up your `/etc/hosts` once you're done test-driving Bistro.
75+
76+
Now, you can go to `http://phabdocker.example.com` in your browser. Phabricator
77+
will ask you to register an admin account. Enter some fake data to continue.
78+
79+
After account setup:
80+
- Go to `http://phabdocker.example.com/bistro`
81+
- Click the "Hostport List" radio button next to "Host:port Source"
82+
- Enter `BACKEND_CONTAINER_IP:31415` into "Host:port Data".
83+
- Click "View Jobs".
84+
- The next page will have colored bars representing groups of tasks.
85+
Click on one of the colored areas, then click on a task links in the
86+
revealed panel to see the task's logs.
87+
88+
89+
## Toy example caveats
90+
91+
- Read `Security: word to the wise` at the top of this file!
92+
93+
- Your Docker-based UI will be in UTC. Change the container's timezone if
94+
that's annoying.
95+
96+
- The in-container Phabricator install has a lot of set-up issues. This is a
97+
minimal example, for production use you would want to address them.
98+
99+
100+
## Docker disk usage tip: finding images unused by the latest build
101+
102+
If you are building a lot of Docker containers, they tend to eat up disk
103+
quickly. This command will list image IDs that are **NOT** in use by your
104+
latest build:
105+
106+
sort <(docker images -qa) <(
107+
grep '^ ---> [0-9a-f]\+$' docker_build.log | cut -f 3- -d\ | sed p
108+
) | uniq -u
109+
110+
Upon checking the output, you can wrap the command with `docker rmi $(...)`
111+
to delete the images.

web_ui/docker_toy/docker_build.sh

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#!/bin/bash -uex
2+
set -o pipefail
3+
#
4+
# See docker_toy/README.md before running this script!
5+
#
6+
7+
# Assume that `docker_toy` is not a symlink, so we can `dirname` twice.
8+
docker_toy_dir=$(dirname "$0")
9+
web_ui_dir=$(dirname "$docker_toy_dir")
10+
11+
tar -C "$web_ui_dir" -czf "$docker_toy_dir/web_ui.tgz" .
12+
cd "$docker_toy_dir"
13+
docker build .
+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#!/bin/bash -uex
2+
set -o pipefail
3+
#
4+
# This is normally started via `docker_toy/README.md`. You can also manually
5+
# run it to integrate this `bistro/web_ui/` code checkout into your current
6+
# Phabricator install. CAVEAT: This code was only tested with the specific
7+
# `github.com/phacility/*` repo hashes in `docker_toy/Dockerfile`.
8+
#
9+
10+
# Make both paths absolute for robustness. However, the bistro UI path may
11+
# include symlink, which we want to preserve, so we avoid `readlink`.
12+
#
13+
# To ensure we exit on error, we do not nest ${} or $() inside $().
14+
web_ui_dir=$(dirname "$0")
15+
web_ui_dir=$(cd "$web_ui_dir" && pwd)
16+
phab_root=${1?First arg -- directory with arcanist/, phabricator/, etc}
17+
phab_root=$(readlink -f "$phab_root")
18+
19+
# Runs $1, which is presumed to be a Phabricator PHP binary with the
20+
# annoying property that it exits with code 0 on some errors.
21+
#
22+
# Only allow $1 to write to stderr, leaving stdout free for plumbing.
23+
wrap_php_errors() {
24+
exception_bytes=$(
25+
set -o pipefail
26+
"$1" 2>&1 | tee /dev/fd/2 | (grep -i exception || :) | wc -c
27+
)
28+
[[ "$exception_bytes" == "0" ]]
29+
}
30+
31+
arc_liberate() {
32+
(
33+
cd "$web_ui_dir/src"
34+
"$phab_root/arcanist/bin/arc" liberate --library-name bistro 2>&1
35+
)
36+
}
37+
38+
set_load_libraries() {
39+
load_libs_json=$( # Not inlined so that python errors exit this script.
40+
python3 -c '
41+
import json, sys
42+
print(json.dumps({"bistro": sys.argv[1]}))
43+
' "$web_ui_dir/src"
44+
)
45+
"$phab_root/phabricator/bin/config" set load-libraries "$load_libs_json"
46+
}
47+
48+
celerity_map() {
49+
# Unfortunately, we cannot just extend CelerityResourcesOnDisk because JS
50+
# resources from the `bistro` module would not be able to access JS
51+
# resources like `javelin-dom` from the `phabricator` module. As of
52+
# 8/2017, Celerity does not seem to support cross-module resolution.
53+
for lang in css js ; do
54+
ln -snf "$web_ui_dir/rsrc/$lang/application/bistro" \
55+
"$phab_root/phabricator/webroot/rsrc/$lang/application/bistro"
56+
done
57+
"$phab_root/phabricator/bin/celerity" map
58+
}
59+
60+
wrap_php_errors arc_liberate
61+
wrap_php_errors set_load_libraries
62+
wrap_php_errors celerity_map
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/**
2+
* @provides bistro-errors
3+
*/
4+
5+
.bistro-error {
6+
background-color: #faa;
7+
max-height: 240px; /* If we change resources, logspam can be massive */
8+
overflow-x: auto; /* If the error is too wide, show a scroll bar */
9+
padding: 5px;
10+
width: 980px;
11+
}
12+
13+
.bistro-error > pre {
14+
padding: 5px;
15+
white-space: pre-wrap;
16+
}
17+
18+
.bistro-errors > h1 {
19+
margin: 10px 0px;
20+
}
21+
22+
/**
23+
* Override the consensus finder's "inconsistent" markup, because multiple
24+
* bottle errors is not in and of itself bad.
25+
*/
26+
.bistro-errors > .bistro-consensus-finder.inconsistent > * {
27+
background-color: inherit;
28+
}
29+
.bistro-errors > .bistro-consensus-finder.inconsistent > p:after {
30+
content: ""; /* No inconsistency warning */
31+
}
32+
.bistro-errors > .bistro-consensus-finder.inconsistent > p {
33+
margin: 0px;
34+
padding: 0px;
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/**
2+
* @provides bistro-job
3+
*/
4+
5+
div.bistro-why-invalid {
6+
max-height: 250px;
7+
overflow: auto; /* If there are too many errors , show a scroll bar */
8+
}
9+
10+
div.bistro-why-invalid > h2 {
11+
margin-bottom: 5px;
12+
}
13+
14+
div.bistro-why-invalid > div {
15+
background-color: #faa;
16+
font-weight: bold;
17+
padding: 5px;
18+
width: 960px;
19+
}
20+
21+
.bistro-consensus-finder.inconsistent div.bistro-why-invalid {
22+
padding: 0px; /* Already padded by the inconsistency rendering */
23+
}
24+
25+
div.bistro-why-invalid > div > pre {
26+
font-weight: normal;
27+
max-height: 100px;
28+
overflow: auto; /* If the error is too tall or wide, show a scroll bar */
29+
padding: 5px;
30+
white-space: pre-wrap;
31+
word-break: break-all;
32+
}
33+
34+
div.bistro-job-secondary-bar {
35+
margin-top: 5px;
36+
padding-left: 15px;
37+
}
38+
39+
div.bistro-job-primary-bar > p {
40+
padding-bottom: 3px;
41+
}
42+
43+
div.bistro-job-primary-bar .stacked-bar-chart td {
44+
line-height: 120%;
45+
padding-bottom: 3px;
46+
padding-top: 3px;
47+
}
48+
49+
/* Segmented sub-bars are smaller & indented 30px beyond the normal bars */
50+
51+
div.bistro-job-primary-sub-bar {
52+
line-height: 90%;
53+
margin-top: 5px;
54+
padding-left: 30px;
55+
}
56+
57+
div.bistro-job-primary-sub-bar .stacked-bar-chart td {
58+
font-size: 10px;
59+
}
60+
61+
div.bistro-job-primary-sub-bar > p {
62+
color: gray;
63+
font-size: 11px;
64+
}
65+
66+
div.bistro-job-secondary-sub-bar {
67+
line-height: 90%;
68+
margin-top: 5px;
69+
padding-left: 45px;
70+
}
71+
72+
div.bistro-job-secondary-sub-bar .stacked-bar-chart td {
73+
font-size: 10px;
74+
}
75+
76+
div.bistro-job-secondary-sub-bar > p {
77+
color: gray;
78+
font-size: 11px;
79+
}

0 commit comments

Comments
 (0)