From 37f1166fd8158af38213ee3c1ceb8c904f04a7ef Mon Sep 17 00:00:00 2001 From: Eric Helgeson Date: Wed, 30 Dec 2020 19:39:32 -0600 Subject: [PATCH] New Web Interface (#69) * gitignore * New Web Interface Fixed spacing/tabs in easy install Added migration check Fix update web not actually updating Migrating from https://github.com/erichelgeson/RaSCSI-web * Allow user to select multiple types when creating images * Show all devices even if nothing is attached. * If attaching an iso to a cd device, dont detach, just insert * UI feedback and restart rascsi service * Check for any non-0 exit code for apache2 detection * Pretty/informative 502 * Add confirms to some actions. Works in netscape 4.7 * Fix order of params for create_new_image * Move non-route method to service * Add method for getting logs * Move settings to single file add ability to mock commands for local dev --- .gitignore | 1 + easyinstall.sh | 89 +++--- src/php/.editorconfig | 8 - src/php/LICENSE | 31 -- src/php/concept_wireframe.png | Bin 164673 -> 0 bytes src/php/lib_rascsi.php | 260 --------------- src/php/rascsi.html | 9 - src/php/rascsi.php | 135 -------- src/php/rascsi_action.php | 297 ------------------ src/php/rascsi_upload.php | 86 ----- src/php/status.php | 44 --- src/web/README.md | 12 + src/web/create_disk.py | 45 +++ src/web/file_cmds.py | 64 ++++ src/web/mock/bin/journalctl | 12 + src/web/mock/bin/rasctl | 12 + src/web/mock/bin/systemctl | 12 + src/web/pi_cmds.py | 20 ++ src/web/ractl_cmds.py | 98 ++++++ src/web/requirements.txt | 12 + src/web/service-infra/502.html | 14 + src/web/service-infra/nginx-default.conf | 12 + src/web/service-infra/rascsi-web.service | 14 + src/web/settings.py | 4 + src/web/start.sh | 58 ++++ .../static/style.css} | 16 + src/web/templates/base.html | 24 ++ src/web/templates/index.html | 213 +++++++++++++ src/web/web.py | 206 ++++++++++++ 29 files changed, 894 insertions(+), 914 deletions(-) create mode 100644 .gitignore delete mode 100644 src/php/.editorconfig delete mode 100644 src/php/LICENSE delete mode 100644 src/php/concept_wireframe.png delete mode 100644 src/php/lib_rascsi.php delete mode 100644 src/php/rascsi.html delete mode 100644 src/php/rascsi.php delete mode 100644 src/php/rascsi_action.php delete mode 100644 src/php/rascsi_upload.php delete mode 100644 src/php/status.php create mode 100644 src/web/README.md create mode 100644 src/web/create_disk.py create mode 100644 src/web/file_cmds.py create mode 100755 src/web/mock/bin/journalctl create mode 100755 src/web/mock/bin/rasctl create mode 100755 src/web/mock/bin/systemctl create mode 100644 src/web/pi_cmds.py create mode 100644 src/web/ractl_cmds.py create mode 100644 src/web/requirements.txt create mode 100644 src/web/service-infra/502.html create mode 100644 src/web/service-infra/nginx-default.conf create mode 100644 src/web/service-infra/rascsi-web.service create mode 100644 src/web/settings.py create mode 100755 src/web/start.sh rename src/{php/rascsi_styles.css => web/static/style.css} (68%) create mode 100644 src/web/templates/base.html create mode 100644 src/web/templates/index.html create mode 100644 src/web/web.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..5ceb3864 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +venv diff --git a/easyinstall.sh b/easyinstall.sh index c3535c45..a3701188 100755 --- a/easyinstall.sh +++ b/easyinstall.sh @@ -34,7 +34,7 @@ function initialChecks() { fi if [ ! -d ~/RASCSI ]; then - echo "You must checkout RASCSI repo into /user/pi/RASCSI" + echo "You must checkout RASCSI repo into /home/pi/RASCSI" echo "$ git clone git@github.com:akuker/RASCSI.git" exit 2 fi @@ -46,9 +46,9 @@ function initialChecks() { function installRaScsi() { sudo apt-get update && sudo apt-get install --yes git libspdlog-dev - cd ~/RASCSI/src/raspberrypi - make all CONNECT_TYPE=FULLSPEC - sudo make install CONNECT_TYPE=FULLSPEC + cd ~/RASCSI/src/raspberrypi + make all CONNECT_TYPE=FULLSPEC + sudo make install CONNECT_TYPE=FULLSPEC sudoIsReady=$(sudo grep -c "rascsi" /etc/sudoers) @@ -61,35 +61,28 @@ www-data ALL=NOPASSWD: /bin/systemctl stop rascsi.service www-data ALL=NOPASSWD: /sbin/shutdown, /sbin/reboot " >> /etc/sudoers' fi - - sudo systemctl restart rsyslog - sudo systemctl enable rascsi # optional - start rascsi at boot - sudo systemctl start rascsi - + + sudo systemctl restart rsyslog + sudo systemctl enable rascsi # optional - start rascsi at boot + sudo systemctl start rascsi } -# install everything required to run an HTTP server (Apache+PHP) -# configure PHP -# install +function stopOldWebInterface() { + APACHE_STATUS=$(sudo systemctl status apache2 &> /dev/null; echo $?) + if [ $APACHE_STATUS -eq 0 ] ; then + echo "Stopping old Apache2 RaSCSI Web..." + sudo systemctl disable apache2 + sudo systemctl stop apache2 + fi +} + +# install everything required to run an HTTP server (Nginx + Python Flask App) function installRaScsiWebInterface() { - - sudo apt install apache2 php libapache2-mod-php -y - - sudo cp ~/RASCSI/src/php/* /var/www/html + stopOldWebInterface + sudo apt install genisoimage python3 python3-venv nginx -y - - PHP_CONFIG_FILE=/etc/php/7.3/apache2/php.ini - - #Comment out any current configuration - sudo sed -i.bak 's/^post_max_size/#post_max_size/g' $PHP_CONFIG_FILE - sudo sed -i.bak 's/^upload_max_filesize/#upload_max_filesize/g' $PHP_CONFIG_FILE - - sudo bash -c 'PHP_CONFIG_FILE=/etc/php/7.3/apache2/php.ini && echo " -# RaSCSI high upload limits -upload_max_filesize = 1200M -post_max_size = 1200M - -" >> $PHP_CONFIG_FILE' + sudo cp -f ~/RASCSI/src/web/service-infra/nginx-default.conf /etc/nginx/sites-available/default + sudo cp -f ~/RASCSI/src/web/service-infra/502.html /var/www/html/502.html mkdir -p $VIRTUAL_DRIVER_PATH chmod -R 775 $VIRTUAL_DRIVER_PATH @@ -97,30 +90,38 @@ post_max_size = 1200M sudo usermod -a -G pi www-data groups www-data - sudo /etc/init.d/apache2 restart + sudo systemctl reload nginx + + sudo cp ~/RASCSI/src/web/service-infra/rascsi-web.service /etc/systemd/system/rascsi-web.service + sudo systemctl daemon-reload + sudo systemctl enable rascsi-web + sudo systemctl start rascsi-web } - +function updateRaScsiGit() { + cd ~/RASCSI + git pull +} function updateRaScsi() { + updateRaScsiGit sudo systemctl stop rascsi - cd ~/RASCSI/src/raspberrypi - - make clean - make all CONNECT_TYPE=FULLSPEC - sudo make install CONNECT_TYPE=FULLSPEC - sudo systemctl start rascsi + cd ~/RASCSI/src/raspberrypi + + make clean + make all CONNECT_TYPE=FULLSPEC + sudo make install CONNECT_TYPE=FULLSPEC + sudo systemctl start rascsi } function updateRaScsiWebInterface() { - sudo /etc/init.d/apache2 stop - cd ~/RASCSI - git fetch --all - cd ~/RASCSI/src/raspberrypi - sudo cp ~/RASCSI/src/php/* /var/www/html - - sudo /etc/init.d/apache2 start + stopOldWebInterface + updateRaScsiGit + sudo cp -f ~/RASCSI/src/web/service-infra/nginx-default.conf /etc/nginx/sites-available/default + sudo cp -f ~/RASCSI/src/web/service-infra/502.html /var/www/html/502.html + sudo systemctl restart rascsi-web + sudo systemctl restart nginx } function showRaScsiStatus() { diff --git a/src/php/.editorconfig b/src/php/.editorconfig deleted file mode 100644 index d03ab4e6..00000000 --- a/src/php/.editorconfig +++ /dev/null @@ -1,8 +0,0 @@ -root = true - -[*.{html,php,htm}] -indent_style = space -indent_size = 3 -charset = utf-8 -trim_trailing_whitespace = true -insert_final_newline = true diff --git a/src/php/LICENSE b/src/php/LICENSE deleted file mode 100644 index ffef9a2f..00000000 --- a/src/php/LICENSE +++ /dev/null @@ -1,31 +0,0 @@ -BSD 3-Clause License - -Copyright (C) 2001-2006 PI.(ytanaka@ipc-tokai.or.jp) -Copyright (C) 2014-2020 GIMONS -Copyright (c) 2020, akuker -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/php/concept_wireframe.png b/src/php/concept_wireframe.png deleted file mode 100644 index 1aea00249fe4af20ce81f2d4300ca2144e58c12c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 164673 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

Z48bG{)}W)!hm<)TCtBmssUNThW-* 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 diff --git a/src/php/lib_rascsi.php b/src/php/lib_rascsi.php deleted file mode 100644 index fb483a47..00000000 --- a/src/php/lib_rascsi.php +++ /dev/null @@ -1,260 +0,0 @@ - - - - - - -'. PHP_EOL; - echo ' '. PHP_EOL; - echo '

RaSCSI - 68kmla Edition

'. PHP_EOL; - echo ' '. PHP_EOL; - echo '
'. PHP_EOL; - echo ' '. PHP_EOL; - if($GLOBALS['DEBUG_ENABLE']){ - echo '

Debug Timestamp: '.time().'

'. PHP_EOL; - } - echo '
'. PHP_EOL; - echo ' '. PHP_EOL; - echo ' '. PHP_EOL; - echo ' '. PHP_EOL; - //echo(exec('whoami')); -} - -function html_generate_image_file_select_list(){ - $all_files = get_all_files(); - foreach(explode(PHP_EOL, $all_files) as $this_file){ - if(strpos($this_file, 'total') === 0){ - continue; - } - $file_name = file_name_from_ls($this_file); - if(strlen($file_name) === 0){ - continue; - } - // Ignore files that start with a . - if(strpos($file_name, '.') === 0){ - continue; - } - - echo ''.PHP_EOL; - } -} - - -function html_generate_scsi_id_select_list(){ - echo ''. PHP_EOL; -} - -function html_generate_scsi_type_select_list(){ - echo ''. PHP_EOL; -} - -function html_generate_warning($message){ - echo ' '. PHP_EOL; - echo ' '. PHP_EOL; - echo ' '. PHP_EOL; - echo ' '. PHP_EOL; - echo '
'. PHP_EOL; - echo ' '.$message.''. PHP_EOL; - echo '
'. PHP_EOL; -} - -function html_generate_success_message($message){ - echo ' '. PHP_EOL; - echo ' '. PHP_EOL; - echo ' '. PHP_EOL; - echo ' '. PHP_EOL; - if(strlen($message) > 0){ - echo ' '. PHP_EOL; - echo ' '. PHP_EOL; - echo ' '. PHP_EOL; - } - echo '
'. PHP_EOL; - echo ' Success'. PHP_EOL; - echo '
'. PHP_EOL; - echo ' '.$message.PHP_EOL; - echo '
'. PHP_EOL; -} - -function html_generate_ok_to_go_home(){ - echo '
'. PHP_EOL; - echo ' '. PHP_EOL; - echo '
'. PHP_EOL; -} - - -function current_rascsi_config() { - $raw_output = shell_exec("/usr/local/bin/rasctl -l"); - $rasctl_lines = explode(PHP_EOL, $raw_output); - - echo '
'. PHP_EOL; - echo '

Current RaSCSI Configuration

'. PHP_EOL; - echo ' '. PHP_EOL; - echo ' '. PHP_EOL; - echo ' '. PHP_EOL; - echo ' '. PHP_EOL; - echo ' '. PHP_EOL; - echo ' '. PHP_EOL; - echo ' '. PHP_EOL; - echo ' '. PHP_EOL; - - $scsi_ids = array(); - - foreach ($rasctl_lines as $current_line) - { - if(strlen($current_line) === 0){ - continue; - } - if(strpos($current_line, '+----') === 0){ - continue; - - } - if(strpos($current_line, '| ID | UN') === 0){ - continue; - } - $segments = explode("|", $current_line); - - $id_config = array(); - $id_config['id'] = trim($segments[1]); - $id_config['type'] = trim($segments[3]); - $id_config['file'] = trim($segments[4]); - - $scsi_ids[$id_config['id']] = $id_config; - } - - - foreach (range(0,7) as $id){ - echo ' '. PHP_EOL; - echo ' '. PHP_EOL; - if(isset($scsi_ids[$id])) - { - echo ' '. PHP_EOL; - if(strtolower($scsi_ids[$id]['file']) == "no media"){ - echo ' '.PHP_EOL; - } - else{ - // rascsi inserts "WRITEPROTECT" for the read-only drives. We want to display that differently. - echo ' '. PHP_EOL; - echo ' '.PHP_EOL; - echo ' '. PHP_EOL; - } - echo ' '. PHP_EOL; - } - else - { - echo ' '. PHP_EOL; - echo ' '. PHP_EOL; - echo ' '. PHP_EOL; - echo ' '. PHP_EOL; - - } - echo ' '. PHP_EOL; - echo ' '. PHP_EOL; - } - echo '
SCSI IDTypeFileFile OpsDevice Ops
'.$id.''.$scsi_ids[$id]['type'].''.PHP_EOL; - echo '
'. PHP_EOL; - echo ' '.PHP_EOL; - echo ' '. PHP_EOL; - echo ' '. PHP_EOL; - echo ' '. PHP_EOL; - echo '
'.PHP_EOL; - echo ' '. PHP_EOL; - echo ' '. PHP_EOL; - echo '
'.str_replace('(WRITEPROTECT)', '', $scsi_ids[$id]['file']). PHP_EOL; - echo ' '.PHP_EOL; - if(strtolower($scsi_ids[$id]['type']) == 'sccd'){ - echo ' '. PHP_EOL; - echo ' '. PHP_EOL; - echo ' '. PHP_EOL; - echo ' '. PHP_EOL; - } - echo ' '. PHP_EOL; - echo '
'. PHP_EOL; - echo ' '. PHP_EOL; - echo ' '. PHP_EOL; - echo ' '. PHP_EOL; - echo '
'. PHP_EOL; - echo '
--'. PHP_EOL; - echo '
'. PHP_EOL; - echo ' '. PHP_EOL; - echo ' '. PHP_EOL; - echo ' '. PHP_EOL; - echo '
'. PHP_EOL; - echo '
'. PHP_EOL; -} -function get_all_files() -{ - $raw_ls_output = shell_exec('ls --time-style="+\"%Y-%m-%d %H:%M:%S\"" -alh --quoting-style=c '.$GLOBALS['FILE_PATH']); - return $raw_ls_output; -} - -function mod_date_from_ls($value){ - $ls_pieces = explode("\"", $value); - if(count($ls_pieces)<1){ - return ""; - } - return $ls_pieces[1]; -} -function file_name_from_ls($value){ - $ls_pieces = explode("\"", $value); - if(count($ls_pieces) < 4){ - return ""; - } - return $ls_pieces[3]; -} -function file_size_from_ls($value){ - $ls_pieces = explode("\"", $value); - $file_props = preg_split("/\s+/", $ls_pieces[0]); - return $file_props[4]; -} -function file_category_from_file_name($value){ - if(strpos($value,".iso") || strpos($value,".cdr") > 0){ - return "CD-ROM Image"; - } - if(strpos($value,".hda") > 0){ - return "Hard Disk Image"; - } - return "Unknown type: " . $value; -} - - - -function type_string_to_rasctl_type($typestr){ - if(strcasecmp($typestr,"Hard Disk") == 0){ - return "hd"; - } - if(strcasecmp($typestr,"CD-ROM") == 0){ - return "cd"; - } - if(strcasecmp($typestr,"Zip Drive") == 0){ - } - if(strcasecmp($typestr,"Filesystem bridge") == 0){ - return "bridge"; - } - return ""; -} - - - - -?> diff --git a/src/php/rascsi.html b/src/php/rascsi.html deleted file mode 100644 index 2dac00d6..00000000 --- a/src/php/rascsi.html +++ /dev/null @@ -1,9 +0,0 @@ - - RaSCSI Control Page - - - - You must use a browser that can display frames - to see this page. - - diff --git a/src/php/rascsi.php b/src/php/rascsi.php deleted file mode 100644 index f18d2b97..00000000 --- a/src/php/rascsi.php +++ /dev/null @@ -1,135 +0,0 @@ - - - - - - - - - - - RaSCSI Main Control Page - - - - - - - -
-

Image File Management

- - - - - - - - - - - '.PHP_EOL; - echo ' '.PHP_EOL; - echo ' '.PHP_EOL; - echo ' '.PHP_EOL; - echo ' '.PHP_EOL; - echo ' '.PHP_EOL; - echo ' '.PHP_EOL; - echo ''.PHP_EOL; - } -?> -
LocationFilenameSizeTypeDate ModifiedActions
SD Card'.$file_name.''.file_size_from_ls($this_file).''.file_category_from_file_name($file_name).''.mod_date_from_ls($this_file).''.PHP_EOL; - echo '
'.PHP_EOL; - echo ' '.PHP_EOL; - echo ' '.PHP_EOL; - echo ' '.PHP_EOL; - echo '
'.PHP_EOL; - echo '
- - -
-
-

Upload New Image File

-
- - - - - -
-

-
- -
-
- -
-

Create New Empty HD Image

-
- - -
- -
-

RaSCSI Service Status

- - - - - -
-
- - -
-
-
- - -
-
- -
-

Raspberry Pi Operations

- - - - - -
-
- - -
-
-
- - -
-
- - - - diff --git a/src/php/rascsi_action.php b/src/php/rascsi_action.php deleted file mode 100644 index ec6740ad..00000000 --- a/src/php/rascsi_action.php +++ /dev/null @@ -1,297 +0,0 @@ - - - - - - - - RaSCSI Action Page - - - - - '; - if($GLOBALS['DEBUG_ENABLE']){ - echo ''.PHP_EOL; - echo ' '.PHP_EOL; - echo '

Debug stuff

'; - - echo '

Post values......................'.PHP_EOL; - echo '
'.PHP_EOL; - var_dump($_POST); - echo '

Running command.... '.$_POST['command'].PHP_EOL; - echo '

'.PHP_EOL; - echo '
'; - } - - if(isset($_POST['command'])) - { - switch(strtolower($_POST['command'])){ - case "eject_disk": - action_eject_disk(); - break; - case "remove_device": - action_remove_device(); - break; - case "connect_new_device": - action_connect_new_device(); - break; - case "insert_disk": - action_insert_disk(); - break; - case "delete_file": - action_delete_file(); - break; - case "create_new_image": - action_create_new_image(); - break; - case "restart_rascsi_service": - action_restart_rascsi_service(); - break; - case "stop_rascsi_service": - action_stop_rascsi_service(); - break; - case "reboot_raspberry_pi": - action_reboot_raspberry_pi(); - break; - case "shutdown_raspberry_pi": - action_shutdown_raspberry_pi(); - break; - default: - action_unknown_command(); - break; - } - } - else{ - html_generate_warning("HTTP command was missing POST information. Are you trying to access this page directly? That won't work"); - echo "
".PHP_EOL; - html_generate_ok_to_go_home(); - } - -function action_eject_disk(){ - $command = 'rasctl -i '.$_POST['id'].' -c eject 2>&1'.PHP_EOL; - exec($command, $retArray, $result); - check_result($result, $command,$retArray); - html_generate_ok_to_go_home(); -} - -function action_remove_device(){ - // Check to see if the user has confirmed - if(isset($_POST['confirmed'])){ - $command = 'rasctl -i '.$_POST['id'].' -c disconnect 2>&1'.PHP_EOL; - exec($command, $retArray, $result); - check_result($result, $command,$retArray); - html_generate_ok_to_go_home(); - } - else{ - check_are_you_sure('Are you sure you want to disconnect SCSI ID ' . $_POST['id'].'? If the host is running, this could cause undesirable behavior.'); - } -} -// function action_connect_new_device(){} -function action_insert_disk(){ - $command = 'rasctl -i '.$_POST['id'].' -c insert -f '.$GLOBALS['FILE_PATH'].'/'.$_POST['file_name'].' 2>&1'.PHP_EOL; - exec($command, $retArray, $result); - check_result($result, $command,$retArray); - html_generate_ok_to_go_home(); -} -function action_create_new_image(){ - // If we already know the size & filename, we can go create the image... - if(isset($_POST['size']) && isset($_POST['file_name'])){ - $command = 'dd if=/dev/zero of='.$GLOBALS['FILE_PATH'].'/'.$_POST['file_name'].' bs=1M count='.$_POST['size']; - exec($command, $retArray, $result); - check_result($result, $command, $retArray); - html_generate_ok_to_go_home(); - } - else{ - echo '

Create a new empty file

'.PHP_EOL; - echo '
'.PHP_EOL; - echo ' '.PHP_EOL; - echo ' '.PHP_EOL; - echo ' '.PHP_EOL; - echo ' '.PHP_EOL; - echo ' '.PHP_EOL; - echo ' '.PHP_EOL; - echo ' '.PHP_EOL; - echo ' '.PHP_EOL; - echo ' '.PHP_EOL; - echo ' '.PHP_EOL; - echo '
File Name:'.PHP_EOL; - echo ' '.PHP_EOL; - echo ' Size:'.PHP_EOL; - echo ' '.PHP_EOL; - echo ' MB'.PHP_EOL; - echo ' '.PHP_EOL; - echo '
'.PHP_EOL; - echo '
'.PHP_EOL; - echo '
Note: Creating a large file may take a long time!'.PHP_EOL; - echo '

'.PHP_EOL; - echo '
'.PHP_EOL; - echo ' '.PHP_EOL; - echo '
'.PHP_EOL; - } -} - -function action_delete_file(){ - // Check to see if the user has confirmed - if(isset($_POST['confirmed'])){ - $command = 'rm '.$GLOBALS['FILE_PATH'].'/'.$_POST['file_name']; - exec($command, $retArray, $result); - check_result($result, $command, $retArray); - html_generate_ok_to_go_home(); - } - else{ - check_are_you_sure('Are you sure you want to PERMANENTLY delete '.$_POST['file_name'].'?'); - } -} - -function action_restart_rascsi_service(){ - // Restart the RaSCSI service - $command = "sudo /bin/systemctl restart rascsi.service 2>&1"; - exec($command, $retArray, $result); - check_result($result, $command,$retArray); - html_generate_ok_to_go_home(); -} - -function action_stop_rascsi_service(){ - // Stop the RaSCSI service - $command = "sudo /bin/systemctl stop rascsi.service 2>&1"; - exec($command, $retArray, $result); - check_result($result, $command,$retArray); - html_generate_ok_to_go_home(); -} - -function action_reboot_raspberry_pi(){ - // Check to see if the user has confirmed - if(isset($_POST['confirmed'])){ - $command = "sleep 2 && sudo reboot 2>&1"; - exec($command, $retArray, $result); - // The unit should reboot at this point. Doesn't matter what we do now... - check_result($result, $command,$retArray); - html_generate_ok_to_go_home(); - } - else{ - check_are_you_sure("Are you sure you want to reboot the Raspberry Pi?"); - } -} - -function action_shutdown_raspberry_pi(){ - // Check to see if the user has confirmed - if(isset($_POST['confirmed'])){ - $command = "sleep 2 && sudo shutdown -h now 2>&1"; - exec($command, $retArray, $result); - // The unit should shutdown at this point. Doesn't matter what we do now... - check_result($result, $command,$retArray); - html_generate_ok_to_go_home(); - } - else{ - check_are_you_sure("Are you sure you want to shut down the Raspberry Pi?"); - } -} - -function action_unknown_command(){ - html_generate_warning('

Unknown command: '.$_POST['command'].'

'); - html_generate_ok_to_go_home(); -} - -function check_result($result,$command,$output){ - if(!$result){ - html_generate_success_message('Command succeeded!'); - } - else{ - html_generate_warning('Command failed!'); - } - echo '
'.$command.'
'.PHP_EOL; - if(count($output) > 0){ - echo '
Output:'.PHP_EOL; - foreach($output as $line){ - echo '
Error message: '.$line.PHP_EOL; - } - echo '
'.PHP_EOL; - } -} - -function check_are_you_sure($prompt){ - echo '

'.$prompt.'

'.PHP_EOL; - echo ' '.PHP_EOL; - echo ' '.PHP_EOL; - echo ' '.PHP_EOL; - echo ' '.PHP_EOL; - echo ' '.PHP_EOL; - echo '
'.PHP_EOL; - echo '
'.PHP_EOL; - foreach($_POST as $key => $value){ - echo ''.PHP_EOL; - } - echo ' '.PHP_EOL; - echo ' '.PHP_EOL; - echo '
'.PHP_EOL; - echo '
'.PHP_EOL; - echo '
'.PHP_EOL; - echo ' '.PHP_EOL; - echo '
'.PHP_EOL; - echo '
'.PHP_EOL; -} - -function action_connect_new_device(){ - // If we already know the type & filename, we can go connect the device... - if(isset($_POST['type']) && isset($_POST['file_name'])){ - $command = 'rasctl -i '.$_POST['id'].' -c attach -t '.type_string_to_rasctl_type($_POST['type']); - if($_POST['file_name'] != "None"){ - $command = $command.' -f '.$GLOBALS['FILE_PATH'].'/'.$_POST['file_name']; - } - exec($command, $retArray, $result); - check_result($result, $command, $retArray); - html_generate_ok_to_go_home(); - } - else{ - - - $id = $_POST['id']; - echo '

Add New Device

'.PHP_EOL; - echo '
'.PHP_EOL; - echo ' '.PHP_EOL; - echo ' '.PHP_EOL; - echo ' '.PHP_EOL; - echo ' '.PHP_EOL; - echo ' '.PHP_EOL; - echo ' '.PHP_EOL; - echo ' '.PHP_EOL; - echo ' '.PHP_EOL; - echo ' '.PHP_EOL; - echo ' '.PHP_EOL; - echo ' '.PHP_EOL; - echo '
SCSI ID:'.PHP_EOL; - echo ' '.PHP_EOL; - echo $id; - echo ' Device:'.PHP_EOL; - html_generate_scsi_type_select_list(); - echo ' File:'.PHP_EOL; - echo ' '.PHP_EOL; - echo ' '.PHP_EOL; - echo ' '.PHP_EOL; - echo '
'.PHP_EOL; - } -} - -function get_new_filename(){ - // Try to find a new file name that doesn't exist. - $i=1; - while(file_exists($GLOBALS['FILE_PATH'].'/'.'new_file'.$i.'.hda')) - { - $i = $i+1; - } - return 'new_file'.$i.'.hda'; -} - -?> - - - - diff --git a/src/php/rascsi_upload.php b/src/php/rascsi_upload.php deleted file mode 100644 index e34fba89..00000000 --- a/src/php/rascsi_upload.php +++ /dev/null @@ -1,86 +0,0 @@ - - - - - - - - RaSCSI Upload Page - - - - - '; - - if($GLOBALS['DEBUG_ENABLE']){ - echo ''.PHP_EOL; - echo ' '.PHP_EOL; - echo '

Debug stuff

'; - - echo '

Post values......................'.PHP_EOL; - echo '
'.PHP_EOL; - var_dump($_POST); - echo '

'.PHP_EOL; - var_dump($_FILES); - echo '

'.PHP_EOL; - echo '
'; - } - - $target_dir = $GLOBALS['FILE_PATH'].'/'; - $target_file = $target_dir.basename($_FILES['file_name']['name']); - $upload_ok=1; - $file_type = strtolower(pathinfo($target_file,PATHINFO_EXTENSION)); - - if(isset($_POST['submit'])) - { - // Check if file already exists - if ($upload_ok && (file_exists($target_file))) { - html_generate_warning('Error: File '.$target_file.' already exists.'); - $upload_ok = 0; - } - - // Check file size. Limit is specified in lib_rascsi.php - if ($upload_ok && ($_FILES["file_name"]["size"] > $GLOBALS['MAX_UPLOAD_FILE_SIZE'])) { - html_generate_warning("Error: your file is larger than the maximum size of " . $GLOBALS['MAX_UPLOAD_FILE_SIZE'] . "bytes"); - $upload_ok = 0; - } - - // Allow certain file formats, also specified in lib_rascsi.php - if($upload_ok && (!in_array(strtolower($file_type),$GLOBALS['ALLOWED_FILE_TYPES']))){ - $error_string = 'File type "'. $file_type. '" is not currently allowed.'. - 'Only the following file types are allowed:
'. - '
    '.PHP_EOL; - foreach($GLOBALS['ALLOWED_FILE_TYPES'] as $ft){ - $error_string = $error_string. '
  • '.$ft.'
  • '.PHP_EOL; - } - $error_string = $error_string.'
