Commit 9109ba4a authored by intrigeri's avatar intrigeri
Browse files

Merge branch 'stable' into devel

parents 5b007c08 43ad44de
......@@ -65,9 +65,6 @@ systemctl mask hwclock-save.service
# Do not run timesyncd: we have our own time synchronization mechanism
systemctl mask systemd-timesyncd.service
# apt-daily.service can only cause problems in our context (#12390)
systemctl mask apt-daily.timer
# Do not let pppd-dns manage /etc/resolv.conf
systemctl mask pppd-dns.service
......
# This configuration should not run during Tails build. It is enabled in the
# end of the build by /config/chroot_local-hooks/99-zz-install-ASP-DPKG-hooks
# end of the build by config/chroot_local-hooks/99-zz-install-ASP-DPKG-hooks
DPkg::Pre-Install-Pkgs { "/usr/local/sbin/tails-additional-software apt-pre"; };
DPkg::Post-Invoke { "/usr/local/sbin/tails-additional-software apt-post"; };
DPkg::Tools::Options::/usr/local/sbin/tails-additional-software::Version "3";
# This effectively disables apt-daily*.{timer,service}, which might
# interfere with Additional Software operations (#12390, #17278)
APT::Periodic::Enable "0";
......@@ -17,6 +17,13 @@ DefaultDependencies=no
Type=oneshot
RemainAfterExit=yes
ExecStop=/bin/rm -rf /lib/live/mount/overlay/rw /lib/live/mount/overlay/work
# Tails sets a very small DefaultTimeoutStopSec= value, that this
# service inherits. There's a risk that this default timeout is too
# short for our ExecStop= step to complete successfully. Were this to
# happen, the impact would be incomplete erasing of memory on
# shutdown, which is not great. So let's reset this timeout to the
# default systemd one for this service.
TimeoutStopSec=90s
[Install]
WantedBy=multi-user.target
......@@ -8,12 +8,24 @@ ExecStop=/bin/sh -c ' \
if mountpoint -q /media/tails-persistence-setup/TailsData \
&& test ! -d /media/tails-persistence-setup/TailsData/apt; then \
echo "Copy APT data to newly created persistent volume"; \
touch /media/tails-persistence-setup/TailsData/apt_sync_started && \
mkdir /media/tails-persistence-setup/TailsData/apt/ && \
cp -a /var/cache/apt/archives \
/media/tails-persistence-setup/TailsData/apt/cache && \
cp -a /var/lib/apt/lists \
/media/tails-persistence-setup/TailsData/apt/; \
/media/tails-persistence-setup/TailsData/apt/ && \
touch /media/tails-persistence-setup/TailsData/apt_sync_completed && \
sync --file-system /media/tails-persistence-setup/TailsData/apt; \
fi'
# Tails sets a very small DefaultTimeoutStopSec= value, that this service
# inherits. In many cases, that value is too short for our ExecStop=
# step to complete successfully (#17278) so we need to bump this timeout here.
#
# APT lists are 215MB large as of 4.6. The cached binary packages can be
# arbitrarily large, let's assume 335MB. So we need to copy 550MB from tmpfs
# to a physical USB stick. Assuming a 2MB/s write rate in the worst case
# scenario, the copy operation can take up to 550/2 = 275 seconds.
TimeoutStopSec=300s
[Install]
WantedBy=multi-user.target
......@@ -26,9 +26,6 @@ os.environ['PATH'] = '/usr/local/bin:/usr/bin:/bin'
os.environ['TEXTDOMAIN'] = 'tails'
CMD = os.path.basename(sys.argv[0])
TORDATE_DIR = '/run/tordate'
TORDATE_DONE_FILE = '{}/done'.format(TORDATE_DIR)
INOTIFY_TIMEOUT = 60
# While running iuk.git:features/frontend:
# - tails-upgrade-frontend never uses more than 100 * 10^6 bytes
# - tails-iuk-get-upgrade-description never uses more than 95 * 10^6 bytes
......@@ -47,10 +44,10 @@ See https://tails.boum.org/doc/first_steps/upgrade#manual\"''')
def main(*args):
if "--no-wait" not in args:
time.sleep(30)
else:
if "--no-wait" in args:
args = (arg for arg in args if arg != "--no-wait")
else:
time.sleep(30)
check_free_memory(MIN_AVAILABLE_MEMORY)
......@@ -65,7 +62,8 @@ def main(*args):
"/bin/sh", "-c",
"xhost +SI:localuser:{user};"
"sudo -u {user} /usr/local/bin/tails-upgrade-frontend {args};"
"xhost -SI:localuser:{user}".format(user=RUN_AS_USER, args=" ".join(args))
"xhost -SI:localuser:{user}".format(user=RUN_AS_USER,
args=" ".join(args))
)
)
......@@ -73,11 +71,12 @@ def main(*args):
def error(msg):
"""Show error and exit."""
cli_text = '{}: {} {}'.format(CMD, gettext('error:'), msg)
dialog_text = '''<b><big>{}</big></b>\n\n{}'''.format(gettext('Error'), msg)
dialog_text = '''<b><big>{}</big></b>\n\n{}'''.format(gettext('Error'),
msg)
print(cli_text, file=sys.stderr)
sh.zenity('--error', '--ellipsize', '--title', "", '--text', dialog_text,
_ok_code=[0,1,5])
_ok_code=[0, 1, 5])
sys.exit(1)
......
......@@ -256,7 +256,7 @@ def save_old_apt_lists(srcdir=APT_LISTS_DIR, destdir=OLD_APT_LISTS_DIR):
logging.warning("Warning: a copy of the APT lists already exists, "
"which should never happen. Removing it.")
delete_old_apt_lists(destdir)
shutil.copytree(srcdir, destdir, symlinks=True)
subprocess.run(['cp', '--archive', srcdir, destdir], check=True)
# Note: we can't do nicer delete + move operations because the directory
......@@ -611,7 +611,8 @@ def upgrade_additional_packages():
delete_old_apt_lists()
# Remove outdated packages from the local package cache. This is needed as
# we disable apt-daily.timer, which would else take care of this cleanup.
# we disable apt-daily*.timer (via APT::Periodic::Enable), which would
# else take care of this cleanup.
# We do this after the upgrade has succeeded so that the old packages
# remain available in the cache in case we have to restore the old lists.
# In the past we did this before upgrading in order to remove the
......
......@@ -559,7 +559,10 @@ Given /^I kill the process "([^"]+)"$/ do |process|
end
Then /^Tails eventually (shuts down|restarts)$/ do |mode|
try_for(3*60) do
# In the Additional Software feature, we need to wait enough for
# tails-synchronize-data-to-new-persistent-volume-on-shutdown.service
# to complete: see its custom, higher-than-default, TimeoutStopSec=.
try_for(6 * 60) do
if mode == 'restarts'
@screen.find('TailsGreeter.png')
true
......
......@@ -107,21 +107,46 @@ def add_after_scenario_hook(&block)
@after_scenario_hooks << block
end
def save_failure_artifact(type, path)
$failure_artifacts << [type, path]
def save_failure_artifact(desc, path)
$failure_artifacts << [desc, path]
end
def save_journal(path)
File.open("#{path}/systemd.journal", 'w') { |file|
$vm.execute('journalctl -a --no-pager > /tmp/systemd.journal')
file.write($vm.file_content('/tmp/systemd.journal'))
}
save_failure_artifact("Systemd journal", "#{path}/systemd.journal")
def _save_vm_file_content(file:, destfile:, desc:)
destfile = $config['TMPDIR'] + '/' + destfile
File.open(destfile, 'w') { |f| f.write($vm.file_content(file)) }
save_failure_artifact(desc, destfile)
rescue Exception => e
info_log("Exception thrown while trying to save the journal: " +
info_log("Exception thrown while trying to save #{destfile}: " +
"#{e.class.name}: #{e}")
end
def save_vm_command_output(command:, id:, basename: nil, desc: nil)
basename ||= "artifact.cmd_output_#{id}"
$vm.execute("#{command} > /tmp/#{basename} 2>&1")
_save_vm_file_content(
file: "/tmp/#{basename}",
destfile: basename,
desc: desc || "Output of #{command}"
)
end
def save_journal
save_vm_command_output(
command: 'journalctl -a --no-pager',
id: 'journal',
basename: 'artifact.journal',
desc: 'systemd Journal'
)
end
def save_vm_file_content(file, desc: nil)
_save_vm_file_content(
file: file,
destfile: 'artifact.file_content_' + file.gsub('/', '_').sub(/^_/, ''),
desc: desc || "Content of #{file}"
)
end
# Due to Tails' Tor enforcement, we only allow contacting hosts that
# are Tor nodes, located on the LAN, or allowed for some operational reason.
# However, when we try to verify that only such hosts are contacted we have
......@@ -276,16 +301,33 @@ After('@product') do |scenario|
# we cause a system crash), so let's collect everything depending
# on the remote shell here:
if $vm && $vm.remote_shell_is_up?
save_journal($config['TMPDIR'])
save_journal
if scenario.feature.file \
== 'features/additional_software_packages.feature'
save_vm_command_output(
command: 'ls -lAR --full-time /var/lib/apt',
id: 'var_lib_apt',
)
save_vm_command_output(
command: 'mount',
id: 'mount',
)
save_vm_command_output(
command: 'ls -lA --full-time /live/persistence/TailsData_unlocked',
id: 'persistent_volume',
)
save_vm_file_content('/var/log/live-persist')
save_vm_file_content('/run/live-additional-software/log')
end
end
$failure_artifacts.sort!
$failure_artifacts.each do |type, file|
$failure_artifacts.each do |desc, file|
artifact_name = sanitize_filename("#{elapsed}_#{scenario.name}#{File.extname(file)}")
artifact_path = "#{ARTIFACTS_DIR}/#{artifact_name}"
assert(File.exist?(file))
FileUtils.mv(file, artifact_path)
info_log
info_log_artifact_location(type, artifact_path)
info_log_artifact_location(desc, artifact_path)
end
if $config["INTERACTIVE_DEBUGGING"]
pause(
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment