Bagaimana cara menonaktifkan `apt-daily.service` di Ubuntu cloud VM image?

60

Gambar Ubuntu server 16,04 rupanya memulai "apt-daily.service" setiap 12 jam atau lebih; layanan ini melakukan berbagai tugas terkait APT seperti memperbarui daftar paket yang tersedia, melakukan peningkatan tanpa pengawasan jika diperlukan, dll.

Ketika mulai dari "snapshot" VM, layanan dipicu segera , karena (saya kira) systemd menyadari dengan cepat bahwa timer seharusnya sudah mati sejak lama.

Namun, menjalankan APT mencegah aptproses lain dari berjalan karena memegang kunci /var/lib/dpkg. Pesan kesalahan yang menunjukkan ini terlihat seperti ini:

E: Could not get lock /var/lib/dpkg/lock-frontend - open (11: Resource temporarily unavailable)
E: Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend), is another process using it?

Saya perlu menonaktifkan tugas APT otomatis ini sampai Ansible telah menyelesaikan pengaturan mesin (yang biasanya melibatkan pemasangan paket); lihat https://github.com/gc3-uzh-ch/elasticluster/issues/304 untuk info dan konteks lebih lanjut.

Saya telah mencoba berbagai opsi untuk menonaktifkan fitur "peningkatan tanpa pengawasan" melalui skrip "data pengguna" cloud-init, tetapi semuanya gagal sejauh ini.

1. Nonaktifkan tugas systemd

tugas systemd apt-daily.servicedipicu oleh apt-daily.timer. Saya telah mencoba untuk menonaktifkan satu atau yang lain, atau keduanya, dengan berbagai kombinasi dari perintah berikut; masih, apt-daily.servicebeberapa saat dimulai setelah VM menjadi siap untuk menerima koneksi SSH ::

    #!/bin/bash

    systemctl stop apt-daily.timer
    systemctl disable apt-daily.timer
    systemctl mask apt-daily.service
    systemctl daemon-reload

2. Nonaktifkan opsi konfigurasi APT::Periodic::Enable

Script /usr/lib/apt/apt.systemd.dailymembaca beberapa variabel konfigurasi APT; pengaturan APT::Periodic::Enablemenonaktifkan fungsi sama sekali (baris 331-337). Saya telah mencoba menonaktifkannya dengan skrip berikut ::

    #!/bin/bash

    # cannot use /etc/apt/apt.conf.d/10periodic as suggested in
    # /usr/lib/apt/apt.systemd.daily, as Ubuntu distributes the
    # unattended upgrades stuff with priority 20 and 50 ...
    # so override everything with a 99xxx file
    cat > /etc/apt/apt.conf.d/99elasticluster <<__EOF
    APT::Periodic::Enable "0";
    // undo what's in 20auto-upgrade
    APT::Periodic::Update-Package-Lists "0";
    APT::Periodic::Unattended-Upgrade "0";
    __EOF

Namun, meskipun APT::Periodic::Enablememiliki nilai 0dari baris perintah (lihat di bawah), unattended-upgradesprogram ini masih berjalan ...

    ubuntu@test:~$ apt-config shell AutoAptEnable APT::Periodic::Enable
    AutoAptEnable='0'

3. Hapus /usr/lib/apt/apt.systemd.dailysemuanya

cloud-initSkrip berikut menghapus skrip upgrade yang tidak dijaga sama sekali ::

    #!/bin/bash

    mv /usr/lib/apt/apt.systemd.daily /usr/lib/apt/apt.systemd.daily.DISABLED

Tetap saja, tugasnya berjalan dan saya bisa melihatnya di tabel proses! meskipun file tidak ada jika diselidiki dari baris perintah ::

ubuntu@test:~$ ls /usr/lib/apt/apt.systemd.daily
ls: cannot access '/usr/lib/apt/apt.systemd.daily': No such file or directory

Tampaknya seolah-olah cloud-initskrip (bersama-sama dengan SSH command-line) dan proses systemd mengeksekusi di filesystem terpisah dan ruang proses ...

Pertanyaan

Apakah ada sesuatu yang jelas saya hilang? Atau adakah keajaiban namespace yang terjadi yang tidak saya sadari?

Yang paling penting: bagaimana saya bisa menonaktifkan apt-daily.servicemelalui cloud-initnaskah?

