Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
7b9dc100
Commit
7b9dc100
authored
Nov 29, 2016
by
Kamil Trzcinski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Rough implementation of build minutes for shared runners [ci skip]
parent
62a4637d
Changes
17
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
170 additions
and
13 deletions
+170
-13
app/controllers/admin/application_settings_controller.rb
app/controllers/admin/application_settings_controller.rb
+1
-0
app/models/application_setting.rb
app/models/application_setting.rb
+3
-0
app/models/ci/build.rb
app/models/ci/build.rb
+6
-0
app/models/project.rb
app/models/project.rb
+20
-1
app/models/project_metrics.rb
app/models/project_metrics.rb
+5
-0
app/services/ci/register_build_service.rb
app/services/ci/register_build_service.rb
+31
-12
app/services/update_build_minutes_service.rb
app/services/update_build_minutes_service.rb
+10
-0
app/views/admin/application_settings/_form.html.haml
app/views/admin/application_settings/_form.html.haml
+7
-0
app/views/admin/projects/show.html.haml
app/views/admin/projects/show.html.haml
+14
-0
app/views/projects/builds/show.html.haml
app/views/projects/builds/show.html.haml
+13
-0
app/workers/clear_shared_runner_minutes_worker.rb
app/workers/clear_shared_runner_minutes_worker.rb
+8
-0
config/initializers/1_settings.rb
config/initializers/1_settings.rb
+4
-0
db/migrate/20161129161815_add_shared_runners_minutes_to_application_settings.rb
...815_add_shared_runners_minutes_to_application_settings.rb
+9
-0
db/migrate/20161129161913_add_shared_runners_minutes_limit_to_projects.rb
...129161913_add_shared_runners_minutes_limit_to_projects.rb
+9
-0
db/migrate/20161129161957_create_table_project_metrics.rb
db/migrate/20161129161957_create_table_project_metrics.rb
+18
-0
db/migrate/20161129162216_add_index_to_project_metrics.rb
db/migrate/20161129162216_add_index_to_project_metrics.rb
+11
-0
lib/api/entities.rb
lib/api/entities.rb
+1
-0
No files found.
app/controllers/admin/application_settings_controller.rb
View file @
7b9dc100
...
...
@@ -103,6 +103,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
:user_oauth_applications
,
:user_default_external
,
:shared_runners_enabled
,
:shared_runners_minutes
,
:shared_runners_text
,
:max_artifacts_size
,
:max_pages_size
,
...
...
app/models/application_setting.rb
View file @
7b9dc100
...
...
@@ -119,6 +119,9 @@ class ApplicationSetting < ActiveRecord::Base
presence:
true
,
numericality:
{
only_integer:
true
,
greater_than: :housekeeping_full_repack_period
}
validates
:shared_runners_minutes
,
numericality:
{
greater_than_or_equal_to:
0
}
validates_each
:restricted_visibility_levels
do
|
record
,
attr
,
value
|
unless
value
.
nil?
value
.
each
do
|
level
|
...
...
app/models/ci/build.rb
View file @
7b9dc100
...
...
@@ -93,6 +93,12 @@ module Ci
end
end
after_transition
any
=>
[
:success
,
:failed
,
:canceled
]
do
|
build
|
build
.
run_after_commit
do
UpdateBuildMinutesService
.
new
(
project
,
nil
).
execute
(
build
)
end
end
after_transition
any
=>
[
:success
]
do
|
build
|
build
.
run_after_commit
do
BuildSuccessWorker
.
perform_async
(
id
)
...
...
app/models/project.rb
View file @
7b9dc100
...
...
@@ -28,6 +28,8 @@ class Project < ActiveRecord::Base
:merge_requests_enabled?
,
:issues_enabled?
,
to: :project_feature
,
allow_nil:
true
delegate
:shared_runners_minutes
,
to: :project_metrics
,
allow_nil:
true
default_value_for
:archived
,
false
default_value_for
:visibility_level
,
gitlab_config_features
.
visibility_level
default_value_for
:container_registry_enabled
,
gitlab_config_features
.
container_registry
...
...
@@ -150,6 +152,7 @@ class Project < ActiveRecord::Base
has_one
:import_data
,
dependent: :destroy
,
class_name:
"ProjectImportData"
has_one
:project_feature
,
dependent: :destroy
has_one
:project_metrics
,
dependent: :destroy
has_many
:commit_statuses
,
dependent: :destroy
,
foreign_key: :gl_project_id
has_many
:pipelines
,
dependent: :destroy
,
class_name:
'Ci::Pipeline'
,
foreign_key: :gl_project_id
...
...
@@ -1232,7 +1235,9 @@ class Project < ActiveRecord::Base
return
true
end
shared_runners_enabled?
&&
Ci
::
Runner
.
shared
.
active
.
any?
(
&
block
)
shared_runners_enabled?
&&
!
shared_runners_minutes_used?
&&
Ci
::
Runner
.
shared
.
active
.
any?
(
&
block
)
end
def
valid_runners_token?
(
token
)
...
...
@@ -1541,6 +1546,20 @@ class Project < ActiveRecord::Base
end
end
def
shared_runners_minutes_limit
read_attribute
(
:shared_runners_minutes_limit
)
||
current_application_settings
.
shared_runners_minutes
end
def
shared_runners_minutes_limit_enabled?
shared_runners_minutes_limit
.
nonzero?
end
def
shared_runners_minutes_used?
shared_runners_enabled?
&&
shared_runners_minutes_limit_enabled?
&&
shared_runners_minutes
.
to_i
<
shared_runners_minutes_limit
end
private
# Check if a reference is being done cross-project
...
...
app/models/project_metrics.rb
0 → 100644
View file @
7b9dc100
class
ProjectMetrics
<
ActiveRecord
::
Base
belongs_to
:project
validates
:project
,
presence:
true
end
app/services/ci/register_build_service.rb
View file @
7b9dc100
...
...
@@ -2,24 +2,16 @@ module Ci
# This class responsible for assigning
# proper pending build to runner on runner API request
class
RegisterBuildService
include
CurrentSettings
def
execute
(
current_runner
)
builds
=
Ci
::
Build
.
pending
.
unstarted
builds
=
if
current_runner
.
shared?
builds
.
# don't run projects which have not enabled shared runners and builds
joins
(
:project
).
where
(
projects:
{
shared_runners_enabled:
true
}).
joins
(
'LEFT JOIN project_features ON ci_builds.gl_project_id = project_features.project_id'
)
.
# this returns builds that are ordered by number of running builds
# we prefer projects that don't use shared runners at all
joins
(
"LEFT JOIN (
#{
running_builds_for_shared_runners
.
to_sql
}
) AS project_builds ON ci_builds.gl_project_id=project_builds.gl_project_id"
).
where
(
'project_features.builds_access_level IS NULL or project_features.builds_access_level > 0'
).
order
(
'COALESCE(project_builds.running_builds, 0) ASC'
,
'ci_builds.id ASC'
)
builds_for_shared_runner_with_build_minutes
else
# do run projects which are only assigned to this runner (FIFO)
builds
.
where
(
project:
current_runner
.
projects
.
with_builds_enabled
).
order
(
'created_at ASC'
)
builds_for_specific_runner
end
build
=
builds
.
find
do
|
build
|
...
...
@@ -41,9 +33,36 @@ module Ci
private
def
builds_for_shared_runner
new_builds
.
# don't run projects which have not enabled shared runners and builds
joins
(
:project
).
where
(
projects:
{
shared_runners_enabled:
true
}).
joins
(
'LEFT JOIN project_features ON ci_builds.gl_project_id = project_features.project_id'
).
where
(
'project_features.builds_access_level IS NULL or project_features.builds_access_level > 0'
)
.
# select projects with allowed number of shared runner minutes
joins
(
'LEFT JOIN project_metrics ON ci_builds.gl_project_id = project_metrics.project_id'
).
where
(
'COALESCE(projects.shared_runner_minutes_limit, ?, 0) > 0 AND '
\
'COALESCE(project_metrics.shared_runner_minutes, 0) < COALESCE(projects.shared_runner_minutes_limit, ?, 0)'
,
current_application_settings
.
shared_runners_minutes
)
# this returns builds that are ordered by number of running builds
# we prefer projects that don't use shared runners at all
joins
(
"LEFT JOIN (
#{
running_builds_for_shared_runners
.
to_sql
}
) AS project_builds ON ci_builds.gl_project_id=project_builds.gl_project_id"
).
order
(
'COALESCE(project_builds.running_builds, 0) ASC'
,
'ci_builds.id ASC'
)
end
def
builds_for_specific_runner
new_builds
.
where
(
project:
current_runner
.
projects
.
with_builds_enabled
).
order
(
'created_at ASC'
)
end
def
running_builds_for_shared_runners
Ci
::
Build
.
running
.
where
(
runner:
Ci
::
Runner
.
shared
).
group
(
:gl_project_id
).
select
(
:gl_project_id
,
'count(*) AS running_builds'
)
end
def
new_builds
Ci
::
Build
.
pending
.
unstarted
end
end
end
app/services/update_build_minutes_service.rb
0 → 100644
View file @
7b9dc100
class
UpdateBuildMinutesService
<
BaseService
def
execute
(
build
)
return
unless
build
.
runner
return
unless
build
.
runner
.
shared?
return
unless
build
.
duration
project
.
find_or_create_project_metrics
.
update_all
(
'shared_runners_minutes = shared_runners_minutes + ?'
,
build
.
duration
)
end
end
app/views/admin/application_settings/_form.html.haml
View file @
7b9dc100
...
...
@@ -215,6 +215,13 @@
=
f
.
label
:shared_runners_enabled
do
=
f
.
check_box
:shared_runners_enabled
Enable shared runners for new projects
.form-group
=
f
.
label
:shared_runners_minutes
,
'Shared runners minutes'
,
class:
'control-label col-sm-2'
.col-sm-10
=
f
.
number_field
:shared_runners_minutes
,
class:
'form-control'
.help-block
Set the maximum amount of minutes that project can use shared runners in period of time
=
link_to
"(?)"
,
help_page_path
(
"user/admin_area/settings/continuous_integration"
,
anchor:
"shared-runners-minutes"
)
.form-group
=
f
.
label
:shared_runners_text
,
class:
'control-label col-sm-2'
.col-sm-10
...
...
app/views/admin/projects/show.html.haml
View file @
7b9dc100
...
...
@@ -90,6 +90,20 @@
%span
.light
archived:
%strong
repository is read-only
-
if
@project
.
builds_enabled?
%li
%span
.light
Shared Runners:
%strong
-
if
@project
.
shared_runners_enabled?
Enabled
-
if
@project
.
shared_runner_minutes_limit
.
nonzero?
=
@project
.
shared_runner_minutes_limit
total minutes
-
elsif
current_application_settings
.
shared_runners_minutes
Unlimited
-
else
Disabled
%li
%span
.light
access:
%strong
...
...
app/views/projects/builds/show.html.haml
View file @
7b9dc100
...
...
@@ -26,6 +26,19 @@
=
link_to
namespace_project_runners_path
(
@build
.
project
.
namespace
,
@build
.
project
)
do
Runners page
-
if
@build
.
project
.
shared_runners_minutes_used?
.bs-callout.bs-callout-warning
%p
You did use all your allowed shared runners minutes:
=
@build
.
project
.
shared_runners_minutes
.
to_i
of
=
@build
.
project
.
shared_runners_minutes_limit
.
Consider looking at
=
link_to
namespace_project_runners_path
(
@build
.
project
.
namespace
,
@build
.
project
)
do
Runners page
.
-
if
@build
.
starts_environment?
.prepend-top-default
.environment-information
...
...
app/workers/clear_shared_runner_minutes_worker.rb
0 → 100644
View file @
7b9dc100
class
ClearSharedRunnerMinutesWorker
include
Sidekiq
::
Worker
include
DedicatedSidekiqQueue
def
perform
ProjectMetrics
.
update_all
(
shared_runner_minutes:
0
)
end
end
config/initializers/1_settings.rb
View file @
7b9dc100
...
...
@@ -403,6 +403,10 @@ Settings.cron_jobs['remove_unreferenced_lfs_objects_worker'] ||= Settingslogic.n
Settings
.
cron_jobs
[
'remove_unreferenced_lfs_objects_worker'
][
'cron'
]
||=
'20 0 * * *'
Settings
.
cron_jobs
[
'remove_unreferenced_lfs_objects_worker'
][
'job_class'
]
=
'RemoveUnreferencedLfsObjectsWorker'
Settings
.
cron_jobs
[
'clear_shared_runner_minutes_worker'
]
||=
Settingslogic
.
new
({})
Settings
.
cron_jobs
[
'clear_shared_runner_minutes_worker'
][
'cron'
]
||=
'0 0 0 * *'
Settings
.
cron_jobs
[
'clear_shared_runner_minutes_worker'
][
'job_class'
]
=
'ClearSharedRunnerMinutesWorker'
#
# GitLab Shell
#
...
...
db/migrate/20161129161815_add_shared_runners_minutes_to_application_settings.rb
0 → 100644
View file @
7b9dc100
class
AddSharedRunnersMinutesToApplicationSettings
<
ActiveRecord
::
Migration
include
Gitlab
::
Database
::
MigrationHelpers
DOWNTIME
=
false
def
change
add_column
:application_settings
,
:shared_runners_minutes
,
:integer
,
null:
false
,
default:
0
end
end
db/migrate/20161129161913_add_shared_runners_minutes_limit_to_projects.rb
0 → 100644
View file @
7b9dc100
class
AddSharedRunnersMinutesLimitToProjects
<
ActiveRecord
::
Migration
include
Gitlab
::
Database
::
MigrationHelpers
DOWNTIME
=
false
def
change
add_column
:projects
,
:shared_runners_minutes_limit
,
:integer
end
end
db/migrate/20161129161957_create_table_project_metrics.rb
0 → 100644
View file @
7b9dc100
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.
class
CreateTableProjectMetrics
<
ActiveRecord
::
Migration
include
Gitlab
::
Database
::
MigrationHelpers
# Set this constant to true if this migration requires downtime.
DOWNTIME
=
false
def
change
create_table
:project_metrics
do
|
t
|
t
.
integer
:project_id
,
null:
false
t
.
integer
:shared_runners_minutes
,
default:
0
,
null:
false
end
add_foreign_key
:project_metrics
,
:projects
,
column: :project_id
,
on_delete: :cascade
end
end
db/migrate/20161129162216_add_index_to_project_metrics.rb
0 → 100644
View file @
7b9dc100
class
AddIndexToProjectMetrics
<
ActiveRecord
::
Migration
include
Gitlab
::
Database
::
MigrationHelpers
DOWNTIME
=
false
disable_ddl_transaction!
def
change
add_concurrent_index
:project_metrics
,
[
:project_id
],
{
unique:
true
}
end
end
lib/api/entities.rb
View file @
7b9dc100
...
...
@@ -108,6 +108,7 @@ module API
expose
:request_access_enabled
expose
:only_allow_merge_if_all_discussions_are_resolved
expose
:approvals_before_merge
expose
:shared_runners_minutes_limit
end
class
Member
<
UserBasic
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment