Skip to content

Commit ed12853

Browse files
authored
Merge pull request #846 from nucleogenic/webui-json-responses
JSON API and test suite for web UI
2 parents 016a616 + 75b0994 commit ed12853

27 files changed

Lines changed: 1374 additions & 277 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ src/raspberrypi/hfdisk/
1111
*~
1212
messages.pot
1313
messages.mo
14+
report.xml
1415

1516
docker/docker-compose.override.yml
1617
/docker/volumes/images/*

docker/rascsi-web/Dockerfile

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,29 @@ FROM "${OS_ARCH}/${OS_DISTRO}:${OS_VERSION}"
66
EXPOSE 80 443
77

88
ARG DEBIAN_FRONTEND=noninteractive
9-
RUN apt-get update && apt-get install -y --no-install-recommends sudo rsyslog procps
9+
RUN apt-get update && apt-get install -y --no-install-recommends sudo systemd rsyslog procps
1010

1111
RUN groupadd pi
1212
RUN useradd --create-home --shell /bin/bash -g pi pi
1313
RUN echo "pi ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
14+
RUN echo "pi:rascsi" | chpasswd
1415

15-
WORKDIR /home/pi
16+
RUN mkdir /home/pi/afpshare
17+
RUN touch /etc/dhcpcd.conf
18+
RUN mkdir -p /etc/network/interfaces.d/
19+
20+
WORKDIR /home/pi/RASCSI
1621
USER pi
17-
COPY --chown=pi:pi . RASCSI
18-
RUN cd RASCSI && ./easyinstall.sh --run_choice=11 --skip-token
22+
COPY --chown=pi:pi . .
23+
24+
# Standalone RaSCSI web UI
25+
RUN ./easyinstall.sh --run_choice=11 --skip-token
26+
27+
# Wired network bridge
28+
RUN ./easyinstall.sh --run_choice=6 --headless
1929

2030
USER root
31+
WORKDIR /home/pi
2132
RUN pip3 install watchdog
2233
COPY docker/rascsi-web/start.sh /usr/local/bin/start.sh
2334
RUN chmod +x /usr/local/bin/start.sh

docker/rascsi/Dockerfile

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@ FROM "${OS_ARCH}/${OS_DISTRO}:${OS_VERSION}"
66
EXPOSE 6868
77

88
ARG DEBIAN_FRONTEND=noninteractive
9-
RUN apt-get update && apt-get install -y --no-install-recommends sudo rsyslog patch
9+
RUN apt-get update && apt-get install -y --no-install-recommends sudo systemd rsyslog patch
1010

1111
RUN groupadd pi
1212
RUN useradd --create-home --shell /bin/bash -g pi pi
1313
RUN echo "pi ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
1414

15-
USER pi
16-
COPY --chown=pi:pi . /home/pi/RASCSI
1715
WORKDIR /home/pi/RASCSI
16+
USER pi
17+
COPY --chown=pi:pi . .
1818

1919
# Workaround for Bullseye amd64 compilation error
2020
# https://github.com/akuker/RASCSI/issues/821
@@ -24,6 +24,7 @@ RUN patch -p0 < docker/rascsi/cfilesystem.patch
2424
RUN ./easyinstall.sh --run_choice=10 --cores=`nproc` --skip-token
2525

2626
USER root
27+
WORKDIR /home/pi
2728
COPY docker/rascsi/rascsi_wrapper.sh /usr/local/bin/rascsi_wrapper.sh
2829
RUN chmod +x /usr/local/bin/rascsi_wrapper.sh
2930
CMD ["/usr/local/bin/rascsi_wrapper.sh", "-L", "trace", "-r", "7", "-F", "/home/pi/images"]

easyinstall.sh

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -691,23 +691,31 @@ function setupWiredNetworking() {
691691
echo "WARNING: If you continue, the IP address of your Pi may change upon reboot."
692692
echo "Please make sure you will not lose access to the Pi system."
693693
echo ""
694-
echo "Do you want to proceed with network configuration using the default settings? [Y/n]"
695-
read REPLY
696694

697-
if [ "$REPLY" == "N" ] || [ "$REPLY" == "n" ]; then
698-
echo "Available wired interfaces on this system:"
699-
echo `ip -o addr show scope link | awk '{split($0, a); print $2}' | grep eth`
700-
echo "Please type the wired interface you want to use and press Enter:"
701-
read SELECTED
702-
LAN_INTERFACE=$SELECTED
695+
if [[ -z $HEADLESS ]]; then
696+
echo "Do you want to proceed with network configuration using the default settings? [Y/n]"
697+
read REPLY
698+
699+
if [ "$REPLY" == "N" ] || [ "$REPLY" == "n" ]; then
700+
echo "Available wired interfaces on this system:"
701+
echo `ip -o addr show scope link | awk '{split($0, a); print $2}' | grep eth`
702+
echo "Please type the wired interface you want to use and press Enter:"
703+
read SELECTED
704+
LAN_INTERFACE=$SELECTED
705+
fi
703706
fi
704707

705708
if [ "$(grep -c "^denyinterfaces" /etc/dhcpcd.conf)" -ge 1 ]; then
706709
echo "WARNING: Network forwarding may already have been configured. Proceeding will overwrite the configuration."
707-
echo "Press enter to continue or CTRL-C to exit"
708-
read REPLY
710+
711+
if [[ -z $HEADLESS ]]; then
712+
echo "Press enter to continue or CTRL-C to exit"
713+
read REPLY
714+
fi
715+
709716
sudo sed -i /^denyinterfaces/d /etc/dhcpcd.conf
710717
fi
718+
711719
sudo bash -c 'echo "denyinterfaces '$LAN_INTERFACE'" >> /etc/dhcpcd.conf'
712720
echo "Modified /etc/dhcpcd.conf"
713721

@@ -720,6 +728,12 @@ function setupWiredNetworking() {
720728
echo "Either use the Web UI, or do this on the command line (assuming SCSI ID 6):"
721729
echo "rasctl -i 6 -c attach -t scdp -f $LAN_INTERFACE"
722730
echo ""
731+
732+
if [[ $HEADLESS ]]; then
733+
echo "Skipping reboot in headless mode"
734+
return 0
735+
fi
736+
723737
echo "We need to reboot your Pi"
724738
echo "Press Enter to reboot or CTRL-C to exit"
725739
read
@@ -1269,6 +1283,7 @@ function runChoice() {
12691283
preparePythonCommon
12701284
cachePipPackages
12711285
installRaScsiWebInterface
1286+
enableWebInterfaceAuth
12721287
echo "Configuring RaSCSI Web Interface stand-alone - Complete!"
12731288
echo "Launch the Web Interface with the 'start.sh' script. To use a custom port for the web server: 'start.sh --web-port=8081"
12741289
;;
@@ -1367,6 +1382,9 @@ while [ "$1" != "" ]; do
13671382
-s | --skip-token)
13681383
SKIP_TOKEN=1
13691384
;;
1385+
-h | --headless)
1386+
HEADLESS=1
1387+
;;
13701388
*)
13711389
echo "ERROR: Unknown parameter \"$PARAM\""
13721390
exit 1

python/common/src/rascsi/file_cmds.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,8 @@ def read_config(self, file_name):
521521
# introduce more sophisticated format detection logic here.
522522
if isinstance(config, dict):
523523
self.ractl.detach_all()
524+
for scsi_id in range(0, 8):
525+
RESERVATIONS[scsi_id] = ""
524526
ids_to_reserve = []
525527
for item in config["reserved_ids"]:
526528
ids_to_reserve.append(item["id"])

python/common/src/rascsi/ractl_cmds.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ def get_server_info(self):
4040
version = (str(result.server_info.version_info.major_version) + "." +
4141
str(result.server_info.version_info.minor_version) + "." +
4242
str(result.server_info.version_info.patch_version))
43-
log_levels = result.server_info.log_level_info.log_levels
43+
log_levels = list(result.server_info.log_level_info.log_levels)
4444
current_log_level = result.server_info.log_level_info.current_log_level
4545
reserved_ids = list(result.server_info.reserved_ids_info.ids)
4646
image_dir = result.server_info.image_files_info.default_image_folder
@@ -113,7 +113,7 @@ def get_network_info(self):
113113
result = proto.PbResult()
114114
result.ParseFromString(data)
115115
ifs = result.network_interfaces_info.name
116-
return {"status": result.status, "ifs": ifs}
116+
return {"status": result.status, "ifs": list(ifs)}
117117

118118
def get_device_types(self):
119119
"""
@@ -140,7 +140,7 @@ def get_device_types(self):
140140
"removable": device.properties.removable,
141141
"supports_file": device.properties.supports_file,
142142
"params": params,
143-
"block_sizes": device.properties.block_sizes,
143+
"block_sizes": list(device.properties.block_sizes),
144144
}
145145
return {"status": result.status, "device_types": device_types}
146146

@@ -394,7 +394,7 @@ def list_devices(self, scsi_id=None, unit=None):
394394

395395
dpath = result.devices_info.devices[i].file.name
396396
dfile = dpath.replace(image_files_info["images_dir"] + "/", "")
397-
dparam = result.devices_info.devices[i].params
397+
dparam = dict(result.devices_info.devices[i].params)
398398
dven = result.devices_info.devices[i].vendor
399399
dprod = result.devices_info.devices[i].product
400400
drev = result.devices_info.devices[i].revision

python/web/.flake8

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[flake8]
2+
max-line-length = 100

python/web/pyproject.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[tool.pytest.ini_options]
2+
addopts = "--junitxml=report.xml"
3+
log_cli = true
4+
log_cli_level = "warn"
5+
6+
[tool.black]
7+
line-length = 100
8+
target-version = ['py37', 'py38', 'py39']

python/web/requirements-dev.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
pytest==7.1.3
2+
pytest-httpserver==1.0.6
3+
black==22.8.0
4+
flake8==5.0.4

python/web/src/static/style.css

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,18 +31,33 @@ table, tr, td {
3131
margin: none;
3232
}
3333

34-
.error {
35-
color: white;
36-
font-size:20px;
37-
background-color:red;
38-
white-space: pre-line;
34+
div.flash {
35+
margin-top: 5px;
36+
margin-bottom: 5px;
3937
}
4038

41-
.message {
39+
div.flash div {
4240
color: white;
43-
font-size:20px;
44-
background-color:green;
41+
font-size: 18px;
4542
white-space: pre-line;
43+
padding: 2px 5px;
44+
}
45+
46+
div.flash div.success {
47+
background-color: green;
48+
}
49+
50+
div.flash div.warning {
51+
background-color: orange;
52+
color: black;
53+
}
54+
55+
div.flash div.error {
56+
background-color: red;
57+
}
58+
59+
div.flash div.info {
60+
background-color: #0d6efd;
4661
}
4762

4863
td.inactive {

0 commit comments

Comments
 (0)