systemd / mkosi

💽 Build Bespoke OS Images
https://mkosi.systemd.io/
1.15k stars 310 forks source link

Post installation script fails when using incremental builds #259

Closed thedrow closed 5 years ago

thedrow commented 6 years ago

When I try to use an incremental build I get the following output:

‣ Removing output files...
‣ Removing output files complete.
DISTRIBUTION:
          Distribution: ubuntu
               Release: bionic
                Mirror: http://archive.ubuntu.com/ubuntu

OUTPUT:
              Hostname: myproject
         Output Format: raw_gpt
                Output: /home/omer/Documents/Projects/myproject/myproject.raw
       Output Checksum: n/a
      Output Signature: n/a
           Output Bmap: n/a
Output nspawn Settings: n/a
           Incremental: yes
             Read-only: no
        XZ Compression: no
            Encryption: no
                Verity: no
              Bootable: no

PACKAGES:
              Packages: linux-image-generic
                        linux-signed-image-generic
                        initramfs-tools
                        lxc
                        weston
                        debsums
                        rkhunter
                        tripwire
                        xwayland
                        p7zip-full
                        network-manager
                        iptables-persistent
                        python3-pip
                        python3-wheel
                        python3-setuptools
                        python3-networkmanager
                        python3-crypto
                        software-properties-common
         Package Cache: none
           Extra Trees: /home/omer/Documents/Projects/myproject/mkosi.extra
        Skeleton Trees: none
          Build Script: none
         Build Sources: /home/omer/Documents/Projects/myproject
       Build Directory: none
        Build Packages: none
     Post Inst. Script: /home/omer/Documents/Projects/myproject/mkosi.postinst
  Scripts with network: yes
       nspawn Settings: none

PARTITIONS:
        Root Partition: 5.0G
        Swap Partition: (disabled)
                   ESP: (disabled)
       /home Partition: (disabled)
        /srv Partition: (disabled)

VALIDATION:
              Checksum: no
                  Sign: no
               GPG Key: default
              Password: set

HOST CONFIGURATION:
    Extra search paths: none
‣ Detaching namespace...
‣ Detaching namespace complete.
‣ Setting up package cache...
‣ Setting up package cache /home/omer/Documents/Projects/myproject/.mkosi-3rfldjtu complete.
‣ Setting up temporary workspace.
‣ Temporary workspace in /var/tmp/mkosi-ekabwagd is now set up.
‣ Basing off cached image myproject.raw.cache-pre-inst...
‣ Copied cached image as /home/omer/Documents/Projects/myproject/.mkosi-dgbqae9m.
‣ Attaching image file...
‣ Attached image file as /dev/loop10.
‣ Mounting image...
‣ Mounting image complete.
‣ Setting up basic OS tree...
‣ Setting up basic OS tree complete.
‣ Mounting Package Cache...
‣ Mounting Package Cache complete.
‣ Assigning hostname...
‣ Assigning hostname complete.
‣ Copying in extra file trees...
‣ Copying in extra file trees complete.
‣ Setting root password...
‣ Running post installation script...
Timezone Asia/Jerusalem does not exist in container, not updating container timezone.
Hit:1 http://archive.ubuntu.com/ubuntu bionic InRelease
Err:1 http://archive.ubuntu.com/ubuntu bionic InRelease
  Couldn't create temporary file /tmp/apt.conf.kXhIcG for passing config to apt-key
Reading package lists... Done
W: An error occurred during the signature verification. The repository is not updated and the previous index files will be used. GPG error: http://archive.ubuntu.com/ubuntu bionic InRelease: Couldn't create temporary file /tmp/apt.conf.kXhIcG for passing config to apt-key
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/bionic/InRelease  Couldn't create temporary file /tmp/apt.conf.kXhIcG for passing config to apt-key
W: Some index files failed to download. They have been ignored, or old ones used instead.
/root/postinst: line 4: update-initramfs: command not found
/root/postinst: line 5: apt-add-repository: command not found
Hit:1 http://archive.ubuntu.com/ubuntu bionic InRelease
Err:1 http://archive.ubuntu.com/ubuntu bionic InRelease
  Couldn't create temporary file /tmp/apt.conf.bAgpxK for passing config to apt-key
