Work in progress: export vm and imported submenu

This commit is contained in:
olevole
2018-03-09 17:25:25 +03:00
parent cb8ca2d937
commit bd69b5a1f9
11 changed files with 186 additions and 59 deletions

View File

@@ -362,6 +362,12 @@ class ClonOS
case 'imageImport':
echo json_encode($this->imageImport());
return;break;
case 'imageExport':
echo json_encode($this->imageExport());
return;break;
case 'imageRemove':
echo json_encode($this->imageRemove());
return;break;
/* case 'saveHelperValues':
echo json_encode($this->saveHelperValues());
@@ -489,6 +495,7 @@ class ClonOS
'removebase'=>'Removing',
'world'=>'Compiling',
'repo'=>'Fetching',
'imgremove'=>'Removing',
);
$res=array();
@@ -580,6 +587,7 @@ class ClonOS
$stat_array['bclone']=&$stat_array['jclone'];
$stat_array['removesrc']=&$stat_array['jremove'];
$stat_array['removebase']=&$stat_array['jremove'];
$stat_array['imgremove']=&$stat_array['jremove'];
if(!empty($obj)) foreach($obj as $key=>$task)
@@ -2852,6 +2860,17 @@ class ClonOS
return $val;
}
function imageExport()
{
// cbsd jexport jname=XXX dstdir=<path_to_imported_dir>
$form=$this->form;
$jname=$form['id'];
if(empty($jname)) $this->messageError('Jname is incorrect in export command! Is «'.$jname.'».');
$cmd='cbsd jexport gensize=1 jname='.$jname.' dstdir='.$this->media_import;
$res=$this->cbsd_cmd('task owner='.$this->_user_info['username'].' mode=new /usr/local/bin/'.$cmd);
return $res;
}
function imageImport()
{
$form=$this->form;
@@ -2880,42 +2899,15 @@ class ClonOS
return $res;
}
/*
По опциям вот так дела обстоят:
function imageRemove()
{
$form=$this->form;
$cmd='cbsd imgremove path='.$this->media_import.' img='.$form['jname'];
$res=$this->cbsd_cmd('task owner='.$this->_user_info['username'].' mode=new /usr/local/bin/'.$cmd);
return $res;
}
Образ - это архив окружения. По-умолчанию, если ты делаешь import на файл образа, он восстановит его с теми же параметрами что было при export.
В CBSD можно рулить тремя параметрами, которые можно переназначить при import, это:
- имя окружения ( $jname ). Если у тебя образ nginx.img и он создан для окружения nginx, то вторично ты из него не сможешь развернуть, если не переназначишь новое имя, тк jname уникально
- IP адрес. Тут тоже можно переназначить IP, чтобы небыло конфликтов с оригиналом или уже развернутым из этого окружения образа
- Имя хоста (FQDN). Это nginx.my.domain например.
В командной строчке это аргументы
cbsd jimport [new_jname=XXX|new_ip4_addr=x.y.a.b|new_host_hostname=XXX.YYY.NNN] <path-to-img>
Я форму вижу вот таким образом, учитывая, что ты хидер можешь читать, это возможно:
пользователь мышкой кликает на образ в списке, тем самым маркируя его (или снимая маркер на импорт). Если маркет ставится, появляются три поля:
Новое имя контейнера: [$jname] ($jname)
Новый IP адрес : [$ip4_addr] ($ip4_addr)
Новый FQDN: [$host_hostname]
Где $jname и $host_name и $ip4_addr ты вычитываешь из старого заголовка и подставляешь сюда.
Можно попробовать еще круче сделать, но это возможно запарно:
при маркере, перед заполнением $jname проверить, если ли уже такой контейнер в системе. Если есть, то поле должно быть пустое
Если пользователь не меняет данные, можно делать
cbsd jimport <path.img>
если меняет любой из них (или все), то аргументы можно дописывать
cbsd jmport new_jname=newjail1 <path.img>
cbsd jmport new_jname=newjail1 new_ip4_addr=10.10.10.10 <path.img>
*/
}

View File

@@ -555,7 +555,10 @@ tr.busy .op-settings span, /*.icon-cog*/
tr.busy .op-reboot span, /*.icon-cancel,*/
tr.busy .op-del span, /*.icon-desktop,*/
tr.busy .op-update span, /*.icon-desktop,*/
tr.busy .op-vnc span { /*.icon-arrows-cw {*/
tr.busy .op-vnc span,
tr.busy .icon-export,
tr.busy .icon-download,
#impslist tr.busy .icon-cancel { /*.icon-arrows-cw {*/
display:none;
}
td.jstatus,
@@ -581,6 +584,19 @@ tr.s-off td.jstatus {
background-color:Seashell;
}
/* мегахак — это чтобы крутился прогресс. В других таблицах он реализован по-другому */
#impslist tr.busy .ops span:first-child {
display:block;
text-align:left;
margin-left:7px;
}
#impslist tr.busy .ops span:first-child::before {
content:'\e839';
animation:spin 2s infinite linear;
}
/* мегахак конец */
tr.maintenance .ops span,
tr.maintenance .op-settings span,
tr.maintenance .op-reboot span,

