Commit 91f35894 authored by Dylan Griffith's avatar Dylan Griffith

Allow to pause,resume,show,edit,destroy group runners (#10244)

parent 1ef9e9c2
class Groups::RunnersController < Groups::ApplicationController
before_action :authorize_admin_pipeline!
before_action :set_runner, only: [:edit, :update, :destroy, :pause, :resume, :show]
def show
end
def edit
end
def update
if Ci::UpdateRunnerService.new(@runner).update(runner_params)
redirect_to group_runner_path(@group, @runner), notice: 'Runner was successfully updated.'
else
render 'edit'
end
end
def destroy
@runner.destroy
redirect_to group_settings_ci_cd_path(@group), status: 302
end
def resume
if Ci::UpdateRunnerService.new(@runner).update(active: true)
redirect_to group_settings_ci_cd_path(@group), notice: 'Runner was successfully updated.'
else
redirect_to group_settings_ci_cd_path(@group), alert: 'Runner was not updated.'
end
end
def pause
if Ci::UpdateRunnerService.new(@runner).update(active: false)
redirect_to group_settings_ci_cd_path(@group), notice: 'Runner was successfully updated.'
else
redirect_to group_settings_ci_cd_path(@group), alert: 'Runner was not updated.'
end
end
private
def set_runner
@runner ||= @group.runners.find(params[:id])
end
def authorize_admin_pipeline!
return render_404 unless can?(current_user, :admin_pipeline, group)
end
def runner_params
params.require(:runner).permit(Ci::Runner::FORM_EDITABLE)
end
end
= form_for runner, url: runner_form_url, html: { class: 'form-horizontal' } do |f|
= form_errors(runner)
.form-group
= label :active, "Active", class: 'control-label'
.col-sm-10
.checkbox
= f.check_box :active
%span.light Paused Runners don't accept new jobs
.form-group
= label :protected, "Protected", class: 'control-label'
.col-sm-10
.checkbox
= f.check_box :access_level, {}, 'ref_protected', 'not_protected'
%span.light This runner will only run on pipelines triggered on protected branches
.form-group
= label :run_untagged, 'Run untagged jobs', class: 'control-label'
.col-sm-10
.checkbox
= f.check_box :run_untagged
%span.light Indicates whether this runner can pick jobs without tags
.form-group
= label_tag :token, class: 'control-label' do
Token
.col-sm-10
= f.text_field :token, class: 'form-control', readonly: true
.form-group
= label_tag :description, class: 'control-label' do
Description
.col-sm-10
= f.text_field :description, class: 'form-control'
.form-group
= label_tag :tag_list, class: 'control-label' do
Tags
.col-sm-10
= f.text_field :tag_list, value: runner.tag_list.sort.join(', '), class: 'form-control'
.help-block You can setup jobs to only use Runners with specific tags. Separate tags with commas.
.form-actions
= f.submit 'Save changes', class: 'btn btn-save'
......@@ -2,9 +2,18 @@
%h4
= runner_status_icon(runner)
%span.commit-sha
= runner.short_sha
= link_to runner.short_sha, group_runner_path(@group, runner), class: 'commit-sha'
%small.edit-runner
= link_to edit_group_runner_path(@group, runner) do
%i.fa.fa-edit.btn
.pull-right
- if runner.active?
= link_to 'Pause', pause_group_runner_path(@group, runner), method: :post, class: 'btn btn-sm btn-danger', data: { confirm: "Are you sure?" }
- else
= link_to 'Resume', resume_group_runner_path(@group, runner), method: :post, class: 'btn btn-success btn-sm'
= link_to 'Remove Runner', group_runner_path(@group, runner), data: { confirm: "Are you sure?" }, method: :delete, class: 'btn btn-danger btn-sm'
.pull-right
%small.light
\##{runner.id}
......
- page_title "Edit", "#{@runner.description} ##{@runner.id}", "Runners"
%h4 Runner ##{@runner.id}
%hr
= render 'form', runner: @runner, runner_form_url: group_runner_path(@group, @runner)
- page_title "#{@runner.description} ##{@runner.id}", "Runners"
%h3.page-title
Runner ##{@runner.id}
.table-holder
%table.table
%thead
%tr
%th Property Name
%th Value
%tr
%td Active
%td= @runner.active? ? 'Yes' : 'No'
%tr
%td Protected
%td= @runner.ref_protected? ? 'Yes' : 'No'
%tr
%td Can run untagged jobs
%td= @runner.run_untagged? ? 'Yes' : 'No'
%tr
%td Tags
%td
- @runner.tag_list.sort.each do |tag|
%span.label.label-primary
= tag
%tr
%td Name
%td= @runner.name
%tr
%td Version
%td= @runner.version
%tr
%td Revision
%td= @runner.revision
%tr
%td Platform
%td= @runner.platform
%tr
%td Architecture
%td= @runner.architecture
%tr
%td Description
%td= @runner.description
%tr
%td Last contact
%td
- if @runner.contacted_at
#{time_ago_in_words(@runner.contacted_at)} ago
- else
Never
......@@ -58,6 +58,13 @@ constraints(::Constraints::GroupUrlConstrainer.new) do
# On CE only index and show actions are needed
resources :boards, only: [:index, :show]
resources :runners, only: [:index, :edit, :update, :destroy, :show] do
member do
post :resume
post :pause
end
end
end
scope(path: '*id',
......
require 'spec_helper'
describe Groups::RunnersController do
let(:user) { create(:user) }
let(:group) { create(:group) }
let(:runner) { create(:ci_runner) }
let(:params) do
{
group_id: group,
id: runner
}
end
before do
sign_in(user)
group.add_master(user)
group.runners << runner
end
describe '#update' do
it 'updates the runner and ticks the queue' do
new_desc = runner.description.swapcase
expect do
post :update, params.merge(runner: { description: new_desc } )
end.to change { runner.ensure_runner_queue_value }
runner.reload
expect(response).to have_gitlab_http_status(302)
expect(runner.description).to eq(new_desc)
end
end
describe '#destroy' do
it 'destroys the runner' do
delete :destroy, params
expect(response).to have_gitlab_http_status(302)
expect(Ci::Runner.find_by(id: runner.id)).to be_nil
end
end
describe '#resume' do
it 'marks the runner as active and ticks the queue' do
runner.update(active: false)
expect do
post :resume, params
end.to change { runner.ensure_runner_queue_value }
runner.reload
expect(response).to have_gitlab_http_status(302)
expect(runner.active).to eq(true)
end
end
describe '#pause' do
it 'marks the runner as inactive and ticks the queue' do
runner.update(active: true)
expect do
post :pause, params
end.to change { runner.ensure_runner_queue_value }
runner.reload
expect(response).to have_gitlab_http_status(302)
expect(runner.active).to eq(false)
end
end
end
......@@ -182,7 +182,7 @@ feature 'Runners' do
end
end
context 'group runners' do
context 'group runners in project settings' do
background do
project.add_master(user)
end
......@@ -200,10 +200,10 @@ feature 'Runners' do
scenario 'group runners are not available' do
visit project_runners_path(project)
expect(page).to have_content 'This group does not provide any group Runners yet.'
expect(page).to have_content 'This group does not provide any group Runners yet'
expect(page).to have_content 'Setup a group Runner manually'
expect(page).not_to have_content 'Ask your group master to setup a group Runner.'
expect(page).to have_content 'Group masters can register group runners in the Group CI/CD settings'
expect(page).not_to have_content 'Ask your group master to setup a group Runner'
end
end
end
......@@ -228,7 +228,7 @@ feature 'Runners' do
expect(page).to have_content 'This group does not provide any group Runners yet.'
expect(page).not_to have_content 'Setup a group Runner manually'
expect(page).not_to have_content 'Group masters can register group runners in the Group CI/CD settings'
expect(page).to have_content 'Ask your group master to setup a group Runner.'
end
end
......@@ -261,4 +261,98 @@ feature 'Runners' do
end
end
end
context 'group runners in group settings' do
given(:group) { create :group }
background do
group.add_master(user)
end
context 'group with no runners' do
scenario 'there are no runners displayed' do
visit group_settings_ci_cd_path(group)
expect(page).to have_content 'This group does not provide any group Runners yet'
end
end
context 'group with a runner' do
let!(:runner) { create :ci_runner, groups: [group], description: 'group-runner' }
scenario 'the runner is visible' do
visit group_settings_ci_cd_path(group)
expect(page).not_to have_content 'This group does not provide any group Runners yet'
expect(page).to have_content 'Available group Runners : 1'
expect(page).to have_content 'group-runner'
end
scenario 'user can pause and resume the group runner' do
visit group_settings_ci_cd_path(group)
expect(page).to have_content('Pause')
expect(page).not_to have_content('Resume')
click_on 'Pause'
expect(page).not_to have_content('Pause')
expect(page).to have_content('Resume')
click_on 'Resume'
expect(page).to have_content('Pause')
expect(page).not_to have_content('Resume')
end
scenario 'user can view runner details' do
visit group_settings_ci_cd_path(group)
expect(page).to have_content(runner.display_name)
click_on runner.short_sha
expect(page).to have_content(runner.platform)
end
scenario 'user can remove a group runner' do
visit group_settings_ci_cd_path(group)
click_on 'Remove Runner'
expect(page).not_to have_content(runner.display_name)
end
scenario 'user edits the runner to be protected' do
visit group_settings_ci_cd_path(group)
first('.edit-runner > a').click
expect(page.find_field('runner[access_level]')).not_to be_checked
check 'runner_access_level'
click_button 'Save changes'
expect(page).to have_content 'Protected Yes'
end
context 'when a runner has a tag' do
background do
runner.update(tag_list: ['tag'])
end
scenario 'user edits runner not to run untagged jobs' do
visit group_settings_ci_cd_path(group)
first('.edit-runner > a').click
expect(page.find_field('runner[run_untagged]')).to be_checked
uncheck 'runner_run_untagged'
click_button 'Save changes'
expect(page).to have_content 'Can run untagged jobs No'
end
end
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment