Skip to content

Commit

Permalink
Merge pull request #1008 from yast/self_update_relurl
Browse files Browse the repository at this point in the history
Self-update: support relative URLs (relurl://) (jsc#SLE-22669)
  • Loading branch information
lslezak committed Dec 16, 2021
2 parents 56d1204 + e10c968 commit bdddb73
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 12 deletions.
42 changes: 41 additions & 1 deletion doc/SELF_UPDATE.md
Expand Up @@ -296,7 +296,47 @@ or by the `setup_dhcp` YaST client which does not need to remember any state.

Currently only HTTP/HTTPS and FTP URL schemes are supported for downloading
the updates. Some additional schemes might work but are not tested and therefore
not supported.
not supported. (See `man zypper` for the complete list of possible URLs.)

Additionally the self-update supports the `relurl://` schema. This refers to a
location relative to the installation repository (defined by the `install` boot
parameter which by default uses the booting device).

### Relative URL Examples

Using a relative URL (relurl://) can be useful when serving the packages via a
local installation server or when building a custom installation medium which
includes a self-update repository.

#### Custom DVD/USB Medium

Assume the installation repository is at the medium root (`/`) and the
self-update repository in the `self_update` subdirectory.

Then you can add the `self_update=relurl://self_update` boot option directly to
the default boot parameters and it will work properly even if the medium is
copied to an USB stick, hard disk or a network server.

#### Installation Server

Relative URL can be also useful when you copy the original installation medium
unmodified to a network server.

Assume that the installation packages are available via
`http://example.com/repo` and a self-update repository is available at
`http://example.com/self_update`.

Then you can use the `install=http://example.com/repo` and
`self_update=relurl://../self_update` boot parameters. *That means you can even
go up in the directory structure using the usual `../` notation!*

The advantage is that you do not need to change the `self_update` parameter
when the repositories are moved to a different location or different server.

But the most beneficial is using a relative URL in an AutoYaST profile. Then the
same AutoYaST profile can work with different product versions without any
change if you use the same repository structure on the server for all versions.


## Error Handling

Expand Down
8 changes: 8 additions & 0 deletions package/yast2-installation.changes
@@ -1,3 +1,11 @@
-------------------------------------------------------------------
Thu Dec 16 13:43:05 UTC 2021 - Ladislav Slezák <lslezak@suse.cz>

- Self-update now supports relative URLs (relurl://), it defines
the self-update repository relatively to the main installation
repository (jsc#SLE-22669)
- 4.4.30

-------------------------------------------------------------------
Thu Dec 16 07:34:27 UTC 2021 - Imobach Gonzalez Sosa <igonzalezsosa@suse.com>

Expand Down
10 changes: 5 additions & 5 deletions package/yast2-installation.spec
Expand Up @@ -17,7 +17,7 @@


Name: yast2-installation
Version: 4.4.29
Version: 4.4.30
Release: 0
Summary: YaST2 - Installation Parts
License: GPL-2.0-only
Expand All @@ -28,8 +28,8 @@ Source1: YaST2-Second-Stage.service
Source2: YaST2-Firstboot.service

BuildRequires: update-desktop-files
# y2packager/exceptions
BuildRequires: yast2 >= 4.4.24
# Yast2::RelURL
BuildRequires: yast2 >= 4.4.28
# CIOIgnore
BuildRequires: yast2-bootloader
# storage-ng based version
Expand Down Expand Up @@ -70,8 +70,8 @@ Requires: iproute2
Requires: pciutils
# tar-gzip some system files and untar-ungzip them after the installation (FATE #300421, #120103)
Requires: tar
# y2packager/exceptions
Requires: yast2 >= 4.4.24
# Yast2::RelURL
Requires: yast2 >= 4.4.28
# CIOIgnore
Requires: yast2-bootloader
Requires: yast2-country >= 3.3.1
Expand Down
19 changes: 18 additions & 1 deletion src/lib/installation/update_repositories_finder.rb
Expand Up @@ -15,6 +15,7 @@

require "yast"
require "installation/update_repository"
require "yast2/rel_url"
require "uri"

Yast.import "Pkg"
Expand All @@ -27,6 +28,7 @@
Yast.import "ProductFeatures"
Yast.import "InstFunctions"
Yast.import "OSRelease"
Yast.import "URL"

module Installation
# Invalid registration URL error
Expand Down Expand Up @@ -150,6 +152,8 @@ def update_urls_from_connect

# Converts the string into an URI if it's valid
#
# Expands a relative URL (relurl://) to an URL relative to the installation
# repository.
# Substituting $arch pattern with the architecture of the current system.
# Substituting these variables with the /etc/os-release content:
# $os_release_name => NAME
Expand All @@ -172,7 +176,20 @@ def get_url_from(url)
Yast::OSRelease.ReleaseVersion)
real_url = real_url.gsub(/\$os_release_version\b/,
Yast::OSRelease.ReleaseVersionHumanReadable)
URI.regexp.match(real_url) ? URI(real_url) : nil

return nil unless URI.regexp.match(real_url)

# convert a relative URL to absolute
if Yast2::RelURL.relurl?(real_url)
# relative URL is relative to the installation repository
relurl = Yast2::RelURL.from_installation_repository(real_url)
absolute_url = relurl.absolute_url
log.info "Relative URL #{Yast::URL.HidePassword(real_url)} "\
"converted to absolute URL #{Yast::URL.HidePassword(absolute_url.to_s)}"
absolute_url
else
URI(real_url)
end
end

# Return the URL of the preferred registration server
Expand Down
24 changes: 19 additions & 5 deletions test/lib/update_repositories_finder_test.rb
Expand Up @@ -30,15 +30,29 @@
.and_return(url_from_linuxrc)
allow(Yast::Pkg).to receive(:GetArchitecture).and_return(arch)
allow(Yast::AutoinstGeneral).to receive(:self_update_url).and_return(nil)
allow(Yast::InstURL).to receive(:installInf2Url)
.and_return("http://example.com/install/sle15-sp3")
end

context "when URL was specified via Linuxrc" do
let(:url_from_linuxrc) { "http://example.net/sles12/" }
context "a normal URL is used" do
let(:url_from_linuxrc) { "http://example.net/sles12/" }

it "returns the updates repository using the URL from Linuxrc" do
expect(Installation::UpdateRepository).to receive(:new)
.with(URI(url_from_linuxrc), :user).and_return(repo)
expect(finder.updates).to eq([repo])
it "returns the updates repository using the URL from Linuxrc" do
expect(Installation::UpdateRepository).to receive(:new)
.with(URI(url_from_linuxrc), :user).and_return(repo)
expect(finder.updates).to eq([repo])
end
end

context "a relative URL is used" do
let(:url_from_linuxrc) { "relurl://../self_update" }

it "returns the updates repository relative to the installation repository" do
expect(Installation::UpdateRepository).to receive(:new)
.with(URI("http://example.com/install/self_update"), :user).and_return(repo)
expect(finder.updates).to eq([repo])
end
end
end

Expand Down

0 comments on commit bdddb73

Please sign in to comment.