#!/bin/sh -ex
# This file is part of Build Your Own Virtual machine.
#
# Copyright 2018 Vincent Ladeuil.

# Some useful commands to debug issues around cloud-init on scaleway:
# curl --local-port 1-1024 http://169.254.42.42/user_data/cloud-init
# cat /run/cloud-init/ds-identify.log
# Cloud init runs four stages: init-local init-network modules-config modules-final

# Create a scaleway image usable with byov from a close-enough bootable
# image. This is mainly installing and configuring cloud-init.

# Cleanup
APT_COMMAND="$(echo {apt.command} | sed -e 's/,/ /g')"
$APT_COMMAND autoremove

# At this point we have cloud-init >= 17.1 with scaleway userdata support.


# Which means /etc/cloud//cloud.cfg.d/90_dpkg.cfg (which can be updated by
# running dpkg-reconfigure cloud-init) should contain:

# datasource_list: [ NoCloud, ConfigDrive, OpenNebula, DigitalOcean, Azure,
# AltCloud, OVF, MAAS, GCE, OpenStack, CloudSigma, SmartOS, Bigstep,
# Scaleway, AliYun, Ec2, CloudStack, None ]

# Very slow boots can be explained by wrongly configured datasources
# running 'cloud-init analyze show' will help to spot them.
# RL example (where Ec2 and CloudStack accounted for 4 mins):
# |`->no network data found from DataSourceEc2 @12.90500s +120.22400s
# |`->no network data found from DataSourceCloudStack @133.13200s +126.56400s
# Finished stage: (init-network) 260.33700 seconds 

# Setup cloud-init config with the bare minimum: Scaleway and the fallback
# None.
# Use a name that sorts after 90_dpkg.cfg to override
cat <<EOC > /etc/cloud/cloud.cfg.d/99_byov.cfg
# Generated by byov at $(date)
datasource_list: [ Scaleway, None]
apt_preserve_sources_list: true
disable_root: false
EOC
chmod 644 /etc/cloud/cloud.cfg.d/99_byov.cfg

# Setup apt sources.list for cases where it's not correctly set
# FIXME: cloud-init probably provides a better way but for now, let's stick
# with the simplest approach of forcing a reduced set of sources (and
# telling cloud-init to apt_preserve_sources_list above) -- vila 2018-01-24
# FIXME:
# https://cloudinit.readthedocs.io/en/latest/topics/examples.html#add-apt-repositories
# is the better way -- vila 2018-10-12
cat <<EOS  > /etc/apt/sources.list
deb {{vm.architecture}.mirror} {vm.release} main universe
deb {{vm.architecture}.mirror} {vm.release}-security main universe
deb {{vm.architecture}.mirror} {vm.release}-updates main universe
EOS

chmod 644 /etc/apt/sources.list
# FIXME: This should be 'apt.update.command' with proper retries.
# -- vila 2018-06-05
$APT_COMMAND update


# FIXME: Disabling seems to be a bad idea as the debian cloud team is aiming
# as turning it on by default
# (https://lists.debian.org/debian-cloud/2018/08/msg00001.html). So, a way
# needs to be found for cloud-init/byov to wait for unattended upgrades to
# complete before attempting apt updates. -- vila 2018-08-02
# Disable unattended upgrades at they cause a race with cloud-init/byov
# when apt-get updat'ing. The list of options below was established from
# /usr/lib/apt/apt.systemd.daily
cat <<EOA > /etc/apt/apt.conf.d/99byov
// Generated by byov at $(date)
// Avoid races with apt-get cloud-init/byov uses
// Delete this file to restore unattended upgrades
APT::Periodic::Enable "0";
APT::Periodic::Update-Package-Lists "0";
APT::Periodic::Download-Upgradeable-Packages "0";
APT::Periodic::AutocleanInterval "0";
APT::Periodic::Unattended-Upgrade "0";
APT::Periodic::AutocleanInterval "0";
APT::Periodic::CleanInterval "0";
EOA

# Avoid a circular dependency:
# Jun 04 21:31:30.292717 image-builder-scw-amd64 systemd[1]: sysinit.target: Found ordering cycle on sysinit.target/start
# Jun 04 21:31:30.292741 image-builder-scw-amd64 systemd[1]: sysinit.target: Found dependency on cloud-init.service/start
# Jun 04 21:31:30.292759 image-builder-scw-amd64 systemd[1]: sysinit.target: Found dependency on networking.service/start
# Jun 04 21:31:30.292776 image-builder-scw-amd64 systemd[1]: sysinit.target: Found dependency on scw-generate-net-config.service/start
# Jun 04 21:31:30.292793 image-builder-scw-amd64 systemd[1]: sysinit.target: Found dependency on sysinit.target/start
# Jun 04 21:31:30.292811 image-builder-scw-amd64 systemd[1]: sysinit.target: Breaking ordering cycle by deleting job cloud-init.service/start
# Jun 04 21:31:30.292827 image-builder-scw-amd64 systemd[1]: cloud-init.service: Job cloud-init.service/start deleted to break ordering cycle starting with sysinit.target/start

# FIXME: Progress on that issue is tracked in:
# https://cloud.scaleway.com/#/tickets/GZIR-4840-TNQC and
# https://bugs.launchpad.net/ubuntu/+source/cloud-init/+bug/1775086. By
# disabling scw-generate-net-config.service we're transferring control of
# the network interfaces from scaleway to cloud-init. Caveat
# emptor. Alternatively cloud-init could be told to not touch the network
# interfaces but having cloud-init on scaleway images would avoid the need
# to maintain several scw-* services. Discussion between both parties should
# reach a consensus. Until then, disabling scw-generate-net-config.service
# has been tested and works properly.  -- vila 2018-06-05
# systemctl --no-pager disable scw-generate-net-config
rm -f /etc/systemd/system/scw*

# ufw complains on this image about wrong access rights, something is fishy
# in the scaleway build pipeline. -- vila 2018-10-15
chmod 755 /etc
chmod 755 /etc/default
chmod 755 /usr

# The incoming shutdown may lose our last modifications, make sure they hit
# the disk. Do it twice because better safe than sorry ;-) (And the second
# one should be extremely fast anyway).
sync
sync

# Debug tricks, thanks to <blackboxsw>

# 'sudo cloud-init clean --logs --reboot' would perform a 'greenfield'
# install as if the system had never run cloud-init before it's what we use
# for upgrade testing and fresh boot validation that will blow away
# /var/log/cloud* /var/lib/cloud/* with the exception of a
# /var/lib/cloud/seed subdir if applicable (as that seeds some metadata on
# some clouds)

