Skip to content

Commit

Permalink
Added Jupyter functionality for beta testing
Browse files Browse the repository at this point in the history
  • Loading branch information
zagganas committed Oct 12, 2021
1 parent 3c68da0 commit dbb13cd
Show file tree
Hide file tree
Showing 31 changed files with 1,694 additions and 48 deletions.
3 changes: 2 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ RUN curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packa
docker-php-ext-enable yaml.so && \
# Install RO-crates using pip3
# Install docker-tar-pusher using pip3
pip3 install rocrate dockertarpusher && \
# Install notebook for password hashing
pip3 install rocrate dockertarpusher notebook && \
# Create the web server folder and navigate to it
mkdir /app/web

Expand Down
2 changes: 1 addition & 1 deletion config/web.php
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@
$config['modules']['gii'] = [
'class' => 'yii\gii\Module',
// uncomment the following to add your IP if you are not connecting from localhost.
'allowedIPs' => ['127.0.0.1', '::1','195.251.63.2','2.84.147.146'],
// 'allowedIPs' => ['127.0.0.1', '::1','195.251.63.2','94.70.57.55','88.197.39.73'],
];
}

Expand Down
6 changes: 6 additions & 0 deletions controllers/AdministrationController.php
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,12 @@ public function actionViewPage($id)
return $this->render('view-page',['page'=>$page]);
}

public function actionJupyter()
{

return $this->render('jupyter');
}



}
366 changes: 366 additions & 0 deletions controllers/JupyterController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,366 @@
<?php
/************************************************************************************
*
* Copyright (c) 2018 Thanasis Vergoulis & Konstantinos Zagganas & Loukas Kavouras
* for the Information Management Systems Institute, "Athena" Research Center.
*
* This file is part of SCHeMa.
*
* SCHeMa is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SCHeMa is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SCHeMa. If not, see <https://www.gnu.org/licenses/>.
*
************************************************************************************/

/**
* The main SCHEMA Controller
*
* @author: Kostis Zagganas
* First Version: November 2018
*/

namespace app\controllers;

use Yii;
use yii\filters\AccessControl;
use yii\httpclient\Client;
use yii\web\Controller;
use app\models\Software;
use app\models\JupyterServer;
use app\models\JupyterImages;
use yii\helpers\Url;
use webvimark\modules\UserManagement\models\User;
use yii\filters\VerbFilter;


class JupyterController extends Controller
{

/**
* {@inheritdoc}
*/
public $freeAccess = false;
public function behaviors()
{
return [
'ghost-access'=> [
'class' => 'webvimark\modules\UserManagement\components\GhostAccessControl',
],
'access' => [
'class' => AccessControl::className(),
'only' => ['logout'],
'rules' => [
[
'actions' => ['logout'],
'allow' => true,
'roles' => ['@'],
],
],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'logout' => ['post'],
],
],
];
}
/**
* {@inheritdoc}
*/
public function actions()
{
return [
'error' => [
'class' => 'yii\web\ErrorAction',
],
'captcha' => [
'class' => 'yii\captcha\CaptchaAction',
'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null,
],
];
}

/**
* Displays the list of all available software
* along with buttons for running and editing software
*
* @return string
*/
public function actionIndex()
{
$username=User::getCurrentUser()['username'];
/*
* This piece of code gets the quotas from CLIMA
* when the platforms are available.
*
* In standalone mode, they are retrieved from the parameters.
*/

if (!Yii::$app->params['standalone'])
{
$projects=JupyterServer::getActiveProjects();
$projects=JupyterServer::matchServersWithProjects($projects);

}
else
{
$server=JupyterServer::find()->where(['active'=>true, 'created_by'=>$username])->one();
$projects=['default'=>['cpu'=> Yii::$app->params['standaloneResources']['maxCores'], 'memory'=>Yii::$app->params['standaloneResources']['maxRam'] ] ];
if (!empty($server))
{
$projects['default']['server']=$server;
}

}

$img=JupyterImages::find()->all();
$images=[];
foreach ($img as $i)
{
$images[$i->image]=$i->description;
}

return $this->render('index',['projects'=>$projects,'images'=>$images]);

}

