Use virt-install to fully automate the install for Devuan with preseed

I recently discovered how to use a Debian preseed file while building a VM in kvm. After hand-crafting my Devuan preseed file, here it is in all my customized and I’m sure duplicate-filled and bogus-answer-encrusted glory.

How I use this

I define a variable, and plug it into the important parts.

vm=d2-04a ; time sudo virt-install -n "${vm}" --memory 2048 \
   --vcpus=1 --os-variant=debiantesting -v \
   --disk path=/var/lib/libvirt/images/"${vm}".qcow2,size=20 \
   -l /mnt/public/Support/SetupsBig/Linux/devuan_ascii_2.0.0-beta_amd64_DVD.iso \
   --initrd-inject=/mnt/public/Support/Platforms/devuan/preseed/preseed.cfg \
   --extra-args "hostname=${vm} NOTIFYEMAIL=bgstack15@gmail.com interface=auto" \
   --debug --network type=bridge,source=br0 --noautoconsole

Some thoughts

For some reason I was unable to get the preseed to work with the non-beta Ascii iso. When I started the preseed vm activity, I already had the beta disc so I was using it first before I downloaded the release disc, which didn’t even work. So I reverted to the beta disc. Please share any results, working or otherwise, you have when trying this with the release disc.
I do some tricky stuff in here with grub and the ceres release. Apparently consolekit messes with some of the files grub wants to lay down in /boot (having to do with locales), so I had to create this complex solution. I don’t even care that it’s “grub-legacy.” It seems a little simpler for a simpler time, and also works, so why bother doing anything different?

The preseed file

# File: /mnt/public/Support/Platforms/devuan/devuan-preseed1.txt
# Locations:
#    /mnt/public/Support/Platforms/devuan/devuan-preseed1.txt
# Author: bgstack15
# Startdate: 2019-06-25
# Title: Kickstart for CentOS 7 for ipa.smith122.com
# Purpose: To provide an easy installation for VMs and other systems in the Mersey network
# History:
#    2017-06 I learned how to use kickstart files for the RHCSA EX-200 exam
#    2017-08-08 Added notifyemail to --extra-args
#    2017-10-29 major revision to use local repository
#    2019-06-25 fork from centos7-ks.cfg
# Usage with virt-install:
#    vm=d2-04a ; time sudo virt-install -n "${vm}" --memory 2048 --vcpus=1 --os-variant=debiantesting -v --disk path=/var/lib/libvirt/images/"${vm}".qcow2,size=20 -l /mnt/public/Support/SetupsBig/Linux/devuan_ascii_2.0.0-beta_amd64_DVD.iso --initrd-inject=/mnt/public/Support/Platforms/devuan/preseed/preseed.cfg --extra-args "hostname=${vm} NOTIFYEMAIL=bgstack15@gmail.com interface=auto" --debug --network type=bridge,source=br0 --noautoconsole
#    vm=d2-04a; sudo virsh destroy "${vm}"; sudo virsh undefine --remove-all-storage "${vm}";
# Reference:
#    https://sysadmin.compxtreme.ro/automatically-set-the-hostname-during-kickstart-installation/
#    /mnt/public/Support/Platforms/CentOS7/install-vm.txt
#    https://serverfault.com/questions/481244/preseed-command-string-fail-with-newline-character-using-virt-install-initrd-inj
#    https://www.debian.org/releases/stable/i386/apbs01.html.en
#    https://github.com/jameswthorne/preseeds/blob/master/debian-7-wheezy-unattended.seed
#    syntax for --location https://www.queryxchange.com/q/1_908324/virt-install-preseed-not-working/
#    example preseed https://www.debian.org/releases/stable/example-preseed.txt
#    skip next dvd question https://unix.stackexchange.com/questions/409212/preseed-directive-to-skip-another-cd-dvd-scanning
#    grub problem caused by consolekit:amd64 https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=915947#10
#    https://stackoverflow.com/questions/39861614/how-to-fully-automate-unattended-virt-install
#    https://www.debian.org/releases/stable/i386/apbs03.html.en
#    https://dev1galaxy.org/viewtopic.php?id=1853
#    https://www.cyberciti.biz/faq/howto-setup-serial-console-on-debian-linux/
# Improve:
#    discover how to send email, using postfix or sendmail. Don't care which, but exclude exim4.
#    echo "$( hostname ) has IP $( ip -4 -o a s eth0 | awk '{print $4}' | sed -r -e 's/\/.*$//' )" | 
#    add the kernel lines: console=ttyS0 console=tty1. Get this to work; tried manually but perhaps devuan doesn't use console the same way?