Reading package lists... Done
W: An error occurred during the signature verification. The repository is not updated and the previous index files will be used. GPG error: http://archive.ubuntu.com/ubuntu bionic InRelease: Couldn't create temporary file /tmp/apt.conf.bAgpxK for passing config to apt-key
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/bionic/InRelease  Couldn't create temporary file /tmp/apt.conf.bAgpxK for passing config to apt-key
W: Some index files failed to download. They have been ignored, or old ones used instead.
Reading package lists... Done
Building dependency tree       
Reading state information... Done
E: Unable to locate package ansible
E: Unable to locate package python-lxc
/root/postinst: line 9: ansible-playbook: command not found
Reading package lists... Done
Building dependency tree       
Reading state information... Done
E: Unable to locate package ansible
E: Unable to locate package python-lxc
Reading package lists... Done
Building dependency tree       
Reading state information... Done
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
‣ Running post installation script complete.
‣ Unmounting Package Cache...
‣ Unmounting Package Cache complete.
‣ Resetting machine ID...
‣ Resetting machine ID complete.
‣ Unmounting image...
‣ Unmounting image complete.
‣ Mounting image...
‣ Mounting image complete.
‣ Unmounting image...
‣ Unmounting image complete.
‣ Detaching image file...
‣ Detaching image file complete.
‣ Linking image file...
‣ Successfully linked /home/omer/Documents/Projects/myproject/myproject.raw.
‣ Resulting image size is 1.0G, consumes 1.0G.

However, a full build results in the following output:

Hit:1 http://archive.ubuntu.com/ubuntu bionic InRelease
Err:1 http://archive.ubuntu.com/ubuntu bionic InRelease
  Couldn't create temporary file /tmp/apt.conf.EdsmWJ for passing config to apt-key
Reading package lists... Done
W: An error occurred during the signature verification. The repository is not updated and the previous index files will be used. GPG error: http://archive.ubuntu.com/ubuntu bionic InRelease: Couldn't create temporary file /tmp/apt.conf.EdsmWJ for passing config to apt-key
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/bionic/InRelease  Couldn't create temporary file /tmp/apt.conf.EdsmWJ for passing config to apt-key
W: Some index files failed to download. They have been ignored, or old ones used instead.
update-initramfs: Generating /boot/initrd.img-4.15.0-20-generic
gpg: Warning: using insecure memory!
gpg: Warning: using insecure memory!
Hit:1 http://archive.ubuntu.com/ubuntu bionic InRelease
Err:1 http://archive.ubuntu.com/ubuntu bionic InRelease
  Couldn't create temporary file /tmp/apt.conf.uaO1Gv for passing config to apt-key
Get:2 http://ppa.launchpad.net/ansible/ansible/ubuntu bionic InRelease [15.9 kB]
Err:2 http://ppa.launchpad.net/ansible/ansible/ubuntu bionic InRelease
  Couldn't create temporary file /tmp/apt.conf.bzwjIb for passing config to apt-key
Reading package lists... Done
W: An error occurred during the signature verification. The repository is not updated and the previous index files will be used. GPG error: http://archive.ubuntu.com/ubuntu bionic InRelease: Couldn't create temporary file /tmp/apt.conf.uaO1Gv for passing config to apt-key
W: GPG error: http://ppa.launchpad.net/ansible/ansible/ubuntu bionic InRelease: Couldn't create temporary file /tmp/apt.conf.bzwjIb for passing config to apt-key
E: The repository 'http://ppa.launchpad.net/ansible/ansible/ubuntu bionic InRelease' is not signed.
N: Updating from such a repository can't be done securely, and is therefore disabled by default.
N: See apt-secure(8) manpage for repository creation and user configuration details.
Hit:1 http://archive.ubuntu.com/ubuntu bionic InRelease
Err:1 http://archive.ubuntu.com/ubuntu bionic InRelease
  Couldn't create temporary file /tmp/apt.conf.273UWX for passing config to apt-key
Get:2 http://ppa.launchpad.net/ansible/ansible/ubuntu bionic InRelease [15.9 kB]
Err:2 http://ppa.launchpad.net/ansible/ansible/ubuntu bionic InRelease
  Couldn't create temporary file /tmp/apt.conf.vqriTG for passing config to apt-key
Reading package lists... Done
W: An error occurred during the signature verification. The repository is not updated and the previous index files will be used. GPG error: http://archive.ubuntu.com/ubuntu bionic InRelease: Couldn't create temporary file /tmp/apt.conf.273UWX for passing config to apt-key
W: GPG error: http://ppa.launchpad.net/ansible/ansible/ubuntu bionic InRelease: Couldn't create temporary file /tmp/apt.conf.vqriTG for passing config to apt-key
E: The repository 'http://ppa.launchpad.net/ansible/ansible/ubuntu bionic InRelease' is not signed.
N: Updating from such a repository can't be done securely, and is therefore disabled by default.
N: See apt-secure(8) manpage for repository creation and user configuration details.
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following additional packages will be installed:
# ...

