diff --git a/.build_id b/.build_id index 298c7617c..50a688c4a 100644 --- a/.build_id +++ b/.build_id @@ -1 +1 @@ -18.09.0.build20181114183007 +18.09.0.build20181115124313 diff --git a/os/packages/osctl/Gemfile b/os/packages/osctl/Gemfile index 72aa0f52e..a65cc77c5 100644 --- a/os/packages/osctl/Gemfile +++ b/os/packages/osctl/Gemfile @@ -1,2 +1,2 @@ source 'https://rubygems.vpsfree.cz' -gem 'osctl', '18.09.0.build20181114183007' +gem 'osctl', '18.09.0.build20181115124313' diff --git a/os/packages/osctl/Gemfile.lock b/os/packages/osctl/Gemfile.lock index c4246f4d6..ab30538c7 100644 --- a/os/packages/osctl/Gemfile.lock +++ b/os/packages/osctl/Gemfile.lock @@ -6,15 +6,15 @@ GEM highline (1.7.10) ipaddress (0.8.3) json (2.1.0) - libosctl (18.09.0.build20181114183007) + libosctl (18.09.0.build20181115124313) require_all (~> 2.0.0) - osctl (18.09.0.build20181114183007) + osctl (18.09.0.build20181115124313) curses gli (~> 2.17.1) highline (~> 1.7.10) ipaddress (~> 0.8.3) json - libosctl (= 18.09.0.build20181114183007) + libosctl (= 18.09.0.build20181115124313) rainbow (~> 3.0.0) require_all (~> 2.0.0) ruby-progressbar (~> 1.9.0) @@ -26,7 +26,7 @@ PLATFORMS ruby DEPENDENCIES - osctl (= 18.09.0.build20181114183007) + osctl (= 18.09.0.build20181115124313) BUNDLED WITH 1.16.3 diff --git a/os/packages/osctl/gemset.nix b/os/packages/osctl/gemset.nix index f25f60f75..e882adc0c 100644 --- a/os/packages/osctl/gemset.nix +++ b/os/packages/osctl/gemset.nix @@ -43,19 +43,19 @@ dependencies = ["require_all"]; source = { remotes = ["https://rubygems.vpsfree.cz"]; - sha256 = "1dsbw1in295jra4bgllklgsf7gvgppr37l7kj6gfhvnvnjdkm09s"; + sha256 = "0ibqm6hs74gh2dn23ir0aqs3l25rssh5wjqbvbjvsnvcbki2lnkj"; type = "gem"; }; - version = "18.09.0.build20181114183007"; + version = "18.09.0.build20181115124313"; }; osctl = { dependencies = ["curses" "gli" "highline" "ipaddress" "json" "libosctl" "rainbow" "require_all" "ruby-progressbar"]; source = { remotes = ["https://rubygems.vpsfree.cz"]; - sha256 = "10mf07cl29l1x6yqrf12m8l70js36qi43wysf6xlyassr9jcphfb"; + sha256 = "1wb7c70bcqvrvr8x85x6iyx7lkl716sbh0k1b72iy3icyzinzil3"; type = "gem"; }; - version = "18.09.0.build20181114183007"; + version = "18.09.0.build20181115124313"; }; rainbow = { source = { diff --git a/os/packages/osctld/Gemfile b/os/packages/osctld/Gemfile index de5e49385..7317177dd 100644 --- a/os/packages/osctld/Gemfile +++ b/os/packages/osctld/Gemfile @@ -1,2 +1,2 @@ source 'https://rubygems.vpsfree.cz' -gem 'osctld', '18.09.0.build20181114183007' +gem 'osctld', '18.09.0.build20181115124313' diff --git a/os/packages/osctld/Gemfile.lock b/os/packages/osctld/Gemfile.lock index da488d8ec..fb767d80a 100644 --- a/os/packages/osctld/Gemfile.lock +++ b/os/packages/osctld/Gemfile.lock @@ -6,29 +6,29 @@ GEM gli (2.17.2) ipaddress (0.8.3) json (2.1.0) - libosctl (18.09.0.build20181114183007) + libosctl (18.09.0.build20181115124313) require_all (~> 2.0.0) netlinkrb (0.18.vpsadminos.0) - osctl-repo (18.09.0.build20181114183007) + osctl-repo (18.09.0.build20181115124313) filelock gli (~> 2.17.1) json - libosctl (= 18.09.0.build20181114183007) + libosctl (= 18.09.0.build20181115124313) require_all (~> 2.0.0) - osctld (18.09.0.build20181114183007) + osctld (18.09.0.build20181115124313) concurrent-ruby (~> 1.0.5) ipaddress (~> 0.8.3) json - libosctl (= 18.09.0.build20181114183007) + libosctl (= 18.09.0.build20181115124313) netlinkrb (= 0.18.vpsadminos.0) - osctl-repo (= 18.09.0.build20181114183007) - osup (= 18.09.0.build20181114183007) + osctl-repo (= 18.09.0.build20181115124313) + osup (= 18.09.0.build20181115124313) require_all (~> 2.0.0) ruby-lxc (= 1.2.3) - osup (18.09.0.build20181114183007) + osup (18.09.0.build20181115124313) gli (~> 2.17.1) json - libosctl (= 18.09.0.build20181114183007) + libosctl (= 18.09.0.build20181115124313) require_all (~> 2.0.0) require_all (2.0.0) ruby-lxc (1.2.3) @@ -37,7 +37,7 @@ PLATFORMS ruby DEPENDENCIES - osctld (= 18.09.0.build20181114183007) + osctld (= 18.09.0.build20181115124313) BUNDLED WITH 1.16.3 diff --git a/os/packages/osctld/gemset.nix b/os/packages/osctld/gemset.nix index aed6b76b5..32ed46c6c 100644 --- a/os/packages/osctld/gemset.nix +++ b/os/packages/osctld/gemset.nix @@ -43,10 +43,10 @@ dependencies = ["require_all"]; source = { remotes = ["https://rubygems.vpsfree.cz"]; - sha256 = "1dsbw1in295jra4bgllklgsf7gvgppr37l7kj6gfhvnvnjdkm09s"; + sha256 = "0ibqm6hs74gh2dn23ir0aqs3l25rssh5wjqbvbjvsnvcbki2lnkj"; type = "gem"; }; - version = "18.09.0.build20181114183007"; + version = "18.09.0.build20181115124313"; }; netlinkrb = { source = { @@ -60,28 +60,28 @@ dependencies = ["filelock" "gli" "json" "libosctl" "require_all"]; source = { remotes = ["https://rubygems.vpsfree.cz"]; - sha256 = "12ss03sqmn7a2rshcjwp0rbslhlvcx7pbx868azxqi4pw4my67f8"; + sha256 = "1j0dz5q7hl1di2rzppfsa0fgin63l4nm3gyib4v726c5403l9dnk"; type = "gem"; }; - version = "18.09.0.build20181114183007"; + version = "18.09.0.build20181115124313"; }; osctld = { dependencies = ["concurrent-ruby" "ipaddress" "json" "libosctl" "netlinkrb" "osctl-repo" "osup" "require_all" "ruby-lxc"]; source = { remotes = ["https://rubygems.vpsfree.cz"]; - sha256 = "0sjcvmpvxfsbsmhlqibcn98xlaj3x23ydybmxnsypfd4snh03h47"; + sha256 = "00w6b0a01ckz7vr2d704j1isx6lnpcrkgn72ddasw392pqli83bi"; type = "gem"; }; - version = "18.09.0.build20181114183007"; + version = "18.09.0.build20181115124313"; }; osup = { dependencies = ["gli" "json" "libosctl" "require_all"]; source = { remotes = ["https://rubygems.vpsfree.cz"]; - sha256 = "04gf1nxw2i4qijddyys6xrggzkr0vca2n24yjb79f78h3dc225xw"; + sha256 = "0piqri8m1drpgcp7bqpgk1kh9kbzssfybbkzvp2whfdpmnkndvm5"; type = "gem"; }; - version = "18.09.0.build20181114183007"; + version = "18.09.0.build20181115124313"; }; require_all = { source = { diff --git a/os/packages/osup/Gemfile b/os/packages/osup/Gemfile index a845685e4..30a6bc15f 100644 --- a/os/packages/osup/Gemfile +++ b/os/packages/osup/Gemfile @@ -1,2 +1,2 @@ source 'https://rubygems.vpsfree.cz' -gem 'osup', '18.09.0.build20181114183007' +gem 'osup', '18.09.0.build20181115124313' diff --git a/os/packages/osup/Gemfile.lock b/os/packages/osup/Gemfile.lock index 6f91efffe..8b4406f9f 100644 --- a/os/packages/osup/Gemfile.lock +++ b/os/packages/osup/Gemfile.lock @@ -3,12 +3,12 @@ GEM specs: gli (2.17.2) json (2.1.0) - libosctl (18.09.0.build20181114183007) + libosctl (18.09.0.build20181115124313) require_all (~> 2.0.0) - osup (18.09.0.build20181114183007) + osup (18.09.0.build20181115124313) gli (~> 2.17.1) json - libosctl (= 18.09.0.build20181114183007) + libosctl (= 18.09.0.build20181115124313) require_all (~> 2.0.0) require_all (2.0.0) @@ -16,7 +16,7 @@ PLATFORMS ruby DEPENDENCIES - osup (= 18.09.0.build20181114183007) + osup (= 18.09.0.build20181115124313) BUNDLED WITH 1.16.3 diff --git a/os/packages/osup/gemset.nix b/os/packages/osup/gemset.nix index 7a16e48cf..a1ac34812 100644 --- a/os/packages/osup/gemset.nix +++ b/os/packages/osup/gemset.nix @@ -19,19 +19,19 @@ dependencies = ["require_all"]; source = { remotes = ["https://rubygems.vpsfree.cz"]; - sha256 = "1dsbw1in295jra4bgllklgsf7gvgppr37l7kj6gfhvnvnjdkm09s"; + sha256 = "0ibqm6hs74gh2dn23ir0aqs3l25rssh5wjqbvbjvsnvcbki2lnkj"; type = "gem"; }; - version = "18.09.0.build20181114183007"; + version = "18.09.0.build20181115124313"; }; osup = { dependencies = ["gli" "json" "libosctl" "require_all"]; source = { remotes = ["https://rubygems.vpsfree.cz"]; - sha256 = "04gf1nxw2i4qijddyys6xrggzkr0vca2n24yjb79f78h3dc225xw"; + sha256 = "0piqri8m1drpgcp7bqpgk1kh9kbzssfybbkzvp2whfdpmnkndvm5"; type = "gem"; }; - version = "18.09.0.build20181114183007"; + version = "18.09.0.build20181115124313"; }; require_all = { source = { diff --git a/os/packages/svctl/Gemfile b/os/packages/svctl/Gemfile index 239616e86..17a00d5d2 100644 --- a/os/packages/svctl/Gemfile +++ b/os/packages/svctl/Gemfile @@ -1,2 +1,2 @@ source 'https://rubygems.vpsfree.cz' -gem 'svctl', '18.09.0.build20181114183007' +gem 'svctl', '18.09.0.build20181115124313' diff --git a/os/packages/svctl/Gemfile.lock b/os/packages/svctl/Gemfile.lock index 81361c06b..d1c0bb6f6 100644 --- a/os/packages/svctl/Gemfile.lock +++ b/os/packages/svctl/Gemfile.lock @@ -2,18 +2,18 @@ GEM remote: https://rubygems.vpsfree.cz/ specs: gli (2.17.2) - libosctl (18.09.0.build20181114183007) + libosctl (18.09.0.build20181115124313) require_all (~> 2.0.0) require_all (2.0.0) - svctl (18.09.0.build20181114183007) + svctl (18.09.0.build20181115124313) gli (~> 2.17.1) - libosctl (= 18.09.0.build20181114183007) + libosctl (= 18.09.0.build20181115124313) PLATFORMS ruby DEPENDENCIES - svctl (= 18.09.0.build20181114183007) + svctl (= 18.09.0.build20181115124313) BUNDLED WITH 1.16.3 diff --git a/os/packages/svctl/gemset.nix b/os/packages/svctl/gemset.nix index b665b3a18..06559727f 100644 --- a/os/packages/svctl/gemset.nix +++ b/os/packages/svctl/gemset.nix @@ -11,10 +11,10 @@ dependencies = ["require_all"]; source = { remotes = ["https://rubygems.vpsfree.cz"]; - sha256 = "1dsbw1in295jra4bgllklgsf7gvgppr37l7kj6gfhvnvnjdkm09s"; + sha256 = "0ibqm6hs74gh2dn23ir0aqs3l25rssh5wjqbvbjvsnvcbki2lnkj"; type = "gem"; }; - version = "18.09.0.build20181114183007"; + version = "18.09.0.build20181115124313"; }; require_all = { source = { @@ -28,9 +28,9 @@ dependencies = ["gli" "libosctl"]; source = { remotes = ["https://rubygems.vpsfree.cz"]; - sha256 = "00m6zqnajijpckclw6d14ypfq7y27s3pcj3a251887yapcx7rbjd"; + sha256 = "1wwsf4z78wl2p9bf297rakyw0539007ky3ipjbvay6d62hdi5k7w"; type = "gem"; }; - version = "18.09.0.build20181114183007"; + version = "18.09.0.build20181115124313"; }; } \ No newline at end of file diff --git a/osctld/lib/osctld/dist_config/base.rb b/osctld/lib/osctld/dist_config/base.rb index a92c5e80f..17c3fdaad 100644 --- a/osctld/lib/osctld/dist_config/base.rb +++ b/osctld/lib/osctld/dist_config/base.rb @@ -94,59 +94,18 @@ def bin_path(_opts) # hostname. # @param old_hostname [OsCtl::Lib::Hostname, nil] def update_etc_hosts(old_hostname = nil) - hosts = File.join(ct.rootfs, 'etc', 'hosts') - return unless writable?(hosts) + path = File.join(ct.rootfs, 'etc', 'hosts') + return unless writable?(path) - regenerate_file(hosts, 0644) do |new, old| - old.each_line do |line| - if (/^127\.0\.0\.1\s/ =~ line || /^::1\s/ =~ line) \ - && !includes_hostname?(line, ct.hostname) + hosts = EtcHosts.new(path) - if old_hostname && includes_hostname?(line, old_hostname) - new.puts(replace_host(line, old_hostname, ct.hostname)) - - else - new.puts(add_host(line.strip, ct.hostname)) - end - - else - new.write(line) - end - end + if old_hostname + hosts.replace(old_hostname, ct.hostname) + else + hosts.set(ct.hostname) end end - # Check if a line of string contains specific hostname - # @param line [String] - # @param hostname [OsCtl::Lib::Hostname] - def includes_hostname?(line, hostname) - /\s#{Regexp.escape(hostname.fqdn)}(\s|$)/ =~ line - end - - # Add `hostname` to `line` from `/etc/hosts` - # - # The hostname is put into the first position. - # - # @param line [String] - # @param hostname [OsCtl::Lib::Hostname] - def add_host(line, hostname) - return if line !~ /^([^\s]+)(\s+)/ - - i = $~.end(2) - "#{$1}#{$2}#{hostname.fqdn} #{line[i..-1]}" - end - - # Remove `hostname` from `line` read from `/etc/hosts` - # - # @param line [String] - # @param hostname [OsCtl::Lib::Hostname] - def replace_host(line, old_hostname, new_hostname) - line.sub( - /(\s)#{Regexp.escape(old_hostname.fqdn)}(\s|$)/, - "\\1#{new_hostname.fqdn}\\2" - ) - end - # Check if the file at `path` si writable by its user # # If the file doesn't exist, we take it as writable. If a block is given, diff --git a/osctld/lib/osctld/etc_hosts.rb b/osctld/lib/osctld/etc_hosts.rb new file mode 100644 index 000000000..1055a3566 --- /dev/null +++ b/osctld/lib/osctld/etc_hosts.rb @@ -0,0 +1,148 @@ +require 'libosctl' + +module OsCtld + # Manipulate localhost hostnames in `/etc/hosts` like files + class EtcHosts + include OsCtl::Lib::Utils::File + + # @return [String] + attr_reader :path + + # @param path [String] path to the hosts file + def initialize(path) + @path = path + end + + # @param hostname [OsCtl::Lib::Hostname] + def set(hostname) + names = all_names(hostname) + + do_edit(names) do |line| + next(line) if (/^127\.0\.0\.1\s/ !~ line && /^::1\s/ !~ line) + + new_line = line.strip + last = nil + + names.each do |name| + next if includes_name?(new_line, name) + + new_line = add_name(new_line, name, after: last) + last = name + end + + new_line << "\n" + new_line + end + end + + # @param old_hostname [OsCtl::Lib::Hostname] + # @param new_hostname [OsCtl::Lib::Hostname] + def replace(old_hostname, new_hostname) + old_names = all_names(old_hostname) + new_names = all_names(new_hostname) + + do_edit(new_names) do |line| + next(line) if (/^127\.0\.0\.1\s/ !~ line && /^::1\s/ !~ line) + + new_line = line.strip + last = nil + + zip_all(new_names, old_names).each do |new_name, old_name| + if old_name && includes_name?(new_line, old_name) + new_line = replace_name(new_line, old_name, new_name || '') + elsif new_name + new_line = add_name(new_line, new_name, after: last) + end + + last = new_name + end + + new_line << "\n" + new_line + end + end + + protected + # Edit the hosts file and let the caller transform it + # + # If the target file exists, it is read and each line is yielded to the + # caller. The caller returns the new value that is written to the target + # file instead of the original line. + # + # If the target file does not exist, it is created and populated with + # `names`. Nothing is yielded to the caller in that case. + # + # @param names [Array] list of hostnames to set + def do_edit(names) + regenerate_file(path, 0644) do |new, old| + if old + old.each_line do |line| + new.write(yield(line)) + end + + else + new.write(<