View File

@@ -20,7 +20,18 @@ if(isset($res['id']) && $res['id']>0)
header('Content-Length: '.filesize($file));
header("Pragma: no-cache");
header("Expires: 0");
readfile($file);
$chunkSize = 1024 * 1024;
$handle = fopen($file, 'rb');
while (!feof($handle))
{
$buffer = fread($handle, $chunkSize);
echo $buffer;
ob_flush();
flush();
}
fclose($handle);
exit;
}

View File

@@ -27,6 +27,7 @@ var clonos={
'repo':{stat:['Fetch','Fetching','Fetched'],cmd:'repoCompile'},
'removesrc':{stat:['Remove','Removing','Removed'],cmd:'srcRemove'},
'removebase':{stat:['Remove','Removing','Removed'],cmd:'baseRemove'},
'imgremove':{stat:['Remove','Removing','Removed'],cmd:'imageRemove'},
},
start:function()
@@ -1630,10 +1631,8 @@ var clonos={
case 'jddm-clone':
case 'jddm-rename':
case 'jddm-helpers':
this.DDMenuSelect(elid);
return;break;
case 'jddm-export':
alert('Экспортируем! :)');
this.DDMenuSelect(elid);
return;break;
}
}
@@ -1700,6 +1699,11 @@ var clonos={
this.vmTemplateRemove(trid);
return;
}
if(tblid=='impslist')
{
this.imageRemove(trid);
return;
}
alert(tblid);
return;break;
case 'icon-arrows-cw':
@@ -2087,6 +2091,10 @@ var clonos={
location.href='/jailscontainers/'+id+'/';
return;
break;
case 'jddm-export':
this.imageExport(id,table_id);
return;
break;
}
break;
case 'bhyveslist':
@@ -2197,6 +2205,16 @@ var clonos={
this.dialogShow1(dialog,'edit');
},
imageExport:function(id,tblid)
{
var mode='imageExport';
var posts=[{'name':'tbl_id','value':tblid},{'name':'id','value':id}]; //,{'name':'dialog','value':'image-import'}
this.loadData(mode,$.proxy(this.onImageExport,this),posts);
},
onImageExport:function(data)
{
},
imageImport:function(id,tblid)
{
var mode='getImportedImageInfo';
@@ -2222,6 +2240,18 @@ var clonos={
{
this.dialogClose();
},
imageRemove:function(id)
{
var c=confirm(this.translate('You want to delete image «'+id+'»! Are you sure?'));
if(!c) return;
var posts=[{'name':'jname','value':id}];
this.loadData('imageRemove',$.proxy(this.onJailStart,this),posts,false);
},
onImageRemove:function(data)
{
debugger;
},
dataReload:function()
{
@@ -2660,11 +2690,17 @@ var clonos={
case 'repo':
if(status==1)
{
/*
if(cmd=='jexport')
{
this.enableWait(id);
}
*/
if(isset(data.data))
{
this.addNewJail(data,cmd);
}
if(['srcup','world','repo'].indexOf(cmd)!=-1)
if(['srcup','world','repo','jexport'].indexOf(cmd)!=-1)
{
this.enableWait(id);
}
@@ -2678,6 +2714,7 @@ var clonos={
case 'bremove':
case 'removesrc':
case 'removebase':
case 'imgremove':
if(status==1)
{
$('#'+this.dotEscape(id)).removeClass('s-on').addClass('s-off').addClass('busy');
@@ -2724,7 +2761,7 @@ var clonos={
{
var cmd=data.cmd;
if(['srcup','repo','world'].indexOf(cmd)!=-1)
if(['srcup','repo','world','jexport'].indexOf(cmd)!=-1)
{
$('#'+this.dotEscape(id))
.removeClass('s-off').removeClass('busy').removeClass('maintenance')
@@ -2763,6 +2800,7 @@ var clonos={
if(['bcreate','bclone'].indexOf(cmd)!=-1) table='bhyveslist';
if(['srcup'].indexOf(cmd)!=-1) table='srcslist';
if(['repo','world'].indexOf(cmd)!=-1) table='baseslist';
if(['jexport'].indexOf(cmd)!=-1) table='impslist';
if(isset(data.data))
{
@@ -2770,7 +2808,7 @@ var clonos={
data.data['jstatus']=this.translate(this.commands[cmd]['stat'][1]);
if(!isset(data.data['id'])) data.data['id']=data['id'];
for(n in data.data)
html=html.replace(new RegExp('#'+n+'#','g'),data.data[n]);
html=html.replace(new RegExp('#'+n+'#','g'),this.translate(data.data[n]));
}
var el=$('#'+this.dotEscape(id));

View File

@@ -30,6 +30,7 @@ clonos.lang={
"Created":"Создано",
"Starting":"Запускается",
"Exporting":"Экспортируется",
"Exported":"Экспортировано",
"Cloning":"Клонируется",
"Cloned":"Клонировано",
"Restarting":"Перезапускаем",
@@ -54,6 +55,9 @@ clonos.lang={
"end":"конец",
"jail":"клетка",
"bhyve":"виртуальная машина",
"This name is already exists!":"Такое имя уже существует!",
"Passwords must match!":"Пароли должны совпадать!",

View File

@@ -79,6 +79,7 @@ $lang=array(
'Create'=>'Создать',
'Cancel'=>'Отменить',
'Save'=>'Сохранить',
'Download'=>'Скачать',
'Delete'=>'Удалить',
'Protected jail'=>'Запрет на удаление',
@@ -151,5 +152,7 @@ $lang=array(
'jail'=>'клетка',
'bhyve'=>'виртуальная машина',
'Since imported name already exist, we are change it'=>'Поскольку оригинальное имя уже существует, мы поменяли его <br />на свободное',
//''=>'',
);

Binary file not shown.

View File

@@ -17,35 +17,74 @@ $images=$this->getImportedImages();
$html='';
$nth=0;
$num=$nth & 1;
$html_tpl='';
$hres=$this->getTableChunk('impslist','tbody');
if($hres!==false)
{
$html_tmp=$hres[1];
$html_tmp=replaceVars($html_tmp,array(
'deltitle'=>' title="'.$this->translate('Delete').'"',
'dnldtitle'=>' title="'.$this->translate('Download').'"',
'imptitle'=>' title="'.$this->translate('Create').'"')
);
$html_tpl_1=$html_tmp;
}
if(!empty($images)) foreach($images as $item)
{
if(!isset($item['type'])) $item['type']='unknown';
$hres=$this->getTableChunk('impslist','tbody');
//$hres=$this->getTableChunk('impslist','tbody');
if($hres!==false)
{
/*
$html_tmp=$hres[1];
$vars=array(
'nth-num'=>'nth'.$num,
'impid'=>$item['name'],
'impname'=>$item['name'],
//'imppath'=>$item['path'],
'imptype'=>$this->translate($item['type']),
$html_tmp=replaceVars($html_tmp,array(
'deltitle'=>' title="'.$this->translate('Delete').'"',
'dnldtitle'=>' title="'.$this->translate('Download').'"',
'imptitle'=>' title="'.$this->translate('Create').'"',
'imptitle'=>' title="'.$this->translate('Create').'"')
);
$html_tpl=$html_tmp;
*/
$html_tpl=$html_tmp;
$filename=$this->media_import.$item['name'];
$sizefilename=$filename.'.size';
if(file_exists($sizefilename))
{
$size=file_get_contents($sizefilename);
}else{
$size=filesize($filename);
}
$filesize=$this->fileSizeConvert($size,1024,true);
$vars=array(
'nth-num'=>'nth'.$num,
'id'=>$item['name'],
'jname'=>$item['name'],
'impsize'=>$filesize,
'jstatus'=>'',
'imptype'=>$this->translate($item['type']),
);
foreach($vars as $var=>$val)
$html_tmp=str_replace('#'.$var.'#',$val,$html_tmp);
$html_tpl=str_replace('#'.$var.'#',$val,$html_tpl);
// $html_tmp=str_replace('#'.$var.'#',$val,$html_tmp);
$html.=$html_tmp;
$html.=$html_tpl;
}
}
function replaceVars($tpl,$vars)
{
foreach($vars as $var=>$val)
$tpl=str_replace('#'.$var.'#',$val,$tpl);
return $tpl;
}
echo json_encode(array(
'tbody'=>$html,
'error'=>false,
'func'=>'fillTable',
'id'=>'impslist',
'template'=>$html_tpl_1,
));

View File

@@ -0,0 +1,21 @@
<?php
$clonos->useDialogs(array(
'jail-import',
'image-import',
// 'jail-settings-config-menu',
));
?>
<h1>Imported images:</h1>
<span class="top-button icon-upload id:jail-import">Import</span></p>
<table class="tsimple" id="impslist" width="100%">
<thead>
<td class="keyname">Image name</td>
<td class="txtcenter wdt-120 impsize">Size</td>
<td class="txtleft wdt-150">Type</td>
<th class="txtcenter wdt-120">Status</th>
<td class="wdt-80">Action</td>
</thead>
<tbody></tbody>
</table>

View File

@@ -1,8 +1,10 @@
<tbody>
<tr id="#impid#">
<td class="txtleft">#impname#</td>
<tr id="#id#">
<td class="txtleft">#jname#</td>
<!-- <td class="txtleft wordwreck"><span class="max-100">#imppath#</span></td> -->
<td class="txtcenter">#impsize#</td>
<td class="txtleft">#imptype#</td>
<td class="jstatus">#jstatus#</td>
<td class="ops">
<span#imptitle# class="icon-export"></span>
<span#dnldtitle# class="icon-download"></span>

View File

@@ -12,8 +12,9 @@ $clonos->useDialogs(array(
<table class="tsimple" id="impslist" width="100%">
<thead>
<td class="keyname">Имя файла</td>
<!-- <td class="txtleft">Путь</td> -->
<td class="txtleft wdt-200">Тип файла</td>
<td class="txtcenter wdt-120 impsize">Размер</td>
<td class="txtleft wdt-150">Тип файла</td>
<th class="txtcenter wdt-120">Статус</th>
<td class="wdt-80">Действия</td>
</thead>
<tbody></tbody>