Added volume info of UI.

This commit is contained in:
kunw 2016-10-25 12:44:27 +08:00
parent 60ae6fba1b
commit 811401f40e
10 changed files with 152 additions and 8 deletions

View File

@ -50,6 +50,7 @@ services:
volumes:
- ./common/config/ui/app.conf:/etc/ui/app.conf
- ./common/config/ui/private_key.pem:/etc/ui/private_key.pem
- /data:/harbor_storage
depends_on:
- log
logging:

62
src/ui/api/systeminfo.go Normal file
View File

@ -0,0 +1,62 @@
package api
import (
"net/http"
"path/filepath"
"syscall"
"github.com/vmware/harbor/src/common/api"
"github.com/vmware/harbor/src/common/dao"
"github.com/vmware/harbor/src/common/utils/log"
)
type SystemInfoApi struct {
api.BaseAPI
currentUserID int
isAdmin bool
}
const harbor_storage_path = "/harbor_storage"
type SystemInfo struct {
HarborStorage Storage `json:"harbor_storage"`
}
type Storage struct {
Total uint64 `json:"total"`
Free uint64 `json:"free"`
}
var systemInfo SystemInfo = SystemInfo{}
func (sia *SystemInfoApi) Prepare() {
sia.currentUserID = sia.ValidateUser()
var err error
sia.isAdmin, err = dao.IsAdminRole(sia.currentUserID)
if err != nil {
log.Errorf("Error occurred in IsAdminRole:%v", err)
sia.CustomAbort(http.StatusInternalServerError, "Internal error.")
}
}
func (sia *SystemInfoApi) GetVolumeInfo() {
if !sia.isAdmin {
sia.RenderError(http.StatusForbidden, "User does not have admin role.")
return
}
var stat syscall.Statfs_t
err := syscall.Statfs(filepath.Join("/", harbor_storage_path), &stat)
if err != nil {
log.Errorf("Error occurred in syscall.Statfs: %v", err)
sia.CustomAbort(http.StatusInternalServerError, "Internal error.")
return
}
storage := Storage{
Total: stat.Blocks * uint64(stat.Bsize),
Free: stat.Bfree * uint64(stat.Bsize),
}
systemInfo.HarborStorage = storage
sia.Data["json"] = systemInfo
sia.ServeJSON()
}

View File

@ -84,6 +84,8 @@ func initRouters() {
beego.Router("/api/users/:id/sysadmin", &api.UserAPI{}, "put:ToggleUserAdminRole")
beego.Router("/api/repositories/top", &api.RepositoryAPI{}, "get:GetTopRepos")
beego.Router("/api/logs", &api.LogAPI{})
beego.Router("/api/systeminfo/volumes", &api.SystemInfoApi{}, "get:GetVolumeInfo")
//external service that hosted on harbor process:
beego.Router("/service/notifications", &service.NotificationHandler{})
beego.Router("/service/token", &token.Handler{})

View File

@ -20,9 +20,9 @@
.module('harbor.optional.menu')
.directive('optionalMenu', optionalMenu);
OptionalMenuController.$inject = ['$scope', '$window', 'I18nService', 'LogOutService', 'currentUser', '$timeout', 'trFilter', '$filter'];
OptionalMenuController.$inject = ['$scope', '$window', 'I18nService', 'LogOutService', 'currentUser', '$timeout', 'trFilter', '$filter', 'GetVolumeInfoService'];
function OptionalMenuController($scope, $window, I18nService, LogOutService, currentUser, $timeoutm, trFilter, $filter) {
function OptionalMenuController($scope, $window, I18nService, LogOutService, currentUser, $timeoutm, trFilter, $filter, GetVolumeInfoService) {
var vm = this;
vm.currentLanguage = I18nService().getCurrentLanguage();
@ -55,16 +55,36 @@
function logOutFailed(data, status) {
console.log('Failed to log out:' + data);
}
var raiseInfo = {
'confirmOnly': true,
'contentType': 'text/html',
'action': function() {}
};
function about() {
$scope.$emit('modalTitle', $filter('tr')('about_harbor'));
$scope.$emit('modalMessage', $filter('tr')('current_version', [vm.version || 'Unknown']));
var raiseInfo = {
'confirmOnly': true,
'contentType': 'text/html',
'action': function() {}
};
vm.modalMessage = $filter('tr')('current_version', [vm.version || 'Unknown']);
GetVolumeInfoService("data")
.then(getVolumeInfoSuccess, getVolumeInfoFailed);
}
function getVolumeInfoSuccess(response) {
var storage = response.data;
vm.modalMessage += '<br/>' + $filter('tr')('current_storage',
[toGigaBytes(storage['harbor_storage']['free']), toGigaBytes(storage['harbor_storage']['total'])]);
$scope.$emit('modalMessage', vm.modalMessage);
$scope.$emit('raiseInfo', raiseInfo);
}
function getVolumeInfoFailed(response) {
$scope.$emit('modalMessage', vm.modalMessage);
$scope.$emit('raiseInfo', raiseInfo);
}
function toGigaBytes(val) {
return Math.round(val / (1024 * 1024 * 1024));
}
}
function optionalMenu() {

View File

@ -42,6 +42,7 @@
'harbor.services.replication.policy',
'harbor.services.replication.job',
'harbor.services.destination',
'harbor.services.system.info',
'harbor.summary',
'harbor.user.log',
'harbor.top.repository',

View File

@ -230,6 +230,7 @@ var locale_messages = {
'about': 'About',
'about_harbor': 'About Harbor',
'current_version': '<label>Version</label>&nbsp;&nbsp;<span>$0</span>',
'current_storage': '<label>Storage</label>&nbsp;&nbsp;<span>$0 GB available of $1 GB.</span>',
'failed_to_get_project_member': 'Failed to get current project member.',
'failed_to_delete_repo': 'Failed to delete repository. ',
'failed_to_delete_repo_insuffient_permissions': 'Failed to delete repository, insuffient permissions.',

View File

@ -230,6 +230,7 @@ var locale_messages = {
'about': '关于',
'about_harbor': '关于 Harbor',
'current_version': '<label>当前版本</label>&nbsp;&nbsp;<span>$0</span>',
'current_storage': '<label>存储情况</label>&nbsp;&nbsp;<span>可用: $0 GB总共 $1 GB。</span>',
'failed_to_get_project_member': '无法获取当前项目成员。',
'failed_to_delete_repo': '无法删除镜像仓库。',
'failed_to_delete_repo_insuffient_permissions': '无法删除镜像仓库,权限不足。',

View File

@ -0,0 +1,20 @@
/*
Copyright (c) 2016 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
(function() {
'use strict';
angular.module('harbor.services.system.info', []);
})();

View File

@ -0,0 +1,33 @@
/*
Copyright (c) 2016 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
(function() {
'use strict';
angular
.module('harbor.services.system.info')
.factory('GetVolumeInfoService', GetVolumeInfoService);
GetVolumeInfoService.$inject = ['$http'];
function GetVolumeInfoService($http) {
return getVolumeInfo;
function getVolumeInfo(path) {
return $http
.get('/api/systeminfo/volumes');
}
}
})();

View File

@ -110,6 +110,9 @@
<script src="/static/resources/js/services/destination/services.delete-destination.js"></script>
<script src="/static/resources/js/services/destination/services.list-destination-policy.js"></script>
<script src="/static/resources/js/services/system-info/services.system-info.module.js"></script>
<script src="/static/resources/js/services/system-info/services.volume-info.js"></script>
<script src="/static/resources/js/session/session.module.js"></script>
<script src="/static/resources/js/session/session.current-user.js"></script>