Something is wrong here but for some reason when it tries to run a full build everything works.

lucaswerkmeister commented 6 years ago

Can you post the config file and build script?

thedrow commented 6 years ago

This is the configuration file:

[Distribution]
Distribution=ubuntu
Release=bionic
Repositories=main restricted universe multiverse

[Output]
Bootable=no
Output=myproject.raw
XZ=no
Hostname=myproject

[Partitions]
RootSize=5G

[Packages]
WithNetwork=yes
Packages=linux-image-generic linux-signed-image-generic initramfs-tools tzdata lxc weston debsums rkhunter tripwire xwayland p7zip-full network-manager iptables-persistent python3-pip python3-wheel python3-setuptools python3-networkmanager python3-crypto software-properties-common python-lxc
Cache=/tmp/

and the script is:

#!/bin/bash

update-initramfs -k all -c
apt-add-repository ppa:ansible/ansible -y
apt-get update
apt-get install ansible -y

ansible-playbook /tmp/playbook.yml --connection=local

apt-get remove --purge ansible python-lxc -y
apt-get autoremove -y
lucaswerkmeister commented 6 years ago

Thanks!

I notice your configuration file is not specifying any BuildPackages – it probably should. (Also, why are you including linux-image-genericand linux-signed-image-generic? – when building a non-bootable image?)

But I admit I’m confused now about the relationship between Packages and BuildPackages. It’s not entirely clear to me if BuildPackages is supposed to be purely additive to Packages, or independent of it. From the source code, it looks like it’s supposed to specify additional packages, and the regular Packages should be included in the build image as well, but that seems to be broken in incremental mode, causing the bug you encountered.

thedrow commented 6 years ago

I'm building an image for a Spyrus Linux2Go device which includes its own boot partition with a proprietary bootloader. BuildPackages is independent. They are installed only during the build process which is used to compile/generate from templates/whatever into a destination directory which is then available during the final image. I'm using ansible to provision the image and after I'm done, I want to remove it. I'd rather use the latest version so I tried using the PPA but that seems impossible for some reason.

lucasdemarchi commented 6 years ago

Try removing the "Cache" entry.

I'd rather use the latest version so I tried using the PPA but that seems impossible for some reason.

You can a actually use a skeleton tree to provide additional repositories. That would allow you to install the package using mkosi's config file. See https://github.com/systemd/mkosi/pull/192

thedrow commented 6 years ago

@lucasdemarchi But I still need to add the PGP keys. This is why apt-add-repository exists. I'm removing the cache entry now. Let's see what it does.

thedrow commented 6 years ago

@lucasdemarchi While your advice helped, it also nullified the reason for me to use incremental builds. The real issue is that apt tries to run with the _apt user. That user doesn't have permissions to the /tmp folder mkosi mounts. Running chown 1777 /tmp as the first step of the post installation script works around that problem.

poettering commented 5 years ago

@lucasdemarchi While your advice helped, it also nullified the reason for me to use incremental builds. The real issue is that apt tries to run with the _apt user. That user doesn't have permissions to the /tmp folder mkosi mounts.

Hmm? What do you mean? /tmp has bad access modes? that is really weird, can you reproduce this?

thedrow commented 5 years ago

I can. Without chmoding /tmp to 777, apt does not work.

poettering commented 5 years ago

Hmm, not sure I follow. you use Cache=/tmp. Note that that refers to to a path on the host, and is what is mounted to /var/cache/apt/archive/ inside of the container. Why would you do something like that? i.e. why mount the whole of your hosts's /tmp into the container like that. I think there's some confusion about what this does.

Note that mkosi has two ways to speed up builds: you can use Cache= to share a package cache between builds. This refers to the package cache of the used package manager, i.e. where your package manager (apt, dnf, ...) places the packages while downloading them, before unpacking them (i.e. all those .deb and .rpm files). Using this will reduce what is downloaded, but all the package unpacking and such you'll still have to pay on every build. However, what's nice is that you can share the package cache between multiple unrelated builds if you like.

And then there's the incremental build stuff. In this mode, after the packages are unpacked and everything we take a snapshot of the disk image, and then can start from there on the next builds. This speeds thing up drastically, since building a new image version from a source tree or such means we can skip the whole package unpacking step and directly go for the source building.

Both schemes, (i.e. the package cache and the incremental image cache) are orthogonal: you can use one, you can use the other, you can use neither or you can use both).

Usually, instead of configuring Cache= explicitly you can just create mkosi.cache in your working directory, which will then be picked up automatically by mkosi.

thedrow commented 5 years ago

That's what I ended up doing. Maybe it is a usage problem on my part. I'll recheck.