Merge remote-tracking branch 'hupstream/dev' into dev

This commit is contained in:
Henry Zhang 2016-10-26 23:29:59 +08:00
commit 9f043586f1
25 changed files with 79 additions and 60 deletions

View File

@ -86,7 +86,7 @@ script:
- docker-compose -f make/docker-compose.test.yml down
- docker-compose -f make/docker-compose.yml up -d
- docker-compose -f make/dev/docker-compose.yml up -d
- docker ps
- go run tests/startuptest.go http://localhost/

View File

@ -25,7 +25,7 @@
#
# package_online:
# prepare online install package
# for example: make package_online -e \
# for example: make package_online -e DEVFLAG=flase\
# REGISTRYSERVER=reg-bj.eng.vmware.com \
# REGISTRYPROJECTNAME=harborrelease
#
@ -33,13 +33,13 @@
# prepare offline install package
#
# pushimage: push Harbor images to specific registry server
# for example: make pushimage -e REGISTRYUSER=admin \
# for example: make pushimage -e DEVFLAG=flase REGISTRYUSER=admin \
# REGISTRYPASSWORD=***** \
# REGISTRYSERVER=reg-bj.eng.vmware.com/ \
# REGISTRYPROJECTNAME=harborrelease
# note**: need add "/" on end of REGISTRYSERVER. If not setting \
# this value will push images directly to dockerhub.
# make pushimage -e REGISTRYUSER=vmware \
# make pushimage -e DEVFLAG=flase REGISTRYUSER=vmware \
# REGISTRYPASSWORD=***** \
# REGISTRYPROJECTNAME=vmware
#
@ -141,6 +141,7 @@ DOCKERIMAGENAME_DB=vmware/harbor-db
# docker-compose files
DOCKERCOMPOSEFILEPATH=$(MAKEPATH)
DOCKERCOMPOSETPLFILENAME=docker-compose.tpl
DOCKERCOMPOSEFILENAME=docker-compose.yml
# version prepare
@ -229,8 +230,8 @@ build: build_$(BASEIMAGE)
modify_composefile:
@echo "preparing tag:$(VERSIONTAG) docker-compose file..."
@cp $(DOCKERCOMPOSEFILEPATH)/$(DOCKERCOMPOSEFILENAME) $(DOCKERCOMPOSEFILEPATH)/docker-compose.$(VERSIONTAG).yml
@$(SEDCMD) -i 's/image\: vmware.*/&:$(VERSIONTAG)/g' $(DOCKERCOMPOSEFILEPATH)/docker-compose.$(VERSIONTAG).yml
@cp $(DOCKERCOMPOSEFILEPATH)/$(DOCKERCOMPOSETPLFILENAME) $(DOCKERCOMPOSEFILEPATH)/$(DOCKERCOMPOSEFILENAME)
@$(SEDCMD) -i 's/image\: vmware.*/&:$(VERSIONTAG)/g' $(DOCKERCOMPOSEFILEPATH)/$(DOCKERCOMPOSEFILENAME)
install: compile build modify_composefile
@echo "loading harbor images..."
@ -249,7 +250,7 @@ package_online: modify_composefile
@$(TARCMD) -zcvf harbor-online-installer-$(VERSIONTAG).tgz \
--exclude=$(HARBORPKG)/common/db --exclude=$(HARBORPKG)/ubuntu \
--exclude=$(HARBORPKG)/photon --exclude=$(HARBORPKG)/kubernetes \
--exclude=$(HARBORPKG)/dev --exclude=docker-compose.yml \
--exclude=$(HARBORPKG)/dev --exclude=$(DOCKERCOMPOSETPLFILENAME) \
--exclude=$(HARBORPKG)/checkenv.sh \
--exclude=$(HARBORPKG)/jsminify.sh \
--exclude=$(HARBORPKG)/pushimage.sh \
@ -275,7 +276,7 @@ package_offline: compile build modify_composefile
@$(TARCMD) -zcvf harbor-offline-installer-$(VERSIONTAG).tgz \
--exclude=$(HARBORPKG)/common/db --exclude=$(HARBORPKG)/ubuntu \
--exclude=$(HARBORPKG)/photon --exclude=$(HARBORPKG)/kubernetes \
--exclude=$(HARBORPKG)/dev --exclude=docker-compose.yml \
--exclude=$(HARBORPKG)/dev --exclude=$(DOCKERCOMPOSETPLFILENAME) \
--exclude=$(HARBORPKG)/checkenv.sh \
--exclude=$(HARBORPKG)/jsminify.sh \
--exclude=$(HARBORPKG)/pushimage.sh \

