This repository has been archived by the owner on Apr 17, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 470
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1096 from mssola/portusctl-registry
portusctl: show a warning if the local registry has not been installed
- Loading branch information
Showing
5 changed files
with
199 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
module Portusctl | ||
# Contains all the needed methods for configuring the registry. You should | ||
# only need to use the `registry` method. | ||
module Registry | ||
# Creates registry's configuration | ||
def registry | ||
if @options["local-registry"] | ||
return unless registry_local? | ||
|
||
# Add the certificated used by Portus to sign the JWT tokens | ||
ssldir = "/etc/registry/ssl.crt" | ||
FileUtils.mkdir_p(ssldir) | ||
FileUtils.ln_sf( | ||
"/etc/apache2/ssl.crt/#{HOSTNAME}-ca.crt", | ||
File.join(ssldir, "portus.crt") | ||
) | ||
|
||
TemplateWriter.process( | ||
"registry.yml.erb", | ||
"/etc/registry/config.yml", | ||
binding | ||
) | ||
else | ||
TemplateWriter.render("registry.yml.erb", binding) | ||
end | ||
end | ||
|
||
protected | ||
|
||
REGISTRY_RPM = "docker-distribution-registry".freeze | ||
ZYPPER_NOT_INSTALLED = 104 # ZYPPER_EXIT_INF_CAP_NOT_FOUND | ||
|
||
# Checks whether the Docker Distribution package is already installed in the | ||
# system. If it is, it will simply return true. Otherwise, it will ask the user | ||
# whether or not to install the package first and then proceed. If the user | ||
# doesn't want that, or some zypper command failed, then it returns false. All | ||
# the decisions to be made by the user can be coerced with the environment | ||
# variable "PORTUSCTL_FORCE". | ||
def registry_local? | ||
if Runner.safe_exec("zypper", ["se", "-ix", REGISTRY_RPM]) | ||
return true if ENV["PORTUSCTL_FORCE"] | ||
|
||
puts "Warning: portusctl will overwrite the existing configuration." | ||
puts "Do you want to proceed ? (Y/n)" | ||
return user_confirm? | ||
end | ||
|
||
return registry_safe_install! if installed_error? | ||
false | ||
end | ||
|
||
# Tries to install the RPM of Docker Distribution. It will forcefully do so if | ||
# the "PORTUSCTL_FORCE" environment variable has been set. | ||
def registry_safe_install! | ||
return install_registry_rpm! if ENV["PORTUSCTL_FORCE"] | ||
|
||
puts "You are using the `--local-registry` flag but the `docker-disitribution-registry` "\ | ||
"package is not installed in the system." | ||
puts "Installing this package after this will overwrite the contents of the " \ | ||
"`/etc/registry/config.yml` file written by portusctl." | ||
puts "Would you like portusctl to automatically install this package ? (Y/n)" | ||
|
||
return install_registry_rpm! if user_confirm? | ||
|
||
puts "Aborting: the registry will not be configured." | ||
false | ||
end | ||
|
||
# Installs the RPM of Docker Distribution. | ||
def install_registry_rpm! | ||
Runner.safe_exec("zypper", ["-q", "-n", "--no-gpg-checks", "in", REGISTRY_RPM]) | ||
end | ||
|
||
# Returns true if the last system() call returned a ZYPPER_NOT_INSTALLED | ||
# error. | ||
def installed_error? | ||
$CHILD_STATUS == ZYPPER_NOT_INSTALLED | ||
end | ||
|
||
# Returns true if the user wrote either "y", "yes" (including uppercase | ||
# variations) or nothing. | ||
def user_confirm? | ||
opt = $stdin.gets.chomp.downcase | ||
opt == "" || opt == "y" || opt == "yes" | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
require_relative "spec_helper" | ||
require "man_pages" | ||
|
||
# Returns the path of the given markdown file. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
require_relative "spec_helper" | ||
|
||
class Klass | ||
include Portusctl::Registry | ||
|
||
def registry_local_test? | ||
registry_local? | ||
end | ||
|
||
def registry_safe_install_test! | ||
registry_safe_install! | ||
end | ||
|
||
def user_confirm? | ||
val = ENV["TEST_CONFIRM"] | ||
val == "y" || val == "yes" | ||
end | ||
|
||
def installed_error? | ||
ZYPPER_NOT_INSTALLED == ENV["TEST_EXIT_STATUS"].to_i | ||
end | ||
end | ||
|
||
class Runner | ||
def self.safe_exec_test(_cmd, _args = []) | ||
ENV["TEST_EXIT_STATUS"].nil? | ||
end | ||
end | ||
|
||
describe Portusctl::Registry do | ||
let(:klass) { Klass.new } | ||
|
||
before :each do | ||
ENV["TEST_CONFIRM"] = nil | ||
ENV["TEST_EXIT_STATUS"] = nil | ||
ENV["PORTUSCTL_FORCE"] = nil | ||
|
||
allow(Runner).to receive(:safe_exec) { Runner.safe_exec_test("zypper") } | ||
end | ||
|
||
context "PORTUSCTL_FORCE has been set" do | ||
it "returns true if the package already exists" do | ||
ENV["PORTUSCTL_FORCE"] = "t" | ||
expect(klass.registry_local_test?).to be_truthy | ||
end | ||
|
||
it "installs the RPM" do | ||
ENV["PORTUSCTL_FORCE"] = "t" | ||
expect(klass.registry_safe_install_test!).to be_truthy | ||
|
||
ENV["TEST_EXIT_STATUS"] = "1" | ||
expect(klass.registry_safe_install_test!).to be_falsey | ||
end | ||
end | ||
|
||
context "Manual execution" do | ||
it "returns true if the package exists and the user wants to overwrite the config" do | ||
|
||
ENV["TEST_CONFIRM"] = "y" | ||
expect(klass.registry_local_test?).to be_truthy | ||
|
||
ENV["TEST_CONFIRM"] = "n" | ||
expect(klass.registry_local_test?).to be_falsey | ||
end | ||
|
||
it "returns false if `zypper se` failed for an unknown reason" do | ||
ENV["TEST_EXIT_STATUS"] = "1" | ||
|
||
expect(klass.registry_local_test?).to be_falsey | ||
end | ||
|
||
it "calls `registry_safe_install!` if the package has not been installed" do | ||
ENV["TEST_EXIT_STATUS"] = "104" | ||
allow_any_instance_of(Klass).to receive(:registry_safe_install!).and_return(true) | ||
|
||
expect(klass.registry_local_test?).to be_truthy | ||
end | ||
|
||
it "installs the rpm if confirmation was given" do | ||
# The user gives confirmation | ||
ENV["TEST_CONFIRM"] = "y" | ||
|
||
# The command succeeds | ||
ENV["TEST_EXIT_STATUS"] = nil | ||
expect(klass.registry_safe_install_test!).to be_truthy | ||
|
||
# The command fails | ||
ENV["TEST_EXIT_STATUS"] = "1" | ||
expect(klass.registry_safe_install_test!).to be_falsey | ||
|
||
# No confirmation: should fail | ||
ENV["TEST_CONFIRM"] = "n" | ||
ENV["TEST_EXIT_STATUS"] = nil | ||
expect(klass.registry_safe_install_test!).to be_falsey | ||
end | ||
end | ||
end |