'; - $error_string = $error_string.'
'; - html_generate_warning($error_string); - $upload_ok = 0; - } - - //Check if $upload_ok is set to 0 by an error - if ($upload_ok != 0) { - if (move_uploaded_file($_FILES["file_name"]["tmp_name"], $target_file)) { - html_generate_success_message(basename( $_FILES["file_name"]["name"]). " has been uploaded."); - } else { - html_generate_warning("There was an unknown error uploading your file."); - } - } - } - else - { - html_generate_warning('The Submit POST information was not populated. Something went wrong'); - } - echo '
'; - - html_generate_ok_to_go_home(); -?> - - - - diff --git a/src/php/status.php b/src/php/status.php deleted file mode 100644 index d49beefc..00000000 --- a/src/php/status.php +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - - - - -'; - echo ''; - echo ''; - echo ''; - echo ''; - echo '
'.$text.' '.date("h:i:sa").'
'; -?> - - diff --git a/src/web/README.md b/src/web/README.md new file mode 100644 index 00000000..82088ba2 --- /dev/null +++ b/src/web/README.md @@ -0,0 +1,12 @@ +# RaSCSI Web + +## Mocking for local development + +Set a few env vars to point to the mock scripts and base dir + +``` +BASE_DIR=/tmp/images/ +PATH=$PATH:`pwd`/mock/bin/ +``` + +Edit response to commands in `mock/bin/*` diff --git a/src/web/create_disk.py b/src/web/create_disk.py new file mode 100644 index 00000000..2958c69d --- /dev/null +++ b/src/web/create_disk.py @@ -0,0 +1,45 @@ +from machfs import Volume, Folder, File + +from settings import * + + +# Build a cd and attempt to fix resource forks if known +def make_cd(file_path, file_type, file_creator): + with open(file_path, "rb") as f: + file_bytes = f.read() + file_name = file_path.split('/')[-1] + file_suffix = file_name.split('.')[-1] + + if file_type is None and file_creator is None: + if file_suffix.lower() == 'sea': + file_type = '.sea' + file_creator = 'APPL' + + v = Volume() + v.name = "TestName" + + v['Folder'] = Folder() + + v['Folder'][file_name] = File() + v['Folder'][file_name].data = file_bytes + v['Folder'][file_name].rsrc = b'' + if not (file_type is None and file_creator is None): + v['Folder'][file_name].type = bytearray(file_type) + v['Folder'][file_name].creator = bytearray(file_creator) + + padding = (len(file_bytes) % 512) + (512 * 50) + print("mod", str(len(file_bytes) % 512)) + print("padding " + str(padding)) + print("len " + str(len(file_bytes))) + print("total " + str(len(file_bytes) + padding)) + with open(base_dir + 'test.hda', 'wb') as f: + flat = v.write( + size=len(file_bytes) + padding, + align=512, # Allocation block alignment modulus (2048 for CDs) + desktopdb=True, # Create a dummy Desktop Database to prevent a rebuild on boot + bootable=False, # This requires a folder with a ZSYS and a FNDR file + startapp=('Folder', file_name), # Path (as tuple) to an app to open at boot + ) + f.write(flat) + + return base_dir + 'test.hda' diff --git a/src/web/file_cmds.py b/src/web/file_cmds.py new file mode 100644 index 00000000..415735a1 --- /dev/null +++ b/src/web/file_cmds.py @@ -0,0 +1,64 @@ +import fnmatch +import os +import subprocess +import time + +from ractl_cmds import attach_image +from settings import * +valid_file_types = ['*.hda', '*.iso', '*.cdr'] +valid_file_types = r'|'.join([fnmatch.translate(x) for x in valid_file_types]) + + +def create_new_image(file_name, type, size): + if file_name == "": + file_name = "new_image." + str(int(time.time())) + "." + type + else: + file_name = file_name + "." + type + + return subprocess.run(["dd", "if=/dev/zero", "of=" + base_dir + file_name, "bs=1M", "count=" + size], + capture_output=True) + + +def delete_image(file_name): + full_path = base_dir + file_name + if os.path.exists(full_path): + os.remove(full_path) + return True + else: + return False + + +def unzip_file(file_name): + import zipfile + with zipfile.ZipFile(base_dir + file_name, 'r') as zip_ref: + zip_ref.extractall(base_dir) + return True + +def rascsi_service(action): + # start/stop/restart + return subprocess.run(["sudo", "/bin/systemctl", action, "rascsi.service"]).returncode == 0 + + +def download_file_to_iso(scsi_id, url): + import urllib.request + file_name = url.split('/')[-1] + tmp_ts = int(time.time()) + tmp_dir = "/tmp/" + str(tmp_ts) + "/" + os.mkdir(tmp_dir) + tmp_full_path = tmp_dir + file_name + iso_filename = base_dir + file_name + ".iso" + + urllib.request.urlretrieve(url, tmp_full_path) + # iso_filename = make_cd(tmp_full_path, None, None) # not working yet + iso_proc = subprocess.run(["genisoimage", "-hfs", "-o", iso_filename, tmp_full_path], capture_output=True) + if iso_proc.returncode != 0: + return iso_proc + return attach_image(scsi_id, iso_filename, "cd") + + +def download_image(url): + import urllib.request + file_name = url.split('/')[-1] + full_path = base_dir + file_name + + urllib.request.urlretrieve(url, full_path) diff --git a/src/web/mock/bin/journalctl b/src/web/mock/bin/journalctl new file mode 100755 index 00000000..69e33536 --- /dev/null +++ b/src/web/mock/bin/journalctl @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +# Mock responses to rascsi-web +case $1 in + -n) + echo "logs $*" + ;; + + **) + echo "default" + ;; +esac diff --git a/src/web/mock/bin/rasctl b/src/web/mock/bin/rasctl new file mode 100755 index 00000000..c414d9b1 --- /dev/null +++ b/src/web/mock/bin/rasctl @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +# Mock responses to rascsi-web +case $1 in + -f) + echo "logs here" + ;; + + **) + echo "default" + ;; +esac diff --git a/src/web/mock/bin/systemctl b/src/web/mock/bin/systemctl new file mode 100755 index 00000000..9cdfa631 --- /dev/null +++ b/src/web/mock/bin/systemctl @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +# Mock responses to rascsi-web +case $1 in + is-active) + echo "is-active" + ;; + + **) + echo "default" + ;; +esac diff --git a/src/web/pi_cmds.py b/src/web/pi_cmds.py new file mode 100644 index 00000000..26f13086 --- /dev/null +++ b/src/web/pi_cmds.py @@ -0,0 +1,20 @@ +import subprocess + + +def rascsi_service(action): + # start/stop/restart + return subprocess.run(["sudo", "/bin/systemctl", action, "rascsi.service"]).returncode == 0 + + +def reboot_pi(): + return subprocess.run(["sudo", "reboot"]).returncode == 0 + + +def shutdown_pi(): + return subprocess.run(["sudo", "shutdown", "-h", "now"]).returncode == 0 + + +def running_version(): + ra_web_version = subprocess.run(["git", "rev-parse", "HEAD"], capture_output=True).stdout.decode("utf-8").strip() + pi_version = subprocess.run(["uname", "-a"], capture_output=True).stdout.decode("utf-8").strip() + return ra_web_version + " " + pi_version diff --git a/src/web/ractl_cmds.py b/src/web/ractl_cmds.py new file mode 100644 index 00000000..38614983 --- /dev/null +++ b/src/web/ractl_cmds.py @@ -0,0 +1,98 @@ +import fnmatch +import os +import subprocess +import re + +from settings import * +valid_file_types = ['*.hda', '*.iso', '*.cdr', '*.zip'] +valid_file_types = r'|'.join([fnmatch.translate(x) for x in valid_file_types]) +# List of SCSI ID's you'd like to exclude - eg if you are on a Mac, the System is usually 7 +EXCLUDE_SCSI_IDS = [7] + + +def is_active(): + process = subprocess.run(["systemctl", "is-active", "rascsi"], capture_output=True) + return process.stdout.decode("utf-8").strip() == "active" + + +def list_files(): + files_list = [] + for path, dirs, files in os.walk(base_dir): + # Only list valid file types + files = [f for f in files if re.match(valid_file_types, f)] + files_list.extend([ + (os.path.join(path, file), + # TODO: move formatting to template + '{:,.0f}'.format(os.path.getsize(os.path.join(path, file)) / float(1 << 20)) + " MB") + for file in files]) + return files_list + + +def get_valid_scsi_ids(devices): + invalid_list = EXCLUDE_SCSI_IDS.copy() + for device in devices: + if device['file'] != "NO MEDIA" and device['file'] != "-": + invalid_list.append(int(device['id'])) + + valid_list = list(range(8)) + for id in invalid_list: + valid_list.remove(id) + valid_list.reverse() + + return valid_list + + +def get_type(scsi_id): + return list_devices()[int(scsi_id)]["type"] + + +def attach_image(scsi_id, image, type): + if type == "cd" and get_type(scsi_id) == "SCCD": + return insert(scsi_id, image) + else: + return subprocess.run(["rasctl", "-c", "attach", "-t", type, "-i", scsi_id, "-f", image], capture_output=True) + + +def detach_by_id(scsi_id): + return subprocess.run(["rasctl", "-c" "detach", "-i", scsi_id], capture_output=True) + + +def disconnect_by_id(scsi_id): + return subprocess.run(["rasctl", "-c", "disconnect", "-i", scsi_id], capture_output=True) + + +def eject_by_id(scsi_id): + return subprocess.run(["rasctl", "-i", scsi_id, "-c", "eject"]) + + +def insert(scsi_id, image): + return subprocess.run(["rasctl", "-i", scsi_id, "-c", "insert", "-f", image], capture_output=True) + + +def rascsi_service(action): + # start/stop/restart + return subprocess.run(["sudo", "/bin/systemctl", action, "rascsi.service"]).returncode == 0 + + +def list_devices(): + device_list = [] + for id in range(8): + device_list.append({"id": str(id), "un": "-", "type": "-", "file": "-"}) + output = subprocess.run(["rasctl", "-l"], capture_output=True).stdout.decode("utf-8") + for line in output.splitlines(): + # Valid line to process, continue + if not line.startswith("+") and \ + not line.startswith("| ID |") and \ + (not line.startswith("No device is installed.") or line.startswith("No images currently attached.")) \ + and len(line) > 0: + line.rstrip() + device = {} + segments = line.split("|") + if len(segments) > 4: + idx = int(segments[1].strip()) + device_list[idx]["id"] = str(idx) + device_list[idx]['un'] = segments[2].strip() + device_list[idx]['type'] = segments[3].strip() + device_list[idx]['file'] = segments[4].strip() + + return device_list diff --git a/src/web/requirements.txt b/src/web/requirements.txt new file mode 100644 index 00000000..64d25bb4 --- /dev/null +++ b/src/web/requirements.txt @@ -0,0 +1,12 @@ +click==7.1.2 +Flask==1.1.2 +itsdangerous==1.1.0 +Jinja2==2.11.2 +machfs==1.2.4 +macresources==1.2 +MarkupSafe==1.1.1 +rsrcfork==1.8.0 +waitress==1.4.4 +Werkzeug==1.0.1 +zope.event==4.5.0 +zope.interface==5.1.2 diff --git a/src/web/service-infra/502.html b/src/web/service-infra/502.html new file mode 100644 index 00000000..f40d9ca8 --- /dev/null +++ b/src/web/service-infra/502.html @@ -0,0 +1,14 @@ + + + RaSCSI-web is Starting + + + + +
+