d-i debian-installer/country string US
d-i debian-installer/keymap select us
d-i debian-installer/language string en
d-i debian-installer/locale string en_US
d-i localechooser/supported-locales string en_US.UTF-8

d-i keyboard-configuration/layoutcode string us
d-i keyboard-configuration/variantcode string
d-i keyboard-configuration/xkb-keymap select us

d-i netcfg/disable_autoconfig boolean false
d-i netcfg/get_domain string ipa.smith122.com
d-i netcfg/wireless_wep string
# disable asking for non-free firmware, because this is a vm and has none
d-i hw-detect/load_firmware boolean false

#d-i apt-setup/enable-source-repositories boolean false
# ORIGINAL d-i apt-setup/services-select multiselect security updates, release updates, backported software
d-i apt-setup/contrib boolean true
d-i apt-setup/disable-cdrom-entries boolean true
d-i apt-setup/non-free boolean true
d-i apt-setup/use_mirror boolean true
d-i mirror/country string manual
d-i mirror/http/directory string /devuan
d-i mirror/http/hostname string deb.devuan.org
d-i mirror/http/proxy string
d-i mirror/protocol string http
d-i mirror/suite string testing

d-i apt-setup/cdrom/set-failed boolean false
d-i apt-setup/cdrom/set-first boolean false
d-i apt-setup/cdrom/set-next boolean false

# my repos and ceres
d-i apt-setup/local0/comment string smith122deb
d-i apt-setup/local0/key string http://albion320.no-ip.biz/smith122/repo/deb/smith122deb.gpg
d-i apt-setup/local0/repository string http://albion320.no-ip.biz/smith122/repo/deb/ /
d-i apt-setup/local1/comment string devuan-deb
d-i apt-setup/local1/key string http://albion320.no-ip.biz/smith122/repo/deb/smith122deb.gpg
d-i apt-setup/local1/repository string http://albion320.no-ip.biz/smith122/repo/devuan-deb/ /
d-i apt-setup/local2/comment string ceres
d-i apt-setup/local2/key string https://pkgmaster.devuan.org/merged/dists/ceres/Release.gpg
d-i apt-setup/local2/repository string http://pkgmaster.devuan.org/merged ceres main contrib non-free
# if for some reason I really need to turn off the gpg key check:
#d-i debian-installer/allow_unauthenticated boolean false

tasksel tasksel/first multiselect standard, ssh-server

# adapted from /mnt/public/Support/Platforms/devuan/devuan.txt, main fluxbox desktop, but for a vm
# no xscreensaver, for a vm.
d-i pkgsel/include string \
   alsamixergui alttab apt-transport-https bgconf bgscripts bgscripts-core \
   cifs-utils curl fluxbox freeipa-client git grub lightdm lightdm-gtk-greeter \
   mlocate net-tools nfs-common ntpdate oddjob-mkhomedir=0.1-1 openssh-server \
   p7zip palemoon palemoon-ublock-origin parted qemu-guest-agent rsync scite \
   screen spice-vdagent strace sudo tcpdump vim vlc volumeicon-alsa waterfox \
   xfce4-terminal xfe xserver-xorg-video-qxl

d-i pkgsel/upgrade select none

popularity-contest popularity-contest/participate boolean true

d-i clock-setup/ntp boolean true
d-i clock-setup/ntp-server string dns1.ipa.smith122.com
d-i time/zone string America/New_York

# skip grub during main part, because we will do it in late_command
d-i grub-installer/skip boolean true
# these next 2 are experimental
d-i grub-installer/skip-again boolean true
d-i grub-installer/skip-confirm boolean true
d-i grub-installer/confirm_skip boolean true
d-i nobootloader/confirmation_common boolean true

d-i lilo-installer/skip boolean true
#d-i grub-installer/with_other_os boolean true
#d-i grub-installer/only_debian boolean true
#d-i grub-installer/grub2_instead_of_grub_legacy boolean true
#d-i grub-installer/bootdev string /dev/vda
#d-i grub-installer/choose_bootdev select /dev/vda
#grub-installer grub-installer/force-efi-extra-removable boolean false

d-i passwd/root-password password f0rg3tkickstart&
d-i passwd/root-password-again password f0rg3tkickstart&