Riccardo Murri
sumber
2
Ini tidak akan membantu Anda sampai dimasukkan ke dalam pembaruan paket resmi, tetapi silakan lihat tambalan yang baru saja saya posting ke bug Debian # 844453 .
zwol
Mungkin Anda kehilangan --nowbendera di systemctl disableperintah untuk membuat perubahan itu efektif dengan segera. Itu masalah saya.
Daniel F
@DanielF no, karena disable --nowsama dengan stopdiikuti oleh disable.
sourcejedi
1
Rupanya ini telah AKHIRNYA diperbaiki dalam systemd pada 2019 Feb: github.com/systemd/systemd/issues/5659 . Jadi semoga saja di Ubuntu 20.04.
jepret

Jawaban:

38

Ya, ada sesuatu yang jelas bahwa saya hilang.

Systemd adalah semua tentang awal bersamaan pelayanan, sehingga cloud-initnaskah dijalankan pada saat yang sama yang apt-daily.servicedipicu. Pada saat cloud-initmengeksekusi payload yang ditentukan pengguna, apt-get updatesudah berjalan. Jadi upaya 2. dan 3. gagal bukan karena beberapa namespace magic, tetapi karena mereka mengubah sistem terlambat untuk apt.systemd.dailymengambil perubahan.

Ini juga berarti bahwa pada dasarnya tidak ada cara untuk mencegah apt.systemd.daily berjalan - seseorang hanya dapat membunuhnya setelah dimulai.

Skrip "data pengguna" ini menggunakan rute ini ::

#!/bin/bash

systemctl stop apt-daily.service
systemctl kill --kill-who=all apt-daily.service

# wait until `apt-get updated` has been killed
while ! (systemctl list-units --all apt-daily.service | egrep -q '(dead|failed)')
do
  sleep 1;
done

# now proceed with own APT tasks
apt install -y python

Masih ada jendela waktu di mana login SSH dimungkinkan namun apt-get tidak akan berjalan, tapi saya tidak bisa membayangkan solusi lain yang dapat bekerja pada stock image cloud Ubuntu 16.04.

Riccardo Murri
sumber
ini bekerja untuk saya di aws ubuntu 16.04, terima kasih atas solusinya
krisdigitx
Ya, saya akan membuat AMI khusus. Ini juga mempercepat pemasangan layanan umum.
giorgiosironi
Ini sepertinya tidak cukup, saya menemukan masih ada contoh-contoh yang teruraiapt-get -o Acquire::http::AllowRedirect=false update
Edward Z. Yang
12

Catatan: Sayangnya bagian dari solusi di bawah ini tidak berfungsi pada sistem Ubuntu 16.04 (seperti yang dimiliki penanya) karena systemd-runpermohonan yang disarankan hanya berfungsi di Ubuntu 18.04 dan lebih tinggi (lihat komentar untuk detailnya ). Saya akan meninggalkan jawabannya di sini karena pertanyaan ini masih menjadi hit populer terlepas dari versi Ubuntu yang Anda gunakan ...

Pada Ubuntu 18.04 (dan lebih tinggi) mungkin ada dua layanan yang terlibat dalam waktu boot untuk memperbarui / meningkatkan. Yang pertama apt-daily.servicemenyegarkan daftar paket. Namun ada yang kedua apt-daily-upgrade.serviceyang benar-benar menginstal paket keamanan kritis. Sebuah jawaban untuk "Memutus dan menonaktifkan / menghapus Upgrade tanpa pengawasan sebelum kembali perintah" Pertanyaan memberikan contoh yang sangat baik tentang bagaimana untuk menunggu kedua ini untuk menyelesaikan (disalin di sini untuk kenyamanan):

systemd-run --property="After=apt-daily.service apt-daily-upgrade.service" --wait /bin/true

(perhatikan ini harus dijalankan sebagai root). Jika Anda mencoba untuk menonaktifkan layanan ini pada boot selanjutnya, Anda perlu menutupi KEDUA layanan:

systemctl mask apt-daily.service apt-daily-upgrade.service

Atau Anda dapat menggunakan systemctl disablekedua layanan DAN pengatur waktu terkait (mis. apt-daily.timerDan apt-daily-upgrade.timer).

Perhatikan teknik penutupan / penonaktifan dalam jawaban ini hanya mencegah pembaruan / peningkatan pada boot berikutnya - mereka tidak akan menghentikannya jika sudah berjalan di boot saat ini.