RaSCSI Web is starting....

+

This page will automatically refresh.

+

First boot and upgrades can take a second to resolve dependancies.

+

If you're seeing this page for over a minute please check the logs at sudo journalctl -f

+
+ \ No newline at end of file diff --git a/src/web/service-infra/nginx-default.conf b/src/web/service-infra/nginx-default.conf new file mode 100644 index 00000000..bffa96cc --- /dev/null +++ b/src/web/service-infra/nginx-default.conf @@ -0,0 +1,12 @@ +# /etc/nginx/sites-available/default +# Simple proxy_pass for RaSCSI-web +server { + location / { + proxy_pass http://localhost:8080; + } + + error_page 502 /502.html; + location = /502.html { + root /var/www/html/; + } +} \ No newline at end of file diff --git a/src/web/service-infra/rascsi-web.service b/src/web/service-infra/rascsi-web.service new file mode 100644 index 00000000..24d667a2 --- /dev/null +++ b/src/web/service-infra/rascsi-web.service @@ -0,0 +1,14 @@ +[Unit] +Description=RaSCSI-Web service +After=network.target + +[Service] +Type=simple +Restart=always +ExecStart=/home/pi/RASCSI/src/web/start.sh +StandardOutput=syslog +StandardError=syslog +SyslogIdentifier=RASCSIWEB + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/src/web/settings.py b/src/web/settings.py new file mode 100644 index 00000000..24acee41 --- /dev/null +++ b/src/web/settings.py @@ -0,0 +1,4 @@ +import os + +base_dir = os.getenv('BASE_DIR', "/home/pi/images/") +MAX_FILE_SIZE = os.getenv('MAX_FILE_SIZE', 1024 * 1024 * 1024 * 2) # 2gb diff --git a/src/web/start.sh b/src/web/start.sh new file mode 100755 index 00000000..ee0b1b37 --- /dev/null +++ b/src/web/start.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash +set -e +# set -x # Uncomment to Debug + +cd $(dirname $0) +# verify packages installed +ERROR=0 +if ! command -v genisoimage &> /dev/null ; then + echo "genisoimage could not be found" + echo "Run 'sudo apt install genisoimage' to fix." + ERROR=1 +fi +if ! command -v python3 &> /dev/null ; then + echo "python3 could not be found" + echo "Run 'sudo apt install python3' to fix." + ERROR=1 +fi +if ! python3 -m venv --help &> /dev/null ; then + echo "venv could not be found" + echo "Run 'sudo apt install python3-venv' to fix." + ERROR=1 +fi +if ! command -v unzip &> /dev/null ; then + echo "unzip could not be found" + echo "Run 'sudo apt install unzip' to fix." + ERROR=1 +fi +if [ $ERROR = 1 ] ; then + echo + echo "Fix errors and re-run ./start.sh" + exit 1 +fi + +if ! test -e venv; then + echo "Creating python venv for web server" + python3 -m venv venv + echo "Activating venv" + source venv/bin/activate + echo "Installing requirements.txt" + pip install -r requirements.txt + git rev-parse HEAD > current +fi + +source venv/bin/activate + +# Detect if someone updates - we need to re-run pip install. +if ! test -e current; then + git rev-parse > current +else + if [ "$(cat current)" != "$(git rev-parse HEAD)" ]; then + echo "New version detected, updating requirements.txt" + pip install -r requirements.txt + git rev-parse HEAD > current + fi +fi + +echo "Starting web server..." +python3 web.py \ No newline at end of file diff --git a/src/php/rascsi_styles.css b/src/web/static/style.css similarity index 68% rename from src/php/rascsi_styles.css rename to src/web/static/style.css index c98b6044..9d5dd136 100644 --- a/src/php/rascsi_styles.css +++ b/src/web/static/style.css @@ -21,8 +21,24 @@ a { text-decoration: none; } +form { + display: inline; +} + table, tr, td { border: 1px solid black; border-collapse:collapse; margin: none; } + +.error { + color: white; + font-size:20px; + background-color:red; +} + +.message { + color: white; + font-size:20px; + background-color:green; +} \ No newline at end of file diff --git a/src/web/templates/base.html b/src/web/templates/base.html new file mode 100644 index 00000000..ddc9dc40 --- /dev/null +++ b/src/web/templates/base.html @@ -0,0 +1,24 @@ + +RaSCSI Control Page + + +
+
+ {% block header %}{% endblock %} +
+
+ {% for category, message in get_flashed_messages(with_categories=true) %} + {% if category == "stdout" or category == "stderr" %} +
{{message}}
+ {% else %} +
{{ message }}
+ {% endif %} + {% endfor %} +
+
+ {% block content %}{% endblock %} +
+ +
\ No newline at end of file diff --git a/src/web/templates/index.html b/src/web/templates/index.html new file mode 100644 index 00000000..a11fab57 --- /dev/null +++ b/src/web/templates/index.html @@ -0,0 +1,213 @@ +{% extends "base.html" %} + +{% block header %} +{% if active %} +Service Running +{% else %} +Service Stopped +{% endif %} + + + + + + +
+ +

RaSCSI - 68kmla Edition

+
+
+ {% endblock %} + + {% block content %} +

Current RaSCSI Configuration

+ + + + + + + + + {% for device in devices %} + + {% if device.id != "7" %} + + + + + {% else %} + + + + + {% endif %} + + {% endfor %} + +
IDTypeFileAction
{{device.id}}{{device.type}}{{device.file}} + {% if device.type == "SCCD" and device.file != "NO MEDIA" %} + + + + + {% else %} +
+ + +
+ {% endif %} +
{{device.id}}-Host Machine-
+ +

Image File Management

+ + + + + + + + {% for file in files %} + + + + + + {% endfor %} + +
FileSizeActions
{{file[0].replace(base_dir, '')}} +
+ + +
+
+
+ + + +
+
+ + +
+ {% if file[0].endswith('.zip') or file[0].endswith('.ZIP') %} +
+ + +
+ {% endif %} +
+ +
+ +

Upload File

+

Uploads file to {{base_dir}}. Max file size is set to {{max_file_size / 1024 /1024 }}MB

+ + + + +
+
+ + + +
+
+ +
+ +

Download File from Web

+

Given a URL, download that file to the {{base_dir}}

+ + + + +
+
+ + + +
+
+ +
+ +

Download File from web and create HFS CD

+

Given a URL this will download a file, create a HFS iso, and mount it on the device id given.

