opkg - Додаткові можливості
Вступ
- Ця інструкція розширює функціональність opkg.
- Для швидкого налаштування скористайтесь розділом автоматизації.
Можливості
- Збереження, відновлення та відкат профілів opkg.
- Підтримка автоматичних та користувацьких профілів.
- Підтримка середовищ RWM, overlay та extroot.
- Визначення встановлених/видалених користувачем пакетів.
- Автоматичне відновлення після оновлення прошивки.
- Оновлення всіх пакетів, для яких доступне оновлення.
- Виправлення символьних посилань на встановлені альтернативи.
- Пошук нових конфігураційних файлів для оновлених пакетів.
Реалізація
- Обгортка викликів opkg для прозорої інтеграції команд.
- Використання UCI та резервних шаблонів для збереження/управління профілями.
- Імпорт користувацьких пакетів із резервних копій Sysupgrade, згідно з реалізацією в OpenWrt.
- Використання Hotplug extras для виявлення підключення до WAN і автоматичного запуску відновлення профілю.
- Застосування файлів блокування (lock) для запобігання конфліктів і зациклень.
- Перезавантаження системи (reboot) після відновлення профілю для застосування змін.
- Отримання профілю за замовчуванням з UCI (або вказаного вручну) для відновлення/відкату.
- Перевага команди `remove` над `install` під час відновлення — для уникнення конфліктів.
- Обмеження обсягу операцій: лише видалити встановлені, встановити відсутні, оновити доступні.
- Послідовна обробка пакетів — для зменшення використання ресурсів та уникнення помилок транзакцій.
Команди
Підкоманда | Опис |
---|---|
init | Ініціалізувати конфігурацію opkg. |
uci [<профіль>] < <uciprof> | Імпортувати профіль opkg з stdin або файлу до UCI. |
import [<резервний профіль>] | Імпортувати профіль opkg із резервної копії Sysupgrade до UCI. |
save | Зберегти поточний профіль opkg у UCI. |
restore [<профіль>] | Відновити профіль opkg:main або порожньо — основний профіль,init — RWM/мінімальний,custom — користувацький профіль. |
rollback [<профіль>] | Відкотити профіль opkg: видалити пакети, встановлені користувачем, встановити видалені користувачем, пропустити оновлені пакети. |
upgr [<тип пакета>] | Оновити пакети за типом:ai або порожньо — усі встановлені,oi — встановлені через overlay. |
export [<тип пакета>] | Експортувати пакети за типом:ai — всі встановлені,au — всі доступні для оновлення,ri — встановлені з ROM,wr — видалені з RWM,wi — встановлені у RWM,or — видалені з overlay,oi — встановлені в overlay,ur — видалені користувачем,ui — встановлені користувачем,pr — видалені з профілю,pi — встановлені з профілю. |
proc <команда> < <список_пакетів> | Обробити список пакетів із stdin за заданою підкомандою. |
reinstall <пакети> | Перевстановити вказані пакети. |
altlink | Виправити символьні посилання для встановлених альтернатив. |
newconf [<шлях>] | Знайти нові конфігурації для оновлених пакетів. |
Інструкції
# Configure profile mkdir -p /etc/profile.d cat << "EOF" > /etc/profile.d/opkg.sh opkg() { local OPKG_CMD="${1}" local OPKG_UCI="$(uci -q get opkg.defaults."${OPKG_CMD}")" case "${OPKG_CMD}" in (init|uci|import|save|restore|rollback|upgr\ |export|proc|reinstall|altlink|newconf) opkg_"${@}" ;; (*) command opkg "${@}" ;; esac } opkg_init() { uci import opkg < /dev/null uci -q batch << EOI set opkg.defaults='opkg' set opkg.defaults.import='/etc/backup/installed_packages.txt' set opkg.defaults.restore='init main' set opkg.defaults.rollback='main' set opkg.defaults.upgr='ai' set opkg.defaults.export='ai' set opkg.defaults.proc='--force-depends' set opkg.defaults.reinstall='--force-reinstall' set opkg.defaults.newconf='/etc' EOI } opkg_uci() { local OPKG_OPT="${1:-${OPKG_UCI}}" local OPKG_OPT="${OPKG_OPT:-main}" if ! uci -q get opkg > /dev/null then opkg init fi uci -q batch << EOI delete opkg.'${OPKG_OPT}' set opkg.'${OPKG_OPT}'='opkg' $(sed -r -e "s/^(.*)\s(.*)$/\ del_list opkg.'${OPKG_OPT}'.'\2'='\1'\n\ add_list opkg.'${OPKG_OPT}'.'\2'='\1'/") commit opkg EOI } opkg_import() { local OPKG_OPT="${1:-${OPKG_UCI}}" if [ -e "${OPKG_OPT}" ] then sed -n -r -e "s/\s(overlay|unknown)$/\ \tipkg/p" "${OPKG_OPT}" \ | opkg uci main fi } opkg_save() { local OPKG_WR="$(opkg export wr)" local OPKG_WI="$(opkg export wi)" local OPKG_UR="$(opkg export ur)" local OPKG_UI="$(opkg export ui)" if uci -q get fstab.rwm > /dev/null \ && grep -q -e "\s/rwm\s" /etc/mtab then { sed -e "s/$/\trpkg/" "${OPKG_WR}" sed -e "s/$/\tipkg/" "${OPKG_WI}" } | opkg uci init fi { sed -e "s/$/\trpkg/" "${OPKG_UR}" sed -e "s/$/\tipkg/" "${OPKG_UI}" } | opkg uci main rm -f "${OPKG_WR}" "${OPKG_WI}" "${OPKG_UR}" "${OPKG_UI}" } opkg_restore() { local OPKG_OPT="${1:-${OPKG_UCI}}" local OPKG_CONF="${OPKG_OPT}" for OPKG_CONF in ${OPKG_CONF} do local OPKG_AI="$(opkg export ai)" local OPKG_PR="$(opkg export pr)" local OPKG_PI="$(opkg export pi)" grep -x -f "${OPKG_AI}" "${OPKG_PR}" \ | opkg proc remove grep -v -x -f "${OPKG_AI}" "${OPKG_PI}" \ | opkg proc install rm -f "${OPKG_AI}" "${OPKG_PR}" "${OPKG_PI}" done } opkg_rollback() { local OPKG_OPT="${1:-${OPKG_UCI}}" local OPKG_CONF="${OPKG_OPT}" local OPKG_UR="$(opkg export ur)" local OPKG_UI="$(opkg export ui)" local OPKG_PR="$(opkg export pr)" local OPKG_PI="$(opkg export pi)" if uci -q get opkg."${OPKG_CONF}" > /dev/null then opkg restore "${OPKG_CONF}" grep -v -x -f "${OPKG_PI}" "${OPKG_UI}" \ | opkg proc remove grep -v -x -f "${OPKG_PR}" "${OPKG_UR}" \ | opkg proc install fi rm -f "${OPKG_UR}" "${OPKG_UI}" "${OPKG_PR}" "${OPKG_PI}" } opkg_upgr() { local OPKG_OPT="${1:-${OPKG_UCI}}" case "${OPKG_OPT}" in (ai|oi) opkg_"${OPKG_CMD}"_type ;; esac | opkg proc upgrade } opkg_upgr_type() { local OPKG_AI="$(opkg export ai)" local OPKG_OI="$(opkg export oi)" local OPKG_AU="$(opkg export au)" case "${OPKG_OPT::1}" in (a) grep -x -f "${OPKG_AI}" "${OPKG_AU}" ;; (o) grep -x -f "${OPKG_OI}" "${OPKG_AU}" ;; esac rm -f "${OPKG_AI}" "${OPKG_OI}" "${OPKG_AU}" } opkg_export() { local OPKG_OPT="${1:-${OPKG_UCI}}" local OPKG_TEMP="$(mktemp -t opkg.XXXXXX)" case "${OPKG_OPT}" in (ai|au) opkg_"${OPKG_CMD}"_cmd ;; (ri|wr|wi|or|oi) opkg_"${OPKG_CMD}"_type ;; (ur|ui) opkg_"${OPKG_CMD}"_run ;; (pr|pi) opkg_"${OPKG_CMD}"_uci ;; esac > "${OPKG_TEMP}" echo "${OPKG_TEMP}" } opkg_export_cmd() { local OPKG_TYPE case "${OPKG_OPT:1}" in (i) OPKG_TYPE="installed" ;; (u) OPKG_TYPE="upgradable" ;; esac opkg list-"${OPKG_TYPE}" \ | sed -e "s/\s.*$//" } opkg_export_type() { local OPKG_INFO="/usr/lib/opkg/info" local OPKG_TYPE case "${OPKG_OPT::1}" in (r) OPKG_INFO="/rom${OPKG_INFO}" ;; (w) OPKG_INFO="/rwm/upper${OPKG_INFO}" ;; (o) OPKG_INFO="/overlay/upper${OPKG_INFO}" ;; esac case "${OPKG_OPT:1}" in (r) OPKG_TYPE="c" ;; (i) OPKG_TYPE="f" ;; esac find "${OPKG_INFO}" -name "*.control" \ -type "${OPKG_TYPE}" 2> /dev/null \ | sed -e "s/^.*\///;s/\.control$//" } opkg_export_run() { local OPKG_AI="$(opkg export ai)" local OPKG_RI="$(opkg export ri)" case "${OPKG_OPT:1}" in (r) grep -v -x -f "${OPKG_AI}" "${OPKG_RI}" ;; (i) grep -v -x -f "${OPKG_RI}" "${OPKG_AI}" ;; esac rm -f "${OPKG_AI}" "${OPKG_RI}" } opkg_export_uci() { local OPKG_TYPE case "${OPKG_OPT:1}" in (r) OPKG_TYPE="rpkg" ;; (i) OPKG_TYPE="ipkg" ;; esac uci -q get opkg."${OPKG_CONF}"."${OPKG_TYPE}" \ | sed -e "s/\s/\n/g" } opkg_proc() { local OPKG_OPT="${OPKG_UCI}" local OPKG_CMD="${1:?}" local OPKG_PKG while read -r OPKG_PKG do opkg "${OPKG_CMD}" "${OPKG_PKG}" ${OPKG_OPT} done } opkg_reinstall() { local OPKG_OPT="${OPKG_UCI}" opkg install "${@}" ${OPKG_OPT} } opkg_altlink() { sed -n -e "/^Alternatives:/\ {s/^\S*\s*//;s/,\s/\n/gp}" /usr/lib/opkg/status \ | sort -n -t ":" \ | while IFS=":" read -r OPKG_PRIO OPKG_LINK OPKG_ALT do ln -f -s "${OPKG_ALT}" "${OPKG_LINK}" done } opkg_newconf() { local OPKG_OPT="${1:-${OPKG_UCI}}" find "${OPKG_OPT}" -name "*-opkg" } EOF . /etc/profile.d/opkg.sh # Configure hotplug mkdir -p /etc/hotplug.d/online cat << "EOF" > /etc/hotplug.d/online/50-opkg-restore OPKG_CONF="$(uci -q get opkg.defaults.restore)" for OPKG_CONF in ${OPKG_CONF} do if [ ! -e /etc/opkg-restore-"${OPKG_CONF}" ] \ && lock -n /var/lock/opkg-restore \ && sleep 10 \ && opkg update then . /etc/profile.d/opkg.sh opkg restore "${OPKG_CONF}" &> \ /var/log/opkg-restore-"${OPKG_CONF}" touch /etc/opkg-restore-"${OPKG_CONF}" lock -u /var/lock/opkg-restore case "${OPKG_CONF}" in (init) ;; (*) reboot ;; esac break fi done EOF cat << "EOF" >> /etc/sysupgrade.conf /etc/hotplug.d/online/50-opkg-restore EOF
Приклади
# Save Opkg profile opkg save # Restore Opkg profile opkg update opkg restore # Roll back Opkg profile opkg rollback # Set up Opkg profiles uci set opkg.defaults.restore="init custom" uci set opkg.init="opkg" uci add_list opkg.init.ipkg="losetup" uci add_list opkg.init.ipkg="parted" uci add_list opkg.init.ipkg="resize2fs" uci set opkg.custom="opkg" uci add_list opkg.custom.rpkg="dnsmasq" uci add_list opkg.custom.rpkg="ppp" uci add_list opkg.custom.ipkg="curl" uci add_list opkg.custom.ipkg="diffutils" uci add_list opkg.custom.ipkg="dnsmasq-full" uci commit opkg # Check Opkg log tail -f /var/log/opkg-* # Upgrade packages opkg update opkg upgr # Maintenance opkg altlink opkg newconf
Автоматизація
wget -U "" -O opkg-extras.sh "https://openwrt.org/_export/code/docs/guide-user/advanced/opkg_extras?codeblock=0" . ./opkg-extras.sh