View File

@ -1,11 +0,0 @@
### A faster way to pull images for Chinese Harbor users
By default, Harbor not only build images according to Dockerfile but also pull images from Docker Hub. For the reason we all know, it is difficult for Chinese Harbor users to pull images from the Docker Hub. We put images on daocloud.io platform, we'll put images on other platforms later. If you have difficulty to pull images from Docker Hub, or you think it wastes too much time to build images. We recommend you to use the following way to accelerate the pulling procedure(make sure you're in the harbor diectory):
```
$ cd contrib
$ cp docker-compose.yml.daocloud ../make
$ cd ../make
$ mv docker-compose.yml docker-compose.yml.bak
$ mv docker-compose.yml.daocloud docker-compose.yml
$ docker-compose up -d
```
Then you'll see docker pulling imges faster than before.

View File

@ -74,7 +74,7 @@ services:
syslog-address: "tcp://127.0.0.1:1514"
tag: "jobservice"
proxy:
image: nginx:1.9.0
image: nginx:1.9
container_name: nginx
restart: always
volumes:

View File

@ -2,7 +2,7 @@
#
# Targets:
#
# build: build harbor ubuntu images
# build: build harbor photon images
# clean: clean ui and jobservice harbor images
# common
@ -29,8 +29,8 @@ JOBSERVICESOURCECODE=$(SRCPATH)/jobservice
JOBSERVICEBINARYPATH=$(MAKEDEVPATH)/jobservice
JOBSERVICEBINARYNAME=harbor_jobservice
# ubuntu dockerfile
DOCKERFILEPATH=$(MAKEPATH)/ubuntu
# photon dockerfile
DOCKERFILEPATH=$(MAKEPATH)/photon
DOCKERFILEPATH_UI=$(DOCKERFILEPATH)/ui
DOCKERFILENAME_UI=Dockerfile
DOCKERIMAGENAME_UI=vmware/harbor-ui
@ -55,21 +55,21 @@ endif
check_environment:
@$(MAKEPATH)/$(CHECKENVCMD)
build:
@echo "building ui container for ubuntu..."
build:
@echo "building ui container for photon..."
$(DOCKERBUILD) -f $(DOCKERFILEPATH_UI)/$(DOCKERFILENAME_UI) -t $(DOCKERIMAGENAME_UI):$(VERSIONTAG) .
@echo "Done."
@echo "building jobservice container for ubuntu..."
@echo "building jobservice container for photon..."
$(DOCKERBUILD) -f $(DOCKERFILEPATH_JOBSERVICE)/$(DOCKERFILENAME_JOBSERVICE) -t $(DOCKERIMAGENAME_JOBSERVICE):$(VERSIONTAG) .
@echo "Done."
@echo "building log container for ubuntu..."
@echo "building log container for photon..."
$(DOCKERBUILD) -f $(DOCKERFILEPATH_LOG)/$(DOCKERFILENAME_LOG) -t $(DOCKERIMAGENAME_LOG):$(VERSIONTAG) .
@echo "Done."
cleanimage:
@echo "cleaning image for ubuntu..."
@echo "cleaning image for photon..."
- $(DOCKERRMIMAGE) -f $(DOCKERIMAGENAME_UI):$(VERSIONTAG)
- $(DOCKERRMIMAGE) -f $(DOCKERIMAGENAME_JOBSERVICE):$(VERSIONTAG)
- $(DOCKERRMIMAGE) -f $(DOCKERIMAGENAME_LOG):$(VERSIONTAG)

View File