+ + + + +
+ +
+ + + + +
+
+ +
+

Create Empty Disk Image File

+ + + + +
+
+ + + + + + + +
+
+ +
+ +

Raspberry Pi Operations

+ + + + + + + +
+
+ +
+
+
+ +
+
+
+ +
+
+{% endblock %} + +{% block footer %} +
{{version}}
+
Logs
+{% endblock %} \ No newline at end of file diff --git a/src/web/web.py b/src/web/web.py new file mode 100644 index 00000000..f2965a7a --- /dev/null +++ b/src/web/web.py @@ -0,0 +1,206 @@ +import os + +from flask import Flask, render_template, request, flash, url_for, redirect, send_file +from werkzeug.utils import secure_filename + +from file_cmds import create_new_image, download_file_to_iso, delete_image, unzip_file, download_image +from pi_cmds import shutdown_pi, reboot_pi, running_version, rascsi_service +from ractl_cmds import attach_image, list_devices, is_active, list_files, detach_by_id, eject_by_id, get_valid_scsi_ids +from settings import * + +app = Flask(__name__) + +@app.route('/') +def index(): + devices = list_devices() + scsi_ids = get_valid_scsi_ids(devices) + return render_template('index.html', + devices=devices, + active=is_active(), + files=list_files(), + base_dir=base_dir, + scsi_ids=scsi_ids, + max_file_size=MAX_FILE_SIZE, + version=running_version()) + +@app.route('/logs') +def logs(): + import subprocess + lines = request.args.get('lines') or "100" + process = subprocess.run(["journalctl", "-n", lines], capture_output=True) + + if process.returncode == 0: + headers = { 'content-type':'text/plain' } + return process.stdout.decode("utf-8"), 200, headers + else: + flash(u'Failed to get logs') + flash(process.stdout.decode("utf-8"), 'stdout') + flash(process.stderr.decode("utf-8"), 'stderr') + return redirect(url_for('index')) + + +@app.route('/scsi/attach', methods=['POST']) +def attach(): + file_name = request.form.get('file_name') + scsi_id = request.form.get('scsi_id') + + # Validate image type by suffix + if file_name.lower().endswith('.iso') or file_name.lower().endswith('iso'): + image_type = "cd" + elif file_name.lower().endswith('.hda'): + image_type = "hd" + else: + flash(u'Unknown file type. Valid files are .iso, .hda, .cdr', 'error') + return redirect(url_for('index')) + + process = attach_image(scsi_id, file_name, image_type) + if process.returncode == 0: + flash('Attached '+ file_name + " to scsi id " + scsi_id + "!") + return redirect(url_for('index')) + else: + flash(u'Failed to attach '+ file_name + " to scsi id " + scsi_id + "!", 'error') + flash(process.stdout.decode("utf-8"), 'stdout') + flash(process.stderr.decode("utf-8"), 'stderr') + return redirect(url_for('index')) + + +@app.route('/scsi/detach', methods=['POST']) +def detach(): + scsi_id = request.form.get('scsi_id') + process = detach_by_id(scsi_id) + if process.returncode == 0: + flash("Detached scsi id " + scsi_id + "!") + return redirect(url_for('index')) + else: + flash(u"Failed to detach scsi id " + scsi_id + "!", 'error') + flash(process.stdout, 'stdout') + flash(process.stderr, 'stderr') + return redirect(url_for('index')) + + +@app.route('/scsi/eject', methods=['POST']) +def eject(): + scsi_id = request.form.get('scsi_id') + process = eject_by_id(scsi_id) + if process.returncode == 0: + flash("Ejected scsi id " + scsi_id + "!") + return redirect(url_for('index')) + else: + flash(u"Failed to eject scsi id " + scsi_id + "!", 'error') + flash(process.stdout, 'stdout') + flash(process.stderr, 'stderr') + return redirect(url_for('index')) + + +@app.route('/pi/reboot', methods=['POST']) +def restart(): + reboot_pi() + flash("Restarting...") + return redirect(url_for('index')) + + +@app.route('/rascsi/restart', methods=['POST']) +def rascsi_restart(): + rascsi_service("restart") + flash("Restarting RaSCSI Service...") + return redirect(url_for('index')) + + +@app.route('/pi/shutdown', methods=['POST']) +def shutdown(): + shutdown_pi() + flash("Shutting down...") + return redirect(url_for('index')) + + +@app.route('/files/download_to_iso', methods=['POST']) +def download_file(): + scsi_id = request.form.get('scsi_id') + url = request.form.get('url') + process = download_file_to_iso(scsi_id, url) + if process.returncode == 0: + flash("File Downloaded") + return redirect(url_for('index')) + else: + flash(u"Failed to download file", 'error') + flash(process.stdout, 'stdout') + flash(process.stderr, 'stderr') + return redirect(url_for('index')) + + +@app.route('/files/download_image', methods=['POST']) +def download_img(): + url = request.form.get('url') + # TODO: error handling + download_image(url) + flash("File Downloaded") + return redirect(url_for('index')) + + +@app.route('/files/upload', methods=['POST']) +def upload_file(): + if 'file' not in request.files: + flash('No file part', 'error') + return redirect(url_for('index')) + file = request.files['file'] + if file: + filename = secure_filename(file.filename) + file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename)) + return redirect(url_for('index', filename=filename)) + + +@app.route('/files/create', methods=['POST']) +def create_file(): + file_name = request.form.get('file_name') + size = request.form.get('size') + type = request.form.get('type') + + process = create_new_image(file_name, type, size) + if process.returncode == 0: + flash("Drive created") + return redirect(url_for('index')) + else: + flash(u"Failed to create file", 'error') + flash(process.stdout, 'stdout') + flash(process.stderr, 'stderr') + return redirect(url_for('index')) + + +@app.route('/files/download', methods=['POST']) +def download(): + image = request.form.get('image') + return send_file(base_dir + image, as_attachment=True) + + +@app.route('/files/delete', methods=['POST']) +def delete(): + image = request.form.get('image') + if delete_image(image): + flash("File " + image + " deleted") + return redirect(url_for('index')) + else: + flash(u"Failed to Delete " + image, 'error') + return redirect(url_for('index')) + + +@app.route('/files/unzip', methods=['POST']) +def unzip(): + image = request.form.get('image') + + if unzip_file(image): + flash("Unzipped file " + image) + return redirect(url_for('index')) + else: + flash(u"Failed to unzip " + image, 'error') + return redirect(url_for('index')) + + +if __name__ == "__main__": + app.secret_key = 'rascsi_is_awesome_insecure_secret_key' + app.config['SESSION_TYPE'] = 'filesystem' + app.config['UPLOAD_FOLDER'] = base_dir + os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True) + app.config['MAX_CONTENT_LENGTH'] = MAX_FILE_SIZE + + from waitress import serve + serve(app, host="0.0.0.0", port=8080)