d-i partman-auto/choose_recipe select home
d-i partman-auto-crypto/erase_disks boolean false
d-i partman-auto/disk string /dev/vda
d-i partman-auto/init_automatically_partition select biggest_free
d-i partman-auto/method string lvm
d-i partman/choose_label string gpt
d-i partman/choose_partition select finish
d-i partman/confirm boolean true
d-i partman/confirm_nooverwrite boolean true
d-i partman/confirm_write_new_label boolean true
d-i partman/default_label string gpt
#d-i partman-lvm/confirm boolean true
d-i partman-lvm/confirm_nooverwrite boolean true
d-i partman-md/confirm_nooverwrite boolean true
#d-i partman/mount_style select uuid
d-i partman-partitioning/confirm_write_new_label boolean true

# Uncomment this to add multiarch configuration for i386
#d-i apt-setup/multiarch string i386

d-i passwd/make-user boolean true
d-i passwd/user-fullname string bgstack15
d-i passwd/username string bgstack15
d-i passwd/user-password-crypted password $6$85aKM2DkiD5g9r3D$zkbcVES1Bzu.b5dBJxklSggEJzswZBlVAyc9LUUIzMA2OLRH2PD2ZWE9Q40Wtw/3OOxDM2nF031hfD4s5LGuG1
d-i passwd/user-default-groups string audio cdrom video

d-i finish-install/reboot_in_progress note
d-i cdrom-detect/eject boolean true

# additional application stuff just in case it works and is useful
# LDAP server URI:
d-i shared/ldapns/ldap-server	string	ldapi:///ipa.smith122.com

d-i openssh-server/password-authentication	boolean	true
d-i openssh-server/permit-root-login	boolean	false

# Remove consolekit from ceres, which disrupts /boot/grub/local/*mo files, that grub-install wants.
d-i preseed/late_command string in-target apt-get purge -q -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" consolekit exim4\* ; \
   apt-get install -q -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" postfix ; \
   in-target grub-install /dev/vda ; in-target update-grub ; \
   in-target wget http://albion320.no-ip.biz/smith122/certs/ca-ipa.smith122.com.crt -O /usr/local/share/ca-certificates/ca-ipa.smith122.com.crt && update-ca-certificates || : ; \
   in-target su bgstack15 -c "sudo /usr/bin/bgconf.py" 1>/root/clone.log 2>&1 ; \
   in-target sed -i -r -e '/^kernel/s/(\s*console=.{1,7}[0-9])*\s*$/ console=tty0 console=ttyS0/;' /boot/grub/menu.lst ; \
   in-target sed -i -r -e '$aT0:23:respawn:/sbin/getty -L ttyS0 9600 vt100' /etc/inittab

Use virt-install to fully automate the install for CentOS/Fedora with kickstart

Here is my kickstart file for CentOS 7. I deploy VMs into my kvm environment with a oneliner, using this kickstart file.

How I use this

I define a variable, and plug it into the important parts.

vm=c7-04a ; time sudo virt-install -n "${vm}" --memory 2048 \
   --vcpus=1 --os-variant=centos7.0 --accelerate -v \
   --disk path=/var/lib/libvirt/images/"${vm}".qcow2,size=20 \
   -l /mnt/public/Support/SetupsBig/Linux/CentOS-7-x86_64-Minimal-1810.iso \
   --initrd-inject=/mnt/public/Support/Platforms/CentOS7/centos7-ks.cfg \
   --extra-args "ks=file:/centos7-ks.cfg SERVERNAME=${vm} NOTIFYEMAIL=bgstack15@gmail.com" \
   --debug --network type=bridge,source=br0 --noautoconsole

Some thoughts

I had to download the 1810 release of the iso, because there was something wrong with the repos or perhaps files in the previous isos, with how they interacted with either the virtual environment or the network or something. But the CentOS-7-x86_64-minimal-1810.iso was important.
I found the SERVERNAME trick on the Internet. You can iterate over /proc/cmdline and react to values you find there, in the %pre or %post scripts.
You will see that I use my own local repositories for the regular CentOS repos, and I add my own internal one (smith122/repo/rpm). Obviously you should find a suitable set of repos for your own.
You will also see that I attempt to download my CA certificates at various points. I’m pretty sure the %pre effort fails, because the system is not on the network yet.

Dependencies

The kickstart file

