Skip to content

Commit 2149943

Browse files
authored
Usability and other improvements (#11)
2 parents 7b7033f + 79f3078 commit 2149943

File tree

22 files changed

+334
-294
lines changed

22 files changed

+334
-294
lines changed

.dockerignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@
1111
aws
1212
binaries
1313
browser-repos
14+
config
1415
database
1516
Dockerfile
1617
docker-compose.yaml
1718
drivers
19+
experiments
1820
extensions
1921
logs
2022
support

.env

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# DO NOT CHANGE OR REMOVE THIS FILE!
2+
# If you wish to modify a variable, do so by assigning it before the command:
3+
# For example, `BUGHOG_VERSION=dev docker compose up` to pull the development version.
4+
5+
BUGHOG_VERSION=latest
6+
BUGHOG_WEB_VERSION=latest
7+
8+
COMPOSE_PROFILES=prod

.gitignore

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
test/resources/repositories
22
browser/binaries/
3-
config/
43
database/data/
54
!**/.gitkeep
65
**/node_modules
@@ -116,7 +115,7 @@ celerybeat.pid
116115
*.sage.py
117116

118117
# Environments
119-
.env
118+
config/.env
120119
.venv
121120
env/
122121
venv/

README.md

Lines changed: 42 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -23,83 +23,85 @@ This framework has been developed as part of the _"A Bug's Life: Analyzing the L
2323
width="100"/>
2424

2525

26-
## Usage
27-
28-
### Prerequisites
29-
- Docker (tested with version 24.0.1)
26+
## Installation
3027

31-
### Installing
32-
BugHog can be installed by following the steps below:
28+
BugHog is compatible with UNIX systems running Docker, including WSL on Windows.
29+
Follow these steps to get started:
3330

34-
1. Clone this repository:
31+
1. **Clone this repository:**
3532

3633
```bash
3734
git clone https://github.com/DistriNet/BugHog
3835
cd BugHog
3936
```
4037

41-
2. Obtain images:
38+
2. **Obtain images:**
4239

4340
You will need at least 5 GB of disk space.
41+
There are two options available to obtain the BugHog images, and you can switch between them by executing the appropriate command.
4442

45-
*Option A: Pulling (fastest)*
43+
***Option A:** Pulling (fastest)*
4644

4745
Use the following command to pull the necessary Docker images:
4846
```bash
4947
docker compose pull core worker web
5048
```
5149

52-
*Option B: Building*
50+
> :bulb: If you prefer to use a version other than the latest, simply modify the `BUGHOG_VERSION` and / or `BUGHOG_WEB_VERSION` variables accordingly.
51+
52+
***Option B:** Building*
5353

54-
If you want to modify the source code, use the following commands to build the necessary Docker images.
55-
Run this script again if you make changes to the source code.
54+
Use the following commands to build the Docker images yourself, for instance after you made changes to the source code:
5655
```bash
5756
docker compose build core worker web
5857
```
5958

6059
> :bulb: For reference, building takes about 4 minutes on a machine with 8 CPU cores and 8 GB of RAM.
6160

62-
### Starting
63-
After pulling or building the images, start BugHog with the following command.
64-
If you switch between pulled and built images, make sure to execute the appropriate commands mentioned above before starting.
61+
62+
## Usage
63+
64+
Launch BugHog using the following command:
6565
```bash
66-
docker compose up core web
66+
docker compose up
6767
```
6868

69+
> :warning: If you use `sudo` with this command, the `PWD` environment variable won't be passed to the BugHog containers, which is necessary for dynamically starting worker containers.
70+
> To avoid this, explicitly pass on this variable: `sudo PWD=$PWD docker compose up`.
71+
6972
Open your web browser and navigate to [http://localhost:5000](http://localhost:5000) to access the graphical interface.
70-
If you started BugHog on a remote server, replace localhost with its IP address.
73+
BugHog is started on a remote server, substitute 'localhost' with its IP address.
74+
75+
BugHog can be stopped through:
76+
```bash
77+
docker compose down
78+
```
7179
7280
> :warning: BugHog's own MongoDB instance will persist data within the [database](database) folder.
7381
> Be sure to back-up accordingly, or use your own MongoDB instance as explained below.
7482

75-
#### Optional: Use your own MongoDB instance
7683

77-
By default, BugHog uses a MongoDB container.
78-
you might want to prefer all data to be stored on your own MongoDB instance.
84+
### Optional: Use your own MongoDB instance
85+
86+
By default, BugHog uses a MongoDB container to store data.
7987
If you prefer storing data in your own MongoDB instance, follow these steps:
8088

81-
1. Create a `.env` file from `.env.example` (both in the [config](config) folder) and fill in the missing values.
89+
1. Create a `.env` file from `.env.example` (both in the [config](config) folder) and fill in the missing database values.
8290

8391
2. (Re)start BugHog.
8492

85-
### Stopping
86-
To stop BugHog, run the following command:
87-
88-
```bash
89-
docker compose down
90-
```
9193

92-
### Adding Your Own Experiments
94+
### Adding your new experiments
9395

9496
Instructions to add your own custom experiments to the server can be found [here](https://github.com/DistriNet/BugHog-web/blob/main/experiments/README.md).
9597
Be sure to restart the BugHog framework when you add a new experiment:
9698

9799
```bash
98100
docker compose down
99-
docker compose up core web
101+
docker compose up
100102
```
101103

102-
### Development
104+
## Development
103105

104106
For extending or debugging the Vue UI, the most convenient approach is to launch an interactive Node environment.
105107
The UI can be visited at [http://localhost:5173](http://localhost:5173).
@@ -108,9 +110,18 @@ The UI can be visited at [http://localhost:5173](http://localhost:5173).
108110
docker compose up node_dev
109111
```
110112

111-
For debugging the core application, consider using the VS Code dev container for an effortless debugging experience.
113+
For debugging the core application, consider using the VS Code dev container.
112114
You can utilize the configuration in [.devcontainer](.devcontainer) for this.
113115

116+
114117
## Additional help
115118

116119
Don't hesitate to open a [GitHub issue](https://github.com/DistriNet/BugHog/issues/new) if you come across a bug, want to suggest a feature, or have any questions!
120+
121+
122+
## Troubleshooting
123+
124+
### WSL on Windows
125+
126+
- Ensure you clone the BugHog project to the WSL file system instead of the Windows file system, and launch it from there.
127+
Virtualization between these file systems can cause complications with file management.

analysis/plot_factory.py

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
1+
from bokeh.core.validation import silence
2+
from bokeh.core.validation.warnings import PALETTE_LENGTH_FACTORS_MISMATCH
13
from bokeh.embed import file_html
24
from bokeh.models import BasicTickFormatter, ColumnDataSource, HoverTool
35
from bokeh.models.glyphs import Circle
46
from bokeh.palettes import Iridescent23
57
from bokeh.plotting import figure, output_file, show
68
from bokeh.resources import CDN
79
from bokeh.transform import factor_cmap
8-
from dotenv import load_dotenv
910

1011
from bci.database.mongo.mongodb import MongoDB
1112
from bci.evaluations.logic import PlotParameters
1213

1314

15+
silence(PALETTE_LENGTH_FACTORS_MISMATCH, True)
16+
1417
class PlotFactory:
1518

1619
@staticmethod
@@ -120,19 +123,3 @@ def __add_outcome_info(params: PlotParameters, docs: dict):
120123
docs_with_outcome.append(new_doc)
121124
docs_with_outcome = PlotFactory.__transform_to_bokeh_compatible(docs_with_outcome)
122125
return docs_with_outcome
123-
124-
125-
if __name__ == '__main__':
126-
load_dotenv()
127-
MongoDB.connect()
128-
db = MongoDB.get_instance()
129-
params = PlotParameters(
130-
'c487155',
131-
'c487155',
132-
'chromium',
133-
'csp_chromium',
134-
major_version_range=(40, 105),
135-
)
136-
PlotFactory.show_plot(params, db)
137-
html = PlotFactory.create_html_plot_string(params, db)
138-
print(html)

bci/configuration.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,15 @@ def get_browser_config_class(browser: str):
2727
case _:
2828
raise ValueError(f'Invalid browser \'{browser}\'')
2929

30+
@staticmethod
31+
def check_required_env_parameters() -> bool:
32+
if (host_pwd:=os.getenv('HOST_PWD')) in ['', None]:
33+
logger.fatal('The "HOST_PWD" variable is not set. If you\'re using sudo, you might have to pass it explicitly, for example "sudo HOST_PWD=$PWD docker compose up"')
34+
return False
35+
else:
36+
logger.debug(f'HOST_PWD={host_pwd}')
37+
return True
38+
3039
@staticmethod
3140
def initialize_folders():
3241
for browser in ['chromium', 'firefox']:

bci/database/mongo/container.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def __create_new_container(user: str, pw: str, db_name, db_host):
5252
remove=True,
5353
labels=['bh_db'],
5454
volumes=[
55-
os.path.join(os.getenv('host_pwd'), 'database/data') + ':/data/db'
55+
os.path.join(os.getenv('HOST_PWD'), 'database/data') + ':/data/db'
5656
],
5757
ports={'27017/tcp': 27017},
5858
environment={

bci/distribution/worker_manager.py

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ def __run_container(self, params: WorkerParameters, cb: Callable, blocking_wait=
4242
time.sleep(5)
4343
container_id = self.container_id_pool.get()
4444
container_name = f'bh_worker_{container_id}'
45-
command = [params.serialize()]
4645

4746
def start_container_thread():
4847
try:
@@ -64,7 +63,7 @@ def start_container_thread():
6463
logger.info(f'Removing old container \'{container.attrs["Name"]}\' to start new one')
6564
container.remove(force=True)
6665
self.client.containers.run(
67-
'registry.gitlab.kuleuven.be/distrinet/research/bughog/core/worker:latest',
66+
'bughog/worker:latest',
6867
name=container_name,
6968
hostname=container_name,
7069
shm_size='2gb',
@@ -73,18 +72,18 @@ def start_container_thread():
7372
detach=False,
7473
remove=True,
7574
labels=['bh_worker'],
76-
command=command,
75+
command=[params.serialize()],
7776
volumes=[
78-
os.path.join(os.getenv('host_pwd'), 'config') + ':/app/config',
79-
os.path.join(os.getenv('host_pwd'), 'browser/binaries/chromium/artisanal') + ':/app/browser/binaries/chromium/artisanal',
80-
os.path.join(os.getenv('host_pwd'), 'browser/binaries/firefox/artisanal') + ':/app/browser/binaries/firefox/artisanal',
81-
os.path.join(os.getenv('host_pwd'), 'experiments') + ':/app/experiments',
82-
os.path.join(os.getenv('host_pwd'), 'browser/extensions') + ':/app/browser/extensions',
83-
os.path.join(os.getenv('host_pwd'), 'logs') + ':/app/logs',
77+
os.path.join(os.getenv('HOST_PWD'), 'config') + ':/app/config',
78+
os.path.join(os.getenv('HOST_PWD'), 'browser/binaries/chromium/artisanal') + ':/app/browser/binaries/chromium/artisanal',
79+
os.path.join(os.getenv('HOST_PWD'), 'browser/binaries/firefox/artisanal') + ':/app/browser/binaries/firefox/artisanal',
80+
os.path.join(os.getenv('HOST_PWD'), 'experiments') + ':/app/experiments',
81+
os.path.join(os.getenv('HOST_PWD'), 'browser/extensions') + ':/app/browser/extensions',
82+
os.path.join(os.getenv('HOST_PWD'), 'logs') + ':/app/logs',
8483
'/dev/shm:/dev/shm',
8584
],
8685
)
87-
logger.debug(f'Container \'{container_name}\' finished experiments with command \'{command}\'')
86+
logger.debug(f'Container \'{container_name}\' finished experiments with parameters \'{repr(params)}\'')
8887
cb()
8988
except docker.errors.APIError:
9089
logger.error(f'Could not run container \'{container_name}\' or container was unexpectedly removed', exc_info=True)

bci/evaluations/logic.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -174,15 +174,24 @@ def create_all_test_params(self) -> list[TestParameters]:
174174
self.database_collection)
175175
for mech_group in self.mech_groups]
176176

177-
def serialize(self) -> str:
178-
return json.dumps({
177+
def _to_dict(self):
178+
return {
179179
'browser_configuration': self.browser_configuration.to_dict(),
180180
'evaluation_configuration': self.evaluation_configuration.to_dict(),
181181
'state': state_factory.to_dict(self.state),
182182
'mech_groups': self.mech_groups,
183183
'database_collection': self.database_collection,
184184
'database_connection_params': self.database_connection_params.to_dict()
185-
})
185+
}
186+
187+
def serialize(self) -> str:
188+
return json.dumps(self._to_dict())
189+
190+
def __repr__(self) -> str:
191+
param_dict = self._to_dict()
192+
# Mask password
193+
param_dict['database_connection_params']['password'] = '*'
194+
return json.dumps(param_dict)
186195

187196
@staticmethod
188197
def deserialize(string: str) -> WorkerParameters:

bci/main.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ class Main:
2121
def initialize():
2222
Main.loggers = Loggers()
2323
Main.loggers.configure_loggers()
24-
Main.master = Master()
24+
if Global.check_required_env_parameters():
25+
Main.master = Master()
2526

2627
@staticmethod
2728
def is_ready() -> bool:

0 commit comments

Comments
 (0)