Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
Next revisionBoth sides next revision
docs:guide-user:additional-software:opkg [2021/05/05 05:13] – [Out of space] vgaeteradocs:guide-user:additional-software:opkg [2023/04/03 00:34] – [Local repository] update vgaetera
Line 3: Line 3:
  
 The ''opkg'' utility is the lightweight package manager used for this job. The ''opkg'' utility is the lightweight package manager used for this job.
-Opkg is a fork of ''ipkg'', the package manager used in NSLU2's [[http://www.nslu2-linux.org/wiki/Optware/|Optware]], which is designed to add software to stock firmware of embedded devices.+Opkg is a fork of ''ipkg'', the package manager used in NSLU2's [[https://web.archive.org/web/20200919214711if_/http://www2.nslu2-linux.org/wiki/pmwiki.php?pagename=Optware/HomePage|Optware]]<sup>(archive link)</sup>, which is designed to add software to stock firmware of embedded devices.
  
 Opkg is a full package manager for the root file system, including kernel modules and drivers, while ipkg is just a way to add software to a separate directory (e.g. ''/opt''). Opkg is a full package manager for the root file system, including kernel modules and drivers, while ipkg is just a way to add software to a separate directory (e.g. ''/opt'').
  
-Opkg is sometimes called //Entware//, as it is used also in the [[http://entware.wl500g.info|Entware repository]] for embedded devices (a fork of OpenWrt community packages repository).+Opkg is sometimes called //Entware//, as it is also the package manager used by the [[https://github.com/Entware/Entware/wiki|Entware repository]] for embedded devices (itself a fork of OpenWrt'community packages repository).
  
 The package manager ''opkg'' attempts to resolve dependencies with packages in the repositories - if this fails, it will report an error and abort the installation of that package. The package manager ''opkg'' attempts to resolve dependencies with packages in the repositories - if this fails, it will report an error and abort the installation of that package.
Line 133: Line 133:
  
 ===== Examples ===== ===== Examples =====
 +==== Basics ====
 <code bash> <code bash>
 # Install a package # Install a package
Line 145: Line 146:
 </code> </code>
  
 +==== Extras ====
 You can make use of [[wp>Glob_(programming)|glob patterns]] directly and also write a little [[wp>Shell script|shell script]] to use [[wp>Regular expression|regular expressions]] and otherwise further process information. You can make use of [[wp>Glob_(programming)|glob patterns]] directly and also write a little [[wp>Shell script|shell script]] to use [[wp>Regular expression|regular expressions]] and otherwise further process information.
 Use a [[wp>Pipeline_(Unix)|pipeline]] and [[man>grep(1)|grep]], or [[man>awk(1)|awk]], or [[man>sed(1)|sed]] to filter that output: Use a [[wp>Pipeline_(Unix)|pipeline]] and [[man>grep(1)|grep]], or [[man>awk(1)|awk]], or [[man>sed(1)|sed]] to filter that output:
Line 151: Line 153:
 opkg list | grep -e <pattern1> -e <pattern2> opkg list | grep -e <pattern1> -e <pattern2>
 opkg list | awk -e '/<pattern>/{print $0}' opkg list | awk -e '/<pattern>/{print $0}'
-opkg info kmod-ipt-* | awk -e '/length/{print $0}'+opkg info kmod-nf-\* | awk -e '/length/{print $0}'
 opkg list-installed | awk -e '{print $1}' | tr '\n' ' ' opkg list-installed | awk -e '{print $1}' | tr '\n' ' '
 for pkg in <package1> <package2> <package3>; do opkg info ${pkg}; done for pkg in <package1> <package2> <package3>; do opkg info ${pkg}; done
Line 157: Line 159:
 </code> </code>
  
-:!: Mass upgrade of all packages is [[meta:infobox:upgrade_packages_warning|strongly discouraged]]. +==== Upgrading packages ==== 
-If you still want to proceedset up [[docs:guide-user:advanced:opkg_extras|Opkg extras]] or use the following one-liner:+<WRAP important> 
 +Mass upgrade of all packages is [[meta:infobox:upgrade_packages_warning|strongly discouraged]]. 
 +The chance of soft-bricking your device is significantso be fully prepared to perform a [[docs:guide-user:troubleshooting:failsafe_and_factory_reset|recovery and factory reset in failsafe mode]]
 +Proceed at your own risk. 
 +</WRAP>
  
 <code bash> <code bash>
Line 252: Line 258:
  
 ==== Proxy support ==== ==== Proxy support ====
 +OpenWrt 21.02:
 +
 +<code bash>
 +# Configure profile
 +mkdir -p /etc/profile.d
 +cat << "EOF" > /etc/profile.d/custom.sh
 +export https_proxy=http://proxy.example.org:8080/
 +EOF
 +. /etc/profile
 +
 +# Workaround
 +sed -i -e "s/https/http/" /etc/opkg/distfeeds.conf
 +</code>
 +
 To use ''opkg'' through a proxy, add the following to ''/etc/opkg.conf'': To use ''opkg'' through a proxy, add the following to ''/etc/opkg.conf'':
  
Line 283: Line 303:
  
 ===== Troubleshooting ===== ===== Troubleshooting =====
-==== Out of space ==== +==== Verbose opkg update ==== 
-If //opkg// runs out of space, it usually fails to recover cleanly leaving dangling lock files in place resulting in a ''//Could not obtain administrative lock//'' error+<code bash> 
-The lock file can be deleted by issuing the ''rm /usr/lib/opkg/lock'' command.+# Save the script 
 +cat << "EOF" > opkg-update.sh 
 +#!/bin/sh 
 +rm -f -R /tmp/opkg-lists 
 +mkdir -p /tmp/opkg-lists 
 +while read TYPE REPO URL 
 +do 
 +wget -O /tmp/opkg-lists/"${REPO}".gz "${URL}"/Packages.gz 
 +wget -O /tmp/opkg-lists/"${REPO}".sig "${URL}"/Packages.sig 
 +gunzip -k /tmp/opkg-lists/"${REPO}".gz 
 +usign -V -P /etc/opkg/keys -m /tmp/opkg-lists/"${REPO}" 2>&1 \ 
 +| grep -e "^OK$"
 +&& mv -f /tmp/opkg-lists/"${REPO}".gz /tmp/opkg-lists/"${REPO}" 
 +done < /etc/opkg/distfeeds.conf 
 +EOF 
 +chmod +x opkg-update.sh
  
-Additionally, //opkg// may not remove the files it was installing. +# Run the script 
- +./opkg-update.sh
-One way to do this is get a list of the files it was installing, then delete them. +
- +
-Replace the url with the appropriate package. +
- +
-<code bash> +
-(cd /; \ +
-wget -q -O - http://download.link.to.package \ +
-| tar -Oxz ./data.tar.gz | tar -tz | xargs rm)+
 </code> </code>
  
-However, the above line does not delete the dependencies that were installed along with the package responsible. +==== Out of space ==== 
-Also, it leaves empty directories around. +Remove partly installed packages and their dependencies if //opkg// runs out of space during a transaction.
-The script below intends to fix those.+
  
 <code bash> <code bash>
 # Save the script # Save the script
-cat << "EOF"opkgremovepartlyinstalledpackage.sh+cat << "EOF"opkg-rm-pkg-deps.sh
 #!/bin/sh #!/bin/sh
-# takes one argument/parameter: the name of the package which didn't install 
-# correctly and should be removed along with its dependencies 
-# example: ./opkgremovepartlyinstalledpackage.sh pulseaudio-daemon 
- 
-# get list of all packages that would be installed along with package x 
-PKGS="$(opkg --force-space --noaction install ${1} \ 
-| grep -e "http:" -e "https:" \ 
-| cut -f 2 -d " " \ 
-| sed -e "s/\.$//")" 
 opkg update opkg update
- +URL="$(opkg --force-space --noaction install "${@}"
-for PKG in ${PKGS+| sed -n -e "/^Downloading\s*/s///p")" 
-do +rm -f /usr/lib/opkg/lock 
-    LIST="$(wget -q -O - "${PKG}" \ +for URL in ${URL
-    | tar -Oxz ./data.tar.gz \ +do FILE="$(wget -q -O - "${URL}" \ 
-    | tar -t -z \ +| tar -O -x -z ./data.tar.gz \ 
-    | sort -r \ +| tar -t -z \ 
-    | sed -e "s/^./\/overlay\/upper/")" +| sort -r \ 
-    for FILE in ${LIST+| sed -e "s|^\.|/overlay/upper|")" 
-    do +for FILE in ${FILE
-        if [ -f "${FILE}"+do if [ -f "${FILE}"
-        then +then rm -f "${FILE}" 
-            echo "Removing file ${FILE}" +elif [ -d "${FILE}"
-            rm -f "${FILE}" +then rmdir "${FILE}" 
-        elif [ -d "${FILE}"+fi 
-        then +done
-            echo "Removing directory ${FILE} if empty" +
-            rmdir "${FILE}" +
-        fi +
-    done+
 done done
-echo "You may need to reboot for the free space to become visible" 
 EOF EOF
-chmod +x ./opkgremovepartlyinstalledpackage.sh+chmod +x opkg-rm-pkg-deps.sh 
 +</code> 
 + 
 +<code bash>
  
 # Run the script # Run the script
-./opkgremovepartlyinstalledpackage.sh <package-name>+./opkg-rm-pkg-deps.sh package_name 
 + 
 +# Reboot to make the free space visible 
 +reboot
 </code> </code>
  
 ==== Local repository ==== ==== Local repository ====
-FIXME Convert this into LEDE and explain what it is actually doing.+There may be use cases where having a package repository on the device itself is advantageous: 
 +  * Unreliable WANs, where the connectivity upstream of the device to a remote repository goes down for an unacceptable period of time. 
 +  * Bandwidth Caps, where the connectivity upstream of the device to a remote repository has a limited amount of data that can be fetched before the connectivity is throttled or goes down until the next period where the cap resets. 
 +  * A repository with customization; built from source, which isn't available from remote repositories. 
 +  * The device acts as a reference device for other systems, to ensure that the package versions across the devices local to the network remain consistent.
  
-Live example:+Set up a local repository for your target. 
 +Assuming about 2-3 GB of free space is available.
  
 <code bash> <code bash>
-r=44685 +# Install packages 
-search="http://downloads.openwrt.org/snapshots/trunk/ar71xx/generic" +opkg update 
-replace="file:///mnt/sdcard/shared/users/www/r$r" +opkg install rsync
-sed -i -e "s!$search!$replace!" /etc/opkg.conf +
-</code>+
  
-Share for a second router:+# Save the script 
 +cat << "EOF" > opkg-sync-local-repo.sh 
 +#!/bin/sh 
 +. /etc/os-release 
 +REPO_LOCAL="file://${1:-/${ID}}/" 
 +REPO_URL="https://downloads.${HOME_URL#*//}" 
 +case "${VERSION_ID}" in 
 +(snapshot) REPO_DIR="downloads/snapshots" ;; 
 +(*) REPO_DIR="downloads/releases/${VERSION_ID}" ;; 
 +esac 
 +REPO_CORE="${REPO_DIR}/targets/${OPENWRT_BOARD}" 
 +REPO_PKGS="${REPO_DIR}/packages/${OPENWRT_ARCH}" 
 +for REPO_DIR in "${REPO_CORE}" "${REPO_PKGS}" 
 +do mkdir -p "${REPO_LOCAL#*//}${REPO_DIR#*/}" 
 +rsync --bwlimit="8M" --del -r -t -v \ 
 +"${REPO_URL/https/rsync}${REPO_DIR}/"
 +"${REPO_LOCAL#*//}/${REPO_DIR#*/}/" 
 +done 
 +EOF 
 +chmod +x opkg-sync-local-repo.sh
  
-<code bash> +# Run the script 
-ln -s /mnt/sdcard/shared/users/www /www/pendrive +./opkg-sync-local-repo.sh /openwrt
-</code>+
  
-In the second router:+# Configure Opkg to use local repo 
 +. /etc/os-release 
 +REPO_LOCAL="file:///${ID}/" 
 +REPO_URL="https://downloads.${HOME_URL#*//}" 
 +sed -i -e "s|${REPO_URL}|${REPO_LOCAL}|" /etc/opkg/distfeeds.conf
  
-<code bash> +# Share the repository on the LAN 
-r=44685 +ln -f -s ${REPO_LOCAL#*///www/${ID} 
-search="downloads.openwrt.org/snapshots/trunk/ar71xx/generic" + 
-replace="192.168.1.1/pendrive/r$r+# Configure Opkg on the clients 
-sed -i -e "s!$search!$replace!" /etc/opkg.conf+. /etc/os-release 
 +REPO_LOCAL="http://192.168.1.1/${ID}/
 +REPO_URL="https://downloads.${HOME_URL#*//}
 +sed -i -e "s|${REPO_URL}|${REPO_LOCAL}|" /etc/opkg/distfeeds.conf
 </code> </code>
 +
 +See also: [[:downloads#how_to_mirror|How to mirror]]
  
 ===== Non-standard installation destinations ===== ===== Non-standard installation destinations =====
Line 384: Line 432:
 </WRAP> </WRAP>
  
-The default opkg.conf actually contains three destinations:+The default ''/etc/opkg.conf'' actually contains three destinations:
  
 <code bash> <code bash>
  • Last modified: 2024/04/12 10:08
  • by virtualguy