# File: /mnt/public/Support/Platforms/CentOS7/centos7-ks.cfg
# Locations:
#    /mnt/public/Support/Platforms/CentOS7/centos7-ks.cfg
# Author: bgstack15
# Startdate: 2017-06-02
# Title: Kickstart for CentOS 7 for ipa.smith122.com
# Purpose: To provide an easy installation for VMs and other systems in the Mersey network
# History:
#    2017-06 I learned how to use kickstart files for the RHCSA EX-200 exam
#    2017-08-08 Added notifyemail to --extra-args
#    2017-10-29 major revision to use local repository
#
#
#
#
# Usage with virt-install:
#    vm=c7-04a ; time sudo virt-install -n "${vm}" --memory 2048 --vcpus=1 --os-variant=centos7.0 --accelerate -v --disk path=/var/lib/libvirt/images/"${vm}".qcow2,size=20 -l /mnt/public/Support/SetupsBig/Linux/CentOS-7-x86_64-Minimal-1810.iso --initrd-inject=/mnt/public/Support/Platforms/CentOS7/centos7-ks.cfg --extra-args "ks=file:/centos7-ks.cfg SERVERNAME=${vm} NOTIFYEMAIL=bgstack15@gmail.com" --debug --network type=bridge,source=br0 --noautoconsole
#    vm=c7-04a; sudo virsh destroy "${vm}"; sudo virsh undefine --remove-all-storage "${vm}";
# Reference:
#    https://sysadmin.compxtreme.ro/automatically-set-the-hostname-during-kickstart-installation/
#    /mnt/public/Support/Platforms/CentOS7/install-vm.txt

#platform=x86, AMD64, or Intel EM64T
#version=DEVEL
# Install OS instead of upgrade
install
# Keyboard layouts
keyboard 'us'
# Root password
rootpw --plaintext SOMETHINGSTRONGHERE
# my user
user --groups=wheel --name=bgstack15-local --password=$6$.gh0u7vg2HDPJPX/$g4Y1l.q76fs7i0UK8t6h83bDIo2YnGGj/1DGeUzzbMTd0pBh4of6jNYWxxws/937sUiPgETqPsYFI5XNrkAle. --iscrypted --gecos="bgstack15-local"

# System language
lang en_US.UTF-8
# Firewall configuration
firewall --enabled --ssh
# Reboot after installation
reboot
# Network information
#attempting to put it in the included ks file that accepts hostname from the virsh command.
#network  --bootproto=dhcp --device=eth0 --ipv6=auto --activate
%include /tmp/network.ks
# System timezone
timezone America/New_York --utc
# System authorization information
auth  --useshadow  --passalgo=sha512
# Use network installation instead of CDROM installation media
url --url="http://www.ipa.smith122.com/mirror/centos/7/os/x86_64/"

# Use text mode install
text
# SELinux configuration
selinux --enforcing
# Do not configure the X Window System
skipx

# Use all local repositories
# Online repos
repo --name=smith122rpm --baseurl=https://www.ipa.smith122.com/smith122/repo/rpm/
repo --name=base --baseurl=https://www.ipa.smith122.com/mirror/centos/$releasever/os/$basearch/
repo --name=updates --baseurl=https://www.ipa.smith122.com/mirror/centos/$releasever/updates/$basearch/
repo --name=extras --baseurl=https://www.ipa.smith122.com/mirror/centos/$releasever/extras/$basearch/
repo --name=epel --baseurl=https://www.ipa.smith122.com/mirror/fedora/epel/$releasever/$basearch

# Offline repos
#
#
#
#
#

firstboot --disabled

# System bootloader configuration
bootloader --location=mbr
# Partition clearing information
clearpart --all --initlabel
# Disk partitioning information
autopart --type=lvm

%pre
echo "network  --bootproto=dhcp --device=eth0 --ipv6=auto --activate --hostname renameme.ipa.smith122.com" > /tmp/network.ks
for x in $( cat /proc/cmdline );
do
   case $x in
      SERVERNAME*)
         eval $x
         echo "network  --bootproto=dhcp --device=eth0 --ipv6=auto --activate --hostname ${SERVERNAME}.ipa.smith122.com" > /tmp/network.ks
         ;;
      NOTIFYEMAIL*)
         eval $x
         echo "${NOTIFYEMAIL}" > /mnt/sysroot/root/notifyemail.txt
         ;;
   esac