@ -1,5 +1,9 @@
package controllers
import (
"net/http"
)
// AccountSettingController handles request to /account_setting
type AccountSettingController struct {
BaseController
@ -7,5 +11,8 @@ type AccountSettingController struct {
// Get renders the account settings page
func (asc *AccountSettingController) Get() {
if asc.AuthMode != "db_auth" {
asc.CustomAbort(http.StatusForbidden, "")
}
asc.Forward("page_title_account_setting", "account-settings.htm")
}

View File

@ -1,5 +1,9 @@
package controllers
import (
"net/http"
)
// ChangePasswordController handles request to /change_password
type ChangePasswordController struct {
BaseController
@ -7,5 +11,8 @@ type ChangePasswordController struct {
// Get renders the change password page
func (asc *ChangePasswordController) Get() {
if asc.AuthMode != "db_auth" {
asc.CustomAbort(http.StatusForbidden, "")
}
asc.Forward("page_title_change_password", "change-password.htm")
}

View File

@ -19,6 +19,7 @@ func (omc *OptionalMenuController) Get() {
var hasLoggedIn bool
var allowAddNew bool
var allowSettingAccount bool
if sessionUserID != nil {
hasLoggedIn = true
@ -34,6 +35,10 @@ func (omc *OptionalMenuController) Get() {
}
omc.Data["Username"] = u.Username
if omc.AuthMode == "db_auth" {
allowSettingAccount = true
}
isAdmin, err := dao.IsAdminRole(sessionUserID.(int))
if err != nil {
log.Errorf("Error occurred in IsAdminRole: %v", err)
@ -45,6 +50,7 @@ func (omc *OptionalMenuController) Get() {
}
}
omc.Data["AddNew"] = allowAddNew
omc.Data["SettingAccount"] = allowSettingAccount
omc.Data["HasLoggedIn"] = hasLoggedIn
omc.TplName = "optional-menu.htm"
omc.Render()

View File

@ -12,7 +12,7 @@ type SignUpController struct {
// Get renders sign up page
func (suc *SignUpController) Get() {
if suc.AuthMode != "db_auth" || !suc.SelfRegistration {
suc.CustomAbort(http.StatusUnauthorized, "Status unauthorized.")
suc.CustomAbort(http.StatusForbidden, "")
}
suc.Data["AddNew"] = false
suc.Forward("page_title_sign_up", "sign-up.htm")

View File

@ -35,7 +35,7 @@ type NotificationHandler struct {
beego.Controller
}
const manifestPattern = `^application/vnd.docker.distribution.manifest.v\d\+json`
const manifestPattern = `^application/vnd.docker.distribution.manifest.v\d\+(json|prettyjws)`
// Post handles POST request, and records audit log or refreshes cache based on event.
func (n *NotificationHandler) Post() {

View File

@ -29,6 +29,7 @@
vm.isOpen = false;
vm.isProjectMember = false;
vm.target = $location.path().substr(1) || 'repositories';
vm.roleId = 0;
vm.isPublic = Number(getParameterByName('is_public', $location.absUrl()));
@ -152,6 +153,9 @@
function getCurrentProjectMemberSuccess(data, status) {
console.log('Successful get current project member:' + status);
vm.isProjectMember = true;
if(data && data['roles'] && data['roles'].length > 0) {
vm.roleId = data['roles'][0]['role_id'];
}
}
function getCurrentProjectMemberFailed(data, status) {
@ -171,7 +175,8 @@
'isOpen': '=',
'selectedProject': '=',
'isPublic': '=',
'isProjectMember': '='
'isProjectMember': '=',
'roleId': '='
},
link: link,
controller: RetrieveProjectsController,

View File

@ -14,7 +14,7 @@
-->
<td width="30%">//vm.username//</td>
<td width="45%"><switch-role roles="vm.roles" edit-mode="vm.editMode" user-id="vm.userId" role-name="vm.roleName"></switch-role></td>
<td width="25%">
<td width="25%" ng-if="vm.currentRoleId == 1">
<a ng-show="vm.userId != vm.currentUserId" href="javascript:void(0);" ng-click="vm.updateProjectMember({projectId: vm.projectId, userId: vm.userId, roleId: vm.roleId})">
<span ng-if="!vm.editMode" class="glyphicon glyphicon-pencil" title="// 'edit' | tr //"></span><span ng-if="vm.editMode" class="glyphicon glyphicon-ok" title="// 'confirm' | tr //">
</a>

View File

@ -87,7 +87,8 @@
'roleName': '=',
'projectId': '=',
'delete': '&',
'reload': '&'
'reload': '&',
'currentRoleId': '@'
},
'controller': EditProjectMemberController,
'controllerAs': 'vm',

View File

@ -21,23 +21,23 @@
<button class="btn btn-primary" type="button" ng-click="vm.search({projectId: vm.projectId, username: vm.username})"><span class="glyphicon glyphicon-search"></span></button>
</span>
</div>
<button ng-if="!vm.isOpen" class="btn btn-success" type="button" ng-click="vm.addProjectMember()"><span class="glyphicon glyphicon-plus"></span>// 'add_member' | tr //</button>
<button ng-if="vm.isOpen" class="btn btn-default" disabled="disabled" type="button"><span class="glyphicon glyphicon-plus"></span>// 'add_member' | tr //</button>
<button ng-if="vm.roleId == 1 && !vm.isOpen" class="btn btn-success" type="button" ng-click="vm.addProjectMember()"><span class="glyphicon glyphicon-plus"></span>// 'add_member' | tr //</button>
<button ng-if="vm.roleId == 1 && vm.isOpen" class="btn btn-default" disabled="disabled" type="button"><span class="glyphicon glyphicon-plus"></span>// 'add_member' | tr //</button>
</div>
<add-project-member ng-show="vm.isOpen" is-open="vm.isOpen" project-id="//vm.projectId//" reload='vm.search({projectId: vm.projectId, username: vm.username})'></add-project-member>
<add-project-member ng-if="vm.isOpen" is-open="vm.isOpen" project-id="//vm.projectId//" reload='vm.search({projectId: vm.projectId, username: vm.username})'></add-project-member>
<div class="search-pane">
<div class="sub-pane">
<div class="table-head-container">
<table class="table table-pane table-header">
<thead>
<th width="30%">// 'username' | tr //</th><th width="45%">// 'role' | tr //</th><th width="25%">// 'operation' | tr //</th>
<th width="30%">// 'username' | tr //</th><th width="45%">// 'role' | tr //</th><th width="25%" ng-if="vm.roleId == 1">// 'operation' | tr //</th>
</thead>
</table>
</div>
<div class="table-body-container">
<table class="table table-pane">
<tbody>
<tr ng-repeat="pr in vm.projectMembers" edit-project-member username="pr.username" project-id="vm.projectId" user-id="pr.user_id" delete="vm.deleteProjectMember({projectId: vm.projectId, userId: pr.user_id})" current-user-id="vm.user.user_id" role-name="pr.role_name" reload='vm.search({projectId: vm.projectId, username: vm.username})'></tr>
<tr ng-repeat="pr in vm.projectMembers" edit-project-member username="pr.username" project-id="vm.projectId" user-id="pr.user_id" delete="vm.deleteProjectMember({projectId: vm.projectId, userId: pr.user_id})" current-user-id="vm.user.user_id" role-name="pr.role_name" reload='vm.search({projectId: vm.projectId, username: vm.username})' current-role-id="//vm.roleId//"></tr>
</tbody>
</table>
</div>

View File

@ -56,11 +56,7 @@
}
function addProjectMember() {
if(vm.isOpen) {
vm.isOpen = false;
}else{
vm.isOpen = true;
}
vm.isOpen = !vm.isOpen;
}
function deleteProjectMember(e) {
@ -105,7 +101,8 @@
'restrict': 'E',
'templateUrl': '/static/resources/js/components/project-member/list-project-member.directive.html',
'scope': {
'sectionHeight': '='
'sectionHeight': '=',
'roleId': '@'
},
'link': link,
'controller': ListProjectMemberController,

View File

@ -12,5 +12,5 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
<button ng-if="vm.isPublic" class="btn btn-success" ng-click="vm.toggle()">// 'button_on' | tr //</button>
<button ng-if="!vm.isPublic" class="btn btn-danger" ng-click="vm.toggle()">// 'button_off' | tr //</button>
<button ng-if="vm.isPublic" class="btn btn-success" ng-disabled="vm.roleId != 1" ng-click="vm.toggle()">// 'button_on' | tr //</button>
<button ng-if="!vm.isPublic" class="btn btn-danger" ng-disabled="vm.roleId != 1" ng-click="vm.toggle()">// 'button_off' | tr //</button>

View File

@ -60,7 +60,8 @@
'templateUrl': '/static/resources/js/components/project/publicity-button.directive.html',
'scope': {
'isPublic': '=',
'projectId': '='
'projectId': '=',
'roleId': '@'
},
'link': link,
'controller': PublicityButtonController,

View File

@ -23,10 +23,10 @@
<a ng-if="vm.tagCount[repo] === 0" role="button" style="text-decoration: none;" data-toggle="collapse" data-parent="" aria-expanded="true" aria-controls="collapse//$index+1//">
<span class="glyphicon glyphicon-book"></span> &nbsp;//repo// &nbsp;&nbsp;<span class="badge">//vm.tagCount[repo]//</span>
</a>
<a ng-show="vm.tagCount[repo] > 0" class="pull-right" style="margin-right: 75px;" href="javascript:void(0)" ng-click="vm.deleteByRepo(repo)" title="// 'delete_repo' | tr //" loading-progress hide-target="true" toggle-in-progress="vm.toggleInProgress[repo + '|']"><span class="glyphicon glyphicon-trash"></span></a>
<a ng-show="vm.tagCount[repo] > 0 && vm.roleId == 1" class="pull-right" style="margin-right: 75px;" href="javascript:void(0)" ng-click="vm.deleteByRepo(repo)" title="// 'delete_repo' | tr //" loading-progress hide-target="true" toggle-in-progress="vm.toggleInProgress[repo + '|']"><span class="glyphicon glyphicon-trash"></span></a>
</h4>
</div>
<list-tag ng-show="vm.tagCount[repo] > 0" associate-id="$index + 1" repo-name="repo" tag-count="vm.tagCount" toggle-in-progress="vm.toggleInProgress" delete-by-tag="vm.deleteByTag()"></list-tag>
<list-tag ng-show="vm.tagCount[repo] > 0" associate-id="$index + 1" repo-name="repo" tag-count="vm.tagCount" toggle-in-progress="vm.toggleInProgress" delete-by-tag="vm.deleteByTag()" role-id="//vm.roleId//"></list-tag>
</div>
</div>
</div>

View File

@ -26,7 +26,7 @@
$scope.subsTabPane = 30;
var vm = this;
vm.sectionHeight = {'min-height': '579px'};
vm.filterInput = '';
@ -155,6 +155,7 @@
function deleteRepositorySuccess(data, status) {
vm.toggleInProgress[vm.repoName + '|' + vm.tag] = false;
vm.retrieve();
$scope.$broadcast('refreshTags', true);
}
function deleteRepositoryFailed(data, status) {
@ -180,7 +181,8 @@
'restrict': 'E',
'templateUrl': '/static/resources/js/components/repository/list-repository.directive.html',
'scope': {
'sectionHeight': '='
'sectionHeight': '=',
'roleId': '@'
},
'link': link,
'controller': ListRepositoryController,

View File

@ -5,7 +5,7 @@
<th width="20%"><span class="glyphicon glyphicon-tags"></span> // 'tag' | tr //</th>
<th width="15%" style="text-align: center;">// 'image_details' | tr //</th>
<th width="40%">// 'pull_command' | tr //</th>
<th width="15%" style="text-align: center;">// 'operation' | tr //</th>
<th width="15%" ng-if="vm.roleId == 1" style="text-align: center;">// 'operation' | tr //</th>
</thead>
<tbody>
<tr ng-repeat="tag in vm.tags">
@ -14,7 +14,7 @@
<td>
<pull-command repo-name="//vm.repoName//" tag="//tag//"></pull-command>
</td>
<td style="text-align: center;"><a href="javascript:void(0);" ng-click="vm.deleteTag({repoName: vm.repoName, tag: tag})" title="// 'delete_tag' | tr //" loading-progress hide-target="true" toggle-in-progress="vm.toggleInProgress[vm.repoName +'|'+ tag]"><span class="glyphicon glyphicon-trash"></span></a></td>
<td style="text-align: center;"><a ng-if="vm.roleId == 1" href="javascript:void(0);" ng-click="vm.deleteTag({repoName: vm.repoName, tag: tag})" title="// 'delete_tag' | tr //" loading-progress hide-target="true" toggle-in-progress="vm.toggleInProgress[vm.repoName +'|'+ tag]"><span class="glyphicon glyphicon-trash"></span></a></td>
</tr>
</tbody>
</table>

View File

@ -85,7 +85,8 @@
'associateId': '=',
'repoName': '=',
'toggleInProgress': '=',
'deleteByTag': '&'
'deleteByTag': '&',
'roleId': '@'
},
'replace': true,
'controller': ListTagController,

View File

@ -21,7 +21,9 @@
{{ if eq .AddNew true }}
<li><a href="/add_new"><span class="glyphicon glyphicon-plus"></span>&nbsp;&nbsp;// 'add_new_title' | tr //</a></li>
{{ end }}
{{ if eq .SettingAccount true }}
<li><a href="/account_setting"><span class="glyphicon glyphicon-pencil"></span>&nbsp;&nbsp;// 'account_setting' | tr //</a></li>
{{ end }}
<li class="dropdown-submenu">
<a tabindex="-1" href="#"><span class="glyphicon glyphicon-globe"></span>&nbsp;&nbsp;//vm.languageName//</a>
<ul class="dropdown-menu">

View File

@ -63,9 +63,9 @@
<td width="15%">//p.repo_count//</td>
<td width="15%" ng-if="vm.isPublic === 0">//vm.getProjectRole(p.current_user_role_id) | tr//</td>
<td width="20%">//p.creation_time | dateL : 'YYYY-MM-DD HH:mm:ss'//</td>
<td width="15%"><publicity-button is-public="p.public" project-id="p.project_id"></publicity-button></td>
<td width="15%"><publicity-button is-public="p.public" project-id="p.project_id" role-id="//p.current_user_role_id//"></publicity-button></td>
<td width="10%">
&nbsp;&nbsp;<a href="javascript:void(0)" ng-click="vm.confirmToDelete(p.project_id, p.name)"><span class="glyphicon glyphicon-trash"></span></a>
&nbsp;&nbsp;<a ng-if="p.current_user_role_id == 1" href="javascript:void(0)" ng-click="vm.confirmToDelete(p.project_id, p.name)"><span class="glyphicon glyphicon-trash"></span></a>
</td>
</tr>
</tbody>

View File

@ -30,13 +30,13 @@
<navigation-details target="vm.target" ng-show="vm.isProjectMember"></navigation-details>
</span>
</div>
<retrieve-projects target="vm.target" is-open="vm.isOpen" selected-project="vm.selectedProject" is-project-member="vm.isProjectMember" is-public="vm.isPublic"></retrieve-projects>
<retrieve-projects target="vm.target" is-open="vm.isOpen" selected-project="vm.selectedProject" role-id="vm.roleId" is-project-member="vm.isProjectMember" is-public="vm.isPublic"></retrieve-projects>
<!-- Tab panes -->
<div class="tab-content" ng-click="vm.closeRetrievePane()">
<input type="hidden" id="HarborRegUrl" value="{{.HarborRegUrl}}">
<list-repository ng-if="vm.target === 'repositories'" section-height="vm.sectionHeight"></list-repository>
<list-repository ng-if="vm.target === 'repositories'" section-height="vm.sectionHeight" role-id="//vm.roleId//"></list-repository>
<list-replication ng-if="vm.target === 'replication'" section-height="vm.sectionHeight"></list-replication>
<list-project-member ng-if="vm.target === 'users'" section-height="vm.sectionHeight"></list-project-member>
<list-project-member ng-if="vm.target === 'users'" section-height="vm.sectionHeight" role-id="//vm.roleId//"></list-project-member>
<list-log ng-if="vm.target === 'logs'" section-height="vm.sectionHeight" target="vm.target"></list-log>
</div>
</div>

View File

@ -1,7 +1,7 @@
version: '2'
services:
registry:
image: library/registry:2.4.0
image: library/registry:2.5.0
restart: always
volumes:
- /data/registry:/storage