Segera
sumber
2
Jawaban yang bagus, terima kasih! Meskipun, perhatikan bahwa systemd-runpada Ubuntu 16.04 terlalu tua untuk mendukung --waitopsi, tetapi seharusnya tidak benar-benar diperlukan untuk tujuan yang ada. (Menurut halaman manual, --waitmenunggu penghentian sebuah unit tetapi cukup untuk menunggu awal yang merupakan perilaku default dari systemd-run.)
Riccardo Murri
Saya berdiri dikoreksi: systemd-runmantra yang diberikan tidak bekerja di Ubuntu 16,04 sama sekali; ia mati dengan pesan kesalahan Penugasan tidak diketahui Setelah = apt-daily.service apt-daily-upgrade.service . Sepertinya beberapa properti unit tidak tersedia di systemd-run, lihat contohnya di sini
Riccardo Murri
@ riccardo-murri Anda mendapatkan saya :-)! Saya benar-benar bertanya-tanya tentang perbedaan 16,04 / 18,04 sendiri (maka si weaselly "hingga dua") dan kemudian lupa untuk memasukkan peringatan. Perubahan apa yang akan Anda sarankan?
Anon
@ riccardo-murri ah itu terlalu buruk saya akan menambahkan peringatan besar ke bagian atas jawaban yang mengatakan itu tidak dapat digunakan di Ubuntu 16.04
Anon
Menonaktifkan layanan dan memulai kembali dan berfungsi!
digz6666
4

Anda dapat menonaktifkan ini melalui modul cloud-init "bootcmd". Ini berjalan sebelum jaringan dinyalakan, yang diperlukan sebelum pembaruan apt bisa mendapatkan kesempatan untuk berjalan.

#cloud-config
bootcmd:
    - echo 'APT::Periodic::Enable "0";' > /etc/apt/apt.conf.d/10cloudinit-disable
    - apt-get -y purge update-notifier-common ubuntu-release-upgrader-core landscape-common unattended-upgrades
    - echo "Removed APT and Ubuntu 18.04 garbage early" | systemd-cat

Setelah Anda masuk ke instance, Anda juga harus menunggu fase akhir cloud-init selesai, karena ia memindahkan sumber / daftar yang ada di sekitar.

# Wait for cloud-init to finish moving apt sources.list around... 
# a good source of random failures
# Note this is NOT a replacement for also disabling apt updates via bootcmd
while [ ! -f /var/lib/cloud/instance/boot-finished ]; do
    echo 'Waiting for cloud-init to finish...'
    sleep 3
done

Ini juga membantu untuk melihat seberapa awal bootcmd berjalan:

# Show microseconds in systemd journal
journalctl -r -o short-precise

Anda dapat memverifikasi ini berfungsi sebagai berikut:

apt-config dump | grep Periodic

# Verify nothing was updated until we run apt update ourselves.
cd /var/lib/apt/lists
sudo du -sh .   # small size
ls -ltr         # old timestamps
Karl Pickett
sumber
2

Tidak akan lebih mudah untuk menutupi unit

systemctl mask apt-daily.service

?


sumber
Tidak berfungsi - lihat bagian 1. Nonaktifkan tugas systemd dalam teks pertanyaan. Tapi terima kasih atas sarannya! :-)
Riccardo Murri
2
menonaktifkan dan menutupi layanan tidak sama. mask buat tautan ke / dev / null. ls -al /etc/systemd/system/ | grep alsa lrwxrwxrwx 1 root root 9 Sep 1 13:17 alsa-init.service -> /dev/nullData kosong.
2
saya menyingkirkan upgrade tanpa pengawasan sudo dpkg-reconfigure -plow unattended-upgradesdan mengabaikannya. Jadi status unit apt-daily.service sudah mati.
Hai @ Bahut terima kasih atas upaya Anda! Namun, pertanyaannya adalah bagaimana menonaktifkan apt-daily.servicedari cloud-initskrip dan sebelum dimulai setelah VM reboot: ini berarti: (1) harus dilakukan secara non-interaktif, (2) harus dilakukan sebelum apt-daily.servicekebakaran untuk pertama kalinya. (Jika pemahaman saya tentang systemd benar, (2) tidak dapat benar-benar diselesaikan cloud-initdan apt-dailydijalankan secara bersamaan - lihat balasan saya sendiri untuk informasi lebih lanjut.)
Riccardo Murri
1
Saya mencoba ini pada mesin fisik normal (yaitu bukan VM) dan dapat mengkonfirmasi itu tidak berfungsi. Anda harus juga menghentikan timer: systemctl stop apt-daily.timer; systemctl nonaktifkan apt-daily.timer
happyskeptic
1

Ini menunggu 1detik dalam putaran whil dan memeriksa apakah kunci dilepaskan.

while : ; do
                sleep 1
                echo $( ps aux | grep -c lock_is_held ) processes are using apt.
                ps aux | grep -i apt
                [[ $( ps aux | grep -c lock_is_held ) > 2 ]] || break
        done
        echo Apt released
Navidzj
sumber