Merge pull request #934 from wknet123/dev-volume-info

Added volume info to UI.
need more test.
This commit is contained in:
yhua123 2016-11-16 18:19:30 +08:00 committed by GitHub
commit 6d901e2335
10 changed files with 158 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:

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

@ -0,0 +1,68 @@
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"
)
//SystemInfoAPI handle requests for getting system info /api/systeminfo
type SystemInfoAPI struct {
api.BaseAPI
currentUserID int
isAdmin bool
}
const harborStoragePath = "/harbor_storage"
//SystemInfo models for system info.
type SystemInfo struct {
HarborStorage Storage `json:"storage"`
}
//Storage models for storage.
type Storage struct {
Total uint64 `json:"total"`
Free uint64 `json:"free"`
}
// Prepare for validating user if an admin.
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.")
}
}
// GetVolumeInfo gets specific volume storage info.
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("/", harborStoragePath), &stat)
if err != nil {
log.Errorf("Error occurred in syscall.Statfs: %v", err)
sia.CustomAbort(http.StatusInternalServerError, "Internal error.")
return
}
systemInfo := SystemInfo{
HarborStorage: Storage{
Total: stat.Blocks * uint64(stat.Bsize),
Free: stat.Bfree * uint64(stat.Bsize),
},
}
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;
var i18n = I18nService();
@ -53,16 +53,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['storage']['free']), toGigaBytes(storage['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

@ -41,6 +41,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

@ -231,6 +231,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

@ -231,6 +231,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>