done
cp -p /run/install/repo/ca-ipa.smith122.com.crt /etc/pki/ca-trust/source/anchors/ 2>/dev/null || :
wget http://www.ipa.smith122.com/smith122/certs/ca-ipa.smith122.com.crt -O /etc/pki/ca-trust/source/anchors/ca-ipa.smith122-wget.com.crt || :
update-ca-trust || :
%end

%post
(
   # Set temporary hostname
   #hostnamectl set-hostname renameme.ipa.smith122.com;

   # Get local mirror root ca certificate
   wget http://www.ipa.smith122.com/smith122/certs/ca-ipa.smith122.com.crt -O /etc/pki/ca-trust/source/anchors/ca-ipa.smith122.com.crt && update-ca-trust

   # Get local mirror repositories
   wget https://www.ipa.smith122.com/smith122/repo/rpm/smith122rpm.repo -O /etc/yum.repos.d/smith122rpm.repo;
   wget http://www.ipa.smith122.com/smith122/repo/rpm/smith122rpm.mirrorlist -O /etc/yum.repos.d/smith122rpm.mirrorlist
   distro=centos7 ; wget https://www.ipa.smith122.com/smith122/repo/mirror/smith122-bundle-${distro}.repo -O /etc/yum.repos.d/smith122-bundle-${distro}.repo && grep -oP "(? /boot/grub2/grub.cfg

   # postfix is already started by default on centos7
   # Send IP address to myself
   thisip="$( ifconfig 2>/dev/null | awk '/Bcast|broadcast/{print $2}' | tr -cd '[^0-9\.\n]' | head -n1 )"
   {
      echo "${SERVER} has IP ${thisip}."
      echo "system finished kickstart at $( date "+%Y-%m-%d %T" )";
   } | /usr/share/bgscripts/send.sh -f "root@$( hostname --fqdn )" \
      -h -s "${SERVER} is ${thisip}" $( cat /root/notifyemail.txt 2>/dev/null )

   # No changes to graphical boot
   #

   # fix the mkhomedir problem
   systemctl enable oddjobd.service && systemctl start oddjobd.service

   # Personal customizations
   mkdir -p /mnt/bgstack15 /mnt/public
   su bgstack15-local -c "sudo /usr/share/bgconf/bgconf.py"

) >> /root/install.log 2>&1
%end

%packages
@core
@^minimal
autossh
bc
bgconf
bgscripts-core
bind-utils
cifs-utils
cryptsetup
dosfstools
epel-release
expect
firewalld
git
iotop
ipa-client
-iwl*-firmware
mailx
man
mlocate
net-tools
nfs-utils
ntp
p7zip
parted
policycoreutils-python
rpm-build
rsync
screen
strace
sysstat
tcpdump
telnet
vim
wget
yum-utils
%end

Libreoffice is not using my gtk theme

LibreOffice was not using my gtk theme (on my devuan netinst, fluxbox, with xfce4-settings-manager, chtheme, and manually written .config/gtk-3.0/settings.ini).

basic interface for libreoffice writer
No theming for Writer

Turns out you simply need to install an additional package:

sudo apt-get install libreoffice-gtk3
libreoffice writer with gtk3 theming
Writer with gtk3 theme applied

Devuan also has a libreoffice-gtk2 package, which I didn’t try.
I haven’t tried a Fedora minimal/net install with Fluxbox and LibreOffice, so I don’t know if the libreoffice-gtk3 rpm is necessary there, but it’s in the repos.

sudo dnf install libreoffice-gtk3

I was impressed by this behavior. Just install an extra .so file, and boom, LibreOffice integrates with your desktop theme. LibreOffice is some great stuff!

References

Ripped off from How to change themes [closed] – Ask LibreOffice

Roll back aborted dnf update, 2019 edition

I had to fix an aborted dnf update. My previous post on this topic

sudo dnf remove $( sudo dnf list installed --showduplicates $( sudo dnf list installed --showduplicates | sort | uniq -w35 -D | awk '/^[a-zA-Z]/{print $1}' | sort | uniq | grep -vE 'kernel|saned' ) | awk '$0 !~ /Packages/{split($1,b,".");if($2 > a[b[1]]){a[b[1]]=$2"."b[2]}} END {for (key in a) {print key"-"a[key]} }' )

Walkthrough of the commands

sudo dnf list installed --showduplicates | sort | uniq -w35 -D | awk '/^[a-zA-Z]/{print $1}' | sort | uniq | grep -vE 'kernel|saned'

Show all installed packages, and then show only the duplicates (up to the first 35 characters; having to take a guess here), and remove any saned and kernel packages. I don’t know why I had to exclude saned: Perhaps I wanted both x86_64 and i386 packages for saned.

sudo dnf list installed --showduplicates $ABOVEVALUES | awk '$0 !~ /Packages/{split($1,b,".");if($2 > a[b[1]]){a[b[1]]=$2"."b[2]}} END {for (key in a) {print key"-"a[key]} }'

So, list the output from the previous statement including duplicates, and then use awk to find the highest version number of each named package and store it to a buffer. Then display that whole buffer at the end. So this now shows only the exact name and version (NEVRA, partially) of what to remove.
So this whole process is here to roll back the partially-updated changes.

sudo dnf remove $ABOVEVALUES

And now remove those packages. This should reset, so that we can then perform a regular upgrade at some later point.

references

  1. awk array in END https://unix.stackexchange.com/questions/183279/how-to-view-all-the-content-in-an-awk-array/183280#183280
  2. Prior use of associative arrays in awk https://bgstack15.wordpress.com/2017/04/11/remove-only-certain-duplicate-lines-with-awk/
  3. prior use of dnf –showduplicates but that didn’t work this time https://bgstack15.wordpress.com/2018/04/03/fedora-remove-duplicate-packages-from-partially-completed-dnf-update/
  4. discussion on NEVRA https://slashterix.wordpress.com/2016/08/06/rpm-version-comparison/

List yum repos that have packages installed and are still defined

yum repolist all $( yum list installed | awk '$NF ~ /@/ && $NF !~ /anaconda/ {split($NF,a,"@");print a[2];}' | sort | uniq ) | awk 'NR > 2 && $1 !~ /repolist/ {split($1,a,"/");print a[1]}'

The idea is to list each installed package which also lists the repo it was installed from, and then organize those repos. Then list them and show the ones that are still defined in yum’s repository files.

Fix vlc ui scaling problems

Vlc disable hidpi scaling

tl;dr

Set the environment variables:

export QT_AUTO_SCREEN_SCALE_FACTOR=0
export QT_SCREEN_SCALE_FACTORS=1

The story

I am testing Fluxbox on Devuan on a physical system (instead of just a VM) with two monitors. I discovered that on one monitor, the ui for vlc is scaled way wrong.
For my left monitor, the buttons are way larger than they should be.
VLC with large buttons and normal menus
And on the other monitor, the buttons were normal-sized, but the menus and other text widgets were way too small.
VLC with normal buttons and tiny menus
When I set the environment variables as described above, vlc appears in the correct scaling. At one point, I had some OS or DE installed that showed that my system viewed the left monitor (HDMI-connected) as a 7″ screen with 1920×1080 resolution, which is why the scaling on the left side was messed up.
VLC with normal buttons and menus
Not only did I add those variable exports to my ~/.fluxbox/startup file, I also wrote a wrapper for vlc as /usr/local/bin/vlc

#!/bin/sh
QT_AUTO_SCREEN_SCALE_FACTOR=0 QT_SCREEN_SCALE_FACTORS=1 /usr/bin/vlc

I was not aware that VLC was a QT program. But, after setting some environment variables,

References

Weblinks

  1. How to Enable hiDPI Scaling? – The VideoLAN Forums

Internet searches

  1. vlc disable hidpi scaling

Read Chrome and Firefox history from command line

Chrome

Shamelessly ripped from How do I access Chrome’s history (saved browsing history) file as a readable format without using third-party applications or extensions? – Quora

You will need a sqlite3 binary, probably from the package sqlite, to read the Chrome history file.

Chrome history in Linux is normally stored as file ~/.config/google-chrome/Default/History.

sqlite3 ~/.config/google-chrome/Default/History "select datetime(last_visit_time/1000000-11644473600,'unixepoch'),url from  urls order by last_visit_time asc" > output.txt

Firefox, Palemoon, Waterfox

This one’s in UTC.
Find the relevant history sqlite file.
For palemoon, it is similar to:

~/".moonchild productions/pale moon/1234abdf.default/places.sqlite"
sqlite3 ~/".moonchild productions/pale moon/1234abdf.default/places.sqlite" "select datetime(h.visit_date/1000000,'unixepoch'),p.url from moz_historyvisits as h, moz_places as p where p.id == h.place_id order by h.visit_date asc;"