public function actionStartServer($project)
{

$form_params =
[
'action' => URL::to(['jupyter/start-server', 'project'=>$project]),
'options' =>
[
'class' => 'jupyter_start_form',
'id'=> "jupyter_start_form"
],
'method' => 'POST'
];

if (!Yii::$app->params['standalone'])
{
/*
* Project does not exist. User is trying something illegal.
*/
$quotas=JupyterServer::getProjectQuotas($project);

if (empty($quotas))
{
return $this->render('project_error',['project'=>$project]);
}
}
else
{
/*
* Project not active in standalone mode, so there's no use searching.
*/
$quotas=['cores'=>Yii::$app->params['standaloneResources']['maxCores'],'ram'=>Yii::$app->params['standaloneResources']['maxRam'] ];
}

/*
* Server has already been activated. User is trying something illegal.
*/
$server=JupyterServer::find()->where(['active'=>true,'project'=>$project])->one();
if (!empty($server))
{
return $this->render('server_already_active');
}

$images=JupyterImages::find()->orderBy('description')->all();
$imageDrop=[];
foreach ($images as $image)
{
$imageDrop[$image->image]=$image->description;
}

$model = new JupyterServer;

if ($model->load(Yii::$app->request->post()) && $model->validate())
{
$model->cpu=$quotas['cores'];
$model->memory=$quotas['ram'];
$model->expires_on=$quotas['end_date'];
$model->project=$project;
$messages=$model->startServer();
$success=$messages[0];
$error=$messages[1];

if (!empty($error))
{
Yii::$app->session->setFlash('danger',$error);
}

if (!empty($success))
{
Yii::$app->session->setFlash('success',$success);
}

return $this->redirect(['jupyter/index']);
}

return $this->render('start_server',['model'=>$model, 'imageDrop'=>$imageDrop,'form_params' => $form_params]);

}
public function actionStopServer($project,$return='s')
{

$server=JupyterServer::find()->where(['active'=>true,'project'=>$project])->one();

if (empty($server))
{
return $this->render('server_already_stopped');
}

$messages=$server->stopServer();
$success=$messages[0];
$error=$messages[1];

if (!empty($error))
{
Yii::$app->session->setFlash('danger',$error);
}

if (!empty($success))
{
Yii::$app->session->setFlash('success',$success);
}
if ($return=='a')
{
return $this->redirect(['jupyter/active-servers']);
}
else
{
return $this->redirect(['jupyter/index']);
}

}

public function actionImageList()
{
if (!User::hasRole("Admin", $superAdminAllowed = true))
{
return $this->render('unauthorized');
}

$images=JupyterImages::find()->orderBy('description')->all();

return $this->render('image_list', ['images'=>$images]);
}

public function actionDeleteImage($id)
{
if (!User::hasRole("Admin", $superAdminAllowed = true))
{
return $this->render('unauthorized');
}

$image=JupyterImages::find()->where(['id'=>$id])->one();

if (empty($image))
{
return $this->render('image_not_found');
}
$name=$image->image;
$image->delete();

Yii::$app->session->setFlash('success',"Image $name deleted successufully");

$this->redirect(['jupyter/image-list']);
}

public function actionNewImage()
{
if (!User::hasRole("Admin", $superAdminAllowed = true))
{
return $this->render('unauthorized');
}

$form_params =
[
'action' => URL::to(['jupyter/new-image']),
'options' =>
[
'class' => 'jupyter_new_image_form',
'id'=> "jupyter_new_image_form"
],
'method' => 'POST'
];

$model=new JupyterImages;

if ($model->load(Yii::$app->request->post()) && $model->validate())
{
$model->save();

Yii::$app->session->setFlash('success',"Image added successufully");

$this->redirect(['jupyter/image-list']);
}

return $this->render('new_image',['model'=>$model,'form_params' => $form_params]);

}

public function actionEditImage($id)
{
if (!User::hasRole("Admin", $superAdminAllowed = true))
{
return $this->render('unauthorized');
}

$model=JupyterImages::find()->where(['id'=>$id])->one();

if (empty($model))
{
return $this->render('image_not_found');
}

$form_params =
[
'action' => URL::to(['jupyter/edit-image','id'=>$id]),
'options' =>
[
'class' => 'jupyter_edit_image_form',
'id'=> "jupyter_new_edit_form"
],
'method' => 'POST'
];

if ($model->load(Yii::$app->request->post()) && $model->validate())
{
$model->save();

Yii::$app->session->setFlash('success',"Image $model->image saved!");

$this->redirect(['jupyter/image-list']);
}

return $this->render('edit_image',['model'=>$model,'form_params' => $form_params]);

}

public function actionActiveServers()
{

if (!User::hasRole("Admin", $superAdminAllowed = true))
{
return $this->render('unauthorized');
}

$servers=JupyterServer::find()->where(['active'=>true])->all();

return $this->render('active_servers',['servers'=>$servers]);

}
}
Loading

0 comments on commit dbb13cd

Please sign in to comment.