From ebd5e9b4549ebc80155a5a8f139efdb40b6f8b12 Mon Sep 17 00:00:00 2001 From: Sean McGivern Date: Wed, 5 Apr 2017 13:19:59 +0100 Subject: [PATCH] Port 'Add EE usage ping' to CE CE port of https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/557 --- .../admin/application_settings_controller.rb | 1 + app/models/application_setting.rb | 3 +- .../application_settings/_form.html.haml | 9 +++++ app/workers/gitlab_usage_ping_worker.rb | 40 +++++++++++++++++++ config/initializers/1_settings.rb | 11 +++++ ..._add_usage_ping_to_application_settings.rb | 7 ++++ db/schema.rb | 1 + spec/workers/gitlab_usage_ping_worker_spec.rb | 29 ++++++++++++++ 8 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 app/workers/gitlab_usage_ping_worker.rb create mode 100644 db/migrate/20160713222618_add_usage_ping_to_application_settings.rb create mode 100644 spec/workers/gitlab_usage_ping_worker_spec.rb diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb index 515d8e1523b..82b01be5a11 100644 --- a/app/controllers/admin/application_settings_controller.rb +++ b/app/controllers/admin/application_settings_controller.rb @@ -135,6 +135,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController :version_check_enabled, :terminal_max_session_time, :polling_interval_multiplier, + :usage_ping_enabled, disabled_oauth_sign_in_sources: [], import_sources: [], diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb index 2961e16f5e0..dd1a6922968 100644 --- a/app/models/application_setting.rb +++ b/app/models/application_setting.rb @@ -238,7 +238,8 @@ class ApplicationSetting < ActiveRecord::Base terminal_max_session_time: 0, two_factor_grace_period: 48, user_default_external: false, - polling_interval_multiplier: 1 + polling_interval_multiplier: 1, + usage_ping_enabled: true } end diff --git a/app/views/admin/application_settings/_form.html.haml b/app/views/admin/application_settings/_form.html.haml index f4ba44096d3..d8b6ce13ca4 100644 --- a/app/views/admin/application_settings/_form.html.haml +++ b/app/views/admin/application_settings/_form.html.haml @@ -486,6 +486,15 @@ Version check enabled .help-block Let GitLab inform you when an update is available. + .form-group + .col-sm-offset-2.col-sm-10 + .checkbox + = f.label :usage_ping_enabled do + = f.check_box :usage_ping_enabled + Usage ping enabled + .help-block + Every week GitLab will report license usage back to GitLab, Inc. + Disable this option if you do not want this to occur. %fieldset %legend Email diff --git a/app/workers/gitlab_usage_ping_worker.rb b/app/workers/gitlab_usage_ping_worker.rb new file mode 100644 index 00000000000..2e039b7f3c5 --- /dev/null +++ b/app/workers/gitlab_usage_ping_worker.rb @@ -0,0 +1,40 @@ +class GitlabUsagePingWorker + LEASE_TIMEOUT = 86400 + + include Sidekiq::Worker + include HTTParty + + # This is not guaranteed to succeed, so don't retry on failure + sidekiq_options queue: :default, retry: false + + def perform + return unless current_application_settings.usage_ping_enabled + + # Multiple Sidekiq workers could run this. We should only do this at most once a day. + return unless try_obtain_lease + + begin + HTTParty.post(url, + body: data.to_json, + headers: { 'Content-type' => 'application/json' } + ) + rescue HTTParty::Error => e + Rails.logger.info "Unable to contact GitLab, Inc.: #{e}" + end + end + + def try_obtain_lease + Gitlab::ExclusiveLease.new('gitlab_usage_ping_worker:ping', timeout: LEASE_TIMEOUT).try_obtain + end + + def data + usage_data = { version: Gitlab::VERSION, + active_user_count: User.active.acount } + + usage_data + end + + def url + 'https://version.gitlab.com/usage_data' + end +end diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb index 4c9d829aa9f..c19ccbb8fd8 100644 --- a/config/initializers/1_settings.rb +++ b/config/initializers/1_settings.rb @@ -110,6 +110,14 @@ class Settings < Settingslogic URI.parse(url_without_path).host end + + # Random cron time every Sunday to load balance usage pings + def cron_random_weekly_time + hour = rand(24) + minute = rand(60) + + "#{minute} #{hour} * * 0" + end end end @@ -355,6 +363,9 @@ Settings.cron_jobs['remove_unreferenced_lfs_objects_worker']['job_class'] = 'Rem Settings.cron_jobs['stuck_import_jobs_worker'] ||= Settingslogic.new({}) Settings.cron_jobs['stuck_import_jobs_worker']['cron'] ||= '15 * * * *' Settings.cron_jobs['stuck_import_jobs_worker']['job_class'] = 'StuckImportJobsWorker' +Settings.cron_jobs['gitlab_usage_ping_worker'] ||= Settingslogic.new({}) +Settings.cron_jobs['gitlab_usage_ping_worker']['cron'] ||= Settings.send(:cron_random_weekly_time) +Settings.cron_jobs['gitlab_usage_ping_worker']['job_class'] = 'GitlabUsagePingWorker' # # GitLab Shell diff --git a/db/migrate/20160713222618_add_usage_ping_to_application_settings.rb b/db/migrate/20160713222618_add_usage_ping_to_application_settings.rb new file mode 100644 index 00000000000..c7c5cdf7a56 --- /dev/null +++ b/db/migrate/20160713222618_add_usage_ping_to_application_settings.rb @@ -0,0 +1,7 @@ +class AddUsagePingToApplicationSettings < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + def change + add_column :application_settings, :usage_ping_enabled, :boolean, default: true, null: false + end +end diff --git a/db/schema.rb b/db/schema.rb index 5689f7331dc..7c5bb94dfb0 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -116,6 +116,7 @@ ActiveRecord::Schema.define(version: 20170408033905) do t.integer "unique_ips_limit_time_window" t.boolean "unique_ips_limit_enabled", default: false, null: false t.decimal "polling_interval_multiplier", default: 1.0, null: false + t.boolean "usage_ping_enabled", default: true, null: false end create_table "audit_events", force: :cascade do |t| diff --git a/spec/workers/gitlab_usage_ping_worker_spec.rb b/spec/workers/gitlab_usage_ping_worker_spec.rb new file mode 100644 index 00000000000..8c5c027ac29 --- /dev/null +++ b/spec/workers/gitlab_usage_ping_worker_spec.rb @@ -0,0 +1,29 @@ +require 'spec_helper' + +describe GitlabUsagePingWorker do + subject { GitlabUsagePingWorker.new } + + it "gathers license data" do + data = subject.data + + expect(data[:version]).to eq(Gitlab::VERSION) + expect(data[:active_user_count]).to eq(User.active.count) + end + + it "sends POST request" do + stub_application_setting(usage_ping_enabled: true) + + stub_request(:post, "https://version.gitlab.com/usage_data"). + to_return(status: 200, body: '', headers: {}) + expect(subject).to receive(:try_obtain_lease).and_return(true) + + expect(subject.perform.response.code.to_i).to eq(200) + end + + it "does not run if usage ping is disabled" do + stub_application_setting(usage_ping_enabled: false) + + expect(subject).not_to receive(:try_obtain_lease) + expect(subject).not_to receive(:perform) + end +end