Import Debian changes 2.0.5.15-ok1
kylin-system-updater (2.0.5.15-ok1) yangtze; urgency=medium * BUG: #140507 : 【2203自适应升级2209】2107升级到2203,再由2203自适应升级至2209-RC6失败 #145229 : 【2203自适应升级2209】升级过程中出现弹窗认证 * 需求号: 无 * 其他改动说明: 无 * 其他改动影响域:系统更新 kylin-system-updater (2.0.5.14) v101; urgency=medium * BUG: #144937 : 【2203自适应升级2209】自动更新下载报错 #144756 : 【在线更新】开启自动更新,kylin-unattended-upgrades服务状态异常 #140277 : 【在线更新】更新失败后查看更新历史,显示包名 * 需求号: 无 * 其他改动说明: 无 * 其他改动影响域:系统更新 kylin-system-updater (2.0.5.13) v101; urgency=medium * BUG: #141330 【在线更新】0521系统在线升级到2203-update1时提示依赖冲突 * 需求号: 无 * 其他改动说明: 无 * 其他改动影响域:系统更新 kylin-system-updater (2.0.5.12) v101; urgency=medium * BUG: #141197 【在线更新】更新升级安装软件包过程中点击电源后还可以正常关机重启、 #141309 【在线更新】自动更新失败 #142560 【2203自适应升级2209】用命令升级完成后,控制面板-关于界面的版本号和系统补丁版本号均为2203 #143275 【2203自适应升级2209】使用自动更新下载安装命令升级成功后,控制面板-更新界面依然能检测出“系统更新”和“系统基础组件” #143274 【2203自适应升级2209】使用自动更新下载安装命令升级成功后,开始菜单缺少部分软件 * 需求号: 无 * 其他改动说明: 无 * 其他改动影响域:系统更新 kylin-system-updater (2.0.5.11) v101; urgency=medium * BUG: #140451 【2203自适应升级2209】自动更新下载报错 #139133 【需求12242】【软件商店客户端】软件卸载后未自动清除卸载后的残留 * 需求号: 无 * 其他改动说明: 无 * 其他改动影响域:系统更新 kylin-system-updater (2.0.5.10) v101; urgency=medium * BUG: #138243 修复优先升级,安装的部分检查出计算依赖错误 * 需求号: 无 * 其他改动说明: 无 * 其他改动影响域:系统更新 kylin-system-updater (2.0.5.9) v101; urgency=medium * BUG: #138243 修复优先升级,安装的部分检查出计算依赖错误 * 需求号: 无 * 其他改动说明: 无 * 其他改动影响域:系统更新 kylin-system-updater (2.0.5.8) v101; urgency=medium * BUG: #135190【2203自适应升级2209】系统更新自动下载和安装,内核未更新 #136765 【离线更新】使用U盘源时,控制面板-更新中,“有更新应用时通知”打开无效果 * 需求号: 无 * 其他改动说明: 无 * 其他改动影响域:系统更新 kylin-system-updater (2.0.5.7) v101; urgency=medium * BUG: #126438 【reopen】【安装器】中文环境下,安装失败或者未授权的错误日志信息显示为英文 #134470 【设计】安装失败日志语言显示异常 #127975 【reopen】【云桌面】【在线更新】累计更新成功后,系统版本号以及补丁包版本号未发生变化 #135020 【在线更新】【PTOF】更新成功后,系统版本号以及补丁包版本号不会变化 #136748 【在线更新】从安装器安装和更新软件后,本地日志未记录数据,未进行上传。 * 需求号: # 无 * 其他改动说明: 无 * 其他改动影响域:系统更新 kylin-system-updater (2.0.5.6) v101; urgency=medium * BUG: #135270【解决方案|更新升级V1.6】【系统更新客户端】客户端进行自动更新,更新失败后,查看更新历史,历史内容显示为空 #135227 【解决方案|更新升级V1.6】【更新升级】未连接网络时,更新界面显示“检查更新异常!”,悬浮提示为“无法访问源管理服务器,请稍后再试” #136093 【解决方案|更新升级V1.6】【更新升级】使用安装器安装deb包,旧的服务没有收集到数据 #135372 【解决方案|更新升级V1.6】【系统更新客户端】客户端进行自动更新,更新后,查看更新历史分组名称显示了包名,应该显示软件名称 #120948 【在线更新】断网时检测更新失败的文案何设计图不符 * 需求号: # 无 * 其他改动说明: 无 * 其他改动影响域:系统更新 kylin-system-updater (2.0.5.5) v101; urgency=medium * BUG: #120948 【在线更新】断网时检测更新失败的文案何设计图不符 # 134470 【设计】安装失败日志语言显示异常 * 需求号: # 无 * 其他改动说明: 无 * 其他改动影响域:系统更新 kylin-system-updater (2.0.5.4) v101; urgency=medium * BUG: #134497 【在线更新】打开设置-更新,自动更新按钮默认是“打开”状态 #134493 【在线更新】【PTOF】更新完成后重启系统,打开设置-更新界面,提示“后台程序未启动” #131509 【更新升级】环境破损修复之后,没有自动安装更新包 #125723 【x100】【系统更新】英文安装操作系统,修改系统语言为中文后,检测更新的提示语仍是英文的 #120948 【在线更新】断网时检测更新失败的文案何设计图不符 #134470 【设计】安装失败日志语言显示异常 #126438 【安装器】中文环境下,安装失败或者未授权的错误日志信息显示为英文 #122425 【在线更新】设置每隔1min38s弹出通知,在弹出的通知弹窗中点击推迟,1min38s后再次弹出更新通知 * 需求号: # 无 * 其他改动说明: 无 * 其他改动影响域:系统更新 kylin-system-updater (2.0.5.3) v101; urgency=medium * BUG: # 125182 【安装器】在安全中心将应用程序来源检查设置为阻止,双击安装未签名deb包,安装失败但是日志为空 # 122183 【在线更新】上午8-12点外仍会弹出更新通知 * 需求号: 无 * 其他改动说明: 无 * 其他改动影响域:系统更新 kylin-system-updater (2.0.5.2) v101; urgency=medium * BUG: #118026 【在线更新】英文环境下,安装和卸载应用时弹出授权界面,提示内容表述方式不一致 #125182 【安装器】在安全中心将应用程序来源检查设置为阻止,双击安装未签名deb包,安装失败但是日志为空 #126365 【安装器】英文状态下授权窗口未中文 #126787 【离线更新】光盘源/U盘源插入被测机器,控制面板-更新界面提示软件源更新失败 #124430 【在线更新】控制面板-更新中“自动下载和安装更新”按钮未与配置文件进行联动 #120948 【在线更新】断网时检测更新失败的文案何设计图不符 * 需求号: 无 * 其他改动说明: 无 * 其他改动影响域:系统更新 kylin-system-updater (2.0.5.1) v101; urgency=medium * BUG: # 121890 【更新升级】部分应用更新完成后,在“查看历史更新”中查不到数据 # 123985 【在线更新】系统存在可选更新且在设置中开启了自动下载和安装更新,系统到达定时下载的时间未进行自动下载 # 110370 【更新升级】 【自动更新】出现一次,自动更新安装服务,将本地安装包地址检测成源地址导致安装报错 * 需求号: # 12722 【更新升级】系统更新全流程监控 # 12720 【更新升级】升级环境检测 # 12721 【更新升级】系统版本号体系 * 其他改动说明: 无 * 其他改动影响域:系统更新 kylin-system-updater (2.0.4.3) v101; urgency=medium * BUG: # 118021 【在线更新】中文环境下,安装和卸载应用时弹出授权界面,提示内容未汉化 # 118026 【在线更新】英文环境下,安装和卸载应用时弹出授权界面,提示内容表述方式不一致 # 122799 【在线更新】配置项中的源地址错误时,客户端重启后打开设置更新,提示后台程序未启动 # 119435 【更新升级】配置组包json格式错误时,system-updater、自动更新服务均不能启动,更新功能失效,需要增加异常处理机制 # 121781 【在线更新】中文环境下,静默更新完成后,右上角及侧边栏通知未汉化 * 需求号: 无 * 其他改动说明: 无 * 其他改动影响域:系统更新 kylin-system-updater (2.0.4.2kord) v101; urgency=medium * BUG: # 118021 【在线更新】中文环境下,安装和卸载应用时弹出授权界面,提示内容未汉化 # 118026 【在线更新】英文环境下,安装和卸载应用时弹出授权界面,提示内容表述方式不一致 # 122799 【在线更新】配置项中的源地址错误时,客户端重启后打开设置更新,提示后台程序未启动 # 119435 【更新升级】配置组包json格式错误时,system-updater、自动更新服务均不能启动,更新功能失效,需要增加异常处理机制 * 需求号: 无 * 其他改动说明: 无 * 其他改动影响域:系统更新 kylin-system-updater (2.0.3.2kord) v101; urgency=medium * BUG: 无 * 需求号: 无 * 其他改动说明: 增加系统版本号 * 其他改动影响域:系统更新 kylin-system-updater (2.0.2kord) v101; urgency=medium * BUG: 113951 【电源管理】偶现机器无法通过关机选项或终端命令睡眠、关机或重启(7/10) * 需求号: 无 * 其他改动说明: 增加系统版本号 * 其他改动影响域:系统更新 kylin-system-updater (2.0.1kord) v101; urgency=medium * BUG: 无 * 需求号: 无 * 其他改动说明: 增加开机定时下载、关机安装功能,仅合入代码未启用功能 * 其他改动影响域:系统更新 kylin-system-updater (2.0.0kord) v101; urgency=medium * BUG: 无 * 需求号: 无 * 其他改动说明: sp3前后端分离: 更新后端+自动更新 * 其他改动影响域:系统更新 kylin-system-updater (1.4.20kord) v101; urgency=medium * BUG: 无 * 需求号: 无 * 其他改动说明: 修复计算删除包异常 * 其他改动影响域:系统更新 kylin-system-updater (1.4.19kord) v101; urgency=medium * BUG: 无 * 需求号: 无 * 其他改动说明: 调整自动更新的开关接口,新增检查更新时候的当前状态显示;优化更新下载阶段增加超时退出功能; * 其他改动影响域:系统更新 kylin-system-updater (1.4.18kord) v101; urgency=medium * BUG: # 109487 【更新升级】【重启提示】【PTOF】全部更新-备份更新方式,备份完成不继续更新流程 # 109871 【自适应升级】【系统更新】单个更新回连后提示您的系统已是最新,实际存在未更新的包 # 108555 【自适应升级】【更新升级】升级系统更新进度在85%卡住,重启控制面板显示英文提示,不显示检测的更新内容,重启后恢复 * 需求号: 无 * 其他改动说明: 无 * 其他改动影响域:系统更新 kylin-system-updater (1.4.17kord) v101; urgency=medium * BUG: #109623 【自适应升级】 【系统更新】光盘源拔出后,还在尝试获取光盘源内容,未自动检测仓库源,可手动恢复 * 需求号: 无 * 其他改动说明: 无 * 其他改动影响域:系统更新 kylin-system-updater (1.4.16kord) v101; urgency=medium * BUG: #108277 【自适应升级】更新升级过程中提示“ukui-kwin-common”缺少依赖 #109095 【自适应升级】【更新升级】 0326arm版本安装system-updater 1.4.14升级后,系统自适应升级过程超时,控制面板中未结束更新一直停留在安装中的状态 #108665 【自适应升级】【更新升级】0326arm进行版本升级后提示升级成功,实际有部分包未安装成功 #109032 【自适应升级】【更新升级】公网不可访问时不能获取更新列表进行更新 #109036 【自适应升级】【更新升级】 自适应升级后,全部更新中包含缺依赖的包,更新完成后在历史记录中缺依赖的包也显示更新成 # 105722 【安装器】【龙芯3A5000】安装器安装用户手册deb时提示依赖错误,但是用dpkg命令可以安装 # 103939 【安装器】安装高版本用户手册后,安装低版本,提示安装失败,dpkg可以安装成功 # 100272 【安装器】双击deb包无法安装,日志中提示存在依赖,但通过dpkg可以安装 * 需求号: 无 * 其他改动说明: 无 * 其他改动影响域:系统更新 kylin-system-updater (1.4.15kord) v101; urgency=medium * BUG: #108555:【自适应升级】【更新升级】升级系统更新进度在85%卡住,重启控制面板显示英文提示,不显示检测的更新内容,重启后恢复 #102591:【控制面板|更新】笔记本在20%低电量时更新未有任何特殊提示,建议增加 #105111:【更新升级】【重启提示】更新完成后出现弹窗提示重启,此时安装另一包(手动安装或者静默更新后台安装包过程中)后点击弹窗中的立即重启,系统不重启也无提示 #102172:【自适应更新】【系统更新】从sp1 0722自适应升级到sp2 1223版本后,更新设置会恢复默认 #102104:【自适应更新】【系统更新】从sp1 0722自适应升级到sp2 1223版本后,上次更新时间与更新历史被清空 * 需求号: 无 * 其他改动说明: 无 * 其他改动影响域:系统更新 kylin-system-updater (1.4.14.1kord) v101; urgency=medium * BUG: #108555:【自适应升级】【更新升级】升级系统更新进度在85%卡住,重启控制面板显示英文提示,不显示检测的更新内容,重启后恢复 #102591:【控制面板|更新】笔记本在20%低电量时更新未有任何特殊提示,建议增加 #105111:【更新升级】【重启提示】更新完成后出现弹窗提示重启,此时安装另一包(手动安装或者静默更新后台安装包过程中)后点击弹窗中的立即重启,系统不重启也无提示 #102172:【自适应更新】【系统更新】从sp1 0722自适应升级到sp2 1223版本后,更新设置会恢复默认 #102104:【自适应更新】【系统更新】从sp1 0722自适应升级到sp2 1223版本后,上次更新时间与更新历史被清空 * 需求号: 无 * 其他改动说明: 无 * 其他改动影响域:系统更新 kylin-system-updater (1.4.13.1kord) v101; urgency=medium * BUG: #108277: 【自适应升级】更新升级过程中提示“ukui-kwin-common”缺少依赖 * 需求号: 无 * 其他改动说明: 无 * 其他改动影响域:系统更新 kylin-system-updater (1.4.13kord) v101; urgency=medium * BUG: 无 * 需求号: 无 * 其他改动说明: 无 * 其他改动影响域:系统更新 kylin-system-updater (1.4.12kord) v101; urgency=medium * BUG: #102172: 【自适应更新】【系统更新】从sp1 0722自适应升级到sp2 1223版本后,更新设置会恢复默认 #102104: 【自适应更新】【系统更新】从sp1 0722自适应升级到sp2 1223版本后,上次更新时间与更新历史被清空 #101852: 【用户手册】【更新升级】用户手册中设置下的更新升级内容与文档不一致 #104435: 【用例240562】设置-更新界面点击菜单栏-帮助,未直接定位到更新部分 #105336: 【更新升级】【重启提示】自动更新安装开始和结束的弹窗内容显示不明确 #105330 【更新升级】【重启提示】存在源中无所需依赖的包时,弹窗是否进行全盘更新,点击确认后控制面板闪退 # 105104 【更新升级】【重启提示】带按钮的强弹窗不应该出现在侧边栏,需修改弹窗类型 # 102465 【系统更新】缺依赖的包,单个更新提示缺依赖后点击全部更新提示更新成功 # 102175 【自适应更新】【系统更新】升级后,更新一个安装时间较长的包,重启控制面板,此时会一直等待收到安装完成的信号后,才能继续检测更新,影响用户体验 # 102015 【97888】【系统更新】使用光盘源更新缺依赖的包提示"没有找到需要升级和安装的包",未提示缺依赖 # 101864 【自适应更新】【自动更新】自动更新下载阶段或者备份前阶段打开控制面板,自动更新服务均不能自动退出 # 101852 【用户手册】【更新升级】用户手册中设置下的更新升级内容与文档不一致 # 101669 【自适应更新】【自动更新】自动更新过滤掉了非正式源,只能获取archive正式源的包,其余源的更新内容不能获取到 # 93555 【系统更新】【SP2 UI走查】更新-页面未按最新设计稿实现 # 90446 【更新升级-需求-9002】【系统更新】点击单个更新后,取消更新按钮未上下对齐 # 89824 【更新升级-需求-9002】【系统更新】单个待更新包选择全部更新,拒绝安装后不应该提示"部分更新失败" * 需求号: 无 * 其他改动说明: 无 * 其他改动影响域:系统更新 kylin-system-updater (1.4.11.2kord) v101; urgency=medium * BUG: #102172: 【自适应更新】【系统更新】从sp1 0722自适应升级到sp2 1223版本后,更新设置会恢复默认 #102104: 【自适应更新】【系统更新】从sp1 0722自适应升级到sp2 1223版本后,上次更新时间与更新历史被清空 #101852: 【用户手册】【更新升级】用户手册中设置下的更新升级内容与文档不一致 #104435: 【用例240562】设置-更新界面点击菜单栏-帮助,未直接定位到更新部分 #105336: 【更新升级】【重启提示】自动更新安装开始和结束的弹窗内容显示不明确 #105330 【更新升级】【重启提示】存在源中无所需依赖的包时,弹窗是否进行全盘更新,点击确认后控制面板闪退 # 105104 【更新升级】【重启提示】带按钮的强弹窗不应该出现在侧边栏,需修改弹窗类型 # 102465 【系统更新】缺依赖的包,单个更新提示缺依赖后点击全部更新提示更新成功 # 102175 【自适应更新】【系统更新】升级后,更新一个安装时间较长的包,重启控制面板,此时会一直等待收到安装完成的信号后,才能继续检测更新,影响用户体验 # 102015 【97888】【系统更新】使用光盘源更新缺依赖的包提示"没有找到需要升级和安装的包",未提示缺依赖 # 101864 【自适应更新】【自动更新】自动更新下载阶段或者备份前阶段打开控制面板,自动更新服务均不能自动退出 # 101852 【用户手册】【更新升级】用户手册中设置下的更新升级内容与文档不一致 # 101669 【自适应更新】【自动更新】自动更新过滤掉了非正式源,只能获取archive正式源的包,其余源的更新内容不能获取到 # 93555 【系统更新】【SP2 UI走查】更新-页面未按最新设计稿实现 # 90446 【更新升级-需求-9002】【系统更新】点击单个更新后,取消更新按钮未上下对齐 # 89824 【更新升级-需求-9002】【系统更新】单个待更新包选择全部更新,拒绝安装后不应该提示"部分更新失败" * 需求号: 无 * 其他改动说明: 无 * 其他改动影响域:系统更新 kylin-system-updater (1.4.11kord) v101; urgency=medium * BUG: #102172: 【自适应更新】【系统更新】从sp1 0722自适应升级到sp2 1223版本后,更新设置会恢复默认 #102104: 【自适应更新】【系统更新】从sp1 0722自适应升级到sp2 1223版本后,上次更新时间与更新历史被清空 #101852: 【用户手册】【更新升级】用户手册中设置下的更新升级内容与文档不一致 #104435: 【用例240562】设置-更新界面点击菜单栏-帮助,未直接定位到更新部分 * 需求号: 无 * 其他改动说明: 无 * 其他改动影响域:系统更新 kylin-system-updater (1.4.10kord) v101; urgency=medium * BUG: #101864: 【自适应更新】【自动更新】自动更新下载阶段或者备份前阶段打开控制面板,自动更新服务均不能自动退出 #104699: 【自适应更新】【自动更新】自动更新过滤掉了非正式源,只能获取archive正式源的包,其余源的更新内容不能获取到 * 需求号: 无 * 其他改动说明: 无 * 其他改动影响域:系统更新 kylin-system-updater (1.4.9kord) v101; urgency=medium * BUG: #105336: 【更新升级】【重启提示】自动更新安装开始和结束的弹窗内容显示不明确 #104275: 【系统更新】自动更新和下载无法使用 * 需求号: 无 * 其他改动说明: 无 * 其他改动影响域:系统更新 kylin-system-updater (1.4.8kord) v101; urgency=medium * BUG: #100272: 【安装器】双击deb包无法安装,日志中提示存在依赖,但通过dpkg可以安装 * 需求号: 无 * 其他改动说明: 无 * 其他改动影响域:系统更新 kylin-system-updater (1.4.7kord) v101; urgency=medium * BUG: #89964: 【更新升级-需求-9002】【系统更新】当前源锁定方案对于私有化部署用户,获取更新包时,不易自由从私有源、公网源之间切换 #89921: 【更新升级-需求-9002】【系统更新】sources.list中sp1源与私有源共存,私有源中包版本高,实际更新获取的是私有源的包,锁定源未生效 * 需求号: 无 * 其他改动说明: 无 * 其他改动影响域:系统更新 kylin-system-updater (1.4.6.1kord) v101; urgency=medium * BUG: 无 * 需求号: 无 * 其他改动说明: 增加重启弹窗 * 其他改动影响域:系统更新 kylin-system-updater (1.4.6kord) v101; urgency=medium * BUG: #102463: 【自动更新】自动更新时源优先级策略未生效,实际获取所有源中最高版本而非按照设置的优先级顺序获取包,导致包版本下载错误 * 需求号: 无 * 其他改动说明: 无 * 其他改动影响域:系统更新 kylin-system-updater (1.4.5kord) v101; urgency=medium * BUG: #102442 【系统更新】【PTOF】系统更新过程重启控制面板,页面展示内容为上次更新时间并持续停留在此页面,此时不能获取更新列表进行更新操作 * 需求号: 无 * 其他改动说明: 无 * 其他改动影响域:系统更新 kylin-system-updater (1.4.4kord) v101; urgency=medium * BUG: 无 * 需求号: 无 * 其他改动说明: 增加自适应更新的安装重启提示 * 其他改动影响域:系统更新 kylin-system-updater (1.4.3kord) v101; urgency=medium * BUG: #94805 【更新升级-需求-9002】【系统更新】更新页面上方文字与图标未对齐 #101985【更新】系统字号为15,点击查看历史设备,左上角“历史更新”字样未随系统字号改变而改变 #101669【自适应更新】【自动更新】自动更新过滤掉了非正式源,只能获取archive正式源的包,其余源的更新内容不能获取到 #102069【安装器】无法安装360助手等三方软件且报错不满足依赖,使用dpkg命令可以成功安装且不需要安装其他依赖 * 需求号: 无 * 其他改动说明: 无 * 其他改动影响域:系统更新 kylin-system-updater (1.4.1.5kord) v101; urgency=medium * BUG: #94805 【更新升级-需求-9002】【系统更新】更新页面上方文字与图标未对齐 #101985【更新】系统字号为15,点击查看历史设备,左上角“历史更新”字样未随系统字号改变而改变 #101333【控制面板】【更新】系统语言为英文,系统字号为15,系统主题为默认,升级页面自动下载与安装更新悬浮框背景为黑色 #101669【自适应更新】【自动更新】自动更新过滤掉了非正式源,只能获取archive正式源的包,其余源的更新内容不能获取到 #102069【安装器】无法安装360助手等三方软件且报错不满足依赖,使用dpkg命令可以成功安装且不需要安装其他依赖 * 需求号: 无 * 其他改动说明: 无 * 其他改动影响域:系统更新 kylin-system-updater (1.4.1.1kord) v101; urgency=medium * BUG: #101309【控制面板】【更新】更新页面图标和检查更新时的动画丢失 #89824【更新升级-需求-9002】【系统更新】单个待更新包选择全部更新,拒绝安装后不应该提示"部分更新失败";且更新失败后应该出现检测更新的按钮 #100839【控制面板|更新】最大字号,一个账户系统语言为英文,一个为中文,英文账户的控制面板-更新界面显示不全 * 需求号: 无 * 其他改动说明: 无 * 其他改动影响域:系统更新插件 kylin-system-updater (1.4.0kord) v101; urgency=medium * BUG: #99496【系统更新】【英文】【UI布局】更新界面提示信息较长时,页面格式变成左右拖动框与其他界面格式不符 #98774【用例104332】【升级】更新历史窗口,左侧名称显示不全 #97888【离线更新】【PTOF】控制面板识别不到光盘源中的包 #97116【控制面板|更新】更新界面检测按钮显示不全 #95290【系统更新】系统语言为英文时,打开控制面板-更新升级页面,再切换到字体页面,将字号切换到15号,返回升级页面,details显示不全 #94804【更新升级-需求-9002】【系统更新】应用后的更新按钮内“更新”字样未居中 #93555【系统更新】【SP2 UI走查】更新-页面未按最新设计稿实现 #85618【内测】【摸底测试】【更新升级】上次更新提示词错误 #85312【内测】【摸底测试】【更新升级】更新失败提示字不合理 #85269【内测】【控制面板|更新】英文模式下检查更新文字显示不全 * 需求号: 无 * 其他改动说明: 修改frame边际,保证在显示器不同缩放情况下仍然能够正常显示 * 其他改动影响域:系统更新插件 kylin-system-updater (1.3.5kord) v101; urgency=medium * BUG: #100356【试用模式】点击设置的更新,控制面板闪退(安装完系统后打开不会闪退) #93390 【控制面板|更新】打开控制面板切换深色主题,不关闭控制面板的前提下更新部分文字未反白 #91169 【更新升级-需求-9002】【系统更新】开启通知可更新应用后不弹窗通知可更新 #99894 【安装器】安装失败-不满足依赖的提示未汉化 #97120 【控制面板|更新】软件源更新失败提示语未汉化 #99500 【系统更新】【英文】【UI布局】更新界面,update settings与下方标题未对齐 #99498 【系统更新】【英文】【UI布局】更新界面,自动更新的第二行介绍显示不全 * 需求号: 无 * 其他改动说明: 修改部分英文表述和中文翻译 * 其他改动影响域:系统更新插件 kylin-system-updater (1.3.4kord) v101; urgency=medium * BUG: #100356【试用模式】点击设置的更新,控制面板闪退(安装完系统后打开不会闪退) #93390 【控制面板|更新】打开控制面板切换深色主题,不关闭控制面板的前提下更新部分文字未反白 #91169 【更新升级-需求-9002】【系统更新】开启通知可更新应用后不弹窗通知可更新 #99894 【安装器】安装失败-不满足依赖的提示未汉化 #97120 【控制面板|更新】软件源更新失败提示语未汉化 #99500 【系统更新】【英文】【UI布局】更新界面,update settings与下方标题未对齐 #99498 【系统更新】【英文】【UI布局】更新界面,自动更新的第二行介绍显示不全 * 需求号: 无 * 其他改动说明: 无 * 其他改动影响域:系统更新插件 kylin-system-updater (1.3.2.1kord) v101; urgency=medium * BUG: 无 * 需求号: 无 * 其他改动说明: 增加运行依赖python3-distro-info * 其他改动影响域:系统更新插件 kylin-system-updater (1.3.2kord) v101; urgency=medium * BUG: 无 * 需求号: 无 * 其他改动说明: 修改与旧版本控制面板的冲突 * 其他改动影响域:系统更新插件 kylin-system-updater (1.3.1kord) v101; urgency=medium * BUG: 无 * 需求号: 无 * 其他改动说明: 修复点击全部升级后执行更新检测的问题 * 其他改动影响域:系统更新全部升级 kylin-system-updater (1.3.0kord) v101; urgency=medium * BUG: #97525: 【安装器】安装器无法安装降级的deb包,终端dpkg可以安装 #85685: 【更新升级】中断自动备份更新过程后,无法再进行自动备份更新 #97859: 【安装器】安装软件包失败的输出日志不够详细 * 需求号: 无 * 其他改动说明: 无 * 其他改动影响域:系统更新 kylin-system-updater (1.2.18.5kord) v101; urgency=medium * BUG: #97525: 【安装器】安装器无法安装降级的deb包,终端dpkg可以安装 * 需求号: 无 * 其他改动说明: 更改logrotate.d/unattended-upgrades * 其他改动影响域:系统更新 kylin-system-updater (1.2.18.4kord) v101; urgency=medium * BUG: #97525: 【安装器】安装器无法安装降级的deb包,终端dpkg可以安装 * 需求号: 无 * 其他改动说明: * 其他改动影响域:系统更新 kylin-system-updater (1.2.18.3kord) v101; urgency=medium * BUG: #97525: 【安装器】安装器无法安装降级的deb包,终端dpkg可以安装 * 需求号: 无 * 其他改动说明: 合并plugin_dev改动,测试 * 其他改动影响域:系统更新 kylin-system-updater (1.2.18.2kord) v101; urgency=medium * BUG: * 需求号: 无 * 其他改动说明: 合并plugin_dev改动,测试 * 其他改动影响域:系统更新 kylin-system-updater (1.2.18.1kord) v101; urgency=medium * BUG: * 需求号: 无 * 其他改动说明: * 其他改动影响域:系统更新 kylin-system-updater (1.2.18kord) v101; urgency=medium * BUG: #95760: 【更新升级-需求-9002】【系统更新】控制面板更新提示更新失败-软件包错误,实际已经安装成功 * 需求号: 无 * 其他改动说明: 修改大数据采集后端dbus接口 * 其他改动影响域:系统更新多维数据采集 kylin-system-updater (1.2.17.3kord) v101; urgency=medium * BUG: #95760: 【更新升级-需求-9002】【系统更新】控制面板更新提示更新失败-软件包错误,实际已经安装成功 * 需求号: 无 * 其他改动说明: 修改大数据采集后端dbus接口 * 其他改动影响域:系统更新多维数据采集 kylin-system-updater (1.2.17.2kord) v101; urgency=medium * BUG: 无 * 需求号: 无 * 其他改动说明: 更改过滤属性获取不正确;新增大数据采集后端dbus接口 * 其他改动影响域:系统更新过滤与多维数据采集 kylin-system-updater (1.2.17.1kord) v101; urgency=medium * BUG: 无 * 需求号: 无 * 其他改动说明:无 * 其他改动影响域:系统更新 kylin-system-updater (1.2.17kord) v101; urgency=medium * BUG: #89964: 【系统更新】当前源锁定方案对于私有化部署用户,获取更新包时,不易自由从私有源、公网源之间切换 #89921: 【系统更新】sources.list中sp1源与私有源共存,私有源中包版本高,实际更新获取的是私有源的包,锁定源未生效 * 需求号: 无 * 其他改动说明:无 * 其他改动影响域:系统更新 kylin-system-updater (1.2.16.3kord) v101; urgency=medium * BUG: #89964: 【系统更新】当前源锁定方案对于私有化部署用户,获取更新包时,不易自由从私有源、公网源之间切换 #89921: 【系统更新】sources.list中sp1源与私有源共存,私有源中包版本高,实际更新获取的是私有源的包,锁定源未生效 * 需求号: 无 * 其他改动说明:无 * 其他改动影响域:系统更新 kylin-system-updater (1.2.16.1kord) v101; urgency=medium * BUG: 无 * 需求号: 无 * 其他改动说明:无 * 其他改动影响域:系统更新 kylin-system-updater (1.2.15.3kord) v101; urgency=medium * BUG: #93483: 【在线更新】控制面板识别不出ftp源中的包 #93484: 【用例104578】单个更新提示不能关机,全部更新能关机 #93312: 【系统升级】详情中的下载大小与实际不符 #89819: 【系统更新】全部更新和单个更新开始过程几秒钟,网速固定是100B/S未显示实际网速;下载完成包后更新,显示0B/0B,建议改为下载完成 #89544: 【系统更新】大包(4g)更新包,在控制面板显示下载大小为0KB,单个更新后不显示下载中而是安装中 * 需求号: 无 * 其他改动说明:无 * 其他改动影响域:系统更新 kylin-system-updater (1.2.15.1kord) v101; urgency=medium * BUG: #90667: 【系统更新】系统更新-单个更新,下载过程中取消按钮不应该被屏蔽 #90446: 【系统更新】点击单个更新后,取消更新按钮未上下对齐 #89817: 【系统更新】控制面板-更新界面未进行英化 #89530: 【系统更新】取消单个更新后还会弹出是否安装的窗口 #85487: 【更新升级】系统语言为英文时,Check Update和back显示不全 #85180: 【更新升级】提示网络异常后仍显示正在下载并安装更新,且全部更新按钮可点击 #69831: 【系统升级】点击全部更新后,软件包更新失败,控制面板中仍显示正在下载和更新 #85315: 【更新升级】更新成功后仍显示正在更新 #90077: 【系统更新】全部更新过程中,更新软件源进度是11% 91% 92%,不是线性增长 * 需求号: 无 * 其他改动说明:无 * 其他改动影响域:系统更新 kylin-system-updater (1.2.15kord) v101; urgency=medium * BUG: #90667: 【系统更新】系统更新-单个更新,下载过程中取消按钮不应该被屏蔽 #90446: 【系统更新】点击单个更新后,取消更新按钮未上下对齐 #89817: 【系统更新】控制面板-更新界面未进行英化 #89530: 【系统更新】取消单个更新后还会弹出是否安装的窗口 #85487: 【更新升级】系统语言为英文时,Check Update和back显示不全 #85180: 【更新升级】提示网络异常后仍显示正在下载并安装更新,且全部更新按钮可点击 #69831: 【系统升级】点击全部更新后,软件包更新失败,控制面板中仍显示正在下载和更新 #85315: 【更新升级】更新成功后仍显示正在更新 #90077: 【系统更新】全部更新过程中,更新软件源进度是11% 91% 92%,不是线性增长 * 需求号: 无 * 其他改动说明:无 * 其他改动影响域:系统更新 kylin-system-updater (1.2.14.1kord) v101; urgency=medium * BUG: #90667: 【系统更新】系统更新-单个更新,下载过程中取消按钮不应该被屏蔽 #90446: 【系统更新】点击单个更新后,取消更新按钮未上下对齐 #89817: 【系统更新】控制面板-更新界面未进行英化 #89530: 【系统更新】取消单个更新后还会弹出是否安装的窗口 #85487: 【更新升级】系统语言为英文时,Check Update和back显示不全 #85180: 【更新升级】提示网络异常后仍显示正在下载并安装更新,且全部更新按钮可点击 #69831: 【系统升级】点击全部更新后,软件包更新失败,控制面板中仍显示正在下载和更新 #85315: 【更新升级】更新成功后仍显示正在更新 #90077: 【系统更新】全部更新过程中,更新软件源进度是11% 91% 92%,不是线性增长 * 需求号: 无 * 其他改动说明:无 * 其他改动影响域:系统更新 kylin-system-updater (1.2.13.3kord) v101; urgency=medium * BUG: #93675: 【系统更新】点击单个更新,准备更新过程中点击取消,仍然可以更新应用 #93668: 【系统更新】点击单个更新,下载过程中点击取消,出现安装中字样再提示本次更新已取消 #93320: 【系统升级】更新过程中退出控制面板,再打开进入升级无法看到正在更新的应用 #93309: 【系统升级】更新过程中,取消按钮置灰无法点击 #90660: 【系统更新】第一次装机,打开控制面板进行系统更新,备份完成后提示备份完成不继续更新流程 #90455: 【系统更新】更新前的备份过程中退出控制面板,再次打开控制面板选择备份更新界面卡在开始备份,正在获取进度,等待上次备份完成才能恢复 #89819: 【系统更新】全部更新和单个更新开始过程几秒钟,网速固定是100B/S未显示实际网速;下载完成包后更新,显示0B/0B,建议改为下载完成 #89527: 【系统更新】单个更新失败后,点击全部更新后取消,失败的单个更新后方出现取消更新的按键 #89517: 【系统更新】备份还原工具运行过程中,进行"备份及更新"提示备份还原工具正在进行其他操作,此时点击单个更新实际开始全部更新 #89449: 【系统更新】全部更新过程中,关闭控制面板后再次打开,一直卡在更新源界面不能检测出待更新的包 #93680: 【系统更新】点击全部更新,有安装弹窗的应用点击拒绝后,操作记录显示应用都安装失败,实际无安装弹窗的应用安装成功 #93671: 【系统更新】系统字号为15时,安装详情应用名称显示不全 #92987: 【控制面板】英文状态下,控制面板中更新未英化 #91435: 【用例87055】设置系统语言为英文,部分显示仍为中文 #91305: 【控制面板|更新】英文模式更新界面英化未完全 #94029: 【控制面板】通知界面缺少"电源管理器、系统更新"设置项 * 需求号: 无 * 其他改动说明:无 * 其他改动影响域:系统更新 kylin-system-updater (1.2.13.2kord) v101; urgency=medium * BUG: 无 * 需求号: 无 * 其他改动说明:更新源过滤机制,取消服务器下发允许的源列表 * 其他改动影响域:系统更新源过滤 kylin-system-updater (1.2.13.1kord) v101; urgency=medium * BUG: #89461:【系统更新】全部更新过程中,点击详情无更新进度;安装过程中点击详情不会显示安装进度 * #93309:【系统升级】更新过程中,取消按钮置灰无法点击 * #89535:【更新升级-需求-9002】【系统更新】全部更新-备份及更新过程中需屏蔽单个更新按键 * 需求号: 无 * 其他改动说明:增加获取破损包的依赖错误描述,状态保留增加取消功能 * 其他改动影响域:系统更新 kylin-system-updater (1.2.13kord) v101; urgency=medium * BUG: #89461:【系统更新】全部更新过程中,点击详情无更新进度;安装过程中点击详情不会显示安装进度 * #93309:【系统升级】更新过程中,取消按钮置灰无法点击 * #89535:【更新升级-需求-9002】【系统更新】全部更新-备份及更新过程中需屏蔽单个更新按键 * 需求号: 无 * 其他改动说明:增加获取破损包的依赖错误描述,状态保留增加取消功能 * 其他改动影响域:系统更新 kylin-system-updater (1.2.12.2kord) v101; urgency=medium * BUG: 无 * 需求号: 无 * 其他改动说明:增加获取破损包的依赖错误描述,状态保留增加取消功能,优化静态变量 * 其他改动影响域: kylin-system-updater (1.2.12.1kord) v101; urgency=medium * BUG: 无 * 需求号: 无 * 其他改动说明:增加获取破损包的依赖错误描述,状态保留增加取消功能,优化静态变量 * 其他改动影响域: kylin-system-updater (1.2.12kord) v101; urgency=medium * BUG: #89818:【系统更新】将系统字体调整为最大,控制面板-更新界面"您的系统已是最新未跟随改变";且界面显示不全 * #89554:【系统更新】控制面板-更新界面没有兼容ukui3.1 * #89817:【系统更新】控制面板-更新界面未进行汉化 * 需求号: 无 * 其他改动说明:增加自主升级功能 * 其他改动影响域: 影响更新检测功能,在更新检测时将更新系统升级包本身 unknown (unknown1) unknown; urgency=unknown * #89810:【系统更新】全部更新缺少错误原因提示,且取消全部下载建议提示下载取消。将依赖冲突的包以虚包形式进行全部更新,提示部分更新失败;空间少于备份空间或者安装包的空间,全部更新后提示部分更新失败。都未展示实际原因 * 需求号: 无 * 其他改动说明:增加自主升级功能,优化进度显示保持功能 * 其他改动影响域: 影响更新检测功能,在更新检测时将更新系统升级包本身 kylin-system-updater (1.2.9kord) v101; urgency=medium * BUG: bug#91191,bug#90533,bug#91103,bug#90454,bug#89871 * 需求号: 9002 * 需求:1.升级依赖修复机制,减小第三方软件对系统更新的影响;2.更新源锁定功能,屏蔽第三方软件源对系统更新的影响 * 其他改动说明:system-updater.conf文件配置;fix升级版本号记录不正确;修复高优先级低版本包被过滤的问题;安装异常时开机进行修复; * 影响域: 系统升级 kylin-system-updater (1.2.8.1kord) v101; urgency=medium * BUG: bug#91191,bug#90533,bug#91103,bug#90454 * 需求号: 9002 * 需求:1.升级依赖修复机制,减小第三方软件对系统更新的影响;2.更新源锁定功能,屏蔽第三方软件源对系统更新的影响 * 其他改动说明:system-updater.conf文件配置;fix升级版本号记录不正确;修复高优先级低版本包被过滤的问题;安装异常时开机进行修复; * 影响域: 系统升级 kylin-system-updater (1.2.7.4kord) v101; urgency=medium * BUG: bug#91191,bug#90533 * 需求号: 9002 * 需求:1.升级依赖修复机制,减小第三方软件对系统更新的影响;2.更新源锁定功能,屏蔽第三方软件源对系统更新的影响 * 其他改动说明:system-updater.conf文件配置;fix升级版本号记录不正确;修复高优先级低版本包被过滤的问题;下载包时可以点击取消按钮; * 影响域: 系统升级 kylin-system-updater (1.2.7.3kord) v101; urgency=medium * BUG: bug#91191 * 需求号: 9002 * 需求:1.升级依赖修复机制,减小第三方软件对系统更新的影响;2.更新源锁定功能,屏蔽第三方软件源对系统更新的影响 * 其他改动说明:system-updater.conf文件配置;fix升级版本号记录不正确; * 影响域: 系统升级 kylin-system-updater (1.2.7.2kord) v101; urgency=medium * BUG: * 需求号: 9002 * 需求:1.升级依赖修复机制,减小第三方软件对系统更新的影响;2.更新源锁定功能,屏蔽第三方软件源对系统更新的影响 * 其他改动说明:升级插件UI修复;添加修复功能;修复安装时preinst报错的问题 * 影响域: 系统升级 kylin-system-updater (1.2.7.1kord) v101; urgency=medium * BUG: * 需求号: 9002 * 需求:1.升级依赖修复机制,减小第三方软件对系统更新的影响;2.更新源锁定功能,屏蔽第三方软件源对系统更新的影响 * 其他改动说明:升级插件UI修复; * 影响域: 系统升级 kylin-system-updater (1.2.7kord) v101; urgency=medium * BUG: * 需求号: 9002 * 需求:1.升级依赖修复机制,减小第三方软件对系统更新的影响;2.更新源锁定功能,屏蔽第三方软件源对系统更新的影响 * 其他改动说明:解决so包含导致的升级问题;增加源优先级的判断,优化优先级问题;规范文件安装路径; * 影响域: 系统升级 kylin-system-updater (1.2.6.3kord) v101; urgency=medium * BUG: * 需求号: 9002 * 需求:1.升级依赖修复机制,减小第三方软件对系统更新的影响;2.更新源锁定功能,屏蔽第三方软件源对系统更新的影响 * 其他改动说明:解决so包含导致的升级问题;增加源优先级的判断;规范文件安装路径; * 影响域: 系统升级 kylin-system-updater (1.2.6.1kord) v101; urgency=medium * BUG: * 需求号: 9002 * 需求:1.升级依赖修复机制,减小第三方软件对系统更新的影响;2.更新源锁定功能,屏蔽第三方软件源对系统更新的影响 * 其他改动说明:解决so包含导致的升级问题 * 影响域: 系统升级 kylin-system-updater (1.2.6kord) v101; urgency=medium * BUG: bug#90102,bug#89338,bug#89792,bug#85318,bug#85325,bug#89813 * 需求号: 9002 * 需求:1.升级依赖修复机制,减小第三方软件对系统更新的影响;2.更新源锁定功能,屏蔽第三方软件源对系统更新的影响 * 其他改动说明:增加调整候选版本的选项,限速功能调整,分组包记录失败修复,修复全盘修复逻辑错误问题,优化逻辑 * 影响域: 系统升级 kylin-system-updater (1.2.5.2kord) v101; urgency=medium * BUG: bug#90102,bug#89338,bug#89792,bug#85318,bug#85325,bug#89813 * 需求号: 9002 * 需求:1.升级依赖修复机制,减小第三方软件对系统更新的影响;2.更新源锁定功能,屏蔽第三方软件源对系统更新的影响 * 其他改动说明:增加调整候选版本的选项,限速功能调整,分组包记录失败修复,修复全盘修复逻辑错误问题, * 影响域: 系统升级 kylin-system-updater (1.2.5.1kord) v101; urgency=medium * BUG: bug#90102,bug#89338,bug#89792,bug#85318,bug#85325 * 需求号: 9002 * 需求:1.升级依赖修复机制,减小第三方软件对系统更新的影响;2.更新源锁定功能,屏蔽第三方软件源对系统更新的影响 * 其他改动说明:增加调整候选版本的选项,限速功能调整,分组包记录失败修复. * 影响域: 系统升级 kylin-system-updater (1.2.5kord) v101; urgency=medium * BUG: bug#89045,bug#89464,bug#89530,bug#89471,bug#89575 * 需求号: 9002 * 需求:1.升级依赖修复机制,减小第三方软件对系统更新的影响;2.更新源锁定功能,屏蔽第三方软件源对系统更新的影响 * 其他改动说明:修复升级记录不全;取消启动自动update;修改接口文档;解决出现升级准备失败的问题;为自动更新提供白名单,插件bug修复 * 影响域: 系统升级 kylin-system-updater (1.2.4.1kord) v101; urgency=medium * BUG: bug#89045,bug#89464 * 需求号: 9002 * 需求:1.升级依赖修复机制,减小第三方软件对系统更新的影响;2.更新源锁定功能,屏蔽第三方软件源对系统更新的影响 * 其他改动说明:修复升级记录不全;取消启动自动update;修改接口文档;解决出现升级准备失败的问题;为自动更新提供白名单. * 影响域: 系统升级 kylin-system-updater (1.2.4kord) v101; urgency=medium * BUG: 无 * 需求号: 9002 * 需求:1.升级依赖修复机制,减小第三方软件对系统更新的影响;2.更新源锁定功能,屏蔽第三方软件源对系统更新的影响 * 其他改动说明: 修复安装更新包kylin-update-desktop-config时报错的问题,优化修复冲突更新时未收起部分更新列表,源过滤速度优化 * 影响域: 系统升级 kylin-system-updater (1.2.3.5kord) v101; urgency=medium * BUG: 无 * 需求号: 9002 * 需求:1.升级依赖修复机制,减小第三方软件对系统更新的影响;2.更新源锁定功能,屏蔽第三方软件源对系统更新的影响 * 其他改动说明: 修复安装更新包kylin-update-desktop-config时报错的问题 * 影响域: 系统升级 kylin-system-updater (1.2.2kord) v101; urgency=medium * BUG: 无 * 需求号: 9002 * 需求:1.升级依赖修复机制,减小第三方软件对系统更新的影响;2.更新源锁定功能,屏蔽第三方软件源对系统更新的影响 * 其他改动说明: 完善升级功能,调整超时时间为20min * 影响域: 系统升级 kylin-system-updater (1.2.0.8.1kord) v101; urgency=medium * BUG: 无 * 需求号: 无 * 其他改动说明: 完善升级功能,源过滤优化,合并系统升级控制面板插件 * 影响域: 系统升级 kylin-system-updater (1.1.9kord) v101; urgency=medium * BUG: 无 * 需求号: 无 * 其他改动说明: 修改词条、国际化、修改编译生成的文件的追踪、增加log日志并修改颜色、取消安装刷新数据库 * 影响域: 系统升级 kylin-system-updater (1.1.7kord) v101; urgency=medium * BUG: 无 * 需求号: 无 * 其他改动说明: 更改数据库插入格式,判断升级方式,增加刷新更新时间的信号,+ ws的修改 * 影响域: 重构系统更新器中数据库部分 kylin-system-updater (1.1.6kord) v101; urgency=medium * 升级禁止关机 kylin-system-updater (1.1.4kord) v101; urgency=medium * 代码优化,新增接口. * 修改数据库结构. kylin-system-updater (1.1.2kord) v101; urgency=medium * 增加数据库接口 . kylin-system-updater (1.1.1kord) v101; urgency=medium * add database . kylin-system-updater (1.0.4kord) v101; urgency=medium * 重新编包,修复依赖,去除无用文件, 修改版本号 kylin-system-updater (2.0.5.4.1) v101; urgency=medium * BUG: # 无 * 需求号: #15034 【更新升级】更新历史中新增自动更新结果显示 #15107】【更新升级】自动更新数据上报 #15089】【更新升级】【P2P】更新策略下发支持P2P配置内容下发(IP) #15109】【更新升级】更新历史中增加历史更新内容日志显示 #15027】【更新升级】更新通知弹窗界面优化 #14380】【更新】搜索只能搜索包的全名,不能模糊搜索,也不能搜索别的字段 * 其他改动说明: 无 * 其他改动影响域:系统更新 kylin-system-updater (1:20.04.9) v101; urgency=medium * for v10sp1 kylin-system-updater (1:20.04.9) focal; urgency=medium * Remove ubuntu-support-status as the term support can be confusing and the Supported field has been removed from Launchpad packages. (LP: #1873362) * Add ubuntu-security-status - a tool for displaying information about packages installed and the kind of updates which they may or may not receive. (LP: #1873362) update-manager (1:20.04.9) focal; urgency=medium * Remove ubuntu-support-status as the term support can be confusing and the Supported field has been removed from Launchpad packages. (LP: #1873362) * Add ubuntu-security-status - a tool for displaying information about packages installed and the kind of updates which they may or may not receive. (LP: #1873362) update-manager (1:20.04.7) focal; urgency=medium [ Marcus Tomlinson ] * Show progress of snap updates (LP: #1871099). * Display an error message when snap updates fail (LP: #1871100). [ Łukasz 'sil2100' Zemczak ] * Adjust dates in hwe-support-status for focal. update-manager (1:20.04.6) focal; urgency=medium * deb2snap: Don't replace debs that were manually installed via another package (LP: #1872958). update-manager (1:20.04.5) focal; urgency=medium * Fix TypeError crash in update() (LP: #1871490). update-manager (1:20.04.4) focal; urgency=medium * Fix pycodestyle and pyflakes autopkgtests. update-manager (1:20.04.3) focal; urgency=medium [ Gunnar Hjalmarsson ] * po/POTFILES.in: Add UpdateManager/backend/__init__.py, so the new translatable strings get included in the translation template (LP: #1868409). [ Brian Murray ] * UpdateManager/UpdateManager.py: Do not offer to upgrade systems running on an i386 host architecture to another release. (LP: #1845690) update-manager (1:20.04.2) focal; urgency=medium * UpdateManager/backend/__init__.py: once apt upgrade completes, use the deb2snap.json file from ubuntu-release-upgrader to perform snap updates. (LP: #1868409) update-manager (1:20.04.1) focal; urgency=medium * UpdateManager/Core/UpdateList.py: remove unused import of subprocess. * janitor/plugincore/manager.py: replace basestring abstract type. update-manager (1:19.04.10) focal; urgency=medium * UpdateManager/Core/UpdateList.py: Use utils.get_dist() instead of platform.dist() to find codename, the latter was removed in Python 3.8 update-manager (1:19.04.9) focal; urgency=medium * tests: Handle the rename of the pep8 tool to pycodestyle. update-manager (1:19.04.8) eoan; urgency=medium * data/gtkbuilder/UpdateManager.ui: enforce icon size for download size icon so it's consistent with the other status icons. (LP: #1790134) update-manager (1:19.04.7) eoan; urgency=medium * Fix E117 over idented code update-manager (1:19.04.5) disco; urgency=medium * UpdateManager/Core/utils.py: when testing to see if a url is downloadable support https in addition to http and ftp. (LP: #1823410) * debian/tests/control: really use pyflakes3 instead of pyflakes, additionally resolve pyflakes3 errors. update-manager (1:19.04.4) disco; urgency=medium [ Colin Watson ] * Use the source version to generate changelog URIs, not the binary version (LP: #655917). update-manager (1:19.04.3) disco; urgency=medium * Add gnome-shell as the first alternate for the polkit-1-auth-agent dependency to allow policykit-1-gnome to be demoted to universe update-manager (1:19.04.2) disco; urgency=medium * UpdateManager/Core/MetaRelease.py: set prompt in MetaReleaseCore so that do-release-upgrade can provide more informative error messages. (LP: #1798618, LP: #1795024) update-manager (1:19.04.1) disco; urgency=medium * Do not show the livepatch reminder if update-manager is running on a distribution without software-properties-gtk. (LP: #1805118) update-manager (1:18.10.10) cosmic; urgency=medium * Stop lazy import of InstallBackends. Lazy imports made update-manager crash when an update-manager update changed the backend API and an updated incompatible backend was loaded to the not updated running update-manager process. (LP: #1795898) * Cancel transaction on exit only when Cancel button is active. Also ignore exception when cancellation fails. (LP: #1790670) update-manager (1:18.10.9) cosmic; urgency=medium * Allow unselecting updates and performing only removals (LP: #1792320) * Stop trying apt_pkg.pkgsystem_(un)lock(), as a normal user it always fails (LP: #1795387) * Keep or delete packages after looping over all of them. This prevents the resolver from changing the packages in the loop resulting in not keeping some phased packages back from being upgraded. (LP: #1072136) * Fix PEP 8 warnings (LP: #1795384) Also ignore "W503 line break before binary operator" because it will become the best practice update-manager (1:18.10.8) cosmic; urgency=medium * Print transaction error and let the user try again applying updates (LP: #1317164) * Don't ask backend to do package operations aready done. Aptdaemon cancels the transaction when asked to remove packages already removed which results the failure being shown to the user. This is unnecessary as update-manager can just filter the package operations to be done using a fresh cache and decrease the likelyhood of hitting a race condition where packages to be removed are already removed. (LP: #1791931) update-manager (1:18.10.7) cosmic; urgency=medium * Fix PEP8 regression from 18.10.4 to allow autopkgtest to pass * Fix unused import of subprocess in Dialogs.py update-manager (1:18.10.6) cosmic; urgency=medium * debian/control: - Build-Depends on python3-distro-info update-manager (1:18.10.5) cosmic; urgency=medium * Add a reminder to enable Livepatch (LP: #1787553). update-manager (1:18.10.4) cosmic; urgency=medium [ Łukasz 'sil2100' Zemczak ] * Ignore Prompt=lts for non-LTS series. This way if a user is on a non-LTS and has Prompt=lts, he/she will be upgraded to the next supported series until finally reaching an LTS. (LP: #1783328) update-manager (1:18.10.3) cosmic; urgency=medium * Add support for HTTPS proxies; this breaks UpdateManager.Core.utils.init_proxy() API - the return value is now a dict, rather than a string (LP: #1771914). update-manager (1:18.10.2) cosmic; urgency=medium * Fix my spelling mistake in the previous upload. Oops. update-manager (1:18.10.1) cosmic; urgency=medium * Block style context changed signal while enforcing the main window's constant size. Thanks to Thomas Waldmann and Sebastien Bacher for the initial analysis of this bug. (LP: #1637180) update-manager (1:18.04.11) bionic; urgency=medium * Add Appstream metadata with compulsory_for_desktop fields to prevent the accidental uninstallation of ubuntu-desktop in GNOME Software. ubuntu-desktop depends on update-manager. * Build-Depend on dh-python * Update translation template update-manager (1:18.04.10) bionic; urgency=medium * Support package removals in install backends and really remove packages (LP: #1624644, #1675079) update-manager (1:18.04.9) bionic; urgency=medium * Keep PEP 8 checks happy update-manager (1:18.04.8) bionic; urgency=medium * Offer removal of unused autoremovable kernel packages (LP: #1624644, #1675079) update-manager (1:18.04.7) bionic; urgency=medium * Comment out the KDE frontend in debian/control so we can remove pykde4 from the archive (LP: #1745741). update-manager (1:18.04.6) bionic; urgency=medium * Use HTTPS for changelogs.ubuntu.com (LP: #1744318) update-manager (1:18.04.5) bionic; urgency=medium * Drop the update-manager-text package and code as it has been broken for a long time and it wasn't used by many people. (LP: #1385524) update-manager (1:18.04.4) bionic; urgency=medium [ Balint Reczey ] * Place .keep files in empty directories to keep them when converting the repo to git * Call do-release-upgrade without pkexec and depend on a version which raises privileges itself (LP: #1748509) [ Jeremy Bicha ] * update-manager: Depend on libgtk3-perl for debconf's GNOME backend. Drop previous Recommends on libgtk2-perl. (LP: #1607929) update-manager (1:18.04.3) bionic; urgency=medium * ubuntu-support-status: use component to differentiate packages supported by the community and packages supported by Canonical. (LP: #1574670) update-manager (1:18.04.2) bionic; urgency=medium * Build from bazaar repository to keep empty dirs in the source package * Break long comment to keep PEP 8 test happy update-manager (1:18.04.1) bionic; urgency=medium [ Jean-Baptiste Lallement ] * UpdateManager/Dialogs.py: Workaround restricted access to GUI applications by user root under wayland to start do-release-upgrade in graphical mode (LP: #1732185) update-manager (1:17.10.11) artful; urgency=medium * UpdateManager/UpdatesAvailable.py: Also mention using COMPRESS=xz in intramfs.conf to free more space in /boot. update-manager (1:17.10.10) artful; urgency=medium * UpdateManager/UpdatesAvailable.py: Provide instructions when mount points have insufficient free space for the upgrade to complete. (LP: #1477455) update-manager (1:17.10.9) artful; urgency=medium [ Łukasz 'sil2100' Zemczak ] * test_update_origin.py: fix the extended origin matcher test as it was making wrong assumptions, not checking if packages actually had ANY package in -security. This should fix the current autopkgtest failures. [ Brian Murray ] * test_update_origin.py: fix some typos. update-manager (1:17.10.8) artful; urgency=medium * UpdateManager/Dialogs.py: use a variable instead of hard coding 1 to allow the translation of the message, thanks to Andrea Azzarone. (LP: #1714489) update-manager (1:17.10.7) artful; urgency=medium * Show status of Canonical's Livepatch service in update-manager dialog window, thanks to Andrea Azzarone. (LP: #1712591) update-manager (1:17.10.6) artful; urgency=medium * UpdateManager.py: Workaround a crash when calling software-properties-gtk by not using --toplevel under wayland (LP: #1703365) update-manager (1:17.10.5) artful; urgency=medium * test_update_origin.py: This does not need to be architecture specific so just set the arch to amd64 like test_update_list.py. * test_utils.py: mock /proc/net/tcp and processes in proc so that we are testing the code and not the system under test. update-manager (1:17.10.4) artful; urgency=medium * UpdateManager/Core/UpdateList.py: Instead of trying to print an error when trying to find the desktop file log it. (LP: #1428297) update-manager (1:17.10.3) artful; urgency=medium * Resolve a multitude of test failures, pep8 and pyflakes issues. update-manager (1:17.10.2) artful; urgency=medium * Recommend libgtk2-perl be installed so we have a working debconf frontend. (LP: #1607929) update-manager (1:17.10.1) artful; urgency=medium [ Steve Langasek ] * ubuntu-support-status: instead of checking the Release timestamp in the releases file for every single package on the system, get the release date from distro-info-data because it will always be the same. This speeds up the script by > 50% in testing. [ Brian Murray ] * update-manager: Clarify that the "-d" switch is only for upgrading from the latest supported release to the development release, not any release. (LP: #1700829) * Remove --sandbox (aufs support) as it has been broken for some time and was rather unused. (LP: #1605259) update-manager (1:17.04.3) zesty; urgency=medium * Use a 64 bit integer for launch-time instead of a 32 bit one which won't work someday. (LP: #1654008) update-manager (1:17.04.2) zesty; urgency=medium [ Jeremy Bicha ] * Update alternate dependencies for policykit-1-gnome: - Add virtual polkit-1-auth-agent - Replace non-existant policykit-1-kde with polkit-kde-agent-1 - Replace razorqt-policykit-agent with lxqt-policykit (since lxqt is the replacement for razorqt) [ Manzur Mukhitdinov ] * UpdateManager/Core/MetaRelease.py: - Add a clearer error message when a network failure occurs [ Brian Murray ] * UpdateManager/Dialogs.py: - Remove misleading ellipsis in “Restart Now” action button. Thanks to Adolfo Jayme for the change. (LP: #1568368) [ Steve Langasek ] * Drop estimate_kernel_size_in_boot() from UpdateManager/Core/utils.py; this was only used in ubuntu-release-upgrader so the code has now moved there (with code fixes). Ensure upgrade ordering with Breaks: on older python3-distupgrade. LP: #1646222. update-manager (1:17.04.1) zesty; urgency=medium * tests/test_hwe_support_status.py: Resolve issues with the test. * data/gtkbuilder/UpdateManager.ui: Set a minimum content height of 80px for the technical description scrolled window. This was the default height gtk3widgets used in GTK versions prior to 3.20. Thanks to Martin Wimpress for the fix. (LP: #1623856) update-manager (1:16.10.7) yakkety; urgency=medium * UpdateManager/Core/MyCache.py: Gracefully handle absence of Launchpadlib module. * Lower python3-launchpadlib Depends: to a Suggests:, to avoid pulling it into "standard" priority. Retrieving PPA changelogs is more of a niche feature which is relevant for desktops, but shoud not drag the entire python3-launchpadlib stack into small installations. Add it as Recommends to the GUI frontends instead, to retain current behaviour on desktops. update-manager (1:16.10.6) yakkety; urgency=medium * UpdateManager/UnitySupport.py: Handle ValueError traceback when checking for Unity and Dbusmenu support. Thanks to Launchpad user flocculant for the patch. (LP: #1629900) update-manager (1:16.10.5) yakkety; urgency=medium [ Brian Murray ] * UpdateManager/UpdateManager.py: when marking HWE packages for install pass on a SystemError and let the problem resolver sort it out. * HweSupportStatus/consts.py: Improve wording of the messages. * hwe-support-status: - decode output when checking for foreign architectures so that the result is unicode not bytes. - add libwayland-egl1-mesa to the list of metapackages. - utilize a virtualbox metapackage set. - Do not show replacements that are already installed on the system. (LP: #1607983) * source_update-manager.py: collect information about the state of HWE support on the system. (LP: #1617080) * source_update-manager.py: only collect HWE information if it exists. [ Jeremy Bicha ] * Add gi.require_version in a few more places to reduce the annoying warnings. (LP: #1573177) update-manager (1:16.10.4) yakkety; urgency=medium * ChangelogViewer: Fix an API call to work with GTK < and ≥ 3.20. Upstream gave gtk_text_view_get_iter_at_location a gboolean return type, which makes gobject-introspection return (return value, out parameter). (LP: #1548425) * ChangelogViewer: Set vexpand so that the changelog TextView takes up all the remaining vertical space. update-manager (1:16.10.3) yakkety; urgency=medium [Nicolas Delvaux] * Attempt to retrieve Changelogs from PPA sources (LP: #253119) * Correctly detect the usage of a username in changelog URIs update-manager (1:16.10.2) yakkety; urgency=medium * Include HWE support tools and information. (LP: #1498059) update-manager (1:16.10.1) yakkety; urgency=medium * Correctly calculate the end of support, and return correctly when support has ended. Patch from Andrew Gaul, with thanks. update-manager (1:16.04.3) xenial; urgency=medium * Quote URL parameters for the Release Announcement. (LP: #1561215) update-manager (1:16.04.2) xenial; urgency=medium [ Tim Lunn ] * UpdateManage/Core/utils.py: Update to use logind inhibitors (LP: #1566141) update-manager (1:16.04.1) xenial; urgency=medium * Update Build-Depends to resolve ftbfs in xenial. update-manager (1:15.10.3) wily; urgency=medium * Pass a '#auto' suffix to aptdaemon for packages that are autoinstalled, so that we have enough information to autoremove them later. Thanks to Michael Vogt <mvo@ubuntu.com> for the patch. LP: #1439769. * Add versioned dependency on aptdaemon (>= 1.1.1+bzr982-0ubuntu13) for the above. update-manager (1:15.10.2) wily; urgency=medium * UpdateManager/Core/UpdateList.py: update the binary packages made by the linux-meta source package. (LP: #1215114) update-manager (1:15.10.1) wily; urgency=medium * UpdateManager/Core/MetaRelease.py: When not running in development mode, if the next release is unsupported do not offer to upgrade to that, but the release after it. When running in development mode continue to offer upgrading to unsupported release. (LP: #1497024) update-manager (1:15.04.7) vivid; urgency=medium * debian/tests/control: pyflakes3 is provided by pyflakes update-manager (1:15.04.6) vivid; urgency=medium * debian/tests/control: switch to using pyflakes3 instead of pyflakes. update-manager (1:15.04.5) vivid; urgency=medium * tests/test_pyflakes.py: switch to using pyflakes3 instead of pyflakes. update-manager (1:15.04.4) vivid; urgency=medium * Properly check for FileNotFoundError when looking for /etc/machine-id. (LP: #1443929) update-manager (1:15.04.3) vivid; urgency=medium * Allow being a child of 'systemd' as well as 'init' .If we're booted with e.g. init=/lib/systemd/systemd then the parent will be systemd. * Use the systemd /etc/machine-id file if available for our unique ID. update-manager (1:15.04.2) vivid; urgency=medium * UpdateManager/Core/utils.py: use rpartition in case the process name contains the right parenthesis character. Thanks to Roman Odaisky for the patch. (LP: #1399916) * UpdateManager/Dialogs.py: set the focus to "Restart Later" instead of "Restart Now", so people don't accidentally reboot. (LP: #1421044) update-manager (1:15.04.1) vivid; urgency=medium * debian/control: Don't depend on gir1.2-vte-2.90, we don't use it (directly) any more. update-manager (1:14.10.6) utopic; urgency=medium * UpdateManager/ChangelogViewer.py: update URL for CVEs (LP: #1374715) update-manager (1:14.10.5) utopic; urgency=medium [ Yu-Cheng Chou ] * UpdateManager/UpdateManager.py: _on_close() should return the value to make close button work properly (LP: #1363580) update-manager (1:14.10.4) utopic; urgency=medium * Fix test_url_downloadable() with proxis: ensure that $no_proxy doesn't prevent us from accessing localhost through proxy. update-manager (1:14.10.3) utopic; urgency=low [ Mitsuya Shibata ] * lp:~cosmos-door/ubuntu/trusty/update-manager/fix1358229: - ensure all scripts are treated as python by gettext LP: #1358229 update-manager (1:14.10.2) utopic; urgency=low * pep8 fixes to fix autopkgtest failure with the latest pep8 update-manager (1:14.10.1) utopic; urgency=low * fix ADT failure update-manager (1:14.10.0) utopic; urgency=low * make meta-release parser stricter to avoid storing the data that e.g. intercepting proxies send (LP: #1310891) update-manager (1:0.196.12) trusty-proposed; urgency=low * use Gtk.init() to ensure update-manager fails with a runtime error message instead of crashing if the display can not be opened (LP: #1269397) update-manager (1:0.196.11) trusty; urgency=low * lp:~mvo/update-manager/lp1202754: - do nt crash if the user clicks "cancel" in the polkit dialog (LP: #1202754) update-manager (1:0.196.10) trusty; urgency=low * debian/control: - add dependencies to the various policykit agents to ensure that update-manager is not run without policykit agent support in the session (LP: #1164558) * tests/test_update_list.py: - test improvements from Barry Warsaw (many thanks!) update-manager (1:0.196.9) trusty; urgency=medium [ Sebastien Bacher ] * UpdateManager/UpdatesAvailable.py: - use the correct icon theme (lp: #1283554) [ Marc Deslauriers ] * UpdateManager/Dialogs.py: close window after requesting reboot. (LP: #1297361) [ Michael Vogt ] * tests/aptroot-update-list-test: - fix test failure caused by not-installable depends (lp: #1295392) update-manager (1:0.196.8) trusty; urgency=medium * source_update_manager.py: set response to None if the problem type is not a bug * UpdateManager/Core/utils.py: do not perform DNS lookups with iptables, thanks to John Edwards for the patch. (LP: #1290825) update-manager (1:0.196.7) trusty; urgency=medium * Fix PEP-8 style error to fix tests. update-manager (1:0.196.6) trusty; urgency=low * Allow user to close the restart required dialog (LP: #1033226) - Add a settings button - Add a "Restart Later" button - Rename existing button to "Restart Now..." - Add secondary text to updates dialog when a restart is still pending from last updates update-manager (1:0.196.5) trusty; urgency=medium * Stop using deprecated GObject constructors with positional arguments (see https://wiki.gnome.org/PyGObject/InitializerDeprecations). update-manager (1:0.196.4) trusty; urgency=low * lp:~mterry/update-manager/requires-restart: - warn if a update requires a reboot (LP: #255443) This requires that the packages that need a reboot set "XB-Restart-Required: system" in the package record update-manager (1:0.196.3) trusty; urgency=low [ Sebastien Bacher ] * lp:~seb128/update-manager/check-none-controller - Check for controller being None before using it (this was accidentally dropped in a previous refactoring). - LP: #1203919 update-manager (1:0.196.2) trusty; urgency=low [ Brian Murray ] * UpdateManager/Core/MetaRelease.py: speed up the check for a new release of Ubuntu. Thanks to Anders Kaseorg for the patch. [ Sebastien Bacher ] * lp:~seb128/update-manager/box-use-vertical-space: - Use the vertical space, GTK 3.10 displays the box shrinked otherwise update-manager (1:0.196.1) trusty; urgency=low * debian/source_update_manager.py: Fix too long line (pep8 error). update-manager (1:0.196) trusty; urgency=low * In the apport hook ask if the bug is about upgrading from one release to another and send bug to ubuntu-release-upgrader. (LP: #1071057) update-manager (1:0.195) trusty; urgency=low * Add support for logind to the restart dialog. Thanks to Thaddaus Tintenfisch for the patch. (LP: #1232363) update-manager (1:0.194) saucy; urgency=low * Fix a bug introduced in the dialog refactor from version 1:0.189 that causes update-manager to crash instead of showing a dialog when there are no updates to apply but the system needs rebooted. LP: #1219414. update-manager (1:0.193) saucy; urgency=low * Fix PEP-8 errors. update-manager (1:0.192) saucy; urgency=low * Core/UpdateList.py: if a package is an ignored phased update mark it for keeping (LP: #1211511) update-manager (1:0.191) saucy; urgency=low * Fix update-manager crashing when trying to raise window. on_button_install_clicked takes only one positional argument, not two. (LP: #1202959) update-manager (1:0.190) saucy; urgency=low * Update for python-distutils-extra 2.38 (yelp-tools style help) update-manager (1:0.189) saucy; urgency=low [ Jeremy Bicha ] * Drop unused system-software-update icons since it is a standard theme icon [ Robert Roth ] * Remove dist-upgrade option description from manpage (LP: #1079136) [ Dylan McCall ] * Refactor dialogs to have a common base. * tests/test_update_error.py: Fix test regression from the above. [ Martin Pitt ] * Drop obsolete GObject.threads_init() calls to avoid warnings at startup. Bump python-gi dependency accordingly. * Drop unused imports and assignments to fix pyflakes errors. * Fix PEP-8 errors. * tests/test_update_error.py: Adjust test_error_no_updates() to current string. update-manager (1:0.188) saucy; urgency=low * Core/UpdateList.py: Drop unused "src_name" variable (pyflakes error). * tests/test_update_list.py: Fix too long line (pep8 error). update-manager (1:0.187) saucy; urgency=low [ Sami Jaktholm ] * Greatly speed up update calculation (LP: #1167277) [ Martin Pitt ] * Drop unnecessary ubuntu-drivers-common build dependency, to ease backporting. [ Brian Murray ] * Modify phased update percentage to use source packages and not binary packages, additionally add a test for this. * Remove check for update-notifier auto-launch gsettings key update-manager (1:0.186) raring; urgency=low [ Sebastien Bacher ] * Use correct variable in error message, fixing a crash (LP: #1142151) update-manager (1:0.185) raring; urgency=low [ Sebastien Bacher ] * Specify a background color for the unity launcher icon (lp: #1081691) [ Michael Terry ] * Look for to-be-updated application icons in app-install-data (LP: #1145157) update-manager (1:0.184) raring; urgency=low [ Michael Terry ] * Don't temporarily freeze when calculating which updates are available. LP: #1137996 [ Colin Watson ] * Allow removals with only Conflicts+Replaces; while policy 7.6.2 quotes Provides in an example, it's clear that Conflicts+Replaces alone should be sufficient to indicate that the target package may be removed. update-manager (1:0.183) raring; urgency=low [ Mike Terry ] * Fix toggling items after doing a deselect-all. (LP: #1129191) [ Colin Watson ] * Fix PEP-8 failures. * Fix pyflakes failures. * Depend on pep8 and pyflakes for the autopkgtest suite. * Use logging.warning rather than deprecated logging.warn. * Fix test_meta_release_core.SillyProxyRequestHandler to write bytes rather than text to its output file object. * Make test_meta_release_core pick a new proxy port for each test. * Use EnvironmentVarGuard in test_meta_release_core to reduce the risk of test isolation bugs. * MetaReleaseCore: Plug some open file object leaks. * Make test_meta_release_core call install_opener(None) every time it changes proxy settings, to avoid stale ones being left around from previous tests. * Reopen cache in GroupingTestCase.setUp, TestCache.setUp, and TestChangelogs.setUp to avoid test isolation bugs. * Remove unnecessary cache update in PhasedTestCase.setUp; reopening the cache is sufficient. * Allow saveDistUpgrade to remove packages provided that upgrade candidates declare Conflicts+Replaces+Provides on them (LP: #1038113). [ Steve Langasek ] * Build-depend on python3-all (>= 3.3.0-2) for pybuild support and drop the now-extraneous overrides from debian/rules; this incidentally works around an issue I don't understand where the package was now failing to build locally from trying to invoke python setup.py instead of python3. update-manager (1:0.182) raring; urgency=low * MetaReleaseCore: Create ~/.cache if it does not exist. update-manager (1:0.181) raring; urgency=low * Use the gnome debconf frontend, accidentally dropped in update-manager 1:0.165 (LP: #1110585). update-manager (1:0.180) raring; urgency=low [ Dylan McCall ] * Make sure text in Install column properly uses ellipses. (LP: #1105363) * Refactor CellAreaPackage class for ease of future changes. update-manager (1:0.179) raring; urgency=low * Properly xml-escape application names too, not just package labels * Make sure dialog buttons are actually at the bottom of the dialog update-manager (1:0.178) raring; urgency=low * Implement the "available updates" details pane from the SoftwareUpdates spec. Specifically, this adds grouping of related updates, adds an "Ubuntu base" group for core packages, and shows only the description summary in the main view. * Show a restart icon next to packages that declare they will need a system restart via XB-Restart-Required: system update-manager (1:0.177) raring; urgency=low * Fix missing import in tests/test_upgrade.py. * Make tests/test_update_list.py more robust against other tests being run before it. * Depend on aptdaemon for DEP-8 tests. * Fix typo in test dpkg status file for test_update_list. * Add Update-Manager::Never-Include-Phased-Updates, the converse of Update-Manager::Always-Include-Phased-Updates; this opts out of upgrading to any package with a Phased-Update-Percentage set. update-manager (1:0.176) raring; urgency=low * Use GLib.timeout_add_seconds instead of deprecated GObject.timeout_add * Keep dialogs 33em wide * Pass update-manager arguments on to do-release-upgrade (LP: #1097907) update-manager (1:0.175) raring; urgency=low [ Eric Williams ] * German translation fix (LP: #1070289) [ Stephen Kraemer ] * UpdateManager/Dialogs.py: made Settings... button open software-properties non-modally. (LP: #1058070) [ Robert Roth ] * Remove package count badge from the unity launcher (LP: #1036891) * Added 6px border to the button box to align the buttons with the contents above (LP: #1081099) [ Michael Vogt ] * debian/rules: - do not call dh_auto_build as as it call py2 even when its not supposed to (LP: #1089808), thanks to Jean-Baptiste Lallement * fix missing "Architecture" when writing out the fake dpkg-status file in the tests (LP: #1089793) update-manager (1:0.174.3) quantal; urgency=low * UpdateManager/UpdatesAvailable.py: - never pass "None" to xml.sax.saxutils.escape (LP: #1044080) update-manager (1:0.174.2) quantal; urgency=low [ Michael Vogt ] * fix crash in UpdateManager.Core.utils.error(), thanks to Christian Parrino (LP: #964674) [ Michael Terry ] * Stop showing Install All Available Updates quicklist item when it isn't appropriate (LP: #1031307). update-manager (1:0.174.1) quantal; urgency=low * po/POTFILES.in: - add missing InstallBackendAptdaemon.py, thanks to Igor Zubarev (LP: #1055594) update-manager (1:0.174) quantal; urgency=low * UpdateManager/ChangelogViewer.py: improve url parsing of changelog files so that more links are created. Thanks to sampo555 for the patch (LP: #1011093). * Add a dependency to update-manager on update-notifier (LP: #1043725) update-manager (1:0.173) quantal; urgency=low * Make update-manager-core depend on ubuntu-release-upgrader-core and update-manager-kde depend on ubuntu-release-upgrader-qt, so that functionality isn't lost on upgrade (LP: #1049062). update-manager (1:0.172) quantal; urgency=low * Remove dependency on update-notifier as it added many dependencies to cloud-images. update-manager (1:0.171) quantal; urgency=low [ Michael Terry ] * Fix test suite to pass when run on non-amd64 machine [ Brian Murray ] * Add a dependency on update-notifier (LP: #1043725) update-manager (1:0.170) quantal; urgency=low * When user cancels/stops the apt cache update, still let them view available updates from a previous cache update. LP: #1024909 update-manager (1:0.169) quantal; urgency=low [ Michael Terry ] * Drop Unity-support gir Recommends down to Suggests. LP: #1029764 [ sampo555 ] * lp:~sampo555/update-manager/fix-for-1031280: - Convert SystemError into string in order to avoid TypeError in UpdateManager.refresh_cache SystemError handles. Fixes LP: #1031280 [ Robert Park ] * Allow test suite to not need to be run as root [ Michael Vogt ] * lp:~mvo/update-manager/phased-updates: - Implement the client part of the "foundations-q-phased-updates". This allows to deploy updates in phases where only a subset of the users will get a update, controlled via the Phased-Updates-Percentage tag in the Packages file. update-manager (1:0.168) quantal; urgency=low * Run tests under xvfb and don't try to use non-existant python3-coverage * Don't throw exception on socket timeout when downloading metarelease file. LP: #818760 update-manager (1:0.167) quantal; urgency=low * Rebuild to get python3 wrapper script (LP: #1023474) update-manager (1:0.166) quantal; urgency=low [ Colin Watson ] * Write metarelease file as UTF-8 (LP: #1020526) [ Michael Terry ] * Use a wrapper script of /bin/sh when calling pkexec, to workaround its requirement that the ppid not be 1. (LP: #1020115) * Update Unity badge count before showing "please restart" dialog * Don't allow closing the "please restart" dialog via window manager * Show "please restart" dialog on startup if needed, instead of only after installing some updates update-manager (1:0.165) quantal-proposed; urgency=low * Implementation of "update on start" feature from spec https://wiki.ubuntu.com/SoftwareUpdates * Use a single main window that changes instead of having modal dialogs * Implement several special-purpose dialogs like "No updates" or "Dist upgrade needed" accordingn to the above spec * Split out release upgrader code and DistUpgrade module into a separate source package * Drop python-update-manager, as it is unused * debian/tests: - Add dep8 tests update-manager (1:0.164) quantal; urgency=low [ Brian Murray ] * DistUpgrade/DistUpgradeApport.py: ensure package install failures are tagged dist-upgrade [ Robert Roth ] * UpdateManager/UpdateManager.py: check for None type from get_last_update_minutes (LP: #1013325) [ Colin Watson ] * DistUpgrade/NvidiaDetector, debian/control: Update symlink to Python 3 version, available as of ubuntu-drivers-common 1:0.2.55. * debian/rules: Make sure to run setup.py with the default python3 last, so that scripts get correct #! lines. [ Barry Warsaw ] * pre-build.sh: - Add python-gi as an explicit dependency. - python3-mock is required. * setup.py: - Fix the installation of the janitor.plugincore package for Python 3. (LP: #1013490) - Calculate the setup() version number from debian/changelog. - Remove package_dir since it's not actually needed. - Whitespace normalization. * tests/Makefile - Add sleep between Python 2 and Python 3 invocation of tests under xvfb-run, otherwise I get crashes where xvfb doesn't come up. update-manager (1:0.163) quantal; urgency=low [ Colin Watson ] * Isolate tests from local configuration in /etc/update-manager/release-upgrades.d/. * Use Python attributes rather than GObject.get_data and GObject.set_data, which have been removed upstream (LP: #1009859). * Switch default view class to Gtk3 and replace python-gobject dependency with python-gi. * Port away from old-style apt.Package candidateFoo and installedFoo properties, preferring candidate.foo and installed.foo. In a number of cases we have to check whether candidate/installed is non-None first. * Use apt_pkg.version_compare rather than apt_pkg.VersionCompare. * Use apt_pkg.uri_to_filename rather than apt_pkg.URItoFileName. * Use apt_pkg.TagFile (and related new-style API) rather than apt_pkg.ParseTagFile. * Use apt_pkg.PackageManager rather than apt_pkg.GetPackageManager. * Use apt_pkg.Acquire rather than apt_pkg.GetAcquire. * Use mark_foo/marked_foo rather than markFoo/markedFoo. * Use apt_pkg.ActionGroup rather than apt_pkg.GetPkgActionGroup. * Use apt_pkg.ProblemResolver rather than apt_pkg.GetPkgProblemResolver. * Use apt_pkg.read_config_file rather than apt_pkg.ReadConfigFile. * Use new spelling of apt_pkg.DepCache methods. * Rename several local cache methods to PEP-8 style to avoid showing up in the output of /usr/share/python-apt/migrate-0.8.py. * Use apt_pkg.size_to_str rather than apt_pkg.SizeToStr. * Use apt_pkg.PackageManager.get_archives rather than apt_pkg.PackageManager.GetArchives. * Use apt_pkg.Acquire.fetch_needed rather than apt_pkg.Acquire.FetchNeeded. * Use new spelling of apt_pkg.Package/Version/Dependency methods. * Use apt_pkg.pkgsystem_lock rather than apt_pkg.PkgSystemLock. * Use new spelling of apt_pkg dependency parsing methods. * Use new spelling of apt_pkg.SourceList methods. * Bump python-apt (build-)dependency to >= 0.8.0. * Add a scheme for excluding false positives from the pyflakes test, and enable it by default. * Rearrange the OptionParser workaround from 1:0.154.5 to work with Python 3, using gettext or ugettext as appropriate. * Always pass bytes to hashlib.md5.update. * Fix DistUpgradeAptCdrom to account for gzip files being opened in binary mode. * Convert the last use of os.popen to subprocess.check_output, which makes it easier to read str rather than bytes. (This requires Python 2.7.) * Decode bytes read from urlopened file objects. * UpdateManager/backend/InstallBackendSynaptic.py - Keep a reference to the data tuple passed to GObject.child_watch_add to avoid attempts to destroy it without a thread context (LP: #724687). - Open temporary synaptic selections file in text mode. * Define __bool__ rather than __nonzero__ method in Python 3. * sort(cmp=) and sorted(cmp=) no longer work in Python 3. Use appropriate key= arguments instead. * Fix ResourceWarning while reading /proc/mounts. * Make update-manager-kde depend on psmisc, for killall. * DistUpgrade/DistUpgradeView.py: - Use floor division in FuzzyTimeToStr. * DistUpgrade/DistUpgradeViewText.py: - Flush stdout after printing confirmation message, since it doesn't have a trailing newline. * Use the appropriate Unicode gettext methods in both Python 2 and 3, and drop lots of Python-3-unfriendly Unicode mangling as a result. * DistUpgrade/DistUpgradeViewKDE.py: - Open the terminal log in binary mode. * data/do-release-upgrade.8: - Provide a more useful NAME section. * DistUpgrade/DistUpgradeCache.py: - Tolerate SyntaxError from attempting to import NvidiaDetector, until such time as a complete ubuntu-drivers-common Python 3 port is in the archive. * Switch #! lines over to python3, apart from dist-upgrader which needs to stay as Python 2 for a while longer (and have some special arrangement for running with Python 3 for upgrades from >= quantal). * Run tests under both Python 2 and 3. [ Adam Conrad ] * Merge branch from Michael Terry to drop auto-upgrade-tester from update-manager and move it into its own source package [ Barry Warsaw ] * Begin refactoring of Computer Janitor code by renaming and re-situating all of it to janitor/plugincore. This will eventually be removed from here into its own separate branch. * Merge the temporary Python 3 sprint branch back into trunk, and close the py3 sprint branch. * Moved UpdateManager/backend and UpdateManager/UnitySupport.py to the python*-update-manager packages for apturl. [ Michael Vogt ] * UpdateManager/GtkProgress.py: - fix python-apt 0.8 API crash [ Stéphane Graber ] * Drop fdsend as it's not used and doesn't build with python3. * Make update-manager-core a binary all packages (everything is python). * Split update-manager-core into python-update-manager, python3-update-manager and update-manager-core. * Build-depend and depend on python-apt >= 0.8.5~ as we need proper python3 support. [ Steve Langasek ] * tests/test_country_mirror.py: the test suite shouldn't fail if $LANG isn't set in the environment. * update-manager is now using python3 as an interpreter, so fix these up to actually be python3 packages. update-manager (1:0.162) quantal; urgency=low * DistUpgrade/build-tarball.sh: - include "DistUpgrade" symlink in tarball to ensure relative imports keep working update-manager (1:0.161) quantal; urgency=low * /usr/share/nvidia-common/obsolete was renamed to /usr/share/ubuntu-drivers-common/obsolete and moved packages. Cope with this. update-manager (1:0.160) quantal; urgency=low [ Colin Watson ] * Use Python 3-style print functions. * Use "except Exception as e" syntax rather than the old-style "except Exception, e". * Fix a few assorted pyflakes warnings. * Use string methods rather than functions from the string module. * Replace most uses of filter and map with list comprehensions or for loops. * Use open() rather than file(). * Use Python 3 renaming of ConfigParser if available. * Use "raise Exception(value)" syntax rather than the old-style "raise Exception, value". * Remove duplicate imports of os.path; 'import os' is enough. * Use Python 3 renamings of urllib, urllib2, and urlparse if available. * Remove all hard tabs from Python code. Python 3 no longer tolerates mixing tabs and spaces for indentation. * Use Python 3 renaming of httplib if available. * Use email.utils.parsedate (with a DST handling correction) rather than the long-deprecated rfc822.parsedate. * Use the threading module instead of thread (renamed to _thread in Python 3). * Tell Python to use absolute imports by default, and annotate cases where we need relative imports. * Update test_proxy to use gsettings and the python-apt 0.8 API. * Use new-style octal literals. * Drop use of deprecated statvfs module. * Use Python 3 renamings of BaseHTTPServer and SocketServer if available. * Modernise use of unittest methods. * Use python-apt 0.8 API spellings of apt_pkg.config methods. * Fix several ResourceWarnings with Python 3. * Port to python-apt 0.8 progress classes. * Since python-gnupginterface is not likely to be ported to Python 3, and since it's almost just as easy to call gpg directly via subprocess, do so. * Use gettext if ugettext does not exist (as in Python 3). * Ignore __pycache__ directories, and exclude them from dist-upgrader tarballs. * Fix up module path when running AutoUpgradeTester/auto-install-tester.py from the build tree. * Add a DistUpgrade -> . symlink in DistUpgrade/, to make it possible to have compatible imports both in update-manager proper and in dist-upgrader tarballs. * Use only absolute imports in AutoUpgradeTester/auto-install-tester.py and DistUpgrade/dist-upgrade.py; these have no __package__ and so cannot use relative imports. * Open subprocesses with universal_newlines=True when expecting to read text from them. On Python 2, this only enables \r\n conversion and the like, but on Python 3 this also causes subprocess-related file objects to read str rather than bytes. * Use "key in dict" rather than "dict.has_key(key)". * Pass globals() to __import__ so that relative imports work. [ Michael Vogt ] * DistUpgrade/*.py: - update for the 12.04 -> 12.10 upgrade * AutoUpgradeTester/profile/defaults.cfg.d/defaults.cfg: - update for precise->quantal * fix some remaining python-apt 0.8+ API issues [ Brian Murray ] * DistUpgrade/DistUpgradeApport.py - check errormsg for the English version of the dependency problems error first (LP: #999890) [ Michael Terry ] * Rename to Software Updater and fix some other strings to match mpt's spec. * lp:~mterry/update-manager/move-changelogs: - implement new app layout update-manager (1:0.156.14.5) UNRELEASED; urgency=low * lp:~ember/update-manager/ubuntu.bug1002956: - fix missing ReleaseNotesViewerWebkit.py support, thanks to Pedro Fragoso (LP: #1002956) update-manager (1:0.156.14.4) precise-security; urgency=low * SECURITY UPDATE: Incorrect permissions on system_state archive may expose repo passwords (LP: #954483) - DistUpgrade/DistUpgradeMain.py: create file with proper permissions. - debian/update-manager-core.postinst: clean up permissions on existing files. - CVE-2012-0948 * SECURITY UPDATE: Apport hook may upload system_state archive containing repo passwords (LP: #954483) - debian/source_update-manager.py: don't upload system_state archives. - CVE-2012-0949 * This package does _not_ contain the changes from (1:0.156.14.2) in precise-proposed. update-manager (1:0.156.14.2) precise-proposed; urgency=low * fix automatic expand of the terminal if no activity happend for >300s (LP: #979661) update-manager (1:0.156.14.1) precise-proposed; urgency=low * DistUpgrade/ReleaseAnnouncement: - add "LTS" to the version update-manager (1:0.156.14) precise; urgency=low * debian/control: - fix description for update-manager-kde (LP: #984906), thanks to Scott Kitterman * DistUpgrade/DistUpgradeController.py: - do not set PYCENTRAL_NO_DPKG_QUERY (LP: #986233) update-manager (1:0.156.13) precise; urgency=low * Improve the error message used when a package cannot be located after updating, probably caused by an overloaded mirror. (LP: #873468) update-manager (1:0.156.12) precise; urgency=low [ Colin Watson ] * data/gtkbuilder/UpgradePromptDialog.ui: - Remove has_separator property from dialog_really_do_not_upgrade (deprecated in GTK+ 2.22, removed in 3.0). * debian/control: - Restore gksu dependency, needed by e.g. check-new-release-gtk (LP: #980637). [ Michael Vogt ] * UpdateManager/UpdateManager.py: - disconnect model and clear store before rebuilding the cache, thanks to Colin Watson * po/*.po: - updated to the latest launchpad (LP: #628157) * DistUpgrade/DistUpgradeController.py: - remove backports sources.list.d file again after its no longer needed (LP: #973717) * DistUpgrade/DistUpgradeController.py: - when checking for the backports, its enough to check is the set of the needed ones is a subset of the found ones (LP: #969182) * DistUpgrade/DistUpgrade.cfg.lucid: - release-upgrader-libapt-pkg-dev is not needed for the upgrade itself * remove skype from the removal blacklist update-manager (1:0.156.11) precise; urgency=low * DistUpgrade/DistUpgrade.cfg.lucid: - add in a missing backported package (LP: #969182) * DistUpgrade/Distupgrade.py: - workaround issue regarding removing selections, thanks to sampo555 for the patch (LP: #945536) * Automatic update of mirrors, demoted packages and of included source packages: base-installer update-manager (1:0.156.10) precise; urgency=low [ Michael Vogt ] * UpdateManager/Core/MyCache.py: - do not attempt to download changelogs from https locations if the uri requires credentials, thanks to Pat McGowan [ Colin Watson ] * UpdateManager/Core/MyCache.py: - Check that pkg.candidate.uri is not None when looking for changelogs (LP: #839986). update-manager (1:0.156.9) precise; urgency=low [ Michael Vogt ] * DistUpgrade/DistUpgradeController.py: - support cdrom-only upgrades properly by using the backported libapt-{pkg,inst} and release-upgrader-python-apt from the CD * DistUpgrade/DistUpgrade.cfg: - update KernelRemoval/Version to match oneirics kernel * DistUpgrade/DistUpgrade.cfg.lucid: - update KernelRemoval/Version to match lucids kernel * data/release-upgrades: - set releae upgrades default to "lts" * DistUpgrade/DistUpgradeCache.py: - when selecting a new default kernel from base-installer, ensure to install the matching kernel headers too if previously kernel headers were installed (LP: #959307) [ Brian Murray ] * debian/source_update-manager.py: pass if attach_gsettings fails like on a server [ Gabor Kelemen ] * lp:~kelemeng/update-manager/bug957552: - Mark two accessible descriptions for translation. LP: #957552 update-manager (1:0.156.8) precise; urgency=low [ Robert Roth ] * Update icon name to use FD.o standard (LP: #921310) [ Julien Lavergne ] * DistUpgrade/DistUpgrade.cfg, DistUpgrade/removal_blacklist.cfg, UpdateManager/Core/utils.py, AutoUpgradeTester/profile/lubuntu/DistUpgrade.cfg: - Add Lubuntu support, and don't upgrade gnome-components which have been removed from Lubuntu installation (LP: #945215) [ Barry Warsaw ] * Improve the warning issued when i8xx graphics hardware is detected. (LP: #941172) [ Brian Murray ] * DistUpgrade/removal_blacklist.cfg: - blacklist gnome-session so that users can always login after a failed partial upgrade (LP: #946539) [ James Hunt ] * Only attempt to stop screensaver if DISPLAY set, and throw away xdg-screensaver output. (LP: #883618) [ Colin Watson ] * Use 'from dbus.mainloop.glib import DBusGMainLoop; DBusGMainLoop(set_as_default=True)' to set up the main loop, rather than importing the deprecated dbus.glib. [ Gabor Kelemen ] * Fix misplaced parentheses. LP: #952959 update-manager (1:0.156.7) precise; urgency=low [ Michael Vogt ] * DistUpgrade/DistUpgradeCache.py: - fix nvidia detection, thanks to Brian Murray * DistUpgrade/xorg_fix_proprietary.py: - fix crash when apt_pkg is not initialized (LP: #942106) * DistUpgrade/DistUpgradeController.py, DistUpgrade/mirrors.cfg: - support upgrades with commercial-ppas in the sources.list (LP: #939461) and add tests * UpdateManager/UpdateManager.py: - fix inaccurate string, thanks to JohnNapster (LP: #942590) [ Brian Murray ] * DistUpgrade/removal_blacklist.cfg: - Only blacklist unity-2d, not all packages whose names start with unity-2d. (LP: #940196) update-manager (1:0.156.6) precise; urgency=low [ Robert Roth ] * lp:~evfool/update-manager/lp930177: - Add missing space (LP: #930177) [ Michael Vogt ] * DistUpgrade/DevelReleaseAnnouncement: - change label from alpha to beta release update-manager (1:0.156.5) precise; urgency=low [ Brian Murray ] * do-release-upgrade: capitalize U in ubuntu * debian/source_update-manager.py: add screenlog.0 from /var/log/dist-upgrade to apport bug reports [ Marc Deslauriers ] * DistUpgrade/DistUpgradeViewKDE.py: fix regression caused by improper return value handling. (LP: #933225) update-manager (1:0.156.4) precise; urgency=low * DistUpgrade/DistUpgrade.cfg.lucid: - Update libapt-pkg and libapt-inst versions. update-manager (1:0.156.3) precise; urgency=low [ Jean-Baptiste Lallement ] * lp:~jibel/update-manager/AutoUpgradeTester-desktoptests: New tests for Ubuntu Desktop LTS upgrade: * autologin check * user settings check: wallpaper, theme, keyboard layout, custom launchers (desktop and panel) * lp:~jibel/update-manager/AutoUpgradeTester-portlocking: - automatically allocate free ssh/vnc ports [ Colin Watson ] * Clean up a few pyflakes warnings. * DistUpgrade/DistUpgradeMain.py - Make sure main.log is actually created. * DistUpgrade/removal_blacklist.cfg: - Only blacklist unity, not all packages whose names start with unity. [ Robert Roth ] * lp:~evfool/update-manager/lp351665: - Use ngettext to humanize size (LP: #351665) * lp:~evfool/update-manager/distupgradefixes: - DistUpgrade changes dialog text fixes (LP: #348517, LP: #513908) - Fix resize on changes dialog to stretch the details (LP: #294293) [ Michael Vogt ] * add humanize_size() test * pyflakes fixes * tests/test_pyflakes.py: - always pyflakes as part of the pre-build process to ensure we are clean * disable apply_dselect_upgrades() update-manager (1:0.156.2) precise; urgency=low [ Michael Vogt ] * DistUpgrade/removal_blacklist.cfg: - add unity, unity-2d [ Brian Murray ] * debian/source_update-manager.py: use attach_file for dist-upgrade log files rather than attach_root_command_outputs resolving the double gzipped apt clone attachment issue [ Matthew Linscott ] * UpdateManager/Core/utils.py - fixed typos in docstring for ExecutionTime [ Daniel Polehn ] * DistUpgrade/DistUpgradeView.py - Made usage of 'canceled' v. 'cancelled' consistent. LP: #918302 update-manager (1:0.156.1) precise; urgency=low * debian/source_update-manager.py: include AptDaemon messages from syslog to help identify failures update-manager (1:0.156) precise; urgency=low [ Michael Vogt ] * pyflake fixes, remove some dead code * update unity dependency [ Brian Murray ] * DistUpgrade/DistUpgradeController.py - call apport-cli directly for bug reporting of errors * check-new-release-gtk - ensure to write a integer when calculating the next time that the release available window will be presented (LP: #873424) - hide redundant release-notes button (LP: #873432) update-manager (1:0.155.3) precise; urgency=low [ Michael Vogt ] * DistUpgrade/removal_blacklist.cfg: - add screen as the server upgrade runs inside it, thanks to Steve Langasek * DistUpgrade/DistUpgradeController.py, DistUpgrade/prerequists-sources.list: - use the release-upgrader-python-apt from lucid-updates instead of lucid-proposed [ Brian Murray ] * UpdateManager/UpdateManager.py - add periods to sentences in refresh_updates_count update-manager (1:0.155.2) precise; urgency=low [ Robert Roth ] * DistUpgrade/DistUpgradeController.py: - Avoid using systemdir abbreviation (LP: #903939) [ Brian Murray ] * debian/source_update-manager.py: - Use attach_gesttings_package instead of attach_gconf [ Jean-Baptiste Lallement ] * lp:~jibel/update-manager/AutoUpgradeTester-aptclone: - support building a profile from a apt-clone file and testing that - add amd64 test profiles update-manager (1:0.155.1) precise; urgency=low * fix crash in backports fetching code update-manager (1:0.155) precise; urgency=low [ Michael Vogt ] * lp:~mvo/update-manager/lucid-precise-upgrades: - support upgrades with multiarch-support (for e.g. flash) from lucid to precise by using the release-upgrader-python-apt from lucid-proposed during the upgrade [ Gabor Kelemen ] * Mark a few strings for translation, make variables reorderable update-manager (1:0.154.6) precise; urgency=low * DistUpgrade/DistUpgrade.ui: - remove <child internal-child="selection"> as this is not supported by the gtkbuilder in lucid and makes the release upgrader crash (LP: #898482) update-manager (1:0.154.5) precise; urgency=low [ Nicholas Skaggs ] * lp:~nskaggs/update-manager/fix-for-702418: - Removed gnome-power-manager dbus interface completely and only use freedesktop interface. Thanks to Nicholas Skaggs (LP: #702418) [ Gabor Kelemen ] * Replace gettext.install() with bindtextdomain() calls. Work around crash in OptionParser when displaying localized --help text, to not regress on bug LP: #557804 * Extract strings for translation from u-m-t and u-s-s executables [ Marc Deslauriers ] * SECURITY UPDATE: arbitrary code execution via directory traversal (LP: #881548) - UpdateManager/Core/DistUpgradeFetcherCore.py: verify signature before unpacking the tarball. - CVE-2011-3152 * SECURITY UPDATE: information leak via insecure temp file (LP: #881541) - DistUpgrade/DistUpgradeViewKDE.py: use mkstemp instead of mktemp. - CVE-2011-3154 [ Michael Vogt ] * UpdateManager/UpdateManager.py: - ensure that the origin headers state of "select all/dselect all" is consistent update-manager (1:0.154.3) precise; urgency=low [ Alexey Feldgendler ] * lp:~feldgendler/update-manager/574436: Introduced the [ThirdPartyMirrors] configuration section for the distribution upgrader. All keys in it must have distinct names, but only values matter. Each value is a third-party source URI. Such whitelisted sources don't get disabled on upgrade; however, if they use "from" release name, it's replaced with the "to" release name. (LP: #574436) update-manager (1:0.154.2) precise; urgency=low * UpdateManager/backend/InstallBackendSynaptic.py - fix crash when using synaptic (LP: #878719) * DistUpgrade/DistUpgradeController.py, DistUpgrade/DistUpgradeMain.py: - before doing the upgrade test if all systemdirs are actually writable, thanks to Brian Murray (LP: #889921) update-manager (1:0.154.1) precise; urgency=low [ Robert Roth ] * Change up-to-date text to up to date (LP: #864336) [ Michael Vogt ] * DistUpgrade/DistUpgradeController.py: - add precise as a LTS release * AutoUpgradeTester/profile/*/DistUpgrade.cfg: - updated to test oneiric->precise and lucid->precise * AutoUpgradeTester/UpgradeTestBackendQemu.py: - add support for different architectures * AutoUpgradeTester/profile/server-amd64/DistUpgrade.cfg: - add amd64 server upgrade test profile * DistUpgrade/DistUpgradeConfigParser.py: - add new "defaults_dir" argument to allow simplifying the auto-upgrade-tester config * DistUpgrade/DistUpgrade.cfg.lucid: - add lucid->precise upgrade config * AutoUpgradeTester/UpgradeTestBackendQemu.py: - dynamically allocate ssh/vnc ports when multiple testers are run update-manager (1:0.154) precise; urgency=low * lp:~barcc/update-manager/all_changes-wrong-use: - Fixed wrong use of self.cache.all_changes[name] in UpdateManager.on_treeview_update_cursor_changed * data/gtkbuilder/UpdateManager.ui: - set default height to 500 (thanks to Sebastien Bacher) * DistUpgrade/DistUpgradeController.py: - do not crash if apt-btrfs-snapshot fails to run (LP: #873411) * UpdateManager/Core/MyCache.py, DistUpgrade/DistUpgradeCache.py: - honor dselect request install state when calcuating the upgrade thanks to Evan for suggesting this * merge fixes from oneiric-proposed * DistUpgrade/* - update for oneiric->precise upgrades update-manager (1:0.152.25.4) oneiric-proposed; urgency=low * DistUpgrade/removal_blacklist.cfg: - ensure that postgresql does not get removed (LP: #871893) update-manager (1:0.152.25.3) oneiric-proposed; urgency=low * DistUpgrade/DistUpgradeCache.py: - fix crash when packages needs downgrading * UpdateManager/Core/utils.py: - do not crash if iptables does not exist, thanks to Daniel Holbach for reporting the issue (LP: #877514) * DistUpgrade/DistUpgradeQuirks.py: - keep poking the screensaver to ensure that it really won't activate during the upgrade (thanks to Jonathan Davies for the report) * tests/test_sources_list.py: - fix test (archive.ubuntu.com no longer listens to ftp) * po/*: - refresh again to fix regression (LP: #877461) update-manager (1:0.152.25.2) oneiric-proposed; urgency=low * refresh translation for the release-upgrader (LP: #873905) update-manager (1:0.152.25.1) oneiric-proposed; urgency=low * DistUpgrade/DistUpgradeController.py: - do not crash if apt-btrfs-snapshot fails to run (LP: #873411) update-manager (1:0.152.25) oneiric; urgency=low * DistUpgrade/DistUpgradeController.py: - add workaround for a python-apt bug that causes the release upgrade to import the old version of "DistInfo" intead of the one that is bundled with the release-upgrader (LP: #871007) update-manager (1:0.152.24) oneiric; urgency=low * AutoUpgradeTester/profile/eduubuntu/DistUpgrade.cfg: - Fix typo, renaming to edubuntu instead update-manager (1:0.152.23) oneiric; urgency=low * DistUpgrade/DistUpgrade.cfg: - ensure that edubuntu-desktop really gets upgraded * AutoUpgradeTester/profile/eduubuntu/DistUpgrade.cfg: - update profile for edubuntu update-manager (1:0.152.22) oneiric; urgency=low * tests/test_update_origin.py, Janitor/computerjanitor/plugin.py: - fix tests * .bzr-builddeb/default.conf: - re-enable pre-build script to ensure we get a updated base-installer, demotions and html Announcements update-manager (1:0.152.21) oneiric; urgency=low * DistUpgrade/DistUpgradeQuirks.py: - increase the amd64 cache size to 48mb to workaround bug LP: #854090 during the natty -> oneiric upgrade update-manager (1:0.152.20) oneiric; urgency=low * DistUpgrade/DistUpgradeQuirks.py: - increase the default cache size on a multiarch system to avoid potential crash in natty apt (LP: #854090) * DistUpgrade/DistUpgradeController.py, UpdateManager/Core/utils.py: - do not leak password from sources.list entries into the logfile (LP: #839094) * UpdateManager/UpdateManager.py: - do not crash if a package can not be put into "install" state, instead, just keep the old (unmarked) state (LP: #850482) * UpdateManager/DistUpgradeFetcher.py: - fix crash for changed gtk2 -> gtk3 API (LP: #859862) * UpdateManager/backend/InstallBackendAptdaemon.py: - remove debug output (LP: #855495) update-manager (1:0.152.19) oneiric; urgency=low * DistUpgrade/DistUpgradeCache.py: - do not use O_SYNC for the apt.log, its not important enough to justify the slowdown (LP: #852128) update-manager (1:0.152.18) oneiric; urgency=low [ Michael Vogt ] * debian/pycompat: - removed, no longer needed * debian/rules: - fix incorrect invocation of --with=python2 [ Robert Roth ] * lp:~evfool/update-manager/handlewarning: - Only disconnect handler if it's still connected (LP: #133139) * lp:~evfool/update-manager/glibchangefix: - Call glib.markup_escape_text() correctly as per current gir (don't pass in string length; LP: #832745) * lp:~evfool/update-manager/fixcopylink: - Fix the "Copy web link" context menu item of the ChangeLog viewer. It did not work before of some Gtk changes, now it does work. Fixes LP: #831944. [ Stefano Rivera ] * extras is another special case where validTo=False (LP: #775694) update-manager (1:0.152.17) oneiric; urgency=low * debian/source-update_manager.py: ask the reporter if their issue is regarding a distribution upgrade if so include log files (LP: #836846) update-manager (1:0.152.16) oneiric; urgency=low * DistUpgrade/DevelReleaseAnnouncement: - prepare text for the beta release update-manager (1:0.152.15) oneiric; urgency=low [ Brian Murray ] * DistUpgrade/DistUpgradeApport.py: - properly add the tag 'dist-upgrade' to the bug report [ Michael Vogt ] * UpdateManager/backend/InstallBackendAptdaemon.py: - fix incorrect initialization * fix GLib.timeout_add_seconds() with the new GIR (LP: #829186) * call software-properties-gtk without gksu, that is no longer needed update-manager (1:0.152.14) oneiric; urgency=low * DistUpgrade/DistUpgradeQuirks.py: - enable multiarch on amd64 during the upgrade - add new "PreCacheOpen" hook and use it for the multiarch enabling * DistUpgrade/DistUpgradeCache.py: - when checking for missing "priority: required" packages ignore the foreign architecture ones update-manager (1:0.152.13) oneiric; urgency=low [ Robert Roth ] * Fix link context menu in changelog viewer (LP: #824957) [ Michael Vogt ] * debian/control: - bump unity dependency to gir1.2-unity-4.0 update-manager (1:0.152.12) oneiric; urgency=low [ Michael Vogt ] * AutoUpgradeTester/UpgradeTestBackendQemu.py: - add NonInterative/AddRepoUpgradeImmediately option that allows installing test package *before* the test upgrade runs (useful for e.g. testing a new apt or dpkg) [ Robert Roth ] * Added default value to be able to start UpdateManager without having gir-unity installed (LP: #823935) * Fixed changelog test with the new wording * Specify default -1 length for terminal response (LP: #817785) update-manager (1:0.152.11) oneiric; urgency=low * DistUpgrade/DistUpgradeViewGtk3.py: - use vte.for_command_full() instead of fork_command() as fork_command is no longer available in the gir-2.90 (LP: #808738) update-manager (1:0.152.10) oneiric; urgency=low [ Michael Vogt ] * merged lp:~evfool/update-manager/pkgsections, many thanks * debian/control: - fix dependency on python-aptdaemon.gtk3widgets * DistUpgrade/DistUpgradeController.py: - only ask for a reboot if the upgrade is not running inside a chroot [ Brian Murray ] * DistUpgrade/DistUpgradeController.py: - when upgrading do not disable deb-src entries in /etc/apt/sources.list * DistUpgrade/DistUpgradeMain.py: - string fix thanks to David Stansby for the fix (LP: #510681) [ Robert Roth ] * Give clear instructions when the last update timestamp is not found (LP: #821345) * Fix operation between NoneType and int (LP: #820126) update-manager (1:0.152.9) oneiric; urgency=low * remove old UpdateManager.glade file * rename data/glade to data/gtkbuilder * merged lp:~rodrigo-moya/update-manager/use-new-power-interface, thanks to Rodrigo Moya * DistUpgrade/DistUpgradeQuirks.py: - when upgrading, ensure that zz-update-grub is early in /etc/kernel/postinst.d to ensure we always have a good grub config and not depend on the package upgrade ordering for that update-manager (1:0.152.8) oneiric; urgency=low [ Robert Roth ] * Ordered the packages alphabetically on the dist-upgrade confirmation dialog. (LP: #764831) * Update last updated text every 15 minutes in the first hour after update (LP: #747336). Thanks to Fredrik Ekelund. [ Michael Vogt ] * UpdateManager/UpdateManager.py, data/glade/UpdateManager.ui: - remove old manual text wrap code that is now superseeded by gtk3 (LP: #812949) * data/glade/UpdateManager.ui: - fix the xalign and expand properties of the various alert labels update-manager (1:0.152.7) oneiric; urgency=low [ Michael Vogt ] * merged lp:~mterry/update-manager/813778 to fix crash in initCache() LP: #813778. Many thanks to Michael Terry * add jenkins slave setup (config, upstart job), similar to the server-isotesting (disabled by default) * DistUpgrade/DistUpgrade.ui: - add minimal size for the details expander (and let glade reindent/reformat the entire file along the way) * merged lp:~evfool/update-manager/stringfixes [ Robert Roth ] * Updated translator comment to follow the Ubuntu Units policy * Display sizes according to the Ubuntu Units Policy (LP: #410310) * Fix ambiguous text explaining updates to running release (LP: #461780) * Added label to distinguish candidate version from installed version (LP: #537942) * Rename Check all/Uncheck all to Select/Deselect all update-manager (1:0.152.6) oneiric; urgency=low * Only build dist-upgrader tarball in the binary-indep target, fixing both the non-x86 build failures, and Soyuz having a hissy fit over multiple identically-named files (LP: #813867) update-manager (1:0.152.5) oneiric; urgency=low * DistUpgrade/DistUpgrade{Cache,Controller}.py: - if btrfs snapshots are used, add the additional required diskspace requierd into the free space calculation * debian/{rules,control}: - move to debhelper 7 update-manager (1:0.152.4) oneiric; urgency=low * merged lp:~evfool/update-manager/fix622489, many thanks to "FooBar" and Robert Roth (evfool) * when downloading the html release notes, ensure to send a query string similar to ubiquity to allow more specific release notes update-manager (1:0.152.3) oneiric; urgency=low * remove unneeded GConf imports (we are using gsettings now) LP: #807715 * a good bunch of pyflakes fixes update-manager (1:0.152.2) oneiric; urgency=low * data/update-manager.convert: - ship gconf->gsettings convert script update-manager (1:0.152.1) oneiric; urgency=low * fix release upgrade view dialog in gtk3 * UpdateManager/UpdateManager.py, check-new-release-gtk: - use GLib.timeout_add(priority, timeout, func, data) instead of the old glib.timeout_add() thanks to Michael Terry (lp:~mterry/update-manager/pygi-cleanups) * check-new-release-gtk, tests/test_end_of_life.py: - fix test failures update-manager (1:0.152) oneiric; urgency=low * ported to gtk3/GI * port from gconf to gsettings * debian/control: - depend on python-gobject with overwrite bugfixes needed for update-manager update-manager (1:0.151.10) oneiric; urgency=low [ Brian Murray ] * In apport hook, collect non-default gconf values. update-manager (1:0.151.9) oneiric; urgency=low * do not crash if lspci is not installed * merged lp:~brian-murray/update-manager/apport-hook-changes, thanks! * merged lp:~eapache/update-manager/unity-urgency-hint, many thanks to Evan Huus (LP: #799173) update-manager (1:0.151.8) oneiric; urgency=low * DistUpgrade/DistUpgradeViewGtk.py: - set DPKG_UNTRANSLATED_MESSAGES to force untranslated dpkg terminal messages for easier package failure duplication detection * DistUpgrade/DistUpgradeCache.py: - when calculating the size of the space required in /boot use the size of the currently running kernel as the base and add a small safety margin (LP: #798462). * import new apt-btrfs-snapshot to fix crash for certain fstab entries (LP: #806065) update-manager (1:0.151.7) oneiric; urgency=low * fix apt-btfs-snapshot releated crash update-manager (1:0.151.6) oneiric; urgency=low * pre-build.sh: - automatically include apt_btrfs_snapshot.py in the release uprader tarball update-manager (1:0.151.5) oneiric; urgency=low * DistUpgrade/DistUpgradeQuirks.py: - warn intel i8xx user that the upgrade to oneiric may cause issues with their particular graphics hardware (LP: #774999) * merge patch from "eapache" to fix the unity progress bars (LP: #796311) update-manager (1:0.151.4) oneiric; urgency=low [ Robert Roth ] * Fix problem of showing only integer MB count and causing size inconsistencies [ Brendan Donegan ] * Updated NetworkManagerHelper with new NM 0.9 states as well as updating the UpdateManager itself to handle codes more robustly [ Michael Vogt ] * merged lp:~brendan-donegan/update-manager/bug791548_networkmanager0.9, many thanks * merged lp:~evfool/update-manager/fixmbcount, many thanks * show progress inside unity, thanks to Bilal Akhtar for the initial version of the patch! update-manager (1:0.151.3) oneiric; urgency=low [ Michael Vogt ] * merged lp:~brendan-donegan/update-manager/bug699660-fix-settings-shortcut thanks to Brendan Donegan * AutoUpgradeTester/profile/*: - updated for natty->oneiric * DistUpgrade/DistUpgradeViewGtk.py: - use VteTerminal "child-exit" signal instead of the Reaper object * optionally use webkit for the release notes viewer [ Brian Murray ] * do-release-upgrade: display version of the new release available not the code name * add an apport hook for update-manager and modify bug reporting instructions to recommend using apport (LP: #721382) update-manager (1:0.151.2) oneiric; urgency=low * fix UnitySupport import update-manager (1:0.151.1) oneiric; urgency=low * merged lp:~bilalakhtar/update-manager/unity-quicklist, many thanks to Bilal Akhtar for adding quickly support * merged lp:~mvo/update-manager/for-unity to make the support optional and to add updates count into the update-manager icon in unity update-manager (1:0.151) oneiric; urgency=low * merged lp:~evfool/update-manager/sectionchecks, many thanks to Robert Roth * DistUpgrade/*: - updated for oneiric * fix arguments from "autInst" to "auto_inst" and "autoFix" -> "auto_fix" update-manager (1:0.150.2) natty-proposed; urgency=low * debian/control: - point to "natty" branch * DistUpgrade/DistUpgrade.cfg: - remove "kde-plasmoid-cwp" early as it will break upgrades later (LP: #773022) * DistUpgrade/DistUpgradeCache.py: - do not fail if not all meta-package can not be upgraded, packages like ubuntu-desktop and xubuntu-desktop have implicit conflicts LP: #775411 update-manager (1:0.150.1) natty-proposed; urgency=low [ Brian Murray ] * DistUpgrade/DistUpgradeApport.py: - do not report zero size attachments (LP: #772052) * DistUpgrade/DistUpgrade.cfg: - enable apport for distribution upgrades (LP: #772913) * DistUpgrade/DistUpgradeController.py: - use service to start apport [ Michael Vogt ] * DistUpgrade/DistUpgrade.cfg: - Remove 'dontzap' from kubuntu-desktops rules (LP: #769680). This fixes a upgrade issue when a old package is leftover update-manager (1:0.150) natty; urgency=low * DistUpgrade/DistUpgradeQuirks.py, tests/test_quirks.py: - don't print a error for already patched files, this removes a misleading error from the upgrade logs - update tests update-manager (1:0.147.6) natty; urgency=low * AutoUpgradeTester/profile/{euca-cloud,euca-nc,xubuntu}/DistUpgrade.cfg: - updated for maverick->natty now that the auto-upgrade-test server has more diskspace * DistUpgrade/DistUpgradeController.py, DistUpgrade/DistUpgradeMain.py: - make running-under-ssh check more robust by looking for sshd parent * DistUpgrade/DistUpgradeViewText.py: - make user confirm information() messages before continuing (important for e.g. the "sshd has started" message) * DistUpgrade/DistUpgradeQuirks.py, DistUpgrade/DistUpgradeController.py: - ensure that new recommends are installed on a desktop mode upgrade even if that got disabled e.g. via synaptic (LP: #759262) - add test for this feature update-manager (1:0.147.5) natty; urgency=low * DistUpgrade/DistUpgradeController.py, DistUpgrade/DistUpgradeMain.py: - fix ssh detection (LP: #744995) update-manager (1:0.147.4) natty; urgency=low * DistUpgrade/DistUpgradeViewKDE.py - Allow to view differences in conf file changes LP: #746431 update-manager (1:0.147.3) natty; urgency=low * merged lp:~evfool/update-manager/fix665173 (LP: #665173), many thanks to Robert Roth (update the test a bit) * merged lp:~evfool/update-manager/fix150677 (LP: #150677), many thanks to Robert Roth * merged lp:~evfool/update-manager/fix727069 (LP: #727069), many thanks to Robert Roth update-manager (1:0.147.2) natty; urgency=low * UpdateManager/backend/InstallBackendAptdaemon.py: - no not trigger a apport exception on user auth issues and if the user does not type the password in time (LP: #626798) update-manager (1:0.147.1) natty; urgency=low * UpdateManager/backend/InstallBackendAptdaemon.py: - use pkgsystem_unlock, improve exception handling, add test * DistUpgrade/DistUpgradeQuirks.py: - add quirks handler for maverick->natty upgrade for the kdegames-card-data case (LP: #745396) * tests/test_quirks.py: - add test for LP: #745396 * UpdateManager/UpdateManager.py, do-release-upgrade: - point to http://www.ubuntu.com/releaseendoflife when the release is end-of-life message is displayed (LP: #671016) * DistUpgrade/EOLReleaseAnnouncement: - improve wording, this is displayed if the user is trying to upgrade from a unsupported version of Ubuntu to a already unsupported version. This now links to http://www.ubuntu.com/releaseendoflife (LP: #671016) update-manager (1:0.147) natty; urgency=low [ Brian Murray] * UpdateManager/ReleaseNotesViewer.py: fix the path for gnome-open and default to xdg-open (LP: #693131) [ Michael Vogt ] * DistUpgrade/apt_clone.py: - use apt_clone.py from the apt-clone package * debian/control: - add apt-clone to the build-depends * DistUpgrade/DistUpgradePatcher.py: - add native ed-style patch implementation as e.g. chroots may not have ed installed and its critical to be able to ensure that pycompile is correct before the upgrade starts * do-release-upgrade: - use apt.progress.text.AcquireProgress to fix deprecation warning * DistUpgrade/DistUpgradeViewText.py: - fix deprecation warning (LP: #744990) * fix deprecation warnings in auxiliary scripts * DistUpgrade/DistUpgradeAptCdrom.py: - fixes with the python-apt 0.8 API update-manager (1:0.146.6) natty; urgency=low * DistUpgrade/DevelReleaseAnnouncement: - fix description to say "BETA" * pre-build.sh: - cleanup cruft test leftover output update-manager (1:0.146.5) natty; urgency=low * fix FTBFS by including a apt_clone.py copy until apt-clone makes it through NEW update-manager (1:0.146.4) natty; urgency=low * DistUpgrade/DistUpgradeMain.py, DistUpgrade/apt_clone.py: Use apt-clone to create system-state instead of custom one (apt-clone_system_state.tar.gz) This makes reproducing problems a lot easier as apt-clone restore <statefile> can be used. It also means that ubiquity can pick up failed upgrades from the state file and finish them. update-manager (1:0.146.3) natty; urgency=low * DistUpgrade/DistUpgradeAptCdrom.py, DistUpgrade/DistUpgradeController.py: - comment out cdrom source after alternative CD based upgrade * DistUpgrade/DistUpgradeController.py: - show error message when cdrom fails to add * tests/test_cdrom.py: - add test for cdrom commenting update-manager (1:0.146.2) natty; urgency=low [ Michael Vogt ] * data/glade/UpdateManager.ui, UpdateManager/UpdateManager.py: - improve wording of roaming warning, thanks to Alex Chiang - make the roaming warning label wrap * UpdateManager/UpdateManager.py: - fix crash in _get_last_apt_get_update_text (LP: #712346) - do not try to download changelogs if NM reports we are disconnected (LP: #19372) [ Julian Taylor ] * use dh_installman to install manpages * move do-release-upgrade manpage to update-manager-core (LP: #695186) [ Martin Pitt ] * debian/control: Update Breaks:/Conflicts: for the moved manpage. update-manager (1:0.146.1) natty; urgency=low [ Michael Vogt ] * merged lp:~evfool/update-manager/fix689034: - Some basic string fixes (lp:#689034), thanks to Robert Roth * UpdateManager/Core/roam.py: - add backend for roaming detection, thanks to Alex Chiang - display warning when on 3g and when roaming (fixes half of LP: 323108) * merged lp:~thibault-lemaitre/ubuntu/natty/update-manager/from_pkg.isInstalled_to_pkg.is_installed that fixes a bunch of deprecated python-apt issues (many thanks!) [ Lionel Le Folgoc ] * UpdateManager/UpdateManager.py: try to reboot using consolekit if gnome-session isn't present (fixes rebooting on Xfce and LXDE, lp: #530161). update-manager (1:0.146) natty; urgency=low * DistUpgrade/DistUpgradeView*.py: - pass apt.Package object to the view instead of strings, this allows to show additional info on the packages (like summary or size) * DistUpgrade/DistUpgradeViewGtk.py: - check for libgtk2-perl for debconf support * AutoUpgradeTester/install_blacklist.cfg: - update blacklist for creating main-all images * UpdateManager/ReleaseNotesViewer.py: - use monospace font (LP: #153228) * DistUpgrade/DistUpgradeController.py: - perform btrfs snapshot on upgrade if apt-btrfs-snapshot is available update-manager (1:0.145.13) natty; urgency=low * fix ReleaseAnnoucement.html auto generation update-manager (1:0.145.12) natty; urgency=low * debian/control: - drop build-depend on fglrx-modalias * DistUpgrade/DistUpgradeQuirks.py: - port fglrx-modalias checking code to new modaliases support from the pkgrecords * tests/test_quirks.py: - update tests update-manager (1:0.145.11) natty; urgency=low * debian/91-release-upgrade: - test if the script exists before running it (thanks to Kees Cook) * pre-build.sh: - auto generate html files from the *ReleaseAnnoucement files * merged lp:~brendan-donegan/update-manager/updated-signal-and-no-update-option (many thanks) update-manager (1:0.145.10) natty; urgency=low * DistUpgrade/DistUpgradeQuirks.py: - fixup internal (ed) based patching tool * DistUpgrade/patches/ - add pycompile patch to ensure clean upgrade even when maverick-updates is not available (LP: #689615) * AutoUpgradeTester/profile/server/DistUpgrade.cfg: - updated for maverick * DistUpgrade/DistUpgradeCache.py: - minor python-apt 0.8 API update * tests/patchdir/_patchdir_foo.f41121a903eafadf258962abc57c8644: - update test for latest internal patching tool update-manager (1:0.145.9) natty; urgency=low * fix FTBFS * improve install-backend error checking update-manager (1:0.145.8) natty; urgency=low * remove update-manager-hildon update-manager (1:0.145.7) natty; urgency=low * UpdateManager/backend/InstallBackendAptdaemon.py: - updated for aptdaemon 0.40 * merged lp:~alexlauni/update-manager/dbus, many thanks update-manager (1:0.145.6) natty; urgency=low * debian/rules: - build with --skip-private, otherwise dh_python2 will generate a incorrect maintainer script for the auto-upgrade-tester package that contains a invalid version range string update-manager (1:0.145.5) natty; urgency=low [ Michael Vogt ] * DistUpgrade/DistUpgradeViewText.py: - start with gnu screen integration * DistUpgrade/DistUpgradeController.py: - when starting a additional sshd detect if there is a firewall running and if so print information that the additional sshd may need to be added to the firewall rules * UpdateManager/Core/utils.py: - add iptables_active() helper * merged lp:~brian-murray/update-manager/has-completed, many thanks This fixes issues with the English past tense * merged lp:~mvo/update-manager/use-screen-in-text-frontend, this will use screen in the text version of the release upgrader * Janitor/plugins/dpkg_status_plugin.py, DistUpgrade/DistUpgradeViewGtk.py: - fix python-apt 0.8 API * merged lp:~kelemeng/update-manager/bug633036 (LP: #633036), many thanks to Gabor Kelemen * debian/rules, debian/control: - use dh_python2 instead of python-central and drop it from the build-depends [ Colin Watson ] * DistUpgrade/*ReleaseAnnouncement: - Fix "Narwahl" typo (LP: #684050). update-manager (1:0.145.4) natty; urgency=low * DistUpgrade/*.ui: - updated window main heading for 11.04 * merged lp:~brian-murray/update-manager/upgrade-canceled-wording with wording and style fixes, many thanks! * DistUpgrade/DistUpgradeCache.py, UpdateManager/Core/utils.py: - check if running inside a chroot and if so, skip kernel selection * UpdateManager/Core/MetaRelease.py: - improve error checking and only present upgrade button if there is a working network - cleanup hardy code update-manager (1:0.145.3) natty; urgency=low * do-release-upgrade: - output if the current release is no longer supported (part of other-ps-n-testing-upgrades-for-preinstall-hw) * check-new-release-gtk: - show "dist-no-longer-supported" dialog if the current release is no longer supported - automatically "unignore" a previously ignored upgrade if the current release becomes EOL * AutoUpgradeTester/profile/*/DistUpgrade.cfg: - update to auto test maverick to natty * DistUpgrade/DistUpgrade.cfg: - update kernel removal for natty too update-manager (1:0.145.2) natty; urgency=low [ Barry Warsaw ] * Add required details to .emit() call. (LP: #631328) [ Michael Vogt ] * debian/control: - add or-dependency for python-aptdaemon-gtk and drop gksu dependency (its either brought in via synaptic or not needed) * UpdateManager/Core/utils.py: - add get_arch() call * DistUpgrade/DistUpgradeController.py, DistUpgrade/DistUpgradeQuirks.py: - use new utils.get_arch() call * merged fixes from lp:~ubuntu-core-dev/update-manager/maverick * debian/rules: - push EOLReleaseAnnouncement to the server too update-manager (1:0.145.1) natty; urgency=low [ Michael Vogt ] * DistUpgrade/EOLReleaseAnnouncement: - add information for the time when the release is EOL (part of the fix for #671016) * UpdateManager/UpdateManager.py: - fix typo in EOL text * DistUpgrade/DistUpgradeController.py: - properly log excepition in the child to the main.log, thanks to Jonathan Davies [ Barry Warsaw ] * In Python 2.7, locale.format() input test has gotten more strict. It does not allow trailing text after the format string. Change this to locale.format_string(). See Python issue 10379. (LP: #673297) update-manager (1:0.145) natty; urgency=low [ Michael Vogt ] * DistUpgrade/*: - updated for natty * tests/test_prerequists.py: - fix jaunty test now that this is moved to old-releases.ubuntu.com * pre-build.sh: - run testsuite on bzr-buildpackage * tests/test_dist_upgrade_fetcher_core.py: - fix test failures and ensure its python-apt 0.8 clean * po/update-manager.pot: - updated * DistUpgrade/DistUpgradeCache.py: - do not crash if no acquire progress is given * DistUpgrade/DistUpgradeController.py, DistUpgrade/DistUpgradeViewNonInteractive.py, UpdateManager/Core/DistUpgradeFetcherCore.py, tests/test_update_origin.py, tests/test_sources_list.py: - fixes in the python-apt 0.8 API * tests/*.py: - fix natty test failures [ Bilal Akhtar ] * UpdateManager/UpdateManager.py: - add more meaningful text if info is out-of-date (LP: #35009) update-manager (1:0.142.22) maverick-proposed; urgency=low [ Barry Warsaw ] * Add required details to .emit() call when running with synaptic as the backend (LP: #631328) [ Michael Vogt ] * DistUpgrade/DistUpgradeQuirks.py: - fixes in the cmov quirks handler (LP: #587186) (thanks to Jean-Baptiste Lallement) update-manager (1:0.142.21) maverick-proposed; urgency=low * DistUpgrade/DistUpgradeQuirks.py: - abort the upgrade if the user runs on a i586 or a i686 with no "cmov" support (LP: #587186) update-manager (1:0.142.20) maverick-proposed; urgency=low [ Michael Vogt ] * UpdateManager/UpdateManager.py: - do not crash if the free space check fails (LP: #656881) * DistUpgrade/DistUpgrade.cfg: - add blcr-dkms to the "BadVersions" variable. The current blcr-dkms source will not build with 2.6.35. Adding it here will cause the upgrade to abort with a message if it is installed. It also means that if support for 2.6.35 is added to blcr-dkms via a SRU that will automatically unblock the upgrade (LP: #555729) * DistUpgrade/DistUpgradeViewGtk.py, DistUpgrade/DistUpgradeViewKDE.py,: - workaround dpkg not sending the correct filename on conffile prompts over the status-fd (LP: #656912) [ Jonathan Riddell ] * DistUpgrade/DistUpgradeViewKDE.py: - disable confDialogue.show_difference_button, workaround for "distupgrade crashed during conf file change review" (LP: #656876) requires release note that user needs to view changes manually on command line update-manager (1:0.142.19) maverick; urgency=low * DistUpgrade/DistUpgradeQuirks.py: - only add extras.ubuntu.com for systems that have the matching keyring (LP: #653200). This ensures its not added on a server upgrade. update-manager (1:0.142.18) maverick; urgency=low [ Alessandro Ghersi ] * DistUpgrade/DistUpgrade.cfg: - make sure that kbluetooth gets removed on upgrade (LP: #653838) [ Jonathan Riddell ] * Add kubuntu-devel-release-upgrade to setup.py update-manager (1:0.142.17) maverick; urgency=low [ Jonathan Riddell] * Add kubuntu-devel-release-upgrade script to run the upgrade command for Kubuntu [ Michael Vogt ] * if foomatic-db-gutenprint needs to be removed during the upgrade because its not compatible with foomatic-db-compressed-ppds, try replacing it with ijsgutenprint-ppds which is the same content, just compressed in the same way like foomatic-db-compressed-ppds (LP: #647460) update-manager (1:0.142.16) maverick; urgency=low * DistUpgrade/ReleaseAnnouncement: - add link to http://www.ubuntu.com/desktop/features to tell users about the new features in this release * DistUpgrade/DistUpgrade.cfg: - help the upgrade by removing printconf, foomatic-db-gutenprint and ebox-printers as they are not compatible with foomatic-db-compressed-ppds (LP: #647460) update-manager (1:0.142.15) maverick; urgency=low * po/*.po: - updated from launchpad translations for the RC candidate * DistUpgrade/DevelReleaseAnnouncement: - updated for RC update-manager (1:0.142.14) maverick; urgency=low [ Michael Vogt ] * DistUpgrade/mirrors.cfg: - add extras.ubuntu.com to known mirrors * DistUpgrade/DistUpgradeQuirks.py: - add extras.ubuntu.com on upgrade * AutoUpgradeTester/jeos/create-base-image.sh: - add workaround for issue with python-vm-builder that generates random filenames in maverick [ Gabor Kelemen ] * Fix invocation of gksu, use the correct .desktop file. Fixes LP: #640906 * Correct misplaced parentheses, so that l10n of strings will work. Fixes LP: #640972 update-manager (1:0.142.13) maverick; urgency=low * DistUpgrade/DistUpgradeView.py: - only show demotions if we have at least one update-manager (1:0.142.12) maverick; urgency=low * DistUpgrade/DevelReleaseAnnouncement: - updated for beta update-manager (1:0.142.11) maverick; urgency=low * DistUpgrade/DistUpgradeController.py: - fix incorrect paramter passed to confirmChanges in doPostUpgrade (thanks to Jonathan Riddel, LP: #624599) update-manager (1:0.142.10) maverick; urgency=low * UpdateManager/UpdateManager.py: - when NM thinks we have no network, do not disable the install button because for dialup users NM is frequently wrong and does not get that there is a network-connection (LP: #624894) (thanks to Mohamed Amine IL Idrissi) update-manager (1:0.142.9) maverick; urgency=low [ Mohamed Amine IL Idrissi ] * UpdateManager/UpdateManager.py: Changed the whitespace place to not confuse translators, many thanks Milo Casagrande (LP: #621373) * DistUpgrade/DistUpgradeView.py: There won't be two spaces in FuzzyTimeToStr when days or hours are > 0 and hours or minutes are equal to 0 (LP: #288912) [ Michael Vogt ] * remove the seperate demotions dialog and move it into the "Confirm changes" step * use a treeview instead of a list to show the details of the changes in the gtk frontend * UpdateManager/UpdateManager.py, data/glade/UpdateManager.ui: - fix label wraping for label_downsize update-manager (1:0.142.8) maverick; urgency=low * UpdateManager/Core/utils.py: - fix typo (LP: #615923) * UpdateManager/UpdateManager.py: - when NM thinks we have no network, do not disable the buttons because for dialup users NM is frequently wrong and does not get that there is a network-connection (thanks to "gambs") update-manager (1:0.142.7) maverick; urgency=low [ Mohamed Amine IL Idrissi ] * Cache is no longer initialized when an operation is not authorized. LP: #394608 * List of updates is active when there are only kept packages. LP: #601127 (thanks, Nicolò Chieffo) [ Michael Vogt ] * merged lp:~simono/update-manager/fixes-bug-563640, many thanks (LP: #563640) * merged lp:~yofel/update-manager/lp601127 (LP: #601127) [ Jean-Baptiste Lallement ] * UpdateManager/Core/MyCache.py: - catch network error when fetching 3rd party changelogs (LP: #565896) [ Brian Murray ] * UpdateManager/UpdateManager.py: grammar fix update-manager (1:0.142.6) maverick; urgency=low [ Mohamed Amine IL Idrissi ] * Implemented battery and network alerts directly in the main window. LP: #484249, #426708, #426710, #494772 [ Michael Vogt ] * UpdateManager/Core/MyCache.py: - support looking for the changelog by source version (and add tests) * UpdateManager/Core/utils.py: - fix crash when reading the synaptic config (LP: #614170) update-manager (1:0.142.5) maverick; urgency=low * more python-apt 0.8 porting * less updates to the progressbar * DistUpgrade/DistUpgradeViewNonInteractive.py: - fix crash in non-interactive upgrader when a conffile prompt is detected update-manager (1:0.142.4) maverick; urgency=low * DistUpgrade/DistUpgradeView.py: - fix missing initializer (python0.8 api releated) LP: #604250 update-manager (1:0.142.3) maverick; urgency=low * merged lp:~and471/update-manager/fix-bug-386196, many thanks * DistUpgrade/DistUpgradeView*.py: - port progress to new python-apt 0.8 API * merged lp:~mdz/update-manager/small-fixes-20100707, many thanks * DistUpgrade/DistUpgradeViewGtk.py: - call progressbar.set_fraction() less often to avoid too much CPU consumption on certain graphic drivers * UpdateManager/GtkProgress.py: - limit the amount of set_fraction() here too (LP: #595845) * UpdateManager/UpdateManager.py: - disconnect the model before adding lots of new items, this speeds up the building of the view massively update-manager (1:0.142.2) maverick; urgency=low * DistUpgrade/DistUpgradeController.py: - use privileged port 1022 instead of 9004 when (optinally) starting a additional sshd * UpdateManager/UpdateManager.py: - fix crash with --no-focus-on-map * data/release-upgrades: - set release upgrade policy to "normal" for maverick (instead of lts) update-manager (1:0.142.1) maverick; urgency=low * UpdateManager/UpdateManager.py: - Show reboot required dialog inline instead of doing a popup dialog. When morphing windows land into maverick they can be used to make the inline information more pretty. But it should be better than the previous popup dialog update-manager (1:0.142) maverick; urgency=low [ Michael Vogt ] * check-new-release-gtk: - fix "ask me later" button time * DistUpgrade/DistUpgradeController.py, DistUpgrade/DistUpgradeCache.py, UpdateManager/Core/MetaRelease.py, UpdateManager/Core/utils.py, UpdateManager/Core/MyCache.py, UpdateManager/Core/UpdateList.py, UpdateManager/GtkProgress.py, UpdateManager/UpdateManager.py: - update for python-apt 0.8 API, add tests (LP: #591236) * check-new-release-gtk: - remove no longer needed warnings filter [ Brian Murray ] * string fix for 'is aborted now' to 'has aborted' * fix in debian/control update-manager (1:0.141) maverick; urgency=low * UpdateManager/backend/__init__.py: - switch to aptdaemon as install backend by default (unless the user has UPDATE_MANAGER_FORCE_BACKEND_SYNAPTIC in his environment) - merged lp:~glatzor/update-manager/ubuntu-glatzor (many thanks!) * DistUpgrade/DistUpgradeController.py: - use pockets from DistUpgrade.cfg instead of hard-coding them * tests/test_sources_list.py: - update tests * UpdateManager/Core/utils.py: - fix url_downloadable and add tests, based on the patch from Paulo Albuquerque, many thanks (LP: #396187) * UpdateManager/UpdateManager.py: - fix typo (thanks to seb128) * DistUpgrade/mirrors.cfg: - support upgrades when sources.list uses the new mirror://mirrors.ubuntu.com/mirrors.txt uri * UpdateManager/GtkProgress.py: - do not open a cache open progress window, instead show the progress inline in the window update-manager (1:0.140) maverick; urgency=low * DistUpgrade/removal_blacklist.cfg: - remove gobuntu-desktop from the removal blacklist * DistUpgrade/DistUpgradeController.py: - start apport only, do not modify any conffile (all versions of apport we upgrade from support this now) * UpdateManager/UpdateManager.py: - fix crash when format string has the wrong number of arguments (LP: #569469) - fix minor UI resize issue (LP: #572228) * DistUpgrade/DistUpgrade.cfg: - add ubuntu-netbook (LP: #574279) * UpdateManager/Core/MetaRelease.py: - add looking for a "UpgradeBroken" tag that contains a reason string if the user should not be allowed to perform a release upgrade * UpdateManager/UpdateManager.py, do-release-upgrade: - honor "UpgradeBroken" flag and error in this case * updated to support lucid to maverick upgrades update-manager (1:0.134.6) lucid; urgency=low * fix FTBFS caused by /usr/bin/check-new-release being a symlink instead of a real file update-manager (1:0.134.5) lucid; urgency=low * DistUpgrade/DistUpgradeAufs.py: - fix crash in aufs (--sandbox mode) update-manager (1:0.134.4) lucid; urgency=low * DistUpgrade/DistUpgrade.cfg, DistUpgrade/DistUpgrade.cfg.hardy: - do not enable apport anymore * DistUpgrade/DistUpgradeViewGtk.py: - set empty dialog titles for error/information dialogs (it looks like glade removed those for some reason from the .ui file) * DistUpgrade/DistUpgradeAufs.py: - fix crash if aufs (--sandbox mode) is used (LP: #562394) * DistUpgrade/DistUpgradeMain.py: - fix generation of system state file for non-existing dirs/files (LP: #561872) * UpdateManager/UpdateManager.py: - provide a LIST_TOGGLE_CHECKED column as a workaround for orca that does not work with values updated via column_install.set_cell_data_func (LP: #561563) * update-manager: - use gettext.install(unicode=True) to avoid breaking with optparse and ja.po (LP: #557804) update-manager (1:0.134.3) lucid; urgency=low * do-release-upgrade: - print when a new release is available in "-q" so that the motd is correct (thanks to Dustin Kirkland) * debian/release-upgrade-motd: - add newline after release info (thanks to Dustin Kirkland) update-manager (1:0.134.2) lucid; urgency=low * DistUpgrade/DistUpgradeMain.py: - ignore lspci errors * UpdateManager/Core/MyCache.py: - simplify url schema for third party changelogs (LP: #45129) * DistUpgrade/DistUpgradeCache.py: - check if the kernel returned from base-installer is downloadable (needed on hardy cdrom only upgrades) * debian/91-release-upgrade: - use a small script instead of a symlink to ensure that dpkg treats them as conffiles (LP: #559194) update-manager (1:0.134.1) lucid; urgency=low * DistUpgrade/DistUpgradeController.py: - honor "DEBIAN_FRONTEND=noninteractive" on pkg failure (LP: #538206) * DistUpgrade/DistUpgradeQuirks.py: - stop apparmor before dpkg starts on hardy -> lucid upgrades to avoid potentially confusing error messages during the upgrade (LP: #559433) * DistUpgrade/DistUpgradeCache.py, DistUpgrade/build-tarball.sh: - include obselte nvidia pkgnames to properly transition old to new drivers (LP: #553369) * DistUpgrade/DistUpgradeViewText.py: - show packages that will be removed (because they were auto installed) as well (LP: #558438) - fix i18n bug in details output * UpdateManager/Core/MyCache.py: - support third party changelogs by using ArchiveURI() and append a similar structure as changelogs.ubuntu.com uses (LP: #45129) * UpdateManager/Core/MetaRelease.py: - do not crash if meta-release file can not be parsed, just remove the broken file instead (LP: #558396) update-manager (1:0.134) lucid; urgency=low [ Barry Warsaw ] * Bump up the amount of /boot space calculated per kernel. The current value appears to undercount by about 260K/kernel. (LP: #132311) [ Michael Vogt ] * refresh translations from launchpad * update "10.04" strings to "10.04 LTS" and unfuzzy translations * when requesting the release announcement, append ?lang=current_lang to the request URI * update quirks for updates from hardy * DistUpgrade/DistUpgrade.cfg, DistUpgrade/DistUpgrade.cfg.hardy: - add extra protection against video driver removal (LP: #556629) * DistUpgrade/DistUpgradeMain.py: - improve logging and save system state before performing the upgrade. Suggested by Matt Zimmerman (LP: #551646) update-manager (1:0.133.11) lucid; urgency=low * UpdateManager/GtkProgress.py: - remove window title on cache progress (LP: #549936) * check-new-release-gtk: - if no ReleaseNotesHtml key is found, do nothing (it means the meta-release file does not support this client) * check-new-release-gtk, UpdateManager/Core/MetaRelease.py: - improve debugging * UpdateManager/Core/utils.py: - add META_RELEASE_FAKE_CODENAME environment that can be used to test/force release upgrades * check-new-release-gtk: - append language parameter to uri - support --debug update-manager (1:0.133.10) lucid; urgency=low * help upgrade by hinting usplash gets removed in favor of plymouth update-manager (1:0.133.9) lucid; urgency=low * DistUpgrade/DistUpgradeController.py, DistUpgrade/DistUpgradeCache.py: - do not warn about demoted packages that get removed later anyway * DistUpgrade/DistUpgrade.cfg, DistUpgrade/DistUpgrade.cfg.hardy: - remove deskbar-applet, and nautilus-cd-burner on ubuntu-desktop upgrade (as discussed with the desktop team) - remove notification-daemon in favor of notify-osd in xubuntu-desktop (LP: #546857) * DistUpgrade/DistUpgrade.cfg.hardy: - remove tracker on hardy ubuntu-desktop upgrade update-manager (1:0.133.8) lucid; urgency=low * DistUpgrade/sources.list.py, distro.py, distinfo.py: - temporarily stop embedding from the python-apt build host because of the python-apt api changes, use 0.7.13.5 version instead * debian/control: - point to lp:~ubuntu-core-dev/update-manager/lucid update-manager (1:0.133.7) lucid; urgency=low [ Nathan Stratton Treadway ] * data/release-upgrades - Provide better explanation of what how the various options in the configuration file control which upgrades are presented to the user. (LP: #522910) [ Barry Warsaw ] * README - Minor clean up. [ Michael Vogt ] * DistUpgrade/DistUpgradeCache.py: - check if the kernel returned from base-installer is upgradable (needed on hardy cdrom only upgrades) * check-new-release-gtk: - fix "ask me later" button time * DistUpgrade/DistUpgradeQuirks.py: - fix 386 kernel check/transition on upgrades from hardy - move kubuntu-kde4-desktop transition into its own function * check-new-release-gtk: - use GtkProgress when downloading the release upgrader [ Dustin Kirkland ] * debian/91-release-upgrade: do the release upgrade check with the quiet option to avoid putting debug messages in the MOTD, LP: #548376 update-manager (1:0.133.6) lucid; urgency=low * DistUpgrade/DistUpgradeView.py: - display the right number of packages that are going to be removed * DistUpgrade/cdromupgrade: - fix cddirname detection when called without a directory prefix * DistUpgrade/DistUpgradeViewGtk.py: - fix crash in webkit progress update-manager (1:0.133.5) lucid; urgency=low [ Markus Korn ] * UpdateManager/Core/utils.py: - Modified UpdateManager.Core.utils.on_battery() to use UPower per default (and DeviceKit.Power as fallback) to check if a system is running on battery (LP: #539211) [ Michael Vogt ] * DistUpgrade/DistUpgrade.cfg: - hint that libparted1.8-12 can be removed to help the upgrader logic' * DistUpgrade/DistUpgradeViewGtk.py: - only run JS progress if there is actually a webkit view * DistUpgrade/DevelReleaseAnnouncement: - fix text to say that its a BETA release (LP: #544544) * DistUpgrade/DistUpgradeViewGtk.py: - only run JS updateProgress script if we have a valid slideshow update-manager (1:0.133.4) lucid; urgency=low [ Michael Vogt ] * DistUpgrade/DistUpgradeController.py, DistUpgrade/DistUpgradeView.py: - detect pre-depends cycle and cleanly revert (LP: #516727) to the old system state * DistUpgrade/DistUpgradeCache.py: - only ensure translations are kept if they are still downloadable, there is a lot of churn in the translations area so its not feasible to keep them all - when checking the kernel list from base-installer, also consider kernels that are marked install (LP: #540114) - check rdepends of all packages (including auto-removal ones) again ensure the removal blacklist is honored in all cases (LP: #540823) * DistUpgrade/DistUpgradeController.py: - show progress information when searching for obsolete software (this can take a bit on a big install) * DistUpgrade/DistUpgradeViewNonInteractive.py: - fix crash in non-interactive mode (thanks to Andreas Hasenack) [ Colin Watson ] * Ship /var/lib/update-notifier directory in update-manager-core, so that it's always there for 91-release-upgrade (LP: #540159). update-manager (1:0.133.3) lucid; urgency=low * DistUpgrade/DistUpgrade.cfg, DistUpgrade/DistUpgrade.cfg.hardy: - do not allow upgrades to openoffice.org-filter-binfilter that causes pre-depends loop (LP: #516727) update-manager (1:0.133.2) lucid; urgency=low * DistUpgrade/DistUpgradeViewNonInteractive.py: - fix regression in conffile prompt handling (LP: #538206) - add default to the "NonInteractive", "DebugBrokenScripts" config option * DistUpgrade/DistUpgradeController.py: - honor "DEBIAN_FRONTEND=noninteractive" in recovery mode as well (LP: #538206) * DistUpgrade/DistUpgrade.cfg: - ensure that gtk-qt-engine is removed on upgrade (LP: #532968) update-manager (1:0.133.1) lucid; urgency=low [ Barry Warsaw ] * Fix obvious NameError by adding a missing import. (LP: #537250) [ David Planella ] * Made some strings translatable and extractable as a fix for LP: #537277 [ Michael Vogt ] * po/*.po: - updated from rosetta * DistUpgrade/DistUpgradeApport.py: - do not try to add directories under /var/log/dist-upgrade to a apport report (LP: #369951) [ Shlomi Loubaton ] * Set text direction for update treeview to be always LTR regardless of current language settings (LP: #316171) update-manager (1:0.133) lucid; urgency=low [ Michael Vogt ] * UpdateManager/Core/MetaRelease.py: - allow upgrade from unsupported version to unsupported version * DistUpgrade/removal_blacklist.cfg: - allow removal of update-manager-kde * check-new-release-gtk: - fixes in the gtk release upgrade check * DistUpgrade/xorg_fix_proprietary.py: - if /etc/X11/XF86Config-4 is found on upgrade, rename it to "XF86Config-4.obsolete" - write log to "/var/log/dist-upgrade/xorg_fixup.log" * do-release-upgrade, check-new-release: - implemented "check-releae-upgrade" as symlink to do-release-upgrade and automatically run with "--check-dist-upgrade-only" when called as c-r-u - add --quiet option to do-release-upgrade * debian/update-manager-core.links: - install /usr/lib/update-manager/check-new-release as symlink to do-release-upgrade -c [ Wesley Schwengle ] * Check for release upgrade is now also possible with do-release-upgrade command: do-release-upgrade -c. (LP: #415026) * Added --version/-V to do-release-upgrade (similar to update-manager) [ Dustin Kirkland ] * debian/91-release-upgrade, debian/update-manager-core.install, - some users are complaining of long login times due to the release check requiring network connectivity; this information clearly doesn't change as frequently as the user logging in, so maintain a cache file in /var/lib, display it if it's populated, but otherwise, update it in the background if its either missing or the file is older than a day old, LP: #522452 [ Jonathan Riddell ] * Do not allow for the removal of update-manager-kde, we do want it after all update-manager (1:0.132.1) lucid; urgency=low * rename update-manager-support-status to ubuntu-support-status * check-new-release-gtk: - add gtk tool for release notification that is designed to be run from update-notifier (desktop-lucid-update-upgrade-requirements) * DistUpgrade/DistUpgradeCache.py: - fix crash in cleanup code - fix crash when /home is missing (LP: #463506) - fix component inconsitency detection debug output * DistUpgrade/DistUpgradeViewGtk.py: - remove old code that moved to python-apt * DistUpgrade/DistUpgradeController.py: - if universe is not enabled, explain that the demoted packages will be suggested for removal in the cleanup stage * UpdateManager/Core/MetaRelease.py: - fix urlopen() crash on hardy->lucid cdrom upgrades update-manager (1:0.132) lucid; urgency=low [ Michael Vogt ] * UpdateManager/Core/MetaRelease.py: - add timeout to meta-release download * UpdateManager/MetaReleaseGObject.py: - make sure threading is enabled * DistUpgrade/DistUpgrade.cfg: - add kubuntu-netbook to known metapackages - remove usplash artwork from KeyDependencies * DistUpgrade/DistUpgradeController.py: - test for server mode again after the sources.list rewrite, to capture the case when the initial sources.list is empty * DistUpgrade/DistUpgradeCache.py: - when showing the demoted packages, skip packages that are automatic installed - improve performance on the removal checks by making use of the auto removable information more agressively - increase space required by the kernel (it grew) * DistUpgrade/DistUpgradeView.py, DistUpgrade/DistUpgradeView{Gtk,KDE}.py: - show only non auto-installed removals bold * update-manager-support-status: - add --show-supported, --show-unsupported and --show-all for summary - add --list option for full details [ Colin Watson ] * update-manager-support-status: - fix typo in get_maintenance_status (LP: #513303) - add support statistics to the output update-manager (1:0.131.4) lucid; urgency=low * update-manager-support-status: - text mode tool that gives a overview on the support status of the packages * DistUpgrade/DistUpgrade.ui, DistUpgrade/window_main.ui: - fix version number (thanks to davmor2) * DistUpgrade/DistUpgrade.cfg.hardy: - fix upgrade target to lucid (LP: #512608) update-manager (1:0.131.3) lucid; urgency=low * DistUpgrade/DistUpgradeController.py: - add missing check for ubuntu-security when testing for mirrors (thanks to Stuart Langridge) * DistUpgrade/DistUpgrade.cfg: - add example SlideshowUrl * DistUpgrade/DistUpgradeController.py, DistUpgrade/DistUpgradeView.py, DistUpgrade/DistUpgradeViewGtk.py: - add slideshow support based on webkit - call percent() JS method on the webkit view * check-new-release: - use exit codes if run with --quiet otherwise only print (LP: #494499) * DistUpgrade/DistUpgradeConfigParser.py: - fix crash in _interpolate (LP: #500705) * UpdateManager/Core/MetaRelease.py: - do not crash on stat failure (LP: #496144) * UpdateManager/Core/MyCache.py: - do not crash if the lock can not be released (LP: #410574) * UpdateManager/SafeGConfClient.py - implement gconfclient that does not crash if gconf is not working (LP: #261471) update-manager (1:0.131.2) lucid; urgency=low * data/release-upgrades: - default to lts->lts upgrade prompts for lucid * AutoUpgradeTester/UpgradeTestBackendQemu.py: - allow virtio for block devices when the virtio option is given in the config * DistUpgrade/DistUpgrade.cfg, DistUpgrade/DistUpgrade.cfg.hardy: - cleanup PostUpgradePurge and add "linux-restricted-modules-common" - cleanup ForcedObsoletes rules - update kernel removal rules and BaseNames - fix belocs-locales-bin upgrade issue (LP: #474543) * DistUpgrade/DistUpgradeController.py: - check forh reboot-required files in partial upgrade mode, update-notifier is no longer doing that by default (foundations-lucid-restart-required-dialog spec) * DistUpgrade/DistUpgrade.ui: - add a bunch of missing "<property name="orientation">" - improve restart-required dialog update-manager (1:0.131.1) lucid; urgency=low * DistUpgrade/DistUpgradeViewNonInteractive.py: - use getWithDefault() for "NonInteractive","ForceOverwrite" (thanks to Free Ekanayaka) * UpdateManager/Core/MyCache.py: - detect dirty dpkg journal and enter recovery mode in this case (thanks to Maco for reporting) * DistUpgrade/DistUpgrade.cfg: - remove kvm-source on upgrade * debian/update-manager-core.links: - use "91-release-upgrade" instead of "91-release_upgrade" to make run-parts happy * fix FTBFS update-manager (1:0.131) lucid; urgency=low * UpdateManager/UpdateManager.py: - do not crash if setlocale() fails (LP: #471378) * UpdateManager/Core/DistUpgradeFetcherCore.py: - add missing "logging" import (LP: #475941) * DistUpgrade/DistUpgradeController.py: - better message for upgrades over ssh (LP: #463257) * UpdateManager/Core/utils.py: - improve proxy check and show error if proxy settings look invalid (LP: #472168) * AutoUpgradeTester/profile/*/DistUpgrade.cfg: - updated to test karimic -> lucid and hardy -> lucid * Janitor/plugins/deb_plugin.py: - use apt.progress.InstallProgress() to keep the computer-janitor UI responsive * AutoUpgradeTester/install_blacklist.cfg: - add ec2 to the blacklist for the kvm based testing * UpdateManager/UpdateManager.py: - show selected and download size in two rows (LP: #434062) * data/do-release-upgrade.8: - man page added, thanks to Willem Bogaerts * DistUpgrade/DistUpgrade.cfg: - add laptop-mode-tools to the forced obsoletes on upgrade (thanks to Steve Langasek) * UpdateManager/UpdateManager.py: - show restart required dialog in u-m when the upgrade is finished with proper parent * AutoUpgradeTester/post_upgrade_tests: - add python import, xorg and kernel tests * UpdateManager/dialog_release_notes.ui: - merged lp:~freinhard/update-manager/ui-fix (many thanks) * UpdateManager/Core/MetaRelease.py: - merge lp:~cristiklein/update-manager/use-xdg (many thanks) update-manager (1:0.130) lucid; urgency=low * UpdateManager/UpdateManager.py: - set heading for the release-upgrader download window * DistUpgrade/DistUpgradeController.py: - force lts for lucid cdrom upgrades * AutoUpgradeTester/profile/: - fix missing BaseMetaPackages * AutoUpgradeTester/UpgradeTestBackendQemu.py: - fix AddRepo code * DistUpgrade/DistUpgradeConfigParser.py: - fix getWithDefault() to use the correct get{int,float,boolean} function based on the type of the default (LP: #465619) Thanks to Brian Murray for spotting this bug * DistUpgrade/DistUpgradeController.py: - fix typo (LP: #470011) * updated for karmic->lucid upgrades and hardy->lucid upgrades * UpdateManager/Core/utils.py:: - fix url_downloadable() when a proxy needs to be used (LP: #446552) update-manager (1:0.126.9) karmic-proposed; urgency=low * DistUpgrade/DistUpgrade.cfg: - really stop enabling apport during the upgrade (LP: #465619) update-manager (1:0.126.8) karmic-proposed; urgency=low * when the server is overloaded and no Release file information can be obtained, show a better error message instead of the bogus "ubuntu-minimal" is missing (LP: #446956) update-manager (1:0.126.7) karmic-proposed; urgency=low * po/*.po: - update translations from LP (LP: #460547) * UpdateManager/Core/DistUpgradeFetcherCore.py: - check if running on a system with noexec /tmp and give a propper error message (LP: #461744) * DistUpgrade/DistUpgradeViewGtk.py: - add missing locale.bindtextdomain() (LP: #460547) update-manager (1:0.126.6) karmic; urgency=low * debian/control: - updated to point the karmic branch * UpdateManager/GtkProgress.py: - fix small cosmetic problem with the release-upgrader download window size * DistUpgrade/xorg_fix_proprietary.py: - if xorg.conf is zero size, remove it (LP: # 439551) * change unicode "◦" to "*" to make translations work (LP: #344693) and unfuzzy translations update-manager (1:0.126.5) karmic; urgency=low * DistUpgrade/DistUpgradeQuirks.py: - generate note if language-support is incomplete * DistUpgrade/DistUpgrade.cfg: - stop enabled apport during the upgrade * DistUpgrade/DistUpgradeView.py - add waitChild implementation from python-apt to ensure its working for buggy hardy python-apt * DistUpgrade/DistUpgradeQuirks.py: - mark mysql-{client,server}-5.0 manual installed in the cluster check (LP: #453513) - check if running under a vserver setup and error if this is the case. upstart does not support this kind of setup (LP: #452011) * UpdateManager/Core/utils.py: - do not show error if DeviceKit.Power is not available (LP: #452004) update-manager (1:0.126.4) karmic; urgency=low * DistUpgrade/DistUpgradeController.py: - fix running under ssh detection * DistUpgrade/DistUpgradeQuirks.py: - add check if NBD clustering is in use in mysql server and do not upgrade to 5.1 is it is (LP: #450837) * DistUpgrade/DistUpgrade.cfg: - remove mysql-server rule, this is now done in the above quirks handler * DistUpgrade/DistUpgradeController.py: - do not do list cleanup so that cancel restores all of the previous state. the cleanup will be done later by the apt cron job update-manager (1:0.126.3) karmic; urgency=low * UpdateManager/UpdateManager.py: - refresh "last updated" text periodically to ensure its not stale (LP: #450286) * DistUpgrade/DistUpgradeViewGtk.py: - deal with io errors when writing the log (LP: #447693) * debian/control: - add or-dependency to qemu-kvm * DistUpgrade/DistUpgrade.cfg: - add policykit-gnome and gnome-mount to the forced obsoleted packages (thanks to seb128) * merge translations from rosetta * DistUpgrade/DistUpgradeQuirks.py: - stop docvert-converter when the upgrade starts, otherwise OOo will not upgrade at all (LP: #450569) * pre-build.sh: - fix bug in the demoted.cfg generation - fixes in cleanup handling * UpdateManager/backend/__init__.py: - honor UPDATE_MANAGER_FORCE_BACKEND_APTDAEMON environment * DistUpgrade/DistUpgrade.cfg.hardy: - updated to include demoted.cfg.hardy update-manager (1:0.126.2) karmic; urgency=low * setup.py: - fix FTBFS - the python from two days ago became stricter than it used to be (thanks to james_w) update-manager (1:0.126.1) karmic; urgency=low * DistUpgrade/DistUpgradeView.py: - log exceptions from pm.DoInstall() into main.log. this helps identifiying Dpkg::Pre-Invoke problems * DistUpgrade/DistUpgradeCache.py: - fix sandbox upgrade mode * DistUpgrade/DistUpgrade.cfg: - hint for mysql-server upgrade (LP: #413789) * UpdateManager/backend/__init__.py: - change order of backends to: synaptic, aptdaemon update-manager (1:0.126) karmic; urgency=low * DistUpgrade/DistUpgrade.cfg: - add gnome-app-install to the ForcedObsoletes * DistUpgrade/DistUpgrade.cfg.hardy: - add ability to upgrade from hardy to karmic (as asked for by Jonathan Riddell) * DistUpgrade/DistUpgradeQuirks.py: - add quirk handler to mark the dependencies of language-support-translations-* as manual on upgrade The language-support-translations- packages are removed in karmic and would otherwise be marked as auto-removable. (LP: #439296) - convert PASS value from 1 to 0 for ntfs entries in /etc/fstab (LP: #441242) and add tests for it - put 386 to generic transition code here and decouple from the kernel selection - inhibit gnome-screensaver once the upgrade started to avoid X crash (LP: #439594) * DistUpgrade/DistUpgradeCache.py: - workaround issues with kdesu when it drop the permission bits in a tmpdir (thanks to Jonathan Riddell) - fix base-installer kernel selection (LP: #441629) - fix log dir does not exist, create it (LP: #441959) * UpdateManager/backend/InstallBackendAptdaemon.py: - give up lock before running aptdaemon (LP: #445920) * po/ - updated from launchpad (required as during a release upgrade we can't use langpacks) update-manager (1:0.125.6) karmic; urgency=low * AutoUpgradeTester/UpgradeTestBackendSSH.py: - use ssh batch mode * AutoUpgradeTester/auto-upgrade-tester: - show log files * DistUpgrade/DevelReleaseAnnouncement: - update for BETA * DistUpgrade/DistUpgradeCache.py: - add new rule to ensure that base meta packages are always kept installed. this helps the server upgrade with the syslogd to rsyslog transition update-manager (1:0.125.5) karmic; urgency=low * DistUpgrade/DistUpgradeQuirks.py - fix kbluetooth name to kbluetooth4 update-manager (1:0.125.4) karmic; urgency=low * DistUpgrade/DistUpgradeQuirks.py: - fix brown paperbag bug in quirks hanlding (LP: #436302) * DistUpgrade/DistUpgradeViewGtk.py: - fix crash in gettext initialization (LP: #436438) update-manager (1:0.125.3) karmic; urgency=low * DistUpgrade/DistUpgrade.cfg.hardy: - fix upgrades from hardy by allowing the removal of sysvutils * data/glade/UpdateManager.ui: - remove dialog title for cache open progress (LP: #435653) * DistUpgrade/DistUpgradeQuirks.py: - add translators hints for some strings (LP: #433116) * UpdateManager/Core/DistUpgradeFetcherCore.py: - fixed typo (thanks to Henrique P. Machado) * UpdateManager/UpdateManager.py: - fix i18n issues with gtkbuilder * DistUpgrade/DistUpgradeQuirks.py: - stop kblueplugd kbluetooth when the upgrade starts to avoid them crashing during the upgrade (thanks to Jonathan Riddell) * UpdateManager/backend/InstallBackendAptdaemon.py - setup correct window icon * data/glade/UpdateManager.ui: - switch from unicode … to "..." until the issues with gettext is resolved (LP: #434107) update-manager (1:0.125.2) karmic; urgency=low [ Michael Vogt ] * DistUpgrade/DistUpgradeCache.py: - add check for 5Mb safety buffer in /tmp, this ensures that dkms can run and ensure we do not run when /tmp is mounted in overflow mode (LP: #427035) * data/glade/UpdateManager.ui: - remove dialog title for the battery warning and fix button order (thanks to Matthew Paul Thomas) * data/glade/UpdateManager.ui: - fix duplicated accelerator keys (LP: #425817) * UpdateManager/UpdateManager.py: - close app when ESC is pressed in the battery warning * UpdateManager/UpdateManager.py: - ensure that the changelog always matches the currently selected pkg by fixing race during download (LP: #424918) * UpdateManager/backend/InstallBackendAptdaemon.py: - do not hang when cancel is clicked (LP: #426718) * add sed patch facility and patch the gnome debconf frontend before the upgrade starts so that it can not crash when perl moves from 5.8.0 to 5.10.0 (LP: #387112) * data/glade/UpdateManager.ui: - use bigger default width (LP: #418201) [ Brian Murray ] * typo fixes (thanks to Brian Murray, LP: #423409) update-manager (1:0.125.1) karmic; urgency=low [ Josh Holland ] * Fixed several typos (LP: #93804, LP: #277731, LP: #404435) [ Rugby471 ] * Center window on the screen (LP: #423355) [ Michael Vogt ] * DistUpgrade/DistUpgrade.ui: - remove unused "destroy_event" handler (LP: #428842) - remove unused handlers to avoid RunTime warning * DistUpgrade/DistUpgradeQuirks.py: - make ARMv6 error message clearer (LP: #409523) * UpdateManager/Core/MetaRelease.py: - more robustness for invalid configuration of the meta-release file (LP: #428558) - more robustness if the server sends invalid meta-release data * UpdateManager/GtkProgress.py: - make button_cancel click event work - add sensible default width * DistUpgrade/DistUpgradeCache.py: - fix crash in partial upgrade (LP: #428203) update-manager (1:0.125) karmic; urgency=low [ Michael Vogt ] * integrate base-installer as a sub-component into the release upgrader and use the base-installer/kernel/*.sh functionality to ensure we select the most appropriate kernel on upgrade (LP: #353534) * integrate automatic updates to base-installer into the pre-build.sh bzr hook * UpdateManager/Core/UpdateList.py, UpdateManager/UpdateManager.py: - filter warnings * UpdateManager/SimpleGtkbuilderApp.py: - use logging instead of sys.stderr * data/glade/UpdateManager.ui: - set explicit translation domain * integrate base-installer component into auto-upgrade-tester [ Steve Langasek ] * Refresh .pot file (and .po files) so that new UI strings are available for translation in LP. LP: #425014. update-manager (1:0.124.11) karmic; urgency=low * DistUpgrade/DistUpgradeView.py: - capture exceptions from pm.DoInstall() properly (fixes a hang when a package fails to install) * DistUpgrade/DistUpgradeViewGtk.py, DistUpgrade/DistUpgradeViewKDE.py: - return the full status of the exited child, not only the return code update-manager (1:0.124.10) karmic; urgency=low * DistUpgrade/removal_blacklist.cfg: - add update-manager so that it does not * typo fixes (thanks to Brian Murray, LP: #418127) * merge the changes of seb128 into bzr * po/POTFILES.in: - fix ui file detection (thanks to Gabor Kelemen) LP: #420209 * DistUpgrade/DistUpgrade.ui: - fix duplicated id (LP: #422665) * fix crash when lsmod is not installed update-manager (1:0.124.9ubuntu1) karmic; urgency=low * Clean build directory update-manager (1:0.124.9) karmic; urgency=low * data/glade/UpdateManager.ui: - don't use some duplicated ids to fix update-manager not starting due to the new gtk version update-manager (1:0.124.8) karmic; urgency=low * make the release-upgrader auto selection for the frontend more robust when no DISPLAY is avaiable * Janitor/computerjanitor/package_cruft.py: - use unicode string here (thanks to liw) * data/glade/UpdateManager.ui: - fix duplicated symbol (LP: #417301) * UpdateManager/UpdateManager.py: - show the on-battery warning on first map only (LP: #416067) * DistUpgrade/DistUpgradeController.py: - do not how a error when the upgrade is canceled by the user during download update-manager (1:0.124.7) karmic; urgency=low * UpdateManager/UpdateManager.py: - recalulcate the heading label size dynamically to work around bugzilla #101968 (thanks to Juergen Kazmirzak for the patch) * UpdateManager/backend/__init__.py: - fix incomplete check for aptdaemon * UpdateManager/backend/InstallBackendAptdaemon.py: - update for latest aptdaemon * DistUpgrade/DistUpgradeController.py: - merge fixes from Brian Murray (thanks!), LP: #404274 update-manager (1:0.124.6) karmic; urgency=low [ Oliver Grawert ] * DistUpgrade/DistUpgradeQuirks.py: add check for ARMv6 or greater to prevent jaunty->karmic upgrades on unsupported armel CPU arches [ Michael Vogt ] * UpdateManager/SimpleGtkbuilderApp.py: - updated to deal with widgets that overwrite get_name * update-manager: - add "--data-dir" switch * use aptdaemon as the install backend (if avaialble) update-manager (1:0.124.5) karmic; urgency=low * debian/update-manager-core.links: change the update-motd link for release_upgrade to match other links (- instead of _), and move it to 91 (just after updates-available at 90), such that it's printed toward the end of the MOTD, rather than at 10, which is the beginning. update-manager (1:0.124.4) karmic; urgency=low * debian/control: recommend libpam-modules, rather than update-motd update-manager (1:0.124.3) karmic; urgency=low [ Michael Vogt ] * UpdateManager/UpdateManager.py: - fix description display (LP: #379945), thanks to Richard Thomas - fix crash in refresh_updates_count() * DistUpgrade/DistUpgradeApport.py: - deal with errors from apport better (LP: #357339), thanks to Patrick Horn) * UpdateManager/ChangelogViewer.py: - fix problem for http://host/document.html. style entries (LP: #396393) [ Dustin Kirkland ] * debian/update-manager-core.links: install 10_release_upgrade into /etc/update-motd.d, rather than the daily; update-motd-3.0 will now run these scripts on login, rather than at specified intervals update-manager (1:0.124.2) karmic; urgency=low * UpdateManager/UpdateManager.py: - make it clearer if a package is a new install (as opposed to a upgrade) - thanks to Cody Sommerville - show amount of selected updates in the UI (LP: #330439) update-manager (1:0.124.1) karmic; urgency=low * fix ftbfs update-manager (1:0.124) karmic; urgency=low * AutoUpgradeTester: - add kubuntu, main-all, lts-server, lts-ubuntu profiles * ported to gtkbuilder * UpdateManager/UpdateManager.py: - warn if running on battery (LP: #377697) - make it less stealty by setting the stick() property if run in auto-open mode (LP: #369820) update-manager (1:0.123) karmic; urgency=low * debian/control: - build auto-upgrade-tester package to allow easy upgrade testing with a set of default profiles * UpdateManager/Core/MyCache.py: - wording fix (thanks to Ng) * DistUpgrade/DistUpgradeViewNonInteractive.py: - fix bug in dpkg_progress_log filea * AutoUpgradeTester/UpgradeTestBackend.py: - import the http_proxy from the environment - make the resultdir configrable and default to /var/cache/auto-upgrade-tester/result/ * AutoUpgradeTester/UpgradeTestBackendQemu.py: - make the path for the kvm working images configurable and default to /var/cache/auto-upgrade-tester * AutoUpgradeTester/auto-upgrade-tester: - move login() into the backends * AutoUpgradeTester/auto-upgrade-tester: - allow shorthand profile names like "ubuntu" instead of full pathes update-manager (1:0.122) karmic; urgency=low * DistUpgrade/DistUpgradeQuirks.py: - add handler to check for wl module and transition to bcmwl-kernel-source (LP: #381684) * DistUpgrade/DistUpgradeViewNonInteractive.py: - add bool option "NonInteractive/DpkgProgressLog" to write a timing log of the upgrade (for the foundations-karmic-pre-unpacking spec) - add "NonInteractive/DebugBrokenScripts" option that will re-run failed maintainer scripts with debug options * DistUpgrade/DistUpgrade.cfg: - add defaults for the NonInteractive section that match the interactive upgrades (for better landscape support) - enable apport again * AutoUpgradeTester/chart_dpkg_progress.py: - add simple tool that can read the dpkg progress information update-manager (1:0.121) karmic; urgency=low * DistUpgrade/DistUpgrade.cfg: - remove obsolete kubuntu-kde4-desktop meta package * DistUpgrade/DistUpgradeCache.py: - when guessing missing meta-packages stop after the first one was found - use internal _lookupPkgRecord() instead of pkg._lookupRecord * DistUpgrade/DistUpgradeQuirks.py: - move the kubuntu-kde4-desktop key dependency transition detection to the from_hardy quirks handler (LP: #368459) * UpdateManager/Core/MyCache.py: - always disable version number range of the changes in the details (LP: #251349) - make the distro supporting the changelogs easier to customize * DistUpgrade/xorg_fix_proprietary.py: - better comment when explaining why stuff got commented out (LP: #300504) * DistUpgrade/DistUpgradeController.py: - after updating the sources.list, check for both existance and downloadability of the BaseMetaPkgs and abort if that is not the case (thanks to Ulrich Kalkkuhl) LP: #370062 * UpdateManager/UpdateManager.py: - show origin field for other updates (like PPAs) to make it easier to see what comes from where (part of the foundations-karmic-apturl-policy spec) update-manager (1:0.120) karmic; urgency=low * The 'Ready for karmic' version * DistUpgrade/DistUpgradeController.py: - do not fail in partial upgrades if apport must be enabled (LP: #357755) - when rewriting sources.list, check for cdrom entries that do not have associated list files and disable them (LP: #366459) - when rewriting sources.list, deal better with apt-cacher apt-torrent style uris (LP: #365537) * DistUpgrade/xorg_fix_proprietary.py: - instead of replacing fglrx->ati and nvidia->nv just comment out the driver and let xorg figure it out with its own magic (LP: #351394) - update tests/ for the change * UpdateManager/UpdateManager.py: - use a gtk link button to point the user to further upgrade information * DistUpgrade/DistUpgradeController.py: - ensure ./imported/invoke-rc.d is executable (LP: #147742) * refactor the quirks handlers and not run them in partial upgrade mode * tests/test_sources_list.py: - update tests for apt-torrent style uris (LP: #365537) * DistUpgrade/DistUpgrade.cfg: - remove edubuntu-desktop from the flavour metapackages, its not its own flavour anymore * help/C/update-manager-C.omf: - point to file:/usr/share/gnome/help/update-manager/C/update-manager.xml (LP: #368140) update-manager (1:0.111.9) jaunty-proposed; urgency=low * DistUpgrade/DistUpgradeCache.py: - increase the size that the kernel requires in /boot (LP: #365623) * DistUpgrade/DistUpgradeApport.py: - fix apport hook integration (LP: #366048) * DistUpgrade/DistUpgradeController.py: - fix crash in partial upgrade (LP: #366048) * DistUpgrade/DistUpgradeQuirks.py: - make the gwenview upgrade transition more robust (LP: #365840) update-manager (1:0.111.8) jaunty-proposed; urgency=low * DistUpgrade/DistUpgrade.cfg: - add "grub" to the list of packages to keep installed (LP: #363465) - ensure brasero is upgraded (thanks to Chris Jones for the report) (LP: #364136) - ensure guidance-power-manager is removed on upgrade (LP: #364620) * DistUpgrade/DistUpgradeCache.py: - support DistUpgradeCache.markUpgrade() * DistUpgrade/mirrors.cfg: - add "mirror.files.bigpond.com" (thanks to wgrant) * debian/control: - build-depend on latest nvidia-common (LP: #363500) to ensure the nvidia-common if is included in the internal copy of u-m * DistUpgrade/DistUpgradeQuirks.py: - when the upgrade starts, remove old hal.postinst to prevent the trigger from running that causes network-manager to shutdown all connections (LP: #327053) * UpdateManager/Core/MetaRelease.py, UpdateManager/MetaReleaseGObject.py: - fix "no longer supported" message (LP: #364583) update-manager (1:0.111.7) jaunty; urgency=low * DistUpgrade/ReleaseAnnouncement: - updated for the final release * DistUpgrade/DistUpgradeQuirks.py: - ensure qwenview is upgraded (LP: #360222) update-manager (1:0.111.6) jaunty; urgency=low * UpdateManager/UpdateManager.py: - fix crash in free space check (LP: #362066) update-manager (1:0.111.5) jaunty; urgency=low * DistUpgrade/DistUpgradeQuirks.py: - do not crash when patch is not installed (LP: #361194) * DistUpgrade/DistUpgradeCache.py: - more debug output update-manager (1:0.111.4) jaunty; urgency=low * DistUpgrade/DistUpgradeViewKDE.py: - make the pyqt4 logger less verbose * DistUpgrade/DistUpgradeController.py: - deal with pre-configure errors more cleanly (LP: #356781) * DistUpgrade/DistUpgradeMain.py: - fix error when the backup log dir already exists * DistUpgrade/DistUpgrade.cfg: - stop enabling apport * DistUpgrade/DevelReleaseAnnouncement: - update text for the release candidate * po/*.po: - translation updates from rosetta update-manager (1:0.111.3) jaunty; urgency=low * DistUpgrade/DistUpgradeQuirks.py: - cleanup the quirks handling for the StartUgrade phase and move the code in here - apply patch for install-docs if the user can not install the fix from {hardy,intrepid}-proposed update-manager (1:0.111.2) jaunty; urgency=low * UpdateManager/Core/MyCache.py: - when calculating what category a update should be put in, make sure that candidate versions for "other updates" always end up there - do not try to get changelogs for packages that do not have a ubuntu origin (LP: #354740) * DistUpgrade/removal_blacklist.cfg: - add skype to the removal blacklist (thanks to Nick Lally) update-manager (1:0.111.1) jaunty; urgency=low * DistUpgrade/DistUpgrade.cfg: - ensure that dontzap is installed on kubuntu (LP: #349263) - ensure to not upgrade to a known broken python2.6 (e.g. if the mirrors do not catch up) * DistUpgrade/DistUpgradeController.py: - avoid conffile prompt because we enabled apport (LP: #348301) - deal better with apt ordering bugs and restore the system cleanly in this case - when commenting out third party sources, leave a space between previous comments (thanks to Sidnei da Silva) * DistUpgrade/DistUpgradeCache.py: - add "BadVersions" config option * UpdateManager/Core/MetaRelease.py: - ignore bad header line errors (LP: #353335) * UpdateManager/UpdateManager.py: - start minimized when run with --no-focus-on-map (LP: #353195) - set urgency hint when in the background (LP: #353195) * po/*.po: - updated translations from rosetta update-manager (1:0.111.0) jaunty; urgency=low * DistUpgrade/DistUpgradeQuirks.py: - fix pre r6xx/7xx fglrx->ati transition * DistUpgrade/DistUpgradeQuirks.py: - fix incorrect variable name * DistUpgrade/DistUpgradeView.py: - remove old crash files on upgrade (thanks to Martin Pitt) update-manager (1:0.110.1) jaunty; urgency=low * DistUpgrade/DistUpgrade.cfg.hardy: - support hardy->jaunty upgrade for kubuntu * po/POTFILES.{in,missing}: - add missing files (thanks to Gabor Kelemen) LP: #347040 * po/*.po: - updated translations from launchpad update-manager (1:0.110.0) jaunty; urgency=low * DistUpgrade/DistUpgradeCache.py: - take changes in update-initramfs into account when calculating the space requirements in /boot (LP: #287826) - when doing the space calculation, show the required space for each directory (if multiple need more space) LP: #219416 * DistUpgrade/DevelReleaseAnnouncement: - updated for beta * UpdateManager/DistUpgradeFetcher.py: - set 5s timeout for the ReleaseNotes fetching (LP: #109397) * UpdateManager/UpdateManager.py: - pass the correct FetchProgress to the release-upgrade fetching code instead of the incorrect OpProgress update-manager (1:0.101.1) jaunty; urgency=low [ Michael Vogt ] * DistUpgrade/DistUpgradeCache.py: - catch cache.update() errors that do not raise exceptions * DistUpgrade/DistUpgradeController.py: - when calculating the obsolete packages, add extra paranoia for odd network failures (LP: #335154) * DistUpgrade/DistUpgradeAufs.py: - do not overlay /var/cache/apt/archives so that the user does not have to download the packages twice - honor the TMPDIR environment (by using tempfile) * DistUpgrade/DistUpgrade.cfg: - add powernowd to the forced obsoleted packages (the kernel does handle that with the builin ondemand governor now) [ Jonathan Riddell ] * DistUpgrade/DistUpgrade.cfg: - remove gtk-qt-engine in Kubuntu upgrades update-manager (1:0.101.0) jaunty; urgency=low [ Brian Murray ] * UpdateManagerHildon/UpdateManagerHildon.py: - wording fix "will be" to "are being" (LP: #338943) [ Michael Vogt ] * UpdateManager/UpdateManagerText.py: - fix crash in changelog display (LP: #341577) (thanks to Steve Beattie) - support NEWS.Debian from the server as well * DistUpgrade/DistUpgradeAufs.py: - fix in is_submount detection (thanks to liw for reporting) [ Gabor Kelemen ] * data/glade/UpdateManager.glade: - fix missing "translatable" property (LP: #342011) update-manager (1:0.100.1) jaunty; urgency=low * DistUpgrade/DistUpgradeCache.py: - fix crash (LP: #340828) when config is undefinied * UpdateManager/UpdateManager.py: - explicitely cast time.time() to int (LP: #340755) update-manager (1:0.100) jaunty; urgency=low [ Andy Whitcroft ] * DistUpgrade/cdromupgrade: - if cdromupgrade is run with a relative path we will fail to find the installer components and error out. Ensure that the path is absolute. (LP: #335360) [ Michael Vogt ] * fix crash when help is not avaialble (LP: #338098) * data/glade/UpdateManager.glade: - remove the "Keep your system up-to-date" text (design team, LP: #336800) * fix crash when no network is avaialble for changelog fetching (LP: #334002) * debian/control: - add conflict against update-manager-kde to update-manager-hildon (LP: #333464) * UpdateManager/Core/MyCache.py: - show proper urls for sources with epochs (LP: #328164), thanks to Richie * UpdateManager/ChangelogViewer.py: - support copy to clipboard for URLs (LP: #85644), thanks to Richie * UpdateManager/UpdateManager.py: - disable fixed-hight mode, it can cause incorrect height calculation (thanks to Richie), LP: #273184 * DistUpgrade/DistUpgradeController.py: - do not allow gtk/kde upgrades over ssh session (LP: #322482) * merged aufs branch (disabled by default but useful for testing) update-manager (1:0.99) jaunty; urgency=low [ Michael Vogt ] * DistUpgrade/DistUpgradeController.py: - enable apport crash capturing during upgrades * DistUpgrade/DistUpgradeView.py: - create /var/lib/pycentral/pkgremove before the upgrade to help pycentral transition to the new python policy (thanks to doko) * ensure pidgin-libnotify is upgraded (LP: #332328) * better wording for aborts (thanks to Gabor Kelemen and Jean-Baptiste Lallement), LP: #289303 * wording fixes, thanks to Brian Murray and Gabor Kelemen LP: #269583 * i18n fix, thanks to Gabor Kelemen, LP: #331821 * support /etc/update-manager/release-upgrades.d/ directory for local overrides of the upgrade process. Useful to force certain site-specific options (like third party repository handling) * allow "[FreeSpace]\nSkipCheck=yes" override to skip free space checks (useful for testing) * support "[Sources"]\nAllowThirdParty=yes" override to skip commenting out of unknown repositories (LP: #147080) * debian/*.install: - updated for the new python layout (/u/l/p/dist-packages instead of /u/l/p/site-packages) * debian/rules: - use DH_PYCENTRAL=include-links instead of "nomove" - use "--install-layout=deb" in distutils * debian/control: - use "XS-Python-Version: all" instead of current * DistUpgrade/DistUpgradeCache.py: - fix modalias path in NvidiaDetector * data/glade/UpdateManager.glade: - add "settings" button * UpdateManager/UpdateManager.py: - open software-properties when settings button is clicked (LP: #334959) - keep track of launch times via gconf (/apps/update-manager/launch_time) * debian/control: - recommend software-properties-gtk [ Brian Murray ] * DistUpgrade/multiple files: - fixed typographical error * DistUpgrade/DistUpgradeViewText.py: - change "Restart required" default to N (LP: #328452) update-manager (1:0.98.1) jaunty; urgency=low * reenable the demotions.cfg generation and mirror updates * setup.py cleanup (thanks to liw) update-manager (1:0.98) jaunty; urgency=low [ Michael Vogt ] * DistUpgrade/DistUpgradeController.py: - fixes in the error string (thanks to Jean-Baptiste Lallement, LP: #298296) * support getting NEWS.Debian information in addition to the changelog * debian/update-manager-core.links: - fix typo (thanks to tjaalton) * merge the 'computer-janitor' core and quirks code into update-manager-core (part of the jaunty-cruftremover-improvements spec) * conflicts with the current version of computer-janitor [ Brian Murray ] * DistUpgrade - Release Announcements: - Modified reporting bugs sections to recommend using ubuntu-bug instead of filing bugs directly in Launchpad. (LP: #327800) update-manager (1:0.97.1) jaunty; urgency=low [ Michael Vogt ] * UpdateManager/UpdateManager.py: - make the gconf handling more robust (LP: #320586) * UpdateManager/Core/MyCache.py: - fix crash when no changelog can be found (LP: #320894) * UpdateManager/Core/MetaRelease.py: - do not crash on disk full (LP: #321872) * DistUpgrade/DistUpgradeController.py: - when commenting out third party repositories add a comment why they were disabled and update them to the current dist to make re-enabling easier * DistUpgrade/DistUpgradeQuirks.py: - run dpkg --forget-old-unvail after the upgrade finished - add "PostCleanup" hook * DistUpgrade/cdromupgrade: - fixed typo (LP: #312184) * add "--no-focus-on-map option to bring update-manager up in the background (UX team) * change default text and add /apps/update-manager/first_run gconf key for the first run welcome message (UX team) * UpdateManager/ChangelogViewer.py: - support "LP: #nr:" linking in changelog entries (LP: #274737) [ Jonathan Riddell ] * DistUpgrade/DistUpgrade.cfg - remove guidance-power-manager on kubuntu-desktop upgrade [ Andy Whitcroft ] * DistUpgrade/cdromupgrade - move to using dists/$CODENAME to locate the installer eliminating any dependance on symlinks in the image. This allows usb-creator based images to be used unmodified. (LP: #326856) update-manager (1:0.97) jaunty; urgency=low * UpdateManager/Core/MetaRelease.py: - remove debug message (LP: #310046) * UpdateManager/Common/utils.py: - when initializing the proxy configuration, do in this order: * check apt setting * check synaptic setting * check users gconf * check http_proxy environment (LP: #24250) * UpdateManager/Core/DistUpgradeFetcherCore.py: - ensure correct error message if downloading failed (LP: #113658) - when fetching from mirrors, add fallback if the mirror is too loaded to cope - improve logic that detects what mirror is in use by sources.list inspection (LP: #107983) * DistUpgrade/DistUpgradeMain.py, dist-upgrade.py: - re-factor and make code more modular - do not overwrite existing log files on upgrade (LP: #111819) * reorganize the imports and get rid of "Common" submodule and merge that all into "Core" * improve the debug output via the "DEBUG_UPDATE_MANAGER" environment update-manager (1:0.96.4) jaunty; urgency=low * DistUpgrade/DistUpgradeController.py: - do not generate apport report against update-manager if cache.commit() failed. the report is generated against the failing package instead (LP: #311220) - honor RELEASE_UPRADER_ALLOW_THIRD_PARTY environment and do not comment out third party repositories in this case (useful internal repositories, make sure that sudo does not clean this env when you make use of it) * DistUpgrade/DistUpgrade.cfg: - remove powermanagement-interface on upgrades for ubuntu and kubuntu (no longer needed by them) * DistUpgrade/DevelReleaseAnnouncement: - include a different release announcement for the development releases * pre-build.sh: - fix version parsing update-manager (1:0.96.3) jaunty; urgency=low * DistUpgrade/DistUpgradeController.py: - when syncing inconsitent components, only sync those we know about (LP: #312092) * tests/test_sources_list.py: - add regression test for #312092 update-manager (1:0.96.2) jaunty; urgency=low * AutoUpgradeTester/UpgradeTestBackendQemu.py: - add "NonInteractive","NoVirtio" switch - enable virtio in the kvm backend by default * AutoUpgradeTester/profile/server/DistUpgrade.cfg: - updated for intrepid->jaunty - add missing kernel removal section * DistUpgrade/DistUpgrade.cfg: - update KernelRemoval section for intrepid->jaunty * DistUpgrade/DistUpgradeApport.py, README: - add new RELEASE_UPRADER_NO_APPORT environement that can be used to force the upgrader to not run apport on pkg failures * DistUpgrade/DistUpgradeViewNonInteractive.py: - use RELEASE_UPRADER_NO_APPORT in the non-interactive upgrade tests * AutoUpgradeTester/profile/ubuntu/DistUpgrade.cfg: - updated for intrepid->jaunty * DistUpgrade/DistUpgrade.cfg: - enable DistUpgrade/xorg_fix_proprietary.py to transition users from proprietary drivers to free drivers if the proprietary driver is no longer available after the upgrade update-manager (1:0.96.1) jaunty; urgency=low * DistUpgrade/DistUpgradeController.py: - deal better with upgrades from EOL releases by testing if the new release is on the country mirror or archive.ubuntu.com or still on old-releases.ubuntu.com (LP: #264181) * debian/control: - disable the auto-upgrader-tester package, its not quite ready yet update-manager (1:0.96) jaunty; urgency=low * UpdateManager/Core/MetaRelease.py: - deal with full disks better when downloading the meta-release information (LP: #98666) * DistUpgrade/DistUpgradeView.py: - make the FuzzyTimeToStr() function not display minutes when the total time is > 3h (LP: #144455) * build update-manager-text package with text/newt based update-manager frontend (update-manager-text) * DistUpgrade/DistUpgradeQuirks.py: - check if both grub and lilo are installed and remove the one that is not used (LP: #314004) * po/POTFILES.in, po/POTFILES.skip: - updated * po/update-manager.pot: - refreshed update-manager (1:0.95.2) jaunty; urgency=low * DistUpgrade/DistUpgradeQuirks.py: - check the support of fglrx against the current PCI card (LP: #284408) * DistUpgrade/xorg_fix_intrepid.py: - do not rewrite multiseat configs (LP: #292774) * UpdateManager/Common/MyCache.py, UpdateManager/Common/UpdateList.py: - move the cache,updatelist implementation out into its own file * fix free space check on regular update-manager invocations (LP: #105113) * debian/rules - remove the arch-build target * DistUpgrade/DistUpgradeController.py: - improvements to the sources.list rewriting, better tests - when rewriting sources.list check for inconsistencies between what components are enabled in intrepid vs intrepid-updates and intrepid-security and automatically enable missing ones for intrepid-updates and intrepid-security - new test if the upgrade is run from a remote login (LP: #301787) update-manager (1:0.95.1) jaunty; urgency=low * DistUpgrade/DistUpgrade.glade, DistUpgrade/window_main.ui: - show 9.04 upgrade target * debian/rules: - calculate demotions based on intrepid->jaunty * DistUpgrade/DistUpgradeCache.py: - when the dist-upgrade calculation fails, show the reason why in the error dialog (LP: #281286) - when a meta package can not be upgraded, show a proper error message with the package in question * DistUpgrade/DistUpgradeQuirks.py: - abort upgrade from hardy if evms is used in /proc/mounts evms got removed from the archive in intrepid (LP: #292179) - do not add "relatime" if "noatime" is already given (thanks to Ken Geis) * DistUpgrade/removal_blacklist.cfg: - remove overly broad postgresql regexp * DistUpgrade/DistUpgradeCache.py: - do not limit the removal blacklist to downloadable packages, this limits it too much * check-new-release: - install check for new releases into update-motd.d/daily update-manager (1:0.95) jaunty; urgency=low * updated for jaunty update-manager (1:0.93.34) intrepid-proposed; urgency=low * UpdateManager/UpdateManager.py: - simply the changelog download logic and make changelog fetching work properly again (now that the server side got improved as well) LP: #40058 update-manager (1:0.93.33) intrepid; urgency=low [ Michael Vogt ] * DistUpgrade/DistUpgradeQuirks.py: - add detection for cards no longer supported via fglrx and ensure transition to "ati" (LP: #284408) * DistUpgrade/DistUpgradeCache.py: - check if the package is actually downloadable in the removal blacklist checking (LP: #293486) [ Jonathan Riddell ] * DistUpgrade/DistUpgradeViewKDE.py: - handle translations of non-ascii string on Cancel button correctly (LP: #291115) update-manager (1:0.93.32) intrepid; urgency=low * DistUpgrade/DistUpgradeQuirks.py: - when transitioning from kubuntu-kde4-desktop to kubuntu-desktop consider key dependencies as well even if kubuntu-kde4-desktop is no longer installed (LP: #277285) update-manager (1:0.93.31) intrepid; urgency=low * DistUpgrade/DistUpgrade.cfg: - remove goubuntu-desktop from metapackages, we do no longer build it (LP: #283712) * DistUpgrade/DistUpgradeCache.py: - never remove packages in the "KeepInstalled" section - keep the GUI alive when calculating the packages to cleanup * DistUpgrade/DistUpgradeQuirks.py: - mark "language-pack-$lang" as manual installed to workaround changes in "language-support-$lang" (LP: #287551) * po/: - updated to the latest translations.launchpad.net version update-manager (1:0.93.30) intrepid; urgency=low * DistUpgrade/DistUpgradeViewText.py: - ignore "default" argument handling in askYesNoQuestion to fix incorrect prompt for cdrom question * DistUpgrade/DistUpgradeQuirks.py: - ensure "landscape-common" is not marked auto-install (LP: #288051) * DistUpgrade/ReleaseAnnouncement: - updated for final release * DistUpgrade/DistUpgradeAptCdrom.py: - ignore "dist-upgrader" dirs when scanning for packages (LP: #288169) update-manager (1:0.93.29) intrepid; urgency=low * fix incorrect case and typo in cpuHasSSESupport(), thanks to Steve Langasek update-manager (1:0.93.28) intrepid; urgency=low * DistUpgrade/DistUpgradeQuirks.py: - do not install nvidia-glx-{173,177} on systems without the "sse" cpu extension (LP: #272498) - fix case-sensitive parsing when checking for the xorg driver * DistUpgrade/DistUpgrade.cfg: - make sure that libflashsupport gets removed on upgrade (LP: #285657) * DistUpgrade/ReleaseAnnouncement: - updated for the release candidate update-manager (1:0.93.27) intrepid; urgency=low * DistUpgrade/xorg_fix_intrepid.py: - only update the InputDevices if xserver-xorg-core actually is version 2:1.5.0 or higher - make section checks case-insensitive (thanks to Alberto Milone) * DistUpgrade/DistUpgrade.glade: - remove has_focus default in the conffiel dialog update-manager (1:0.93.26) intrepid; urgency=low * DistUpgrade/DistUpgradeController.py: - workaround kde tmpfile permissions (LP: #277431) * UpdateManager/Common/utils.py: - do not crash if gconfd is not availabe/unusable (LP: #281248) * DistUpgrade/DistUpgradeViewKDE.py: - do not use "kde" frontend during the upgrade, it crashes because of the kde3->kde4 transition if run at the wrong time (LP: #283942) * DistUpgrade/DistUpgradeView.py: - ignore SIGPIPE when forking the Dpkg::Pre-Install scripts to fix error with etckeeper (LP: #283642) * po/ - updated from rosetta update-manager (1:0.93.25) intrepid; urgency=low [ Jonathan Riddell ] * DistUpgrade/DistUpgradeQuirks.py: - Fix crash from not having gettext imported [ Michael Vogt ] * revert the fglrx->ati transition (LP: #247376) update-manager (1:0.93.24) intrepid; urgency=low * DistUpgrade/DistUpgradeController.py: - disable the apt.cron.daily script during the upgrade (LP: #277079) * DistUpgrade/DistUpgradeAptCdrom.py: - work around the problem that the hardy "apt-cdrom add" will fail when no uncompressed Packages files are on the CD (LP: 276349) update-manager (1:0.93.23) intrepid; urgency=low * DistUpgrade/xorg_fix_intrepid.py: - comment out input devices from xorg.conf (handled via hal now). Thanks to Alberto Milone for his help, LP: #247608 update-manager (1:0.93.22) intrepid; urgency=low * DistUpgrade/DistUpgradeQuirks.py: - add rule to force kdelibs5-dev upgrade (LP: #279621), thanks to ScottK * DistUpgrade/DistUpgradeViewGtk.py: - do not hang if a script fails to run (LP: #280236) * DistUpgrade/DistUpgradeController.py: - do not run post-upgrade quirks handler in partial upgrade mode because they only apply to real release upgrades update-manager (1:0.93.21) intrepid; urgency=low * Add useDevelopmentRelease and useProposed to DistUpgradeFetcherKDE.py * Fix call to error() in DistUpgradeFetcherCore.py update-manager (1:0.93.20) intrepid; urgency=low * DistUpgrade/DistUpgradeGettext.py: - translated the empty "" into "" (the qt frontend may call this on empty strings in translate_widget) * DistUpgrade/DistUpgradeQuirks.py: - make sure to write a final newline in /etc/fstab when adding the relatime option (LP: #279093) update-manager (1:0.93.19) intrepid; urgency=low * UpdateManager/Core/MetaRelease.py: - fix crash in CDROM upgrade (LP: #276363) * DistUpgrade/DistUpgradeQuirks.py: - fix crash in nvidia handling (thanks to Spencer Janssen) update-manager (1:0.93.18) intrepid; urgency=low * DistUpgrade/DistUpgrade.cfg: - add KeepInstalled rule for adept to help the dependency resolver (thanks to MvG) - add kubuntu-kde4-desktop metapackage so that the meta package detection works for kde4 (LP: #274706) * DistUpgrade/DistUpgradeCache.py: - fix log for kept packages - make the log of the obsolete removal less verbose - fix kubuntu-kde4-desktop upgrades (LP: #274706) * DistUpgrade/ReleaseAnnouncement: - udpated for BETA * DistUpgrade/DistUpgradeViewGtk.py: - fix typo and unfuzzy translations. Thanks to Brian Murray for the patch, LP: #272726) * UpdateManager/UpdateManager.py: - add gconf key /apps/update-manager/show_versions to show version information (disabled by default, LP: #189406) * DistUpgrade/DistUpgradeQuirks.py: - add intrepidPreUpgrade() handler that detects fglrx in xorg.conf and warns about it before the upgrade - consolidate the various quirks into this file - add check for the nvidia-glx-71 and nvidia-glx-96 drivers and warn if they will be required * DistUpgrade/xorg_fix_intrepid.py: - add script that is run after the upgrade that ensures that the xorg.conf file gets transitioned to a free driver if the proprietary one does not work for intrepid - transition from fglrx and nvidia-glx-{71,96} to the free driver (LP: #274303) update-manager (1:0.93.17) intrepid; urgency=low [ Michael Vogt ] * UpdateManager/UpdateManager.py: - fix typo (thanks to "Richie", LP: #271139) * DistUpgrade/DistUpgradeCache.py: - remove the landscape-client stub package on desktop upgrades [ Jonathan Riddell ] * DistUpgrade/DistUpgradeViewKDE.py fix crash when translating dialogue update-manager (1:0.93.16) intrepid; urgency=low [ Michael Vogt ] * DistUpgrade/DistUpgradeController.py: - automatically add "relatime" to the mount options of ext2/ext3 * UpdateManager/Core/MetaRelease.py: - fix typo (thanks to Daniel Garcia) * DistUpgrade/DistUpgradeCache.py: - fix the removal of obsolete kernel packages when the old kernel abi package gets removed from -update and/or -security * UpdateManager/UpdateManager.py: - be more robust against server errors when fetching the changelogs (LP: #262982) * debian/control: - update the version dependency for python-apt, we need stuff from 0.7.5 (LP: #257781) * DistUpgrade/DistUpgradeView.py:# - make FuzzyTimeToStr() properly deal with plural forms (LP: #267234) [ Brian Murray ] * UpdateManager/UpdateManager.py: - preserve epoch in package version for changelogs at launchpad.net (LP: #270527) update-manager (1:0.93.15) intrepid; urgency=low * UpdateManager/Core/DistUpgradeFetcherCore.py: - fix incorrect import update-manager (1:0.93.14) intrepid; urgency=low * po/*.po: - updated to the latest launchpad translations * DistUpgrade/DistUpgradeGettext.py: - add more robust version of gettext() that does not crash if incorrect number arguments is passed (LP: #269379) update-manager (1:0.93.13) intrepid; urgency=low * DistUpgrade/DistUpgrade.cfg: - better KeyDependencies for ubuntu-desktop to make the detection more robust update-manager (1:0.93.12) intrepid; urgency=low * DistUpgrade: load DistUpgradeViewKDE not KDE4 * DistUpgradeViewKDE: Fix various translations * DistUpgradeViewKDE: Add window icon update-manager (1:0.93.11) intrepid; urgency=low [ Jonathan Riddell ] * DistUpgradeViewKDE: don't use setHeaderHidden, doesn't exist in Qt 4.3 * DistUpgradeViewKDE: Disable terminal button until terminal exists [ Michael Vogt ] * rename DistUpgradeViewKDE4.py to DistUpgradeViewKDE.py because adept runs this frontend explicitely (instead of letting dist-upgrade.py decide) update-manager (1:0.93.10) intrepid; urgency=low [ Jonathan Riddell ] * Add missing debian/update-manager-kde.install [ Michael Vogt ] * transition landscape.canonical.com to the main repository (LP: #268551) update-manager (1:0.93.9) intrepid; urgency=low * do not build depend on nvidia-common for lpia update-manager (1:0.93.8) intrepid; urgency=low [ Michael Vogt ] * DistUpgrade/DistUpgradeCache.py: - transition "kubuntu-desktop-kde4" to "kubuntu-desktop" (thanks to Jonathan Riddell) * DistUpgrade/DistUpgradeCache.py, DistUpgrade/DistUpgradeController.py: - fixes in the "AllowUnauthenticated" code (thanks to Adam Conrad) * debian/update-manager-hildon.install: - install only selected bits from Comon/ [ Emmet Hikory ] * Removed check to set automatic notifications in update-manager-hildon update-manager (1:0.93.7) intrepid; urgency=low * Move Common/utils.py to update-manager-core * Fix build when rebuilding with -nc * UpdateManager/DistUpgradeFetcherKDE.py shouldn't import ReleaseNotesViewer * DistUpgrade/cdromupgrade should be intrepid update-manager (1:0.93.6) intrepid; urgency=low * Make DistUpgradeFetcherKDE.py work as a module not just a standalone script update-manager (1:0.93.5) intrepid; urgency=low [ Michael Vogt ] * DistUpgrade/DistUpgradeCache.py: - install new recommends on the hardy->intrepid upgrade (unless overwriten with the RELEASE_UPGRADE_NO_RECOMMENDS environment) * AutoUpgradeTester/UpgradeTestBackendQemu.py: - run ssh in the auto tester with "-t" * UpdateManager/UpdateManager.py: - fix plural forms (thanks to Bruce Cowan, LP: #189921) * DistUpgrade/DistUpgradeViewGtk.py: - show kB/sec (LP: #257778) [ Jonathan Riddell ] * Add KDE upgrade checking tools for use by Adept update-manager (1:0.93.4) intrepid; urgency=low * DistUpgrade/removal_blacklist.cfg: - add openssh-blacklist-extra and openssh-extra * UpdateManager/UpdateManager.py: - do not crash if lsb_release can not be run (LP: #255319) * DistUpgrade/DistUpgradeApport.py: - do not generate apport reports against a package if the error indicates that its a full disk, this is a bug in update-manager than (failed to do the full disk checking) * DistUpgrade/DistUpgrade.cfg: - force obsoletion of cups-pdf on ubuntu-desktop, kubuntu-desktop and xubuntu-desktop * DistUpgrade/DistUpgradeController.py: - increase KERNEL_INITRD_SIZE a bit update-manager (1:0.93.3) intrepid; urgency=low * fix ftbfs on powerpc update-manager (1:0.93.2) intrepid; urgency=low * DistUpgrade/DistUpgradeCache.py: - work around problem with packages with no priority (LP: #253255) * DistUpgrade/DistUpgradeViewGtk.py: - detect ctrl-c presses in the terminal and warn the user that it will kill the upgrade (LP: #90866) * DistUpgrade/DistUpgrade.cfg: - when being run by the sandbox-upgrader, do not reboot automatically after the upgrade finished * DistUpgrade/DistUpgradeController.py: - when a upgrade is cancelt due to network errors, inform that the downloaded files will be kept (LP: #242111) update-manager (1:0.93.1) intrepid; urgency=low * UpdateManager/UpdateManager.py: - make the init_proxy stuff look for the apt.conf proxy as well (thanks to vega--) * do-release-upgrade: - unify proxy configuration between gtk and cli UI * fix FBTFS by removing the kdepyuic calls during build (no longer needed in qt4) update-manager (1:0.93) intrepid; urgency=low [ Michael Vogt ] * UpdateManager/UpdateManager.py: - fix typo (LP: #252195) * DistUpgrade/DistUpgradeController.py: - fix crash in cleanup code [ Jonathan Riddell ] * port the kde frontend to qt4 update-manager (1:0.92) intrepid; urgency=low * DistUpgrade/DistUpgradeCache.py: - use nvidia-common to detect what driver package is needed and install it if the user had a previous nvidia driver (thanks to Alberto Milone) * improvements to the NonInteractive frontend update-manager (1:0.91.10) intrepid; urgency=low * UpdateManager/Core/DistUpgradeFetcherCore.py: - improved error handling for people who run /tmp with noexec (LP: #219518) * DistUpgrade/ReleaseAnnouncement: - fixes in the announcement text (thanks to Brian Murray, LP: #250693) * DistUpgrade/removal_blacklist.cfg: - remove nvidia-glx from the removal blacklist, the naming schema changed in intrepid and the old packages need to go way (LP: #249329) update-manager (1:0.91.9) intrepid; urgency=low * UpdateManager/Core/MetaRelease.py: - make the default meta-release location easily changable via /etc/update-manager/meta-release * data/meta-release: - make the default configuration easier configurable * data/release-upgrades: - default to "normal" upgrades for intrepid update-manager (1:0.91.8) intrepid; urgency=low * data/glade/UpdateManager.glade: - make the shortcut key in the auto-updates dialog consistent with the main one (LP: 246321) * DistUpgrade/ReleaseAnnouncement: - updated for intrepid (LP: #246538) update-manager (1:0.91.7) intrepid; urgency=low * DistUpgrade/DistUpgradeController.py: - add logging for kept packages - make the "use-network" question on cdrom upgrades more clear (LP: #229508) - do not just exit on upgrades with errors but show a proper finished message * DistUpgrade/DistUpgradeApport.py: - only run apport-{gtk,qt} if DISPLAY is set * DistUpgrade/DistUpgradeView{Gtk,KDE}.py: - do not show a error dialog for folloup errors from earlier errors (thanks to Alexander Sack for the report) update-manager (1:0.91.6) intrepid; urgency=low * Make "--mode={server,desktop}" obsolete by adding automatic detection for this. This eliminates the bugreports where people run the text do-release-upgrade client that defaults to server mode * UpdateManager/UpdateManager.py: - improve the changelog version number scanner - if no information is available yet, display a launchpad link for interested people (not fetching from there automatically to not hammer LP too much) update-manager (1:0.91.5) intrepid; urgency=low * DistUpgrade/DistUpgradeController.py: - support "old-releases.ubuntu.com" as a valid mirror and auto transition from that to the regular archive (LP: #235527) - add extra paraonoia when adding a missing admin group (thanks to LaMont Jones) LP: #241723 * UpdateManager/ChangelogViewer.py: - support "exo-open" (xfce) too (LP: #240473) * DistUpgrade/mirrors.cfg: - remove ftp.caliu.info (LP: #231966) * DistUpgrade/DistUpgradeController.py: - fix typo and unfuzzy translations (LP: #220505) * UpdateManager/UpdateManager.py, data/update-manager.schemas.in: - provide a gconf key /apps/update-manager/autoclose_install_window to make it possible to prevent automatic closing of the installation window (LP: #183209) * DistUpgrade/DistUpgrade.cfg.dapper: - remove ports.ubuntu.com from powerpc, it is not available on ports.ubuntu.com but on archive.ubuntu.com (LP: #241729) update-manager (1:0.91.4) intrepid; urgency=low * update-manager: - string fixes (LP: #230865) * UpdateManager/UpdateManager.py: - support selecting/dselecting entire update categories by double clicking on the list header update-manager (1:0.91.3) intrepid; urgency=low * DistUpgrade/mirrors.cfg: - remove ftp.caliu.info (LP: #231966) * UpdateManager/UpdateManager.py, data/update-manager.schemas.in: - provide a gconf key /apps/update-manager/autoclose_install_window to make it possible to prevent automatic closing of the installation window (LP: #183209) update-manager (1:0.91.2) intrepid; urgency=low [ Brian Murray ] * String fix for "a unresolvable problem" (LP: #196269) * String fix for "A upgrade to" (LP: #196229) * String fix for "is in a inconsistent state" (LP: #197015) update-manager (1:0.91.1) intrepid; urgency=low * debian/control: - add missing python-vte dependency to update-manager-hildon update-manager (1:0.91) intrepid; urgency=low * DistUpgrade/DistUpgradeCache.py: - fix bug in withNetwork value propergation (LP: #227197) * DistUpgrade/DistUpgradeController.py: - fix bug with sources.list rewriting when mixed deb http://unknown-miror\ndeb-src http://known-mirror entries are used (#221730) * UpdateManager/Common/utils.py: - fix inhibit path (LP: #140754), thanks to Andreas Dalsgaard * DistUpgrade/DistUpgradeViewText.py: - use sensible-pager first and fallback to "more" if that is not available (thanks to Mithrandir) * DistUpgradeView{Gtk,KDE,Text}.py: - only overwrite the DEBIAN_FRONTEND if it is not set already (thanks to Guy Sheffer) * UpdateManagerHildon/UpdateManagerHildon.py: - add hildon support (thanks to Tollef Fog Heen and Emmet Hikory) update-manager (1:0.90.0) intrepid; urgency=low * merged branches: - ~alefteris/update-manager/alefteris (thanks!) * UpdateManager/Core/DistUpgradeFetcherCore.py: - do not crash if the tarfile can not be read (LP: #203504) * fix a bunch of spelling mistakes (LP: #213040), thanks to Peter Cordes * AutoUpgradeTester/automatic-upgrade-testing: - add "--additional-pkgs" argument that can be used to install the given packages (seperated with ",") into the VM before the upgrade is performed * DistUpgrade/DistUpgradeConfigParser.py: - write error to log in getListFromFile() if file is not found * DistUpgrade/DistUpgradeCache.py: - fix plural form text (LP: #226695) * update-manager-core.install, update-manager.install: - move the DistUpgrade part into update-manager-core * DistUpgrade/DistUpgradeController.py, update-manager, dist-upgrade.py: - move partialUpgrade() functionality into the controller and expose it with --partial in dist-upgrade.py * DistUpgrade/DistUpgrade.cfg: - prepare for hardy->intrepid upgrades update-manager (1:0.87.27) hardy-proposed; urgency=low * DistUpgrade/DistUpgradeCache.py: - make networkless upgrades more robust (LP: #227197) * po/ko.po: - fix translation for y/n prompt so that korean users can actually continue (LP: #223419) * DistUpgrade/DistUpgradeViewGtk.py: - work around hang in svg loader (LP: #186465) update-manager (1:0.87.26) hardy-proposed; urgency=low * DistUpgrade/DistUpgradeController.py: - run in server mode on a server CD (LP: #222895) - deal with the landscape.canonical.com repository (LP: #224308) * DistUpgrade/DistUpradeCache.py: - make the code more robust against unavailable package records (LP: #223619) * DistUpgrade/cdromupgrade: - allow passing of arguments (like --mode=server) to better support server upgrades with the dvd (LP: #222895) * po/uk.po: - fix translation so that it gets the expected number of arguments (LP: #224294) update-manager (1:0.87.25) hardy-proposed; urgency=low * DistUpgrade/DistUpgradeApport.py: - fix typo in log dir (LP: #223743) * DistUpgrade/DistUpgradeController.py: - if the "Crux" theme is used on dapper during the upgrade, switch to "Human" because Crux is known to crash (LP: #69124) * DistUpgrade/DistUpgradeCache.py: - do not crash if a meta package is not available in the cache (e.g. xubuntu-desktop that moved from main to universe) * DistUpgrade/DistUpgrade.cfg.dapper: - fix incorrect xubuntu-desktop detection * DistUpgrade/DistUpgradeView.py: - make sure that self.confirmChangesMessage is always initialized (LP: #221023) * DistUpgrade/mirrors.cfg: - added missing russion mirror (LP: #221730) - fixed incorrect mirror lines * DistUpgrade/DistUpgrade.cfg: - better detection to missing dependencies to fix ubuntustudio-desktop upgrade problem (LP: #219659) * util/demotions.py: - do not consider powerpc anymore, its not available on archive.ubuntu.com anymore * debian/rules: - do not run tests in arch-build target (only useful when there is a development release available to upgrade to) update-manager (1:0.87.24) hardy; urgency=low * DistUpgrade/ReleaseAnnouncement: - modified https url to http so it is clickable (LP: #220386) * po/en_GB.po: - unfuzzy typo correction update-manager (1:0.87.23) hardy; urgency=low * DistUpgrade/DistUpgrade.cfg.dapper: - Add 'bash' to BaseMetaPkgs. This is needed because ubuntu-meta was uploaded into dapper-updates and that means that we the detection of a missing main archive in sources.list will not work correctly (LP: #220078) * DistUpgrade/ReleaseAnnouncement: - updated in preparation for the final release update-manager (1:0.87.22) hardy; urgency=low * UpdateManager/UpdateManager.py: - only set http proxy if hostname/port is valid (LP: #219227) * DistUpgrade/DistUpgradeController.py: - some more debug logging - fix missing cache open - smaller default network time out - run the initial cache.update() on the unmodified sources.list with only a single retry because it may contain sources that do not respond update-manager (1:0.87.21) hardy; urgency=low * DistUpgrade/DistUpgradeController.py: - transition sparc users to ports.ubuntu.com on upgrade * DistUpgrade/DistUpgrade.cfg.dapper: - point to ports.ubuntu.com when fetching release-upgrader-{apt,dpkg} on dapper->hardy upgrades update-manager (1:0.87.20) hardy; urgency=low * DistUpgrade/DistUpgradeView.py: - fix incorrect _() call (thanks to Timo Jyrinki) * DistUpgrade/mirrors.cfg: - fix ports.ubuntu.com mirror URI (LP: #215346) * run dpkg with --force-overwrite by default on the server too to make the upgrade more robust. this can be overwriten with the RELEASE_UPGRADE_NO_FORCE_OVERWRITE environment update-manager (1:0.87.19) hardy; urgency=low * DistUpgrade/DistUpgradeCache.py: - only try to upgrade held-back packages in the edgyQuirks handler if they are actually upgradable (thanks to Lamont Jones and James Troup) * po/fi.po - unfuzzy string (thanks to Timo Jyrinki) update-manager (1:0.87.18) hardy; urgency=low * DistUpgrade/DistUpgradeCache.py: - remove mail-notificaton, gnome-translate from hardy quirks list (LP: #215690) * UpdateManager/DistUpgradeFetcher.py: - use sensible gksu prompt when asking for release upgrade (LP: #161888) update-manager (1:0.87.17) hardy; urgency=low * DistUpgrade/DistUpgradeController.py: - when run from a CDROM upgrade on dapper, ensure to fetch the right files on tryUpdateSelf() (#215673) - ensure that language-support-$lang packages get upgraded if they are installed * UpdateManager/Core/MetaRelease.py: - support forceLTS option (#215673) * DistUpgrade/DistUpgradeView.py: - work around gutsy->hardy nvidia-glx uprade problem when libqt-perl is used (#205079) * DistUpgrade/ReleaseAnnouncement: - updated for RC update-manager (1:0.87.16) hardy; urgency=low * DistUpgrade/DistUpgradeViewText.py: - show prompt again after showing details - use pager for long change entries (thanks to James Troup) - fix text wrap to not break lines on "-" (e.g. in package names) * DistUpgradeController.py: - do not leave 20archive.save files around - make the code that asks about starting a new ssh daemon (if run under ssh) more robust - set status to "Calculating changes" again after displaying demoted packages - improve logging if prerequisites download fails * DistUpgrade/DistUpgradeCache.py: - improve the evms detection/removal (thanks to Lamont Jones) * DistUpgrade/DistUpgrade.cfg.dapper: - add "lvm2" to the KeepInstalledPkgs (LP: #211488) - sync RemoveObsoletes, ForcedObsoletes, KeepInstalledSections with DistUpgrade.cfg - text wrap questions too * po/*.po: - updated translations (LP: #210699) update-manager (1:0.87.15) hardy; urgency=low * DistUpgrade/DistUpgradeCache.py: - fix fd leak * DistUpgrade/DistUpgradeController.py: - abort when debsig-verify is installed, it makes any upgrade fail (LP: #208957) - run migrate-fstab-to-uuid.sh as PostInstallScript (LP: #209347) - set RELEASE_UPGRADE_MODE={server,desktop} environment * DistUpgrade/DistUpgradeViewKDE.py: - fix crash/race in terminal key press handler (LP: #205445) - fix encoding issue (LP: #208390) - call it 8.04 LTS (LP: #204659) * DistUpgrade/DistUpgradeViewGtk.py: - fix incorrect pango attribute assignment (LP: #207742) - call it 8.04 LTS (LP: #204659) * UpdateManager/UpdateManager.py: - do not crash if gconf database is not writable (LP: #208687) - do not crash on BadStatusLine exceptions (LP: #204075) * po/*.po: - make update-po update-manager (1:0.87.14) hardy; urgency=low * DistUpgrade/ReleaseAnnouncement: - Fix typo * DistUpgrade/DistUpgradeViewKDE.py: - Add show/hide to upgrade package list * DistUpgrade/window_main.ui: - Sync strings with GTK frontend to pick up translations - Update icon to Oxygen update-manager (1:0.87.13) hardy; urgency=low * DistUpgrade/DistUpgradeController.py: - only ask once about the sshd (LP: #156625) * DistUpgrade/DistUpgradeCache.py: - add hardyQuirks handler to deal with a gnome-translate upgrade issues (thanks to Daniel Holbach) - fix naming of the quirksHandlers * DistUpgrade/DistUpgrade.cfg: - add "ksplash-engine-moodin" to ForcedObsoletes * DistUpgrade/removal_blacklist.cfg: - add "^postgresql-.*"to the removal blacklist * DistUpgrade/DistUpgradeViewText.py: - flush() output in updateStatus() - show the demoted packages in a more readable manner - use textwrap when displaying text * DistUpgrade/DistUpgradeCache.py: - fix bug that prevented proper error message on upgrade calculation error in the text frontend - fix text download progress * DistUpgrade/ReleaseAnnouncement - updated for BETA update-manager (1:0.87.12) hardy; urgency=low * DistUpgrade/DistUpgradeViewKDE.py: - fix display of non-ascii chars - improve editing capabilities of the terminal (should be fine with the readline fontend now) update-manager (1:0.87.11) hardy; urgency=low * DistUpgrade/DistUpgradeControler.py: - when upgrading without network and with a empty sources.list, do not ask to add network sources * DistUpgrade/DistUpgradeCache.py: - do not crash if lookupRecords() failed (LP: #199482) * UpdateManager/UpdateManager.py: - use absolute path when calling gksu (LP: #194166), Thanks to Mihai Varzaru and James Westby * data/update-manager.desktop.in: - improve consistency with the rest of gnome (LP: #150205) * DistUpgrade/DistUpgradeViewKDE.py: - do no longer use konsole during upgrades but use a dumb terminal instead that only supports basic editing - log terminal activity to /var/log/dist-upgrade/term.log update-manager (1:0.87.10) hardy; urgency=low * remove code duplication in the confirmChanges() code and make the warning more readable (LP: #188724) * DistUpgrade/DistUpgradeController.py: - when adding prerequists, ensure that no duplicated lines are added, plus add test for this (thanks to Kolbjørn Barmen) - honor APT::Get::AllowUnauthenticated (thanks to Kolbjørn Barmen) * DistUpgrade/cdromupgrade: - updated to hardy - fix bug in path handling (LP: #155833) * DistUpgrade/prerequists-sources.list: - remove cruft update-manager (1:0.87.9) hardy; urgency=low * rebuild due to python-central issues update-manager (1:0.87.8) hardy; urgency=low * deal with packages in broken reqreinst state by offering to remove them (LP: #1922578) * UpdateManager/UpdateManager.py: - display a meaningful message when no information of the last update can be found (LP: 192328) update-manager (1:0.87.7) hardy; urgency=low [ Michael Vogt ] * UpdateManager/Core/MetaRelease.py: - honor DEBUG_UPDATE_MANAGER environment and give some debug output on the meta-release fetching/parsing * UpdateManager/DistUpgradeFetcher.py: - cancel if the ReleaseNotes window is closed via the window close control (thanks to Matthew Paul Thomas) * DistUpgrade/DistUpgradeViewGtk.py: - show update details in smaller font instead of italic * more UI improvements as suggested by Matthew Paul Thomas * DistUpgrade/DistUpgradeControler.py: - enforce KeepInstalledSection rule only when running on a network, otherwise we run into CD upgrade issues - when fetching the prerequists, be more robust in the mirror selection (and add tests for this) * DistUpgrade/DistUpgrade.cfg: - add slocate to the force obsoletes, mlocate replaces it [ Brian Murray ] * Dialog enhancements and typo fixes (LP: 182055) update-manager (1:0.87.6) hardy; urgency=low * DistUpgrade/DistUpgradeCache.py: - fix removal of obsolete packages (regression from 0.87.5) update-manager (1:0.87.5) hardy; urgency=low * UpdateManager/UpdateManager.py: - use /var/lib/apt/periodic/update-success-stamp for the calculation when the last update was performed (LP: #185894) * DistUpgrade/DistUpgradeController.py: - if the upgrade can not be calculated in partial upgrade mode, do not recommend reporting a bug (most likely transient anyway) * DistUpgradeView/DistUpgradeViewText.py: - make the restart required question more clear (LP: #155554) * UpdateManager/Core/DistUpgradeFetcherCore.py: - tidy up output when show authentication message * data/update-manager.8: - man page fixes (LP: #185615) * update-manager: - run gtk.init_check() to catch errors when DISPLAY is not set (pygtk does not do that automatically) update-manager (1:0.87.4) hardy; urgency=low * UpdateManager/UpdateManager.py: - run the partial upgrader with error correction if the dependencies on the system are not ok (it will fix most problems) * DistUpgrade/DistUpgradeController.py, DistUpgradeCache.py: - if dpkg was interrupted, run "dpkg --configure -a" automatically - if the prerequists can not be authenticated, * DistUpgradeView/DistUpgradeView.py: - when calculating the download time in estimatedDownloadTime, use the average download speed so far (if available) update-manager (1:0.87.3) hardy; urgency=low * add ports.ubuntu.com to the valid mirrors (LP: #184663) * add --proposed to the options for do-release-upgrade (LP: #109290) * fix crash in apport report duplicate checking update-manager (1:0.87.2) hardy; urgency=low * DistUpgrade/DistUpgradeApport.py: - better detection for followup errors when a package failed earlier * DistUpgrade/DistUpgradeController.py: - Be more tolerant against errors in the initial apt-get update operation. We disable third party sources on the later sources.list rewrite anyway update-manager (1:0.87.1) hardy; urgency=low * UpdateManager/UpdateManager.py: - fix crash if /var/lib/apt/periodic/update-stamp does not exists (LP: #181390) - fix misleading string when cache is rebuild (LP: #179354) * DistUpgrade/DistUpgradeCache.py: - be more careful with the obsoletes checking and get not confused if the hardy version is older than the gutsy one (LP: #181201) update-manager (1:0.87) hardy; urgency=low * typo fixes (thanks to Brian Murray, LP: #99513, LP: #158175) * fix incorrect textual description (thanks to Brian Murray, LP: #145130) * support release-upgrades from dapper for architectures on ports.ubuntu.com * UpdateManager/UpdateManager.py: - remove the "from $version to $version" from the main list as this is duplicated information from the details tab - wording fixes (thanks to Matthew Paul Thomas) - if the update was successful, automatically close the install window - when no updates are available, display the information when the last apt-get update like operation was performed - if there are broken dependencies on the system, try to fix them on startup * data/UpdateManager.glade: - do not display what software updates are in startup progress dialog, this is already displayed in the main UI (thanks to Matthew Paul Thomas) - align the ""Download size:" text so that it matches the text inside the buttons update-manager (1:0.86) hardy; urgency=low * DistUpgrade/DistUpgradeController.py: - merged fixes from Brian Murray (thanks!); LP: #162978, LP: #64473 - fix getting prerequists for ports.ubuntu.com (thanks to lamont) * DistUpgrade/DistUpgradeCache.py: - keep the lists dir locked all the time to avoid a possible race * DistUpgrade/DistUpgrade.cfg: - added gobuntu-desktop to the list of supported meta-packages * data/update-manager.desktop.in: - remove deprecated entries (thanks to Kmos) * UpdateManager/Core/MetaRelease.py: - add support to prompt only for specifc release upgrades (e.g. lts->lts) * data/release-upgrades: - set the default prompting for hardy to "Prompt only for a new lts version" * DistUpgrade/DistUpgrade.cfg.dapper, DistUpgrade/prerequists-sources.list.dapper: - add support for dapper->hardy upgrades * DistUpgrade/DistUpgradeConfigParser.py: - add overwrite support for the configuration to support upgrades to multiple target releases with the same upgrader * data/update-manager.schemas.in: - /apps/update-manager/check_dist_upgrades is deprecated * utils/demotions.py: - make it more flexible to support generating both dapper and gutsy demotions update-manager (1:0.85.4) hardy; urgency=low * DistUpgrade/DistUpgradeCache.py: - do not use python2.5 try:/expect:/finally: - we need to run on 2.4 as well for dapper->hardy (LP: #164947) update-manager (1:0.85.3) hardy; urgency=low * DistUpgrade/DistUpgrade.cfg, DistUpgrade/DistUpgrade.glade, DistUpgrade/ReleaseAnnouncement, DistUpgrade/window_main.ui: - updated for hardy * DistUpgrade/DistUpgradeControler.py,: DistUpgrade/DistUpgradeCache.py: - better description whats happening when calculating the release-upgrade - keep the GUI responsive while calculating the upgrade update-manager (1:0.85.2) hardy; urgency=low * debian/control: - added missing "XS-Vcs-Bzr" header (thanks to Brian * debian/rules: - dh_iconcache is obsolete, use dh_icons instead update-manager (1:0.85.1) hardy; urgency=low * fix FTBFS update-manager (1:0.85) hardy; urgency=low * DistUpgrade/DistUpgradeCache.py: - fix crash when packages get downgraded (LP: #154257) * DistUpgrade/DistUpgradeController.py: - fix typo in classname (thanks to Matt T. Proud) * DistUpgrade/DistUpgrade.cfg: - update for hardy update-manager (1:0.81) gutsy; urgency=low [ Jonathan Riddell ] * DistUpgrade/DistUpgradeViewKDE.py: - Add word wrap to quesiton dialogue [ Michael Vogt ] * DistUpgrade/DistUpgradeControler.py: - make the commercial archive transition more robust - when forcing the evms removal, ensure that all evms rdepends get obsoleted so that the safety checks in the upgrader do not kick in and prevent the removal - when calculating the size required in /boot take into account that installed initramfs images create a .bak file * updated list of demoted packages * updated ReleaseAnnouncement to include final text * updated demotions and mirrors to current gutsy update-manager (1:0.80) gutsy; urgency=low * DistUpgrade/DistUpgradeControler.py: - enable transition to gutsy partner repository on upgrade now that we have a archive - workaround kde tempdir handling (LP: #149186) update-manager (1:0.79) gutsy; urgency=low * DistUpgrade/DistUpgradeControler.py: - do not log apts debug output to the user in server upgrade mode - when running in partial upgrade mode, do not run apport, this is handled by the libapt apport integration now, (LP:#139394) * DistUpgrade/DistUpgradeCache.py,DistUpgradeControler.py: - detect and workaround upgrade issues with envy * update-manager: - show version with --version (LP: #137353) * DistUpgrade/DistUpgradeViewKDE.py: - fix crash with invalid utf-8 in polish locale (LP: #145351) * UpdateManager/UpdateManager.py: - remove debug output (LP: #145494) * DistUpgrade/DistUpgradeControler.py: - fix lock detection (LP: #145463) * UpdateManager/Common/utils.py: - show "0 KB" download size if there is nothing to download (LP: #145308) * DistUpgrade/demoted.cfg, utils/demotions.py: - do not display demotions if they are replaced by something that is in main (e.g. gaim->pidgin, LP: #145767) * DistUpgrade/ReleaseAnnouncement: - update for the beta release * DistUpgrade/DistUpgradeControler.py: - fix typo in pre-requists (thanks to Stuart Bishop) * debian/control: - tighten update-manager depend on update-manager-core * UpdateManager/Core/DistUpgradeFetcherCore.py: - move country_mirror code into Core (LP: #145116) * UpdateManager/Core/MetaReleaseCore.py, tests/interactive_fetch-release_upgrader.py: - fix test failure update-manager (1:0.78) gutsy; urgency=low * DistUpgrade/DistUpgradeViewKDE.py: - Fix button in conffile dialogue update-manager (1:0.77) gutsy; urgency=low * DistUpgrade/DistUpgradeViewKDE.py: - fix crash in conffile dialogue setup update-manager (1:0.76) gutsy; urgency=low [ Michael Vogt ] * DistUpgrade/DistUpgradeCache.py: - ensure that the util-linux -> nfs-common transition happens (LP: #141559) [ Jonathan Riddell ] * DistUpgrade/DistUpgradeViewKDE.py: - copy Xauthority file if necessary update-manager (1:0.75) gutsy; urgency=low * DistUpgrade/DistUpgradeViewGtk.py: - work around broken vte forkpty() env add * DistUpgrade/DistUpgradeControler.py: - fix type of installed_demotions from apt.Package to pkgname (LP: #144417) * po/*.po: - updated from latest launchpad translations * UpdateManager/DistUpgradeFetcherCore.py: - fix missing command line propergation when run as non-root (LP: #144451) update-manager (1:0.74) gutsy; urgency=low * DistUpgrade/DistUpgradeCache.py: - ensure that users with the "lowlatency" kernel get transitioned correctly to a new kernel (LP: #129458) * DistUpgrade/DistUpgradeControler.py: - work around kde being too clever in tempdirs (LP: #139319) * po/POTFILES.in: - add missing files (LP: #141033) update-manager (1:0.73) gutsy; urgency=low * UpdateManager/UpdateManager.py: - display new installs in the list * UpdateManager/Common/utils.py: - fix countrymirror to deal with non-utf8 locales (LP: #138299) * tests/test_update_origin.py: - added test for this country_mirror() * DistUpgrade/DistUpgradeControler.py: - check trust of pre-requists files before downloading them - support pre-requists on the CD as well - preserve the logs on self update from the net * DistUpgrade/build-tarball.sh: - fix auto-generation of target distro in cdromupgrade script (LP:#138354) * data/update-manager.8: - new manpage (thanks to Bruno Mangin, LP: #107015) update-manager (1:0.72) gutsy; urgency=low * UpdateManager/Core/MetaRelease.py: - fix target filename for meta-release files so that correct I-M-S information is used * DistUpgrade/DistUpgrade.cfg: - use "release-upgrader-dpkg", "release-upgrader-apt" as update-pre-requists to fully support dpkg triggers (LP: #134000) - add mythubuntu-desktop to the valid metapackages * DistUpgrade/DistUpgradeControler.py: - fix pre-requists fetching, do not run the resolver as the udebss are not installable on a regular system - generate more log information to make diagnosing problems easier - setup RELEASE_UPGRADE_IN_PROGRESS environemnt - use custom invoke-rc.d during the upgrade so that failures to restart a daemon are not fatal * DistUpgrade/prerequists-sources.list: - point to the archive for the pre-requists now update-manager (1:0.71) gutsy; urgency=low [ Michel Vogt ] * DistUpgrade/DistUpgradeViewGtk.py: - fix crash in _terminal_log code * DistUpgrade/DistUpgradeControler.py: - disable archive.canonical.com for now until a gutsy repository is created there - fix size requirement reporting (LP: #137539) [ Jonathan Riddell ] * DistUpgrade/DistUpgradeViewKDE.py - Implement show/hide button on conf file dialogue * DistUpgrade/removal_blacklist.cfg - Add xubuntu-desktop and gobuntu-desktop update-manager (1:0.70) gutsy; urgency=low [ Jonathan Riddell ] * DistUpgrade/DistUpgradeViewKDE.py - Use apport for crashes - Don't use dcop, it doesn't work with kdesudo - Fix UI layout [ Michael Vogt ] * DistUpgrade/DistUpgradeControler.py: - show human readable size when displaying "not enough free space" error - when rewriting sources.list, transition the commercial package archive to the new location and "partner" name * DistUpgrade/DistUpgradeCache.py: - fix bogus log messages about missing "required" priority packages * DistUpgrade/DistUpgradeViewGtk.py: - remove debug messages * DistUpgrade/DistUpgrade.cfg: - remove gnome-cups-manager on upgrade, system-config-printer replaces it (LP: #107766) - set cursor to the start of the details list (LP: #134873) - added ubuntustudio-desktop, ichthux-desktop to valid metapackages (LP: #131936) * DistUpgrade/dist-upgrade.py, DistUpgrade/DistUpgradeViewText.py, DistUpgrade/DistUpgradeViewKDE.py, DistUpgrade/DistUpgradeViewGtk.py: - make logdir a config option too * UpdateManager/UpdateManager.py, UpdateManager/Common/utils.py: - move inhibit_sleep(), allow_sleep() into common code and call the freedesktop dbus interface instead of the deprecated gnome interface (LP: #136617) * tests/test_sources_list.py, tests/data-sources-list-test: - added tests for sources.list rewriting update-manager (1:0.69) gutsy; urgency=low [ Michael Vogt ] * UpdateManager/Core/MetaRelease.py: - remove zero size meta-release files (LP: #127263) * utils/demoted.cfg: - updated to current gutsy * DistUpgrade/DistUpgrade.cfg: - added "esound", "esound-common" to forced obsoleted packages (replaced by pulseaudio) [ Jonathan Riddell ] * Change version text from 7.04 to 7.10 in KDE frontend update-manager (1:0.68) gutsy; urgency=low * UpdateManager/DistUpgradeFetcherCore.py: - be extra paranoid when using ${countrymirror} * DistUpgrade/DistUpgradeControler.py: - support countrymirror in prerequists.sources.list file too * UpdateManager/Common/utils.py: - added country_mirror() function update-manager (1:0.67) gutsy; urgency=low * UpdateManager/UpdateManager.py, tests/test_update_origin.py: - when checking for update category (Security, Important, ...) not only check candidateVersion but all intermediate versions too - added test for the new matcher behaviour * DistUpgrade/DistUpgradeControler.py: - fix PreRequists fetching - better error checking/logging * DistUpgrade/DistUpgradeViewGtk.py, DistUpgrade/DistUpgradeViewKDE.py,: - improve error message when a package fails to install (thanks to Chris Jones) * DistUpgrade/DistUpgradeViewGtk.py: - show "cancel" button while fetching stuff * UpdateManager/DistUpgradeFetcher.py, UpdateManager/DistUpgradeFetcherCore.py: - support ${countrymirror} in meta-release information * setup.py, setup.cfg: - updated for new python-distutils-extra update-manager (1:0.66) gutsy; urgency=low * DistUpgrade/DistUpgradeControler.py: - support listing and fetching of upgrade PreRequists - transition archive.canonical.com to new layout - mark evms as obsolete if it is not in use - transition powerpc users to ports.ubuntu.com - implement Depends checking for the selected View (as speced in https://wiki.ubuntu.com/UpgradePrerequisites) * DistUpgrade/Core/DistUpgradeFetcherCore.py: - added ignore-time-conflict when calling gpg (thanks to Evan) * utils/demoted.cfg, DistUpgrade/mirrors.cfg, DistUpgrade/ReleaseAnnouncement: - updated for current gutsy * DistUpgrade/DistUpgrade.cfg: - mark desktop-effects as obsolete on ubuntu-desktop upgrades (the appearance capplet replaces it) update-manager (1:0.65) gutsy; urgency=low * debian/rules: - add test for fetching the upgrader to release to arch-build target * update-manager.py: - fix breakage in "partial upgrade" mode update-manager (1:0.64) gutsy; urgency=low * UpdateManager/DistUpgradeFetcher.py: - add missing "import os" * update-manager.py: - fix incorrect STEP_FETCH_INSTALL import (Fixes LP:#120484) update-manager (1:0.63) gutsy; urgency=low * fix i18n issue (Fixes LP:#114207) * DistUpgrade/DistUpgradeCache.py: - if "386" (UP) kernel is installed on SMP machine, automatically switch to SMP kernel (Fixes LP: #106387) * DistUpgrade/DistUpgrade.cfg: - set python2.3 to remove list to ensure smooth upgrade (Fixes LP: #108147) * DistUpgrade/DistUpgradeControler.py: - show total needed space in not-enough-free-space message (Fixes LP: #46775) - fix in snapshot feature (Fixes LP: #108413) - deal better with very slow downloads (disable cache cleanup) - improve free space calculation in /boot (Fixes LP: #116163, #104337) - implement SystemCleanup spec kernel removal - implement SystemCleanup spec unused dependencies removal * Separate downloading and upgrading (Fixes LP: #91978) * Show demotions before runing the upgrade (Fixes LP: #91998) * UpdateManager/UpdateManager.py: - re-check for new releases too when the user clicks on "Check" (Fixes LP: #107452) update-manager (1:0.62) gutsy; urgency=low * revert locking fix, it broke release upgrades * fix upgrade string update-manager (1:0.61) gutsy; urgency=low * add missing dh_gconf (LP#114569) * fix mispelled entry in removal_blacklist (LP#107558) * fix locking problem (LP#108446) * make the wording of the free space message more clear update-manager (1:0.60) gutsy; urgency=low * DistUpgrade/DistUpgradeControler.py: - fix free space check when the dir checked is a symlink (LP#106804) - increase minAge for the apt cleanup cron job during the upgrade to fix race for people with very slow network (LP#109548) - deal with invalid lines in /proc/mounts when calculating the free space (LP#108284) * cdromupgrade: - do not call any authentication mechanism, that is the responsibility of the user (LP#107431) * DistUpgrade/DistUpgradeViewKDE.py: - fix a bug in the cdrom progress (LP#107451) * DistUpgrade/DistUpgradeViewText.py: - send correct package failure information to log (LP#109209) * DistUpgrade/crashdialog.ui - Fix bug report URL in crash dialogue (LP#108969) * UpdateManager/Core/MetaRelease.py: - fix in I-M-S 304 handling (LP#109216) * DistUpgrade/DistUpgradeCache.py: - check RemovalBlacklist early when removing a package to work-around crash in problem resolver (LP#109014) * DistUpgrade/DistUpgrade.cfg: - updated for gutsy - add "ltsp-client", "ltspfsd" to the remove list to ensure that it does not get installed on a regular system (LP#109638) * DistUpgrade/DistUpgradeApport.py: - protect against errors when launching apport (LP#108131) update-manager (1:0.59.21) feisty-proposed; urgency=low * UpdateManager/Core/MetaRelease.py: - send pragma: no-cache (LP#107716) - fix bug in time representation for i-m-s (LP#107716) update-manager (1:0.59.20) feisty; urgency=low * DistUpgrade/DistUpgradeViewKDE.py: - do not crash in utf8() if the str is already unicode (LP#106863) update-manager (1:0.59.19) feisty; urgency=low * DistUpgrade/DistUpgradeViewKDE.py: - disable apt-listchanges in the kde frontend too - fix broken terminal interaction (LP#106367) - ensure that there is only a single konsole widget visible (LP#106541) update-manager (1:0.59.18) feisty; urgency=low [ Michael Vogt ] * DistUpgrade/DistUpgradeViewKDE.py: - fix i18n initialization (LP#106221) [ Jonathan Riddell ] * DistUpgrade/DistUpgradeViewKDE.py: - fix encoding in dialog_error (LP#106221) update-manager (1:0.59.17) feisty; urgency=low * DistUpgrade/DistUpgradeViewGtk.py: - fix crash in on_window_main_delete_event() (LP#104701) * DistUpgrade/apt-autoinst-fixup.py: - set mdadm to manually installed (LP#105663) * DistUpgrade/DistUpgradeControler.py: - add python symlink sanity check (LP#75557) * DistUpgrade/ReleaseAnnouncement: - prepare for the final version * po/ - updated to the latest translations from rosetta update-manager (1:0.59.16) feisty; urgency=low * set useDevelopmentRelease=False in the self updater on the CD (LP#99171) * fix another issue with a unresponsive GUI * work around upgrade issue with pango-libthai (LP#104384) update-manager (1:0.59.15) feisty; urgency=low * DistUpgrade/DistUpgradeControler.py: - keep the GUI alive while calculating the obsolete packages update-manager (1:0.59.14) feisty; urgency=low * DistUpgrade/DistUpgradeControler.py: - fix sources.list rewriting for people with internal or unofficial mirrors (LP#73463) * DistUpgrade/DistUpgradeCache.py: - workaround apache2/php5 upgrade failures (LP#95325) update-manager (1:0.59.13) feisty; urgency=low * po/POTFILES.in: - reomove [type: ] this confused intltool * DistUpgradeControler.py: - work around problem with kde tempfile extraction (LP#99380) update-manager (1:0.59.12) feisty; urgency=low * DistUpgrade/DistUpgradeViewKDE.py: - set debian frontend to "kde" * DistUpgrade/DistUpgradeCache.py: - do not crash when uname -r can't be parsed (LP#97663) - remove the nfs upgrade question again, the kernel team fixed the regression * DistUpgrade/DistUpgradeApport.py: - do not crash if no apport gui is available (LP#97498) * DistUpgrade/DistUpgradeViewText.py: - support details in text-mode (LP#94129) * DistUpgrade/DistUpgradeControler.py: - fix incorrect auto-installed information from meta-pkgs (LP#86921) - rewrite /etc/fstab cdrom entries (LP#86424,#79327) - fix upgrade for people with no admin group (LP#93279) - when encountering a error, first show the error dialog, then run the recover (LP#92366) * dist-upgrade.py: - support fallback when a frontend view can not be imported (LP#89568) - log the version of the upgrader as well * DistUpgrade/mirrors.cfg: - updated with the current mirror RSS feed from LP update-manager (1:0.59.11) feisty; urgency=low * DistUpgrade/DistUpgradeViewKDE.py: - fix crash in mediaChange (LP#96849) * DistUpgrade/DistUpgradeViewText.py: - fix crash on broken packages (LP#96444) * DistUpgrade/DistUpgradeCache.py: - ensure that the latest kernel is always selected (LP#96196) - added nfs-common check in feistyQuirks and ask to install it if it appears to be missing * DistUpgrade/DistUpgradeControler.py: - add any additional sanity check at the start of the upgrade to check if the base distro is supported update-manager (1:0.59.10) feisty; urgency=low [ Jonathan Riddell ] * DistUpgrade/DistUpgradeViewKDE.py: - i18n KDE frontend fixes, LP#95638, LP#94927 - set text on confirm dialogue buttons - (re)spawn embedded konsole for each fork, fixes crash when removing packages - Add on_window_main_delete_event, stops the user closing the window update-manager (1:0.59.9) feisty; urgency=low [Sebastian Heinlein] * Hide help button - the outdated documentation is confusing (LP#44944) [Michael Vogt] * Use .update-manager-core dir * Fix bug in writable check for /var/lib/update-manager (LP#95599) * Ensure that /var/lib/update-manager is available * inhibit sleep when runing the release upgrader(LP#70058) * make sure that we do not run with a interactive debconf frontend on server upgrade (for packages like quagga) * fix race condition in free space checking (LP#96482), thanks to Jane Silber for reporting update-manager (1:0.59.8) feisty; urgency=low * DistUpgrade/DistUpgradeViewKDE.py: - fix crash in error dialog (LP#94229) - i18n KDE frontend * DistUpgrade/DistUpgradeCache.py: - mention xubuntu-desktop too (LP#94443) * DistUpgrade/DistUpgradeCache.py: - fix in the logfile handling in server mode * DistUpgrade/DistUpgrade.cfg: - fix KeyDependency for xubuntu detection * UpdateManager/UpdateManager.py: - do not crash if UnInhibit dbus signal can not be send (LP#86572) update-manager (1:0.59.7) feisty; urgency=low * NEWS: removed empty file (LP#92250) * DistUpgrade/DistUpgradeControler.py: - fix wording of the "use network" question - better apport integration - fix in the progress reporting where the report was off-by-one * DistUpgrade/DistUpgradeFetcherSelf.py: - fix run_options argument * UpdateManager/Core/MetaRelease.py: - fix race conditin in download thread (thanks to Matt Zimmerman for reporting the issue) * do-release-upgrade: - added option --frontend, --mode update-manager (1:0.59.6) feisty; urgency=low * DistUpgrade/DistUpgradeView.py, DistUpgradeControler.py: - fixes in the apport integration update-manager (1:0.59.5) feisty; urgency=low * UpdateManager/fakegconf.py: - Fix missing {get,set}_string() in fakegconf * DistUpgrade/dialog_changes.ui - Fix alignment of image * DistUpgrade/dialog_error.ui - Fix caption - Make text box read only * DistUpgrade/DistUpgradeViewKDE.py - remove unused argument to reportBug() - fix caption of information box - show close button on error box update-manager (1:0.59.4) feisty; urgency=low * data/glade/UpdateManager.glade: - improve the wording of the dist-upgrade required dialog (LP#88706) * update-manager: - set better dialog caption (LP#88706) * DistUpgrade/DistUpgradeControler.py: - supress reboot notification when a upgrade is in progress (LP#91999) update-manager (1:0.59.3) feisty; urgency=low * DistUpgrade/DistUpgradeViewKDE.py: - Fix incorrect variable name, LP No 91887 update-manager (1:0.59.2) feisty; urgency=low * DistUpgrade/DistUpgradeViewKDE.py: - Fix reference to konsole_frame (LP No 84717 comment 33) update-manager (1:0.59.1) feisty; urgency=low [ Michael Vogt ] * DistUpgrade/DistUpgradeViewGtk.py: - do not fail if loading the svg pixbuf loader fails (LP#91593) [ Jonathan Riddell ] * DistUpgrade/DistUpgradeViewKDE.py: - import KRun, closes https://launchpad.net/bugs/91072 - fix non-existant variable use, closes https://launchpad.net/bugs/91386 - fix incorrect method name, closes https://launchpad.net/bugs/91295 update-manager (1:0.59) feisty; urgency=low * DistUpgrade/DistUpgradeViewKDE.py - quit any running instances of Adept * DistUpgrade/dist-upgrade.py - improve error message when failing to load frontend update-manager (1:0.58) feisty; urgency=low * UpdateManager/UpdateManager.py: - do not crash if download size can not be calculated (LP#90547) * fix build for all python versions (thanks to doko for help!) (LP#90269) * strip changelog epoch too (LP#45566) * fix spelling mistakes (thanks to Bruce Cowan, LP#90833) * update download size if "check/uncheck" all was selected from right-click menu * correct download speed string (LP#73721) * fix in the german translation (LP#68384) update-manager (1:0.57.8) feisty; urgency=low * debian/rules: - moved dist-upgrade_$version generation to binary-indep update-manager (1:0.57.7) feisty; urgency=low * DistUpgrade/DistUpgradeView.py: - revert earlier commit in FuzzyTimeToStr() to make it not crash * debian/rules: - strip the epoch before runing dpkg-addfiles update-manager (1:0.57.6) feisty; urgency=low [ Jonathan Riddell ] * DistUpgrade/DistUpgradeViewKDE.py - Fix crash with incorrect connect() calls [ Michael Vogt ] * UpdateManager/ChangelogViewer.py: - fix some margins (thanks to Sebastian Heinlein) update-manager (1:0.57.5) feisty; urgency=low * UpdateManager/UpdateManager.py: - check for None in toggled() (LP#88032) update-manager (1:0.57.4) feisty; urgency=low * DistUpgrade/DistUpgradeControler.py: - workaround problem in python-apt (no support for PyLong in SizeToStr) LP#84019 * DistUpgrade/DistUpgradeViewGtk.py: - keep a reference of the svg pibbuf loader around (LP#86699) * UpdateManager/fakegconf.py: - fix crash on xubuntu when gconf is not available (LP#86673) update-manager (0.57.3) feisty; urgency=low * debian/rules: - build a raw-dist-upgrader in additon to the debs * data/glade/UpdateManager.glade: - fix bad grammar (thanks to Matthew Thomas) LP#85258 - make Update Manager the consistent name (thanks to Matthew Thomas) LP#85253 * merged ReleaseAnnouncement wording update from Brian Murray * UpdateManager/Core/MetaRelease.py: - fix missing import (LP#85515) update-manager (0.57.2) feisty; urgency=low * fix crash in upgrade mode (LP#84915) update-manager (0.57.1) feisty; urgency=low * fix proxy authentication parser (lp: #83563) * fix crash in check_all_updates_installable() (LP#84776) * fix exception when strange permissions are set on meta-release file (LP#84724) * fix error dialog if cache init fails (LP#83185) update-manager (0.57) feisty; urgency=low * added clickable CVE and buglinks update-manager (0.56.1) feisty; urgency=low * fix FTBFS * update po/ update-manager (0.56) feisty; urgency=low * added --proposed switch to fetch a release-upgrader from a different location (similar to the -proposed pocket in the archive) * split into update-manager and update-manager-core and support cli release upgrades with the later * added fdsend module to support file descriptor passing over sockets this will allow a better seperation between frontend and backend in the future update-manager (0.55.1) feisty; urgency=low * fix FTBFS (missing cdbs b-d) update-manager (0.55) feisty; urgency=low * moved software-properties into its own source package to support a kde frontend update-manager (0.53.6) feisty; urgency=low * properly extract the package name that fails before calling out to apports package_hook * fix crash on exit before the main loop is run (lp: #82744) update-manager (0.53.5) feisty; urgency=low * update to the new exceptions from python-dbus in setupDBus (lp: #81802) * fix FTFBS update-manager (0.53.4) feisty; urgency=low * fix python dependency (lp: #80976) * add apport support to send in bugreports update-manager (0.53.3) feisty; urgency=low * fix python dependency (lp: #80976) * fix the GenericName in update-manager and software-properties (lp: #78932) * workaround problem when a meta-release file is created by root in the users homedir (lp: #80713) update-manager (0.53.2) feisty; urgency=low * fix the cdromupgrade script to use feisty update-manager (0.53.1) feisty; urgency=low * Build-depend on python-dev. update-manager (0.52) feisty; urgency=low * UpdateManager/UpdateManager.py: - more robust error reporting from libapt (lp: #74797) * SoftwareProperties/SoftwareProperties.py: - do not crash if template is missing (lp: #70580) * updated to latest python policy update-manager (0.51) feisty; urgency=low * data/channels/Ubuntu.info.in: - updated for feisty update-manager (0.50) feisty; urgency=low * support --disable-component (AlwaysEnableUniverseMultiverse spec) * look for lsb_release in PATH instead of hardcoding it (lp: #73075) update-manager (0.45.1) edgy-updates; urgency=low * handle unexpected data from data more gracefuly (lp: #68553) update-manager (0.45) edgy; urgency=low * debian/control: - added dependency on python-gconf - removed recommends on python-gnome2 update-manager (0.44.17) edgy; urgency=low * memory leak fixed (lp: #43096) update-manager (0.44.16) edgy; urgency=low * fix proxy usage when runing in non-root mode (lp: #40626) update-manager (0.44.15) edgy; urgency=low * added missing python-vte dependency (lp: #63609) * added missing gksu dependency (lp: #63572) * don't remove xchat automatically anymore on upgrade (leftover from breezy->dapper) (lp: #63881) * do not come up with bogus dist-upgrade suggestions * fix bad english grammar (lp: #63761, #63474) * fix in the edgyUpdates quirks handler (lp: #63723) * catch error from _tryMarkObsoleteForRemoval() (lp: #63617) * fix plural forms for ro, pl (lp: #46421) * properly escape comments before displaying them (lp: #63475) update-manager (0.44.14) edgy; urgency=low * fix some incorrect i18n markings (lp: #62681) update-manager (0.44.13) edgy; urgency=low * fix missing i18n declarations (lp: #62519) * data/glade/SoftwareProperties.glade: - fix missing "translatable" property (lp: #62681) * DistUpgrade: - deal better with the python transition and the hpijs upgrade (lp: #62948) * UpdateManager/UpdateManager.py: - put the cancel button inside the text-area to avoid flickering - make sure that src_ver is always initialized (thanks to Simira for reporting) - filter python-apt future warning (especially for seb128) * DistUprade/DistUpgradeControler.py: - check for self.sources, self.aptcdrom before using it (lp: #61852) update-manager (0.44.12) edgy; urgency=low * DistUpgrade/DistUpgradeViewGtk.py: - use '%d' instead of '%s' where appropriate (lp: #60239) * fixed lots of typos (lp: #60633) update-manager (0.44.11) edgy; urgency=low * UpdateManager/UpdateManager.py: - fix error in get_changelog (lp: #59940). Thanks to Denis Washington - bugfix in the ListStore - use the update-manager desktop file when runing synaptic as the backend to get a consistent UI - UI improvements (thanks to Sebastian Heinlein!) - remove branding update-manager (0.44.10) edgy; urgency=low * aptsources.py: - fix add_component() to avoid duplicated components - added MirrorsFile key to DistInfo code to have a better idea about the available mirrors * debian/control: - updated dbus dependencies (lp: #59862) update-manager (0.44.9) edgy; urgency=low * SoftwareProperties/SoftwareProperties.py: - bugfix in the popcon enable code (lp: #59540) update-manager (0.44.8) edgy; urgency=low * fix missing /var/log/dist-upgrade update-manager (0.44.7) edgy; urgency=low * UpdateManager/UpdateManager.py: - be more accurate about dependencies when the user selects only a supset of the packages update-manager (0.44.6) edgy; urgency=low * SoftwareProperties/SoftwareProperties.py: - fix inconsistency in the new software-sources dialog * integrate DistUpgrade code into UpdateManager to make sure that after e.g. a CDROM upgrade the rest of the system can still be fully upgraded over the net update-manager (0.44.5) edgy; urgency=low * install the DistUpgrade package too * data/channels/Ubuntu.info.in: - warty is no longer officially supported update-manager (0.44.4) edgy; urgency=low * SoftwareProperties/SoftwareProperties.py: - don't bomb when searching for the mirror (lp: #57015) * UpdateManager/UpdateManager.py: - added "%s-proposed" to the list of known origins update-manager (0.44.3) edgy; urgency=low * help/C/update-manager-C.omf: - fix url (thanks to daniel holbach, lp: #45548) * show the units better * don't jump around on row activation (thanks to Sebastian Heinlein) * send "inhibit sleep" to power-manager while applying updates (lp #40697) update-manager (0.44.2) edgy; urgency=low * added select all/unselect all (thanks to Sebastian Heinlein) * wording fixes * fix update counting bug update-manager (0.44.1) edgy; urgency=low * make UpdateManager check for new distribution releases by default again * fix dist-upgrade fetching when run as non-root. * sort the package list by the origin (UpdateManagerEdgy spec) update-manager (0.44) edgy; urgency=low * new SoftwareProperties GUI (thanks to Sebastian Heinlein) * support easy Popcon pariticipation update-manager (0.43) edgy; urgency=low * fixes in the changelog reading code * speedup in the cache clear code * runs as user by default now * uses dbus to implement singleton behaviour * updated the software-properties code to know about edgy update-manager (0.42.2ubuntu22) dapper; urgency=low * UpdateManager/UpdateManager.py: - fix a 'brown paperback' bug when the Meta-Release file checked (#46537) update-manager (0.42.2ubuntu21) dapper; urgency=low * UpdateManager/UpdateManager.py: - when a distribution release becomes available, display the version, not the codename (as per https://wiki.ubuntu.com/CodeNamesToVersionNumbers) - fix a string that was not marked transltable update-manager (0.42.2ubuntu20) dapper; urgency=low * SoftwareProperties/aptsources.py, channels/Ubuntu.info.in: - remove the codenames from the releases (as per https://wiki.ubuntu.com/CodeNamesToVersionNumbers) update-manager (0.42.2ubuntu19) dapper; urgency=low * help/C/figures: - applied "pngcrush" on the figures in the manual, this saves 4 MB uncompressed (ubuntu: #45901) update-manager (0.42.2ubuntu18) dapper; urgency=low * data/SoftwareProperties.glade: - fix missing 'translatable="yes"' property (ubuntu: #44409) - increase width to 620 (ubuntu: #40540) update-manager (0.42.2ubuntu17) dapper; urgency=low * debian/control: - depend on later python-apt (#45325) * SoftwareProperties/SoftwareProperties.py: - fix key updating after import (ubuntu #44927) * UpdateManager/UpdateManager.py: - remove debug output update-manager (0.42.2ubuntu16) dapper; urgency=low * use version and section of the source package (if this information is available) when building the changelog URL (ubuntu #40058) * SoftwareProperties/SoftwareProperties.py: - if no config is found create a new one (ubuntu: #37560) * UpdateManager/UpdateManager.py: - fix problem in changelog reading code when matching against installed versions with epochs (ubuntu: #40058) update-manager (0.42.2ubuntu15) dapper; urgency=low * disable the install button if there no updates (ubuntu: #42284) (Thanks to Sebastian Heinlein) * show main window *after* restoring the size (ubuntu: #42277) (Thanks to Sebastian Heinlein) * fix broken spelling, typos, wording (ubuntu: #42431, #28777, #40425, #40727) * help/C: merged from the docteam svn (ubuntu: 36092) update-manager (0.42.2ubuntu14) dapper; urgency=low * wording/glade file fixes (thanks to Sebastian Heinlein) * many updates to the dist-upgrader code update-manager (0.42.2ubuntu13) dapper; urgency=low * po/POTFILES.in: add missing desktop file (ubuntu: #39410) * UpdateManager/UpdateManager.py: - fix in the get_changelog logic (ubuntu: #40058) - correct a error in the changelog parser (ubuntu: #40060) - fix download size reporting (ubuntu: #39579) * debian/rules: added dh_iconcache * setup.py: install the icons into the hicolor icon schema (thanks to Sebastian Heinlein) update-manager (0.42.2ubuntu12) dapper; urgency=low * channels/*.in: typo fix * po/POTFILES.in: add missing files (ubuntu: #38738) * fix the help string in update-manager (ubuntu: #23274) * fix the bad grammar in "Cannot install all available updates" (ubuntu: #32864) * don't inform about new distro release on dapper by default (can be changed via a gconf setting/commandline switch) * fix UI issue of the edit dialog for given templates (thanks to Chipzz for the patch) update-manager (0.42.2ubuntu11) dapper; urgency=low * debian/control: - depend on unattended-upgrades - move python-gnome2 to recommends (we only use gconf from it) * UpdateManager/fakegconf.py: update for xubuntu (thanks to Jani Monoses) update-manager (0.42.2ubuntu10) dapper; urgency=low * update-manger: fix a missing import (#36138) * typo fix (#36123) * correct dapper version number (#36136) * keybindings fixed (#36116) * calc the update before downloading the changelog (#36140) * add a fake gconf interface for xubuntu (nop for normal ubuntu) (Thanks to Jani Monoses for the patch) update-manager (0.42.2ubuntu9) dapper; urgency=low * Better English (tm) (fixes #35985) * Use the the number of available and not selected updates to determinate if the system is up-to-date (fixes #35300) * fix ui problem with software preferences (fixes #35987) * fix width problem in SoftwareProperties update-manager (0.42.2ubuntu8) dapper; urgency=low * fix a FTBFS update-manager (0.42.2ubuntu7) dapper; urgency=low * various spelling fixes and ui-glitches update-manager (0.42.2ubuntu6) dapper; urgency=low * po/pt_BR.po: updated translation (thanks to Carlos Eduardo Pedroza Santiviago) * po/pt.po: updated Portugise translation (thanks to Rui Azevedo) * debian/control: arch: all now * debian/rules: undo the detection in favour of the simpler update of the desktop files * data/gnome-software-properties.desktop.in, update-manager.desktop.in: - added X-Ubuntu-Gettext-Domain * help/*: updated to latest svn update-manager (0.42.2ubuntu5) dapper; urgency=low * debian/rules: Add gettext domain to .server and .desktop files to get language pack support for them. (Similarly to cdbs' gnome.mk) update-manager (0.42.2ubuntu4) dapper; urgency=low * removed some of the gnome dependencies (gconf still in) * the ReleaseNotes dialog has clickable links now (thanks to Sebastian Heinlein) update-manager (0.42.2ubuntu3) dapper; urgency=low * fixed description of the ubuntu repository (#30813) * use the new synaptic --parent-window-id switch when runing the backend update-manager (0.42.2ubuntu2) dapper; urgency=low * SoftwareProperties/SoftwareProperties.py: - re-added the internet update options (#27932) * data/gnome-software-properties.desktop: - use gksu instead of gksudo (#30057) * wording fixes (#30296) update-manager (0.42.2ubuntu1) dapper; urgency=low * UpdateManager/MetaRelease.py: - never offer a upgrade to a unsupported (i.e. developer) dist * data/gnome-software-properties.desktop.in: use X-KDE-SubstituteUID=true * small UI layout changes (should fix the cancel/close button problem) update-manager (0.42.1ubuntu1) dapper; urgency=low * UpdateManagert: improved the HIG complicane more, removed some of the uglines from the last version (Malone #22090) * SoftwareProperties: improved the HIG complicane (Malone #28530) (thanks to Sebastian Heinlein) update-manager (0.42ubuntu1) dapper; urgency=low * improved the HIG comlicane, thanks to Sebastian Heinlein: - Rename the button "close" to "cancel" - Move status bar to a separate dialog - Wording - Add a wider border around the changelog and description - Align and capitalize the button "Cancel downloading" (ubuntu: #28453) * bugfixes in the cache locking update-manager (0.40.2) dapper; urgency=low * SoftwareProperties/SoftwareProperties.py: - fix a problem with transient/parent window in custom apt line dialog (ubuntu #21585) - fix a problem in the conf file writer that can lead to absurdly large files update-manager (0.40.1) dapper; urgency=low * SoftwareProperties/SoftwareProperties.py: - make it embedded friendlier update-manager (0.40) dapper; urgency=low * new upstream release: - switched from autotools to distutils - massive code cleanups - use SimpleGladeApp now - SoftwareProperties has a new GUI - UpdateManager has support for upgrading from one dist to another now (given that the required "recipe" for the upgrade is available) See https://wiki.ubuntu.com/AutomaticUpgrade for details - use python-apt for "reload" and "add cdrom" now - improved the handling of sources.list a lot (including support for /etc/apt/sources.list.d) * support for the AutomaticUpgrades spec added via the meta-release information * data/update-manager.desktop.in: - use X-KDE-SubstituteUID added and use gksu now update-manager (0.37.1+svn20050404.15) breezy; urgency=low * added intltool to build-depends (for rosetta) update-manager (0.37.1+svn20050404.14) breezy; urgency=low * debian/rules: - run intltool-update -p for rosetta * src/update-manager.in: - release the lock before runing gnome-software-properties (ubuntu #17022) update-manager (0.37.1+svn20050404.13) breezy; urgency=low * src/update-manager.in: - use the right column for type-ahead searching (ubuntu #16853) update-manager (0.37.1+svn20050404.12) breezy; urgency=low * added locking support * use explicit path to python2.4 (thanks anthony!) (Ubuntu #16087) * CTRL-{w,q} close the update-manager window (Ubuntu #15729) update-manager (0.37.1+svn20050404.11) breezy; urgency=low * fix a typo in the reload tooltip (thanks to P Jones) (ubuntu #14699) update-manager (0.37.1+svn20050404.10) breezy; urgency=low * fix for a typo in the source of the last upload (*cough*) update-manager (0.37.1+svn20050404.9) breezy; urgency=low * do a "save" dist-upgrade (add only, no removes) update-manager (0.37.1+svn20050404.8) breezy; urgency=low * if repository window is running from inside synaptic, don't show "Add cdrom" button (it's available in the synaptic menu already) update-manager (0.37.1+svn20050404.7) breezy; urgency=low * if running from inside another application (e.g. synaptic), make sure the dialogs get a correct parent (ubuntu #14001) * if nothing changed, do not run "reload" if runing from inside synaptic update-manager (0.37.1+svn20050404.6) breezy; urgency=low * remove (parts of) ubuntu branding from the application * make it run only with python2.4 (ubuntu #10876) * make sure to always properly escape the strings displayed in the treeview update-manager (0.37.1+svn20050404.5) breezy; urgency=low * updates where not shown sometimes, fixed that (ubuntu #13410) update-manager (0.37.1+svn20050404.4) breezy; urgency=low * re-read the sources.list after a "add-custom" (ubuntu #9855) * settings window has a title (ubuntu #10756) * default actions for the buttons (ubuntu #10741) * various typos fixed (ubuntu #9866) * make sure that no dialogs are opened without a parent (ubuntu #10284) update-manager (0.37.1+svn20050404.3) breezy; urgency=low * use breezy as default for newly created sources (ubuntu #13009) * be more carefull with preserving the mirror * a better explaination for the "Reload" button (ubuntu #11432) update-manager (0.37.1+svn20050404.2) breezy; urgency=low * fix a small problem in the parsing code (ubuntu #8754) update-manager (0.37.1+svn20050404.1) hoary; urgency=low * pickup the correct proxy settings from apt (#8668) update-manager (0.37.1+svn20050404) hoary; urgency=low * translation updates: - xh, fr update-manager (0.37.1+svn20050403) hoary; urgency=low * translation updates: - pt_BR, tw * documentation updates (thanks to Sean Wheller and Jeff Schering) * small fixes: - make sure to not duplicate sources.list entires (even for mirrors) - added the hoary-updates to the templates and matchers (#8600) - some missing i18n strings marked as such (thanks to Zygmunt Krynicki) - don't fail on missing net connections - always update the status label update-manager (0.37.1+svn20050323) hoary; urgency=low * translation updates * gui can set the new apt cache properties now * warn about broken packages (#7688) * only ask to reload the package list if something changed (#7871) * various focus fixes (#7900) update-manager (0.37.1+svn20050314) hoary; urgency=low * new svn snapshot, lot's of bugfixes and i18n updates. - fix for a ui problem (#6837) - read pined packages correctly (#7058) - update list correctly after reload (#7182) - tell user when dist-upgrade is needed (#7271) - cdrom sources can be added now too (#7315) - meta-release file bugfix (#7330) - translation updates (da, fr, es, ro, pl) update-manager (0.37.1+svn20050304) hoary; urgency=low * new snapshot, use python-apt depcache now update-manager (0.37.1+svn20050301) hoary; urgency=low * new snapshot, better de.po, better i18n support update-manager (0.37.1+svn20050228.1) hoary; urgency=low * fixed a FTBFS (because of the "cleanfiles" in Makefile.am) update-manager (0.37.1+svn20050228) hoary; urgency=low * get the correct candidate version for updatable packages (ubuntu #6825) update-manager (0.37.1+svn20050221) hoary; urgency=low * new svn snapshot, fixes: - #6756: window size too big - #6767, #6780: gnome-software-properties window broken update-manager (0.37.1+svn20050219) hoary; urgency=low * new svn snapshot, fixes: - #6565, #6565 (typo) - #6634 (remeber last details state) - #6635 (progress dialog merged in main window) - #6578 (hide details if no updates are available) update-manager (0.37.1) hoary; urgency=low * typo (#6542) * package list is sorted now * applied "hide details if system is update-to-date" patch (#6578, thanks to Jorge Bernal) update-manager (0.37) hoary; urgency=low * test for lock file and show error if the lock is already taken * use utf8 for the description * changelogs are fetched from http://changelogs.ubuntu.com/ now (closes: #6315) * handle 404 from http and set the error accordingly * set main_window to not sensitive when downloading changelogs * if no updates are available, hide the checkbox column (closes: #6443) update-manager (0.36.6) hoary; urgency=low * various bugfixes and embedding of synaptics progress windows update-manager (0.36.5) hoary; urgency=low * disabled sources can now be displayed too (optional preference) * comments can be added * various bugfixes update-manager (0.36.4) hoary; urgency=low * regression of the last upload fixed * gnome-software-properties can be embedded into other windows now (usefull for e.g. synaptic) update-manager (0.36.3) hoary; urgency=low * updates to the main window design update-manager (0.36.2) hoary; urgency=low * new main window layout in update-manager (Michiel design, looks _so_ nice) update-manager (0.36.1) hoary; urgency=low * columns are resizable now (closes: #5541) * lot's of typo/gui-glitches fixes (closes: #5200, #5816, #5801, #5802) update-manager (0.36) hoary; urgency=low * new upstream release, added support to control APT::Periodic::* variables in gnome-software-properties update-manager (0.35) hoary; urgency=low * new upstream release - typo fix (closes: #5200) update-manager (0.34) hoary; urgency=low * new upstream release update-manager (0.33) hoary; urgency=low * new upstream release, featuring the gnome-software-properties update-manager (0.32) hoary; urgency=low * new upstream release update-manager (0.31-1ubuntu1) hoary; urgency=low * Update Build-Deps and fix FTBFS. update-manager (0.31-1) hoary; urgency=low * new upstream release, added icon, desktop file and bugfix update-manager (0.3-1) hoary; urgency=low * New upstream release, inital ubuntu release update-manager (0.2-1) unstable; urgency=low * New upstream release. update-manager (0.1-2) unstable; urgency=low * Um Yeah. update-manager (0.1-1) unstable; urgency=low * Initial Release.
This commit is contained in:
commit
d53aac9b40
|
@ -0,0 +1,86 @@
|
|||
### Software Updater for apt
|
||||
|
||||
- 目录架构:
|
||||
|
||||
```shell
|
||||
backend debian Makefile plugin README.MD
|
||||
```
|
||||
|
||||
- 其中分为控制面板插件目录`plugin` and 更新后端目录`backend`,两个模块相互隔离,公用一个包来安装
|
||||
|
||||
- GitLab分支介绍
|
||||
|
||||
- backend_dev:后端更新代码维护的分支
|
||||
- plugin_dev:控制面板插件维护的分支
|
||||
- dev:分支只要负责将后端更新代码和插件的代码进行合并编包测试的分支,最新的代码在此分支上
|
||||
- master:负责最终出版本的分支,dev上验证成功后,将代码合并到master上进行编包
|
||||
|
||||
|
||||
|
||||
- 安装依赖
|
||||
|
||||
```
|
||||
sudo apt install dh-python python3-all python3-distutils-extra gir1.2-snapd-1 apt-clone intltool at-spi2-core -y
|
||||
```
|
||||
|
||||
-
|
||||
|
||||
|
||||
|
||||
### 后端服务:
|
||||
|
||||
- 后端服务主要负责更新、安装、升级等等各种安装和下载的过程处理
|
||||
|
||||
- 查看后端日志:`tail -f /var/log/kylin-system-updater/kylin-system-updater.log.1`
|
||||
|
||||
- 调试后端代码:
|
||||
|
||||
- 进入backend目录下直接运行`kylin-system-updater`
|
||||
|
||||
- 调试参数
|
||||
|
||||
```shell
|
||||
-d 日志直接输出到终端,不输出到log文件中
|
||||
-n 不更新摸板不刷新source.list and important 列表
|
||||
-r 替换已经运行的后端程序
|
||||
-c 关闭源过滤等各种过滤代码
|
||||
|
||||
```
|
||||
|
||||
|
||||
### 配置文件
|
||||
|
||||
- 名称:`system-updater.conf`
|
||||
|
||||
- 路径:`/var/lib/kylin-system-updater`
|
||||
|
||||
- 配置项:
|
||||
|
||||
```shell
|
||||
#自动更新使用
|
||||
[AutoUpgrade]
|
||||
#升级列表,自动更新使用
|
||||
upgradelist =
|
||||
|
||||
#系统状态
|
||||
[SystemStatus]
|
||||
#标志是否异常强制关闭
|
||||
isabnormalreboot = False
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 文档
|
||||
|
||||
#### Aptdaemon
|
||||
|
||||
- https://pythonhosted.org/aptdaemon/aptdaemon.client.html?highlight=commit_packages#aptdaemon.client.AptClient.commit_packages
|
||||
|
||||
#### python-apt
|
||||
|
||||
- https://apt-team.pages.debiahn.net/python-apt/library/apt_pkg.html
|
||||
|
||||
#### 方法与信号接口文档
|
||||
|
||||
- 参考interface.md 文档
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
# AlertWatcher.py
|
||||
# -*- Mode: Python; indent-tabs-mode: nil; tab-width: 4; coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2010 Mohamed Amine IL Idrissi
|
||||
#
|
||||
# Author: Mohamed Amine IL Idrissi <ilidrissiamine@gmail.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
# USA
|
||||
|
||||
from __future__ import absolute_import
|
||||
import logging
|
||||
|
||||
from gi.repository import GObject
|
||||
import dbus
|
||||
from dbus.mainloop.glib import DBusGMainLoop
|
||||
|
||||
|
||||
class AlertWatcher(GObject.GObject):
|
||||
""" a class that checks for alerts and reports them, like a battery
|
||||
or network warning """
|
||||
|
||||
__gsignals__ = {"network-alert": (GObject.SignalFlags.RUN_FIRST,
|
||||
None,
|
||||
(GObject.TYPE_INT,)),
|
||||
"battery-alert": (GObject.SignalFlags.RUN_FIRST,
|
||||
None,
|
||||
(GObject.TYPE_BOOLEAN,)),
|
||||
"network-3g-alert": (GObject.SignalFlags.RUN_FIRST,
|
||||
None,
|
||||
(GObject.TYPE_BOOLEAN,
|
||||
GObject.TYPE_BOOLEAN,)),
|
||||
}
|
||||
|
||||
def __init__(self):
|
||||
GObject.GObject.__init__(self)
|
||||
DBusGMainLoop(set_as_default=True)
|
||||
self.bus = dbus.Bus(dbus.Bus.TYPE_SYSTEM)
|
||||
# make it always connected if NM isn't available
|
||||
self.network_state = 3
|
||||
|
||||
def check_alert_state(self):
|
||||
try:
|
||||
#network
|
||||
obj = self.bus.get_object("org.freedesktop.NetworkManager",
|
||||
"/org/freedesktop/NetworkManager")
|
||||
obj.connect_to_signal(
|
||||
"StateChanged",
|
||||
self._on_network_state_changed,
|
||||
dbus_interface="org.freedesktop.NetworkManager")
|
||||
interface = dbus.Interface(obj, "org.freedesktop.DBus.Properties")
|
||||
self.network_state = interface.Get(
|
||||
"org.freedesktop.NetworkManager", "State")
|
||||
self._network_alert(self.network_state)
|
||||
|
||||
# power
|
||||
# obj = self.bus.get_object('org.freedesktop.UPower',
|
||||
# '/org/freedesktop/UPower')
|
||||
# obj.connect_to_signal("Changed", self._power_changed,
|
||||
# dbus_interface="org.freedesktop.UPower")
|
||||
# self._power_changed()
|
||||
# 3g
|
||||
# self._update_3g_state()
|
||||
except dbus.exceptions.DBusException as e:
|
||||
logging.error(str(e))
|
||||
pass
|
||||
|
||||
def _on_network_state_changed(self, state):
|
||||
self._network_alert(state)
|
||||
# self._update_3g_state()
|
||||
|
||||
# def _update_3g_state(self):
|
||||
# from .roam import NetworkManagerHelper
|
||||
# nm = NetworkManagerHelper()
|
||||
# on_3g = nm.is_active_connection_gsm_or_cdma()
|
||||
# is_roaming = nm.is_active_connection_gsm_or_cdma_roaming()
|
||||
# self._network_3g_alert(on_3g, is_roaming)
|
||||
|
||||
# def _network_3g_alert(self, on_3g, is_roaming):
|
||||
# self.emit("network-3g-alert", on_3g, is_roaming)
|
||||
|
||||
def _network_alert(self, state):
|
||||
self.network_state = state
|
||||
self.emit("network-alert", state)
|
||||
|
||||
# def _power_changed(self):
|
||||
# obj = self.bus.get_object("org.freedesktop.UPower",
|
||||
# "/org/freedesktop/UPower")
|
||||
# interface = dbus.Interface(obj, "org.freedesktop.DBus.Properties")
|
||||
# on_battery = interface.Get("org.freedesktop.UPower", "OnBattery")
|
||||
# self.emit("battery-alert", on_battery)
|
|
@ -0,0 +1,602 @@
|
|||
# DataAcquisition.py
|
||||
# supervisory control and data acquisition
|
||||
|
||||
#!/usr/bin/python3
|
||||
import os
|
||||
import json
|
||||
import dbus
|
||||
import uuid
|
||||
import time
|
||||
import socket
|
||||
import base64
|
||||
import shutil
|
||||
import hashlib
|
||||
import logging
|
||||
import tarfile
|
||||
import requests
|
||||
import datetime
|
||||
import threading
|
||||
|
||||
from email import message
|
||||
from datetime import datetime
|
||||
from binascii import a2b_hex
|
||||
from Crypto.PublicKey import RSA
|
||||
from urllib import parse, request
|
||||
from PyQt5.QtCore import QSettings
|
||||
from SystemUpdater.Core import enums
|
||||
from Crypto.Cipher import PKCS1_OAEP
|
||||
from json.decoder import JSONDecodeError
|
||||
from dbus.exceptions import DBusException
|
||||
from SystemUpdater.Core.UpdaterConfigParser import UpgradeConfig
|
||||
|
||||
LOCALTIDDIR = "/var/lib/kylin-system-updater/"
|
||||
LOCALTIDFILE = "tidfile.conf"
|
||||
MSGSNDDIR = "/var/lib/kylin-system-updater/sendinfos/"
|
||||
|
||||
SOURCE_PKGNAME = {
|
||||
'Kylin System Updater': 'kylin-system-updater',
|
||||
'Kylin Unattended Upgrade': 'unattended-upgrades'
|
||||
}
|
||||
|
||||
class UpdateMsgCollector():
|
||||
ACTION_DEFUALT_STATUS = -1
|
||||
ACTION_UPDATE = 0
|
||||
ACTION_INSTALL = 1
|
||||
ACTION_INSTALL_DEB = 2
|
||||
ACTION_CHECK_RESOLVER = 3
|
||||
ACTION_DOWNLOADONLY = 4
|
||||
ACTION_FIX_BROKEN = 5
|
||||
ACTION_REMOVE_PACKAGES = 6
|
||||
ACTION_FIX_INCOMPLETE = 7
|
||||
ACTION_CLEAN = 8
|
||||
ACTION_INSTALL_SHUTDOWN = 9
|
||||
|
||||
MODE_DEFAULT_STATUS = -1
|
||||
|
||||
#1、ACTION_INSTALL 安装的子类
|
||||
#部分升级
|
||||
MODE_INSTALL_PARTIAL = 0
|
||||
#全部升级
|
||||
MODE_INSTALL_ALL = 1
|
||||
#系统全盘升级
|
||||
MODE_INSTALL_SYSTEM = 2
|
||||
#后端内部安装包使用 目前 更新配置包和升级本身使用
|
||||
MODE_INSTALL_SINGLE = 3
|
||||
|
||||
#2、更新的子类
|
||||
MODE_UPDATE_CACHE = 0
|
||||
MODE_UPDATE_ALL = 1
|
||||
|
||||
mode_map = {
|
||||
MODE_INSTALL_PARTIAL:"upgrade_system",
|
||||
MODE_INSTALL_ALL:"upgrade_all",
|
||||
MODE_INSTALL_PARTIAL:"upgrade_partial"
|
||||
}
|
||||
action_map = {
|
||||
ACTION_CHECK_RESOLVER:enums.MONIT_DEPRESOLUT,
|
||||
ACTION_INSTALL:enums.MONIT_INSTALL,
|
||||
ACTION_INSTALL_DEB:enums.MONIT_INSTALLDEB,
|
||||
10:enums.MONIT_FINISH,
|
||||
"finish-update":enums.MONIT_FINISH,
|
||||
"finish-install":enums.MONIT_FINISH
|
||||
}
|
||||
messageType_map = {
|
||||
# InstallBackend.ACTION_CHECK_RESOLVER:"UpdateDetect",
|
||||
ACTION_CHECK_RESOLVER:"DepResolution",
|
||||
# InstallBackend.ACTION_CHECK_RESOLVER:"Downloading",
|
||||
ACTION_INSTALL:"Installing",
|
||||
# InstallBackend.ACTION_CHECK_RESOLVER:"UpgradeFinish",
|
||||
ACTION_INSTALL_DEB:"InstallerInfo",
|
||||
10:"Background-Upgrade",
|
||||
"finish-update":"UpdateInfos",
|
||||
"finish-install":"InstallInfos"
|
||||
}
|
||||
|
||||
def __init__(self, manager=None):
|
||||
self.uuid = ''
|
||||
self.status = ''
|
||||
self.upgrade_mode = ''
|
||||
self.upgrade_action = ''
|
||||
self.UploadMessage = {}
|
||||
self.PackageInfo = {}
|
||||
self.UpdateInfos = {}
|
||||
self.background_version = {}
|
||||
self.background_upgradable = []
|
||||
self.background_list = []
|
||||
self.upgrade_list = []
|
||||
self.waitSendList = []
|
||||
self.cache = None
|
||||
self.updateManager = manager
|
||||
# 转换 & 加密
|
||||
self.convertor = FormatConvert(self)
|
||||
# 发送器
|
||||
self.sender = MessageSend(self)
|
||||
logging.info("Initialize Update MessageSend Collector to success...")
|
||||
|
||||
def GenUploadMessage(self, dict_message, local_uuid = ''):
|
||||
UploadMessage = {}
|
||||
# 获取将要上传的数据,获取东八区时间
|
||||
UploadMessage['createTimeStamp'] = get_east_8_time()
|
||||
try:
|
||||
if "packageName" in dict_message.keys():
|
||||
dict_message.pop("packageName")
|
||||
for key in dict_message.keys():
|
||||
UploadMessage[key] = dict_message[key]
|
||||
if local_uuid != '':
|
||||
UploadMessage['UUID'] = str(local_uuid)
|
||||
else:
|
||||
UploadMessage['UUID'] = str(uuid.uuid1())
|
||||
except Exception as e:
|
||||
logging.error(str(e))
|
||||
|
||||
json_UploadMessage = self.convertor.dictConvertJson(UploadMessage)
|
||||
|
||||
logging.debug('Generate UploadMessage: %s.',json_UploadMessage)
|
||||
self.UploadMessage = UploadMessage.copy()
|
||||
UploadMessage.clear()
|
||||
|
||||
def GenPackageInfo(self, messageType, packageName):
|
||||
PackageInfo = {}
|
||||
PackageInfo['messageType'] = str(messageType)
|
||||
PackageInfo['packageName'] = str(packageName)
|
||||
key = str(packageName)+'_'+str(messageType)
|
||||
# 获取本地tid
|
||||
self.sender.GetLocalTid(key)
|
||||
PackageInfo["tid"] = str(self.sender.localtid)
|
||||
|
||||
json_PackageInfo = self.convertor.dictConvertJson(PackageInfo)
|
||||
|
||||
logging.debug('Generate PackageInfo: %s.',json_PackageInfo)
|
||||
self.PackageInfo = PackageInfo.copy()
|
||||
PackageInfo.clear()
|
||||
|
||||
def setUploadMessage(self, KeyValue):
|
||||
# FIXME:数据获取顺序问题
|
||||
pass
|
||||
|
||||
def UpdateMsg(self, messageType, json_message, uuid = ''):
|
||||
# para: messageType(消息类型): "UpdateInfos"、 "InstallInfos"、 "RemoveInfo"
|
||||
# para: dict_message(数据内容): 必须包含 "packageName"、"source"", 采集器会进行检测
|
||||
dict_message = self.convertor.JsonConvertDict(json_message)
|
||||
if messageType == "":
|
||||
messageType = "SystemUpdate"
|
||||
if type(dict_message) != type(dict) and "appname" not in dict_message.keys():
|
||||
raise AttributeError("'%s' object has no attribute '%s'" % ("dict message", "appname"))
|
||||
|
||||
# 生成UploadMessage与PackageInfo
|
||||
try:
|
||||
self.GenPackageInfo(messageType, "kylin-system-updater")
|
||||
self.GenUploadMessage(dict_message, local_uuid = uuid)
|
||||
except Exception as e:
|
||||
logging.error(str(e))
|
||||
|
||||
# sha256
|
||||
json_UploadMessage = self.convertor.dictConvertJson(self.UploadMessage)
|
||||
json_PackageInfo = self.convertor.dictConvertJson(self.PackageInfo)
|
||||
shaValue = self.convertor.Sha256Value(json_UploadMessage)
|
||||
encodeMsg = self.convertor.EncodeRSAtoBase64(shaValue)
|
||||
|
||||
# dbus发送
|
||||
try:
|
||||
self.sender.MsgSendToServer(json_UploadMessage, json_PackageInfo, encodeMsg)
|
||||
except Exception as e:
|
||||
logging.error(e)
|
||||
|
||||
def Generate_Msg(self, upgrade_list, mode):
|
||||
try:
|
||||
self.upgrade_list = upgrade_list
|
||||
self.upgrade_mode = mode
|
||||
self.uuid = str(uuid.uuid1())
|
||||
self.UpdateInfos.update({"upgradeMode":self.mode_map.get(self.upgrade_mode, "default-mode")})
|
||||
except DBusException as e:
|
||||
logging.error(e)
|
||||
|
||||
def Upgrade_Process_Msg(self, action, dict_msg = {}):
|
||||
if self.updateManager.configs_uncover.getWithDefault("SystemStatus", "upload_upgrade_log", False) == True:
|
||||
tmp_dict = {}
|
||||
tmp_dict.update(dict_msg)
|
||||
try:
|
||||
self.UpdateInfos.update({"step":self.action_map.get(action, "")})
|
||||
if self.upgrade_mode == self.MODE_INSTALL_SYSTEM:
|
||||
self.UpdateInfos.update({"appname":"Upgrade System"})
|
||||
tmp_dict.update(self.UpdateInfos)
|
||||
json_file = json.dumps(tmp_dict.copy())
|
||||
self.UpdateMsg(self.messageType_map.get(action, ""), json_file, self.uuid)
|
||||
else:
|
||||
if action == self.ACTION_INSTALL_DEB:
|
||||
tmp_dict.update({"step":self.action_map.get(action, "")})
|
||||
json_file = json.dumps(tmp_dict.copy())
|
||||
self.UpdateMsg(self.messageType_map.get(action, ""), json_file, self.uuid)
|
||||
else:
|
||||
tmp_dict.update(self.UpdateInfos)
|
||||
json_file = json.dumps(tmp_dict.copy())
|
||||
self.UpdateMsg(self.messageType_map.get(action, ""), json_file, self.uuid)
|
||||
except Exception as e:
|
||||
logging.error(e)
|
||||
tmp_dict.clear()
|
||||
|
||||
def make_background_version(self,pkg):
|
||||
if pkg.is_installed == True:
|
||||
self.background_version.update({pkg.name:pkg.installed.source_version})
|
||||
else:
|
||||
self.background_version.update({pkg.name:"Unknown"})
|
||||
self.background_list.append(pkg.name)
|
||||
|
||||
def Msg_Clean(self):
|
||||
self.UploadMessage = {}
|
||||
self.PackageInfo = {}
|
||||
self.UpdateInfos = {}
|
||||
class FormatConvert():
|
||||
def __init__(self, DataCollector):
|
||||
#秘钥
|
||||
self.publickey = UniqueKey()
|
||||
self.collector = DataCollector
|
||||
|
||||
def dictConvertJson(self, dict_msg):
|
||||
#字典转换为json格式字符串
|
||||
json_file = ''
|
||||
try:
|
||||
json_file = json.dumps(dict_msg)
|
||||
except JSONDecodeError as e:
|
||||
logging.error(str(e))
|
||||
return json_file
|
||||
|
||||
def JsonConvertDict(self, json_file):
|
||||
# json格式字符串转换为字典
|
||||
dict_file = {}
|
||||
try:
|
||||
dict_file = json.loads(json_file)
|
||||
except JSONDecodeError as e:
|
||||
logging.error(str(e))
|
||||
return dict_file
|
||||
|
||||
def Sha256Value(self, json_file):
|
||||
# 计算sha256值
|
||||
hsobj = hashlib.sha256()
|
||||
try:
|
||||
hsobj.update(json_file.encode("utf-8"))
|
||||
except ValueError as e:
|
||||
logging.error("SHA256 value error: %s.",str(e))
|
||||
except Exception as e:
|
||||
logging.error(str(e))
|
||||
|
||||
return hsobj.hexdigest()
|
||||
|
||||
def EncodeRSAtoBase64(self, value):
|
||||
# 将value进行RSA加密并base64转码
|
||||
try:
|
||||
# 计算hex值
|
||||
value_hex = a2b_hex(value)
|
||||
# 加载公钥,填充格式OAEP
|
||||
uniqueKey = self.publickey.keyvalue.encode('utf-8')
|
||||
uniqueKeyorig = base64.b64decode(uniqueKey) # 公钥文件
|
||||
rsa_pubkey = RSA.importKey(uniqueKeyorig) # RSA公钥
|
||||
oaep_pub = PKCS1_OAEP.new(rsa_pubkey) # OAEP填充
|
||||
# 加密数据
|
||||
encodemsg = oaep_pub.encrypt(value_hex)
|
||||
# 加密数据Base64转码
|
||||
enMsg = base64.b64encode(encodemsg)
|
||||
except ValueError:
|
||||
logging.error("Value error: %s.", value)
|
||||
except TypeError:
|
||||
logging.error("RSA key has no private half.")
|
||||
return enMsg
|
||||
|
||||
|
||||
class MessageSend():
|
||||
ERR_PARA_FROMAT = 1
|
||||
ERR_NO_LOACLTID = 2
|
||||
ERR_ABNORMAL_SHA = 3
|
||||
ERR_UPLOADMSG_SHA = 4
|
||||
ERR_UPLOADMSG_CTS = 5
|
||||
|
||||
def __init__(self, DataCollector=None) -> None:
|
||||
# self.convertor = FormatConvert()
|
||||
if DataCollector == None:
|
||||
self.collector = UpdateMsgCollector()
|
||||
else:
|
||||
self.collector = DataCollector
|
||||
|
||||
def MsgSendToServer(self, UploadMessage, PackageInfo, encodeMsg):
|
||||
daqbus = dbus.SystemBus()
|
||||
try:
|
||||
daqobj = daqbus.get_object('com.kylin.daq', '/com/kylin/daq')
|
||||
daqinterface = dbus.Interface(daqobj, dbus_interface='com.kylin.daq.interface')
|
||||
except DBusException as e:
|
||||
logging.error("kylin-daq service error: "+str(e))
|
||||
return
|
||||
try:
|
||||
retval,retid = daqinterface.UploadMessage(PackageInfo, UploadMessage, encodeMsg)
|
||||
except AttributeError:
|
||||
logging.error("Call UploadMessage: Attribute Error.")
|
||||
self.Send_finally(retval, retid, PackageInfo, UploadMessage, encodeMsg)
|
||||
|
||||
def Send_finally(self, retval, retid, json_PackageInfo, json_UploadMessage, encodeMsg):
|
||||
# 根据发送结果进行处理
|
||||
result = ''
|
||||
PackageInfo = self.collector.convertor.JsonConvertDict(json_PackageInfo)
|
||||
if retval != 0:
|
||||
if retval == self.ERR_PARA_FROMAT:
|
||||
result = "Parameter format error"
|
||||
logging.debug("Sent Status: false - packageName: %s : result: %s.", PackageInfo['packageName'], result)
|
||||
elif retval == self.ERR_NO_LOACLTID:
|
||||
result = "The tid value in packageInfo is abnormal, but the message is saved successfully"
|
||||
logging.debug("Sent Status: false - packageName: %s : result: %s.", PackageInfo['packageName'], result)
|
||||
# 将返回的tid保存到本地
|
||||
key = PackageInfo['packageName']+'_'+PackageInfo['messageType']
|
||||
self.SaveTid(key, retid)
|
||||
elif retval == self.ERR_ABNORMAL_SHA:
|
||||
result = "Abnormal UploadedMessage Sha256"
|
||||
logging.debug("Sent Status: false - packageName: %s : result: %s.", PackageInfo['packageName'], result)
|
||||
elif retval == self.ERR_UPLOADMSG_SHA:
|
||||
result = "Description The UploadedMessageSha256 was decrypted incorrectly"
|
||||
logging.debug("Sent Status: false - packageName: %s : result: %s.", PackageInfo['packageName'], result)
|
||||
elif retval == self.ERR_UPLOADMSG_CTS:
|
||||
result = "The createTimeStamp field of UploadedMessage is abnormal"
|
||||
logging.debug("Sent Status: false - packageName: %s : result: %s.", PackageInfo['packageName'], result)
|
||||
elif retval == self.ERR_UPLOADMSG_CTS:
|
||||
result = "Invalid key included in \"uploadedMessage\" or \"packageInfo\": <@timestamp>,<_id>,<_index>,<_type>,<createTime>,<highlight>,<sn>,<sort>, check upload field"
|
||||
logging.debug("Sent Status: false - packageName: %s : result: %s.", PackageInfo['packageName'], result)
|
||||
else:
|
||||
logging.debug("Sent Status: false - packageName: %s : retval: %s.", PackageInfo['packageName'], retval)
|
||||
# 上传失败写入本地json
|
||||
if retval != self.ERR_NO_LOACLTID or retval == self.ERR_NO_LOACLTID:
|
||||
self.WriteToJson(PackageInfo['messageType'], json_PackageInfo, json_UploadMessage, encodeMsg)
|
||||
elif retval == 0:
|
||||
result = "Send to server success"
|
||||
logging.debug("Sent Status: True - packageName: %s : result: %s.", PackageInfo['packageName'], result)
|
||||
|
||||
def GetLocalTid(self, key):
|
||||
# 试图获取本地tid
|
||||
try:
|
||||
# 存放至数据库
|
||||
tid = self.collector.updateManager.sqlite3_server.select_from_tid("tid",key)
|
||||
if tid == "None" or tid == None:
|
||||
self.localtid = ""
|
||||
else:
|
||||
self.localtid = tid
|
||||
except Exception as e:
|
||||
logging.error(str(e))
|
||||
|
||||
def SaveTid(self, key, localtid):
|
||||
if len(localtid) == 0:
|
||||
return
|
||||
_localtid = str(localtid)
|
||||
try:
|
||||
# 写入数据库
|
||||
self.collector.updateManager.sqlite3_server.insert_into_tid(key, _localtid)
|
||||
except Exception as e:
|
||||
logging.error(str(e))
|
||||
|
||||
def WriteToJson(self, messageType, json_PackageInfo, json_UploadMessage, encodeMsg):
|
||||
#发送失败时,写入本地json中定时发送
|
||||
Msg = {}
|
||||
Msg["PackageInfo"] = json_PackageInfo
|
||||
Msg["UploadMessage"] = json_UploadMessage
|
||||
Msg["encodeMsg"] = str(encodeMsg)
|
||||
json_file = self.collector.convertor.dictConvertJson(Msg)
|
||||
# 保存信息
|
||||
try:
|
||||
if not os.path.exists(MSGSNDDIR):
|
||||
os.mkdir(MSGSNDDIR)
|
||||
# 根据messageType保存信息
|
||||
with open(MSGSNDDIR+messageType+".json","a") as f:
|
||||
f.write(json_file)
|
||||
f.write("\n")
|
||||
except Exception as e:
|
||||
logging.error(str(e))
|
||||
|
||||
def _TimedTransmission(self, file_path = MSGSNDDIR):
|
||||
classify_list = [name for name in os.listdir(file_path) if name.endswith(".json")]
|
||||
for f in classify_list:
|
||||
# 循环发送每一个文件
|
||||
self._ReadFromFile(os.path.join(file_path, f))
|
||||
|
||||
def _ReadFromFile(self, json_path):
|
||||
new_lines = []
|
||||
# 从本地文件读取
|
||||
if not os.path.exists(json_path):
|
||||
return
|
||||
with open(json_path, "r+") as f:
|
||||
lines = f.readlines()
|
||||
|
||||
# file is empty and path is exit -> remove file
|
||||
if len(lines) == 0 and os.path.exists(json_path):
|
||||
os.remove(json_path)
|
||||
return
|
||||
|
||||
#send installinfo or updateinfo
|
||||
for line in lines:
|
||||
(retval,retid) = self._file_send_server(line)
|
||||
if retval != 0: # success
|
||||
new_lines.append(line)
|
||||
if os.path.exists(json_path):
|
||||
os.remove(json_path)
|
||||
if len(new_lines) != 0:
|
||||
with open(json_path, "w+") as f:
|
||||
for line in lines:
|
||||
f.write(line)
|
||||
|
||||
def _file_send_server(self, json):
|
||||
UploadMessage = {}
|
||||
PackageInfo = {}
|
||||
encodeMsg = ''
|
||||
dict_msg = self.collector.convertor.JsonConvertDict(json)
|
||||
if 'UploadMessage' in dict_msg.keys():
|
||||
UploadMessage = dict_msg['UploadMessage']
|
||||
UploadMessage = self.collector.convertor.dictConvertJson(UploadMessage)
|
||||
if 'PackageInfo' in dict_msg.keys():
|
||||
PackageInfo = dict_msg['PackageInfo']
|
||||
PackageInfo = self.collector.convertor.dictConvertJson(PackageInfo)
|
||||
if 'encodeMsg' in dict_msg.keys():
|
||||
encodeMsg = str(dict_msg['encodeMsg'])
|
||||
if len(UploadMessage) == 0 or len(PackageInfo) == 0 or encodeMsg == '':
|
||||
logging.error("Msg error")
|
||||
return 6, ''
|
||||
daqbus = dbus.SystemBus()
|
||||
try:
|
||||
daqobj = daqbus.get_object('com.kylin.daq', '/com/kylin/daq')
|
||||
daqinterface = dbus.Interface(daqobj, dbus_interface='com.kylin.daq.interface')
|
||||
except DBusException as e:
|
||||
logging.error(str(e))
|
||||
try:
|
||||
retval,retid = daqinterface.UploadMessage(PackageInfo, UploadMessage, encodeMsg)
|
||||
except AttributeError:
|
||||
logging.error("Call UploadMessage: Attribute Error.")
|
||||
return (retval,retid)
|
||||
|
||||
class UniqueKey():
|
||||
keyvalue = "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FR\
|
||||
OEFNSUlCQ2dLQ0FRRUFzdW1NTFJEdlFNb0tEQkRJODRqSgpqc1A0Mk55V0pWVEZob2Jra3ZiT05j\
|
||||
dExYTXVzRmo2TzJUblZYU3Z6VlVLSjRqZkpwT2l2WEphOVB5Z2wzYTRnClBzSU40enNCMEdOY0tr\
|
||||
R3VsS2RrV2x6S3lWQ2xlTzhiQnN6SjkwbTc3cWF6YWg3a1A0TUl0WTVFczBpSkpiR0oKN1MxcERj\
|
||||
MlJkNnVFQWJLaXJyRTFlNzlFTEd4am5VN2V5NWkyRDE2WWJoZEQwZ2lNa2RHR3piQXBKTWZWRVJR\
|
||||
TQo1NXorMFVqdS8zSFJhNFY3b3p2TGRPRE5HUURaeWNJU0l3VHBLbFR3RjBxazdCNjVhTUlJenQ1\
|
||||
dnhOK1lxYU1GClppZFRLNzcxNjdqNEExZ3F3MG45bjlybWVXUGRWZ3dudnRtVXp4Q1krNk05SXpK\
|
||||
TDI3eWpRUTV1WGQ3RVdMT3IKbndJREFRQUIKLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg=="
|
||||
|
||||
class PHPServer(threading.Thread):
|
||||
LOG_PATH = "/var/log/kylin-system-updater"
|
||||
KYLIN_SOFTWARE_PROPERTIES_LOG = "/var/log/kylin-software-properties.log"
|
||||
PINGBACK_INTERNET_URL = "http://archive1.kylinos.cn:32294/kylin-update-manager-server/main.php?"
|
||||
PINGBACK_INTERNET_FILE_URL = "http://archive1.kylinos.cn:32294/kylin-update-manager-server/get_file.php?"
|
||||
PINGBACK_INTRANET_URL = "http://archive.kylinos-intranet.cn/kylin-update-manager-server/main.php?"
|
||||
PINGBACK_INTRANET_FILE_URL = "http://archive.kylinos-intranet.cn/kylin-update-manager-server/get_file.php?"
|
||||
SYSTEM_VERSION_PATH = "/etc/kylin-version/kylin-system-version.conf"
|
||||
|
||||
def get_values(self, _appname="", _appversion="", _state='', _errorcode='', _errorstring=""):
|
||||
self.appname = _appname
|
||||
self.appversion = _appversion
|
||||
self.status = _state
|
||||
self.errorcode = _errorcode
|
||||
self.errorstring = _errorstring
|
||||
|
||||
def run(self):
|
||||
# 获取本机ip
|
||||
try:
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
s.connect(('8.8.8.8', 80))
|
||||
host_ip = s.getsockname()[0]
|
||||
except:
|
||||
host_ip = 'Ip failed to get'
|
||||
# 获取系统版本
|
||||
with open('/etc/lsb-release', 'r') as f:
|
||||
for line in f.readlines():
|
||||
if line.strip().startswith('DISTRIB_DESCRIPTION='):
|
||||
versions = line.strip().split('=')
|
||||
if "V10" in line and "SP1" in versions[1]:
|
||||
version = "V10SP1"
|
||||
else:
|
||||
version = "V10Pro"
|
||||
break
|
||||
# 获取软件版本
|
||||
output = os.popen('dpkg -l|grep kylin-system-updater').readlines()
|
||||
if output:
|
||||
soft_version = output[0].strip().split()[2]
|
||||
# 获取时间
|
||||
nowtime = time.strftime('%Y-%m-%d-%H:%M:%S', time.localtime(time.time()))
|
||||
# 获取Mac
|
||||
mac = uuid.UUID(int=uuid.getnode()).hex[-12:]
|
||||
host_mac = ":".join([mac[e:e + 2] for e in range(0, 11, 2)])
|
||||
# 获取序列号
|
||||
if os.path.exists("/etc/.kyinfo"):
|
||||
settings = QSettings("/etc/.kyinfo", QSettings.IniFormat)
|
||||
settings.beginGroup("servicekey")
|
||||
key = str(settings.value("key")).strip()
|
||||
settings.endGroup()
|
||||
else:
|
||||
key = "0"
|
||||
try:
|
||||
# 用于收集源管理器的更新日志
|
||||
if self.status != "success":
|
||||
# nowtime = datetime.utcnow( ).strftime ( '%Y-%m-%d %H:%M:%S.%f' )[:-3]
|
||||
nowtime = get_east_8_time()
|
||||
log_dir = os.path.join(self.LOG_PATH, host_mac + "_" + nowtime)
|
||||
log_file_gzip = log_dir + ".tar.gz"
|
||||
os.makedirs(log_dir, exist_ok=True)
|
||||
|
||||
#get updater log
|
||||
updater_path = os.path.join(log_dir,"kylin-system-updater")
|
||||
os.makedirs(updater_path, exist_ok=True)
|
||||
#get updater log
|
||||
if os.path.exists("/var/log/kylin-system-updater/kylin-system-updater.log.1"):
|
||||
shutil.copy("/var/log/kylin-system-updater/kylin-system-updater.log.1", log_dir)
|
||||
if os.path.exists("/var/log/kylin-system-updater/kylin-system-updater.log.1.1.gz"):
|
||||
shutil.copy("/var/log/kylin-system-updater/kylin-system-updater.log.1.1.gz", log_dir)
|
||||
|
||||
#get apt log
|
||||
if os.path.exists("/var/log/apt/history.log"):
|
||||
shutil.copy("/var/log/apt/history.log", log_dir)
|
||||
if os.path.exists("/var/log/apt/term.log"):
|
||||
shutil.copy("/var/log/apt/term.log", log_dir)
|
||||
|
||||
#get version file
|
||||
if os.path.exists(self.SYSTEM_VERSION_PATH):
|
||||
shutil.copy(self.SYSTEM_VERSION_PATH, log_dir)
|
||||
gZipFile(log_dir, log_file_gzip)
|
||||
header = {'Content-Type': "multipart/form-data", "Accept-Encoding": "gzip"}
|
||||
try:
|
||||
with open(log_file_gzip, "rb") as f:
|
||||
requests.post(self.PINGBACK_INTRANET_FILE_URL + "filename=" + os.path.basename(log_file_gzip),
|
||||
data=f.read(), headers=header)
|
||||
except:
|
||||
with open(log_file_gzip, "rb") as f:
|
||||
requests.post(self.PINGBACK_INTERNET_FILE_URL + "filename=" + os.path.basename(log_file_gzip),
|
||||
data=f.read(), headers=header)
|
||||
shutil.rmtree(log_dir)
|
||||
os.remove(log_file_gzip)
|
||||
else:
|
||||
log_file_gzip = ""
|
||||
kmg_tmp = {'ip': host_ip, 'version': version, 'soft_version': soft_version, 'datetime': nowtime,
|
||||
'host_mac': host_mac, 'appname': self.appname, 'appversion': self.appversion, 'serial_number': key,
|
||||
'state': self.status, 'filename': log_file_gzip, 'errorcode': self.errorcode, 'errorstring': self.errorstring}
|
||||
kmg = parse.urlencode(kmg_tmp)
|
||||
logging.debug("PHPServer UpdateInfos: %s .", kmg_tmp)
|
||||
# 优先使用内网服务器,再使用外网
|
||||
try:
|
||||
url = self.PINGBACK_INTRANET_URL + kmg
|
||||
req = request.urlopen(url=url, timeout=3)
|
||||
logging.info("The Intranet log server is successfully accessed, pkgname:%s .",self.appname)
|
||||
except:
|
||||
url = self.PINGBACK_INTERNET_URL + kmg
|
||||
req = request.urlopen(url=url, timeout=3)
|
||||
logging.info("The external log server is successfully accessed, pkgname:%s .",self.appname)
|
||||
except Exception as e:
|
||||
logging.error("Failed to access the external log server: %s, pkgname:%s .", e, self.appname)
|
||||
if os.path.isfile(log_file_gzip):
|
||||
os.remove(log_file_gzip)
|
||||
|
||||
def PHPSeverSend(_appname="", _appversion="", _statue="", _errorcode="", _errorstring=""):
|
||||
send_thread = PHPServer()
|
||||
send_thread.get_values(_appname=_appname, _appversion=_appversion, _state=_statue, _errorcode=_errorcode, _errorstring=_errorstring)
|
||||
send_thread.start()
|
||||
|
||||
def gZipFile(src, dst):
|
||||
with tarfile.open(dst, "w:gz") as tar:
|
||||
tar.add(src, arcname=os.path.basename(src))
|
||||
|
||||
def get_east_8_time():
|
||||
import time
|
||||
# UTC时间
|
||||
utc_time = datetime.utcnow()
|
||||
# 转时间字符串
|
||||
utc_time = utc_time.strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]
|
||||
time_suffix = utc_time.split(".")[1]
|
||||
# 字符串转时间元祖
|
||||
utc_time = time.strptime(utc_time, "%Y-%m-%d %H:%M:%S.%f")
|
||||
# 时间元祖转时间戳
|
||||
utc_time = time.mktime(utc_time)
|
||||
# 生成东八区时间时间戳
|
||||
now_time = utc_time + 8*60*60
|
||||
# 时间戳转时间元祖
|
||||
now_time = time.localtime(now_time)
|
||||
# 时间元祖转字符串
|
||||
now_time = time.strftime("%Y-%m-%d %H:%M:%S",now_time)
|
||||
now_time = now_time + "." +time_suffix
|
||||
return now_time
|
||||
# return 0
|
||||
|
||||
if __name__ == "__main__":
|
||||
# 执行定时发送
|
||||
ms = MessageSend()
|
||||
ms._ReadFromFile("/var/lib/kylin-system-updater/sendinfos/testMsg.json")
|
|
@ -0,0 +1,400 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import os
|
||||
import logging
|
||||
import sqlite3
|
||||
from operator import itemgetter
|
||||
from gettext import gettext as _
|
||||
from optparse import OptionParser
|
||||
|
||||
DB_UPDATER = "/var/cache/kylin-update-manager/kylin-update-manager.db"
|
||||
DB_UPGRADE = "/var/cache/kylin-system-updater/kylin-system-updater.db"
|
||||
VER_DB = "/usr/share/kylin-system-updater/kylin-system-updater.db"
|
||||
|
||||
def dateMigration(options=None, old_db=None, old_db_cursor=None, new_db=None, new_db_cursor=None):
|
||||
print(_("Loading Sqlite3Server..."))
|
||||
if options==None:
|
||||
old_path = DB_UPDATER
|
||||
new_path = DB_UPGRADE
|
||||
try:
|
||||
if old_db==None and old_db_cursor==None:
|
||||
old_db = sqlite3.connect(old_path, check_same_thread=False)
|
||||
old_db_cursor = old_db.cursor()
|
||||
if new_db==None and new_db_cursor==None:
|
||||
new_db = sqlite3.connect(new_path, check_same_thread=False)
|
||||
new_db_cursor = new_db.cursor()
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
sql_commnd = ""
|
||||
old_cfg_dict = {}
|
||||
new_cfg_dict = {}
|
||||
# step 1: 更新旧配置数据
|
||||
try:
|
||||
print("更新旧配置数据")
|
||||
sql_commnd = "SELECT * FROM display where id=1"
|
||||
old_db_cursor.execute(sql_commnd)
|
||||
old_cfg = old_db_cursor.fetchone()
|
||||
for od in old_db_cursor.description:
|
||||
old_cfg_dict.update({str(od[0]):old_cfg[old_db_cursor.description.index(od)]})
|
||||
new_db_cursor.execute(sql_commnd)
|
||||
new_cfg = new_db_cursor.fetchone()
|
||||
for od in new_db_cursor.description:
|
||||
new_cfg_dict.update({str(od[0]):new_cfg[new_db_cursor.description.index(od)]})
|
||||
|
||||
if "download_limit" in new_cfg_dict.keys() and "download_limit_value" in new_cfg_dict.keys():
|
||||
if new_cfg_dict['download_limit'] != None or new_cfg_dict['download_limit_value'] != None:
|
||||
print("目标数据库有更新的配置项")
|
||||
else:
|
||||
sql_commnd = "UPDATE display set check_time='"+old_cfg_dict['check_time']+"' Where id=1"
|
||||
new_db_cursor.execute(sql_commnd)
|
||||
new_db.commit()
|
||||
sql_commnd = "UPDATE display set update_time='"+old_cfg_dict['update_time']+"' Where id=1"
|
||||
new_db_cursor.execute(sql_commnd)
|
||||
new_db.commit()
|
||||
sql_commnd = "UPDATE display set auto_check='"+old_cfg_dict['auto_check']+"' Where id=1"
|
||||
new_db_cursor.execute(sql_commnd)
|
||||
new_db.commit()
|
||||
sql_commnd = "UPDATE display set system_version='"+old_cfg_dict['system_version']+"' Where id=1"
|
||||
new_db_cursor.execute(sql_commnd)
|
||||
new_db.commit()
|
||||
if old_cfg_dict['auto_backup'] != None:
|
||||
sql_commnd = "UPDATE display set auto_backup='"+old_cfg_dict['auto_backup']+"' Where id=1"
|
||||
new_db_cursor.execute(sql_commnd)
|
||||
new_db.commit()
|
||||
if 'download_limit' in old_cfg_dict.keys() and old_cfg_dict['download_limit'] != None:
|
||||
sql_commnd = "UPDATE display set download_limit='"+old_cfg_dict['download_limit']+"' Where id=1"
|
||||
new_db_cursor.execute(sql_commnd)
|
||||
new_db.commit()
|
||||
if 'download_limit_value' in old_cfg_dict.keys() and old_cfg_dict['download_limit_value'] != None:
|
||||
sql_commnd = "UPDATE display set download_limit_value='"+old_cfg_dict['download_limit_value']+"' Where id=1"
|
||||
new_db_cursor.execute(sql_commnd)
|
||||
new_db.commit()
|
||||
|
||||
except Exception as e:
|
||||
print(e)
|
||||
print("更新配置文件错误")
|
||||
return
|
||||
|
||||
# step 2: 更新installed
|
||||
try:
|
||||
print("更新installed")
|
||||
update_record_dict = {}
|
||||
tmp_update_record_dict = []
|
||||
sql_commnd = "SELECT * FROM installed"
|
||||
old_db_cursor.execute(sql_commnd)
|
||||
update_record = old_db_cursor.fetchall()
|
||||
sql_commnd = "SELECT * FROM updateinfos"
|
||||
new_db_cursor.execute(sql_commnd)
|
||||
new_update_record = new_db_cursor.fetchall()
|
||||
|
||||
for ur in update_record:
|
||||
id,appname,version,time,description,icon,statue,keyword,errorcode = ur
|
||||
if errorcode in range(200):
|
||||
errorcode = 'null'
|
||||
update_record_dict.clear()
|
||||
update_record_dict.update({"appname":appname})
|
||||
update_record_dict.update({"version":version})
|
||||
update_record_dict.update({"time":time})
|
||||
update_record_dict.update({"description":description})
|
||||
update_record_dict.update({"icon":icon})
|
||||
update_record_dict.update({"statue":statue})
|
||||
update_record_dict.update({"keyword":'1'})
|
||||
update_record_dict.update({"errorcode":errorcode})
|
||||
tmp_update_record_dict.append(update_record_dict.copy())
|
||||
for ur in new_update_record:
|
||||
id,appname,version,description,date,status,keyword,errorcode = ur
|
||||
if errorcode in range(200):
|
||||
errorcode = 'null'
|
||||
update_record_dict.clear()
|
||||
update_record_dict.update({"appname":appname})
|
||||
update_record_dict.update({"version":version})
|
||||
update_record_dict.update({"time":date})
|
||||
update_record_dict.update({"description":description})
|
||||
update_record_dict.update({"icon":None})
|
||||
update_record_dict.update({"statue":status})
|
||||
update_record_dict.update({"keyword":'1'})
|
||||
update_record_dict.update({"errorcode":errorcode})
|
||||
tmp_update_record_dict.append(update_record_dict.copy())
|
||||
|
||||
# 按时间排序
|
||||
tmp_update_record_dict = sorted(tmp_update_record_dict, key=itemgetter('time'))
|
||||
print("更新installed success")
|
||||
|
||||
except Exception as e:
|
||||
print(e)
|
||||
print("更新安装记录错误")
|
||||
return
|
||||
|
||||
try:
|
||||
# 删除 tmp
|
||||
# DeleteTable(options.new_path+':'+'tmp')
|
||||
# 创建表
|
||||
sql_commnd = "create table IF NOT EXISTS tmp('id' INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,\
|
||||
'appname' TEXT,\
|
||||
'version' TEXT,\
|
||||
'description' TEXT,\
|
||||
'date' TEXT,\
|
||||
'status' TEXT,\
|
||||
'keyword' TEXT,\
|
||||
'errorcode' TEXT) "
|
||||
new_db_cursor.execute(sql_commnd)
|
||||
# 更新数据
|
||||
for urd in tmp_update_record_dict:
|
||||
new_db_cursor.execute(
|
||||
"insert into tmp (appname, version, description, date, status, keyword, errorcode) values(?,"
|
||||
"?,?,?,?,?,?)",
|
||||
(urd['appname'], urd['version'], urd['description'], urd['time'], urd['statue'], urd['keyword'], urd['errorcode']))
|
||||
new_db.commit()
|
||||
|
||||
# 删除updateinfos
|
||||
sql_commnd = "drop table updateinfos"
|
||||
new_db_cursor.execute(sql_commnd)
|
||||
new_db.commit()
|
||||
# 修改表名
|
||||
sql_commnd = "alter table tmp rename to updateinfos"
|
||||
new_db_cursor.execute(sql_commnd)
|
||||
new_db.commit()
|
||||
except Exception as e:
|
||||
print(e)
|
||||
print("安装记录迁移错误")
|
||||
return
|
||||
print("数据迁移成功.")
|
||||
|
||||
def CleanTable(db_table):
|
||||
db_path, table_name = str(db_table).split(":")
|
||||
if not os.path.isfile(db_path):
|
||||
print("db path error.")
|
||||
exit(-1)
|
||||
print(_("Loading Sqlite3Server..."))
|
||||
try:
|
||||
db = sqlite3.connect(db_path, check_same_thread=False)
|
||||
db_cursor = db.cursor()
|
||||
sql_commnd = 'delete from '+table_name
|
||||
db_cursor.execute(sql_commnd)
|
||||
db.commit()
|
||||
print("clean %s success."%table_name)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
print("clean %s error."%table_name)
|
||||
|
||||
def DeleteTable(db_table):
|
||||
db_path, table_name = str(db_table).split(":")
|
||||
if not os.path.isfile(db_path):
|
||||
print("db path error.")
|
||||
exit(-1)
|
||||
print(_("Loading Sqlite3Server..."))
|
||||
try:
|
||||
db = sqlite3.connect(db_path, check_same_thread=False)
|
||||
db_cursor = db.cursor()
|
||||
sql_commnd = 'drop table '+table_name
|
||||
db_cursor.execute(sql_commnd)
|
||||
db.commit()
|
||||
print("delete %s success."%table_name)
|
||||
except Exception as e:
|
||||
print("delete %s error: %s"%(table_name,e))
|
||||
|
||||
def _has_first_migration(new_db, new_db_cursor):
|
||||
try:
|
||||
sql_commnd = "select * from sqlite_master where type='table' and name='display';"
|
||||
new_db_cursor.execute(sql_commnd)
|
||||
retval = new_db_cursor.fetchone()
|
||||
for rv in retval:
|
||||
if "firstmigration" in str(rv):
|
||||
return True
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return False
|
||||
|
||||
def _is_first_migration(new_db, new_db_cursor):
|
||||
try:
|
||||
sql_commnd = "select firstmigration from display;"
|
||||
new_db_cursor.execute(sql_commnd)
|
||||
retval = new_db_cursor.fetchone()
|
||||
if "yes" in retval:
|
||||
return True
|
||||
else :
|
||||
return False
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return False
|
||||
|
||||
def _is_display_exist_fields(field, db, db_cursor):
|
||||
try:
|
||||
sql_commnd = "select * from sqlite_master where type='table' and name='display';"
|
||||
db_cursor.execute(sql_commnd)
|
||||
retval = db_cursor.fetchone()
|
||||
for rv in retval:
|
||||
if field in str(rv):
|
||||
return True
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return False
|
||||
return False
|
||||
|
||||
def _is_updateinfos_exist_fields(field, db, db_cursor):
|
||||
try:
|
||||
sql_commnd = "select * from sqlite_master where type='table' and name='updateinfos';"
|
||||
db_cursor.execute(sql_commnd)
|
||||
retval = db_cursor.fetchone()
|
||||
for rv in retval:
|
||||
if field in str(rv):
|
||||
return True
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return False
|
||||
return False
|
||||
|
||||
def _add_display_fields(fields_default, default_table = True):
|
||||
try:
|
||||
if "=" not in fields_default:
|
||||
print("format: field=value")
|
||||
return False
|
||||
field, value = fields_default.split('=')
|
||||
# print(_("Loading Sqlite3Server..."))
|
||||
db = sqlite3.connect(DB_UPGRADE, check_same_thread=False)
|
||||
db_cursor = db.cursor()
|
||||
if default_table:
|
||||
if _is_display_exist_fields(field, db, db_cursor):
|
||||
print("field %s is exist."%field)
|
||||
return False
|
||||
# 字段不存在,新增字段
|
||||
sql_commnd = "alter table display add column "+field+" TEXT;"
|
||||
db_cursor.execute(sql_commnd)
|
||||
sql_commnd = "UPDATE display SET "+field+"='"+value+"'"
|
||||
db_cursor.execute(sql_commnd)
|
||||
db.commit()
|
||||
else:
|
||||
if _is_updateinfos_exist_fields(field, db, db_cursor):
|
||||
print("field %s is exist."%field)
|
||||
return False
|
||||
# 字段不存在,新增字段
|
||||
sql_commnd = "alter table updateinfos add column "+field+" TEXT;"
|
||||
db_cursor.execute(sql_commnd)
|
||||
db.commit()
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return False
|
||||
print("Succeeded in adding field: '%s' "%field)
|
||||
return True
|
||||
|
||||
def _add_new_table(table):
|
||||
table = str(table).strip()
|
||||
if "=" not in table:
|
||||
return False
|
||||
opt, fields = table.split('=')
|
||||
try:
|
||||
if fields == 'tid_search':
|
||||
db = sqlite3.connect(DB_UPGRADE, check_same_thread=False)
|
||||
db_cursor = db.cursor()
|
||||
sql_commnd = "create table IF NOT EXISTS tid_search('id' INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,\
|
||||
'key' TEXT,\
|
||||
'tid' TEXT) "
|
||||
db_cursor.execute(sql_commnd)
|
||||
db.commit()
|
||||
db.close()
|
||||
except Exception as e:
|
||||
print(e)
|
||||
return False
|
||||
|
||||
def CopyData():
|
||||
try:
|
||||
# 判断新字段是否存在
|
||||
if (os.path.exists(VER_DB) and os.path.exists(DB_UPGRADE)):
|
||||
print(_("Loading Sqlite3Server..."))
|
||||
try:
|
||||
new_db = sqlite3.connect(DB_UPGRADE, check_same_thread=False)
|
||||
new_db_cursor = new_db.cursor()
|
||||
ver_db = sqlite3.connect(VER_DB, check_same_thread=False)
|
||||
ver_db_cursor = ver_db.cursor()
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
if (_has_first_migration(new_db, new_db_cursor)): # 存在 firstmigration
|
||||
if (_is_first_migration(new_db, new_db_cursor)):
|
||||
# 数据迁移
|
||||
dateMigration(new_db=new_db, new_db_cursor=new_db_cursor)
|
||||
sql_commnd = "UPDATE display SET firstmigration='no';"
|
||||
new_db_cursor.execute(sql_commnd)
|
||||
new_db.commit()
|
||||
else:
|
||||
print("No data migration is required ...")
|
||||
else:# 不存在firstmigration
|
||||
# 新增 firstmigration 字段
|
||||
sql_commnd = "alter table display add column firstmigration text;"
|
||||
new_db_cursor.execute(sql_commnd)
|
||||
sql_commnd = "UPDATE display SET firstmigration='yes';"
|
||||
new_db_cursor.execute(sql_commnd)
|
||||
#数据迁移
|
||||
dateMigration(new_db=new_db, new_db_cursor=new_db_cursor)
|
||||
sql_commnd = "UPDATE display SET firstmigration='no';"
|
||||
new_db_cursor.execute(sql_commnd)
|
||||
new_db.commit()
|
||||
|
||||
else :
|
||||
print("Not found kylin-system-updater.db, ensure that \'kylin-system-updater\' is successfully installed ... ")
|
||||
exit(-1)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Begin parsing of options
|
||||
parser = OptionParser()
|
||||
parser.add_option ("-d", "--debug", action="store_true", default=False,
|
||||
help=_("Show debug messages"))
|
||||
parser.add_option ("-o", "--old-path", dest="old_path",
|
||||
help=_("Enter the old database address"))
|
||||
parser.add_option ("-n", "--new-path", dest="new_path",
|
||||
help=_("Enter the new database address"))
|
||||
parser.add_option ("-c", "--clean-table", dest="clean_table",
|
||||
help=_("Clear the table"))
|
||||
parser.add_option ("-r", "--delete-table", dest="delete_table",
|
||||
help=_("Delete the table"))
|
||||
parser.add_option ("-m", "--data-migration", default=False, action="store_true",
|
||||
dest="data_migration", help=_("data migration"))
|
||||
parser.add_option ("-f", "--add-display-fields",
|
||||
dest="add_display_fields", help=_("add display fields"))
|
||||
parser.add_option ("-u", "--add-updateinfos-fields",
|
||||
dest="add_updateinfos_fields", help=_("add updateinfos fields"))
|
||||
parser.add_option ("-t", "--add-new-table",
|
||||
dest="add_new_table", help=_("add new table"))
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
if options.clean_table:
|
||||
if ":" not in options.clean_table:
|
||||
print("format error: <database:table>")
|
||||
else:
|
||||
CleanTable(str(options.clean_table))
|
||||
|
||||
if options.delete_table:
|
||||
if ":" not in options.delete_table:
|
||||
print("format error: <database:table>")
|
||||
else:
|
||||
DeleteTable(str(options.delete_table))
|
||||
|
||||
if options.add_display_fields:
|
||||
_add_display_fields(str(options.add_display_fields))
|
||||
|
||||
if options.add_updateinfos_fields:
|
||||
_add_display_fields(str(options.add_updateinfos_fields), default_table = False)
|
||||
|
||||
if options.add_new_table:
|
||||
_add_new_table(str(options.add_new_table))
|
||||
|
||||
if options.data_migration:
|
||||
CopyData()
|
||||
exit(0)
|
||||
|
||||
if options.old_path or options.new_path:
|
||||
# 检查文件
|
||||
if not options.old_path or not options.new_path:
|
||||
print("parameter error")
|
||||
exit(-1)
|
||||
if not os.path.isfile(options.old_path):
|
||||
print("The source database file does not exist")
|
||||
exit(-1)
|
||||
if not os.path.isfile(options.new_path):
|
||||
print("The destination database file does not exist")
|
||||
exit(-1)
|
||||
dateMigration(options)
|
|
@ -0,0 +1,683 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
from math import log10
|
||||
import os
|
||||
import re
|
||||
import json
|
||||
import yaml
|
||||
import shutil
|
||||
import sqlite3
|
||||
import logging
|
||||
import datetime
|
||||
from gettext import gettext as _
|
||||
from sys import exec_prefix
|
||||
from SystemUpdater.Core.DataAcquisition import PHPSeverSend
|
||||
from SystemUpdater.Core.UpdaterConfigParser import UpgradeConfig
|
||||
from SystemUpdater.Core.utils import get_config_patch
|
||||
|
||||
import apt_pkg
|
||||
from ..backend import InstallBackend
|
||||
|
||||
DB_FILE = os.path.join("/var/cache/kylin-system-updater/kylin-system-updater.db")
|
||||
# UMDB_FILE = os.path.join("/var/cache/kylin-system-updater/kylin-system-updater.db")
|
||||
INSTALLED_LIST = [{"item": "errorcode", "type": "int", "default": "0"}]
|
||||
DISPALY_LIST = []
|
||||
|
||||
class Sqlite3Server(object):
|
||||
def __init__(self, updateManager):
|
||||
self.connect = None
|
||||
self.window_main = updateManager
|
||||
self.config_path = get_config_patch()
|
||||
self.init_sqlit()
|
||||
|
||||
# uncoverable配置文件
|
||||
self.ucconfigs = UpgradeConfig(datadir = "/etc/kylin-version", name = "kylin-system-version.conf")
|
||||
self._system_version_config()
|
||||
|
||||
# 初始化连接数据库,修改为使用时连接
|
||||
def init_sqlit(self):
|
||||
try:
|
||||
logging.info(_("Initialize database files ..."))
|
||||
if not os.path.isfile(DB_FILE):
|
||||
if not os.path.isdir(os.path.dirname(DB_FILE)):
|
||||
os.makedirs(os.path.dirname(DB_FILE))
|
||||
shutil.copy("/usr/share/kylin-system-updater/kylin-system-updater.db", os.path.dirname(DB_FILE))
|
||||
except Exception as e:
|
||||
logging.error("Failed to initialize database files: %s", str(e))
|
||||
|
||||
#connect连接数据库
|
||||
def connect_database(self):
|
||||
try:
|
||||
logging.debug("Connect database ...")
|
||||
self.connect = sqlite3.connect(DB_FILE, check_same_thread=False)
|
||||
self.cursor = self.connect.cursor()
|
||||
except Exception as e:
|
||||
logging.error("Failed to connect database: %s", str(e))
|
||||
|
||||
#disconnect连接数据库
|
||||
def disconnect_database(self):
|
||||
try:
|
||||
logging.debug("Disconnect database ...")
|
||||
if self.connect != None:
|
||||
self.connect.close()
|
||||
if self.connect != None:
|
||||
del self.cursor
|
||||
except Exception as e:
|
||||
logging.error("Failed to disconnect database: %s", str(e))
|
||||
|
||||
# 数据库表格中动态增加新的字段用于扩展
|
||||
def insert_new_field(self):
|
||||
if len(INSTALLED_LIST) == 0 and len(DISPALY_LIST) == 0:
|
||||
return
|
||||
self.cursor.execute("select sql from sqlite_master where name='installed'")
|
||||
installed_sql = self.cursor.fetchone()[0]
|
||||
pattern = re.compile(r'\"\w+\"')
|
||||
installed_sql_list = pattern.findall(installed_sql)
|
||||
for value in INSTALLED_LIST:
|
||||
for field in installed_sql_list:
|
||||
if value["item"] == str(field).strip("\""):
|
||||
break
|
||||
elif field == installed_sql_list[len(installed_sql_list) - 1]:
|
||||
try:
|
||||
if value["default"] != "":
|
||||
sql = 'alter table installed add column "' + value["item"] + '" ' + value["type"] \
|
||||
+ ' default ' + str(value["default"])
|
||||
else:
|
||||
sql = 'alter table installed add column "' + value["item"] + '" ' + value["type"]
|
||||
self.cursor.execute(sql)
|
||||
logging.info(_("installed table insert new field: %s"), value["item"])
|
||||
except:
|
||||
logging.error(_("installed table failed to insert a new field:"), value["item"], exc_info=True)
|
||||
|
||||
self.cursor.execute("select sql from sqlite_master where name='display'")
|
||||
display_sql = self.cursor.fetchone()[0]
|
||||
pattern = re.compile(r'\"\w+\"')
|
||||
display_sql_list = pattern.findall(display_sql)
|
||||
for value in DISPALY_LIST:
|
||||
for field in display_sql_list:
|
||||
if value["item"] == str(field).strip("\""):
|
||||
break
|
||||
elif field == display_sql_list[len(display_sql_list) - 1]:
|
||||
try:
|
||||
if value["default"] != "":
|
||||
sql = 'alter table display add column "' + value["item"] + '" ' + value["type"] \
|
||||
+ ' default ' + str(value["default"])
|
||||
else:
|
||||
sql = 'alter table installed add column "' + value["item"] + '" ' + value["type"]
|
||||
self.cursor.execute(sql)
|
||||
logging.info(_("display table insert new field: %s"), value["item"])
|
||||
except:
|
||||
logging.error(_("display table failed to insert a new field: %s"), value["item"], exc_info=True)
|
||||
|
||||
# 写入数据到installed表中
|
||||
def insert_into_installed(self, *args, **kwargs):
|
||||
self.connect_database()
|
||||
self.cursor.execute(
|
||||
"insert into installed (appname, version, time, description, icon, statue, keyword, errorcode) values(?,"
|
||||
"?,?,?,?,?,?,?)", (args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]))
|
||||
self.connect.commit()
|
||||
logging.info("Database: Insert (%s=%s) To installed Complete ...", args[0], args[1])
|
||||
self.disconnect_database()
|
||||
|
||||
# 写入数据到display表中
|
||||
def insert_into_display(self, *args, **kwargs):
|
||||
self.connect_database()
|
||||
try:
|
||||
sql = "update display set " + args[0] + "='" + args[1] + "' where id = 1"
|
||||
self.cursor.execute(sql)
|
||||
self.connect.commit()
|
||||
except Exception as e:
|
||||
logging.error("Insert error: %s.", str(e))
|
||||
self.disconnect_database()
|
||||
return False
|
||||
logging.info("Database: Insert (%s=%s) To display Complete ...", args[0], args[1])
|
||||
self.disconnect_database()
|
||||
return True
|
||||
|
||||
# 写入数据到tid_search表中
|
||||
def insert_into_tid(self, *args, **kwargs):
|
||||
self.connect_database()
|
||||
self.cursor.execute(
|
||||
"insert into tid_search (key, tid) values(?,?)",
|
||||
(args[0], args[1]))
|
||||
self.connect.commit()
|
||||
logging.info("Database: Insert (%s=%s) To tid_search Complete ...", args[0], args[1])
|
||||
self.disconnect_database()
|
||||
|
||||
# 搜索tid_search表,获取tid值
|
||||
def select_from_tid(self, *args, **kwargs):
|
||||
retval = ''
|
||||
self.connect_database()
|
||||
try:
|
||||
sql = "select "+args[0]+" from tid_search where key='"+args[1]+"'"
|
||||
self.cursor.execute(sql)
|
||||
rets = self.cursor.fetchall()
|
||||
if len(rets)!= 0:
|
||||
if len(rets[0])!=0:
|
||||
ret_first = rets[0]
|
||||
retval = str(ret_first[0])
|
||||
except Exception as e:
|
||||
logging.error("Insert error: %s.", str(e))
|
||||
self.disconnect_database()
|
||||
logging.info("Database: Select tid_search data Complete...")
|
||||
self.disconnect_database()
|
||||
return retval
|
||||
|
||||
# 读出display表中数据
|
||||
def select_from_display(self, *args, **kwargs):
|
||||
self.connect_database()
|
||||
try:
|
||||
sql = "select "+args[0]+" from display"
|
||||
self.cursor.execute(sql)
|
||||
self.connect.commit()
|
||||
retval = str(self.cursor.fetchone()[0])
|
||||
except Exception as e:
|
||||
logging.error("select error: %s.", str(e))
|
||||
self.disconnect_database()
|
||||
return "Error"
|
||||
logging.info("Database: Search display Complete (%s) ...", args[0])
|
||||
self.disconnect_database()
|
||||
return retval
|
||||
|
||||
# 写入updateinfos表中
|
||||
def insert_into_updateinfo(self, *args, **kwargs):
|
||||
self.connect_database()
|
||||
try:
|
||||
self.cursor.execute(
|
||||
"insert into updateinfos (appname, version, description, date, status, keyword, errorcode, appname_cn, status_cn, changelog) values(?,"
|
||||
"?,?,?,?,?,?,?,?,?)",
|
||||
(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9]))
|
||||
self.connect.commit()
|
||||
except Exception as e:
|
||||
logging.error("Insert error: %s.", str(e))
|
||||
self.disconnect_database()
|
||||
logging.info(_("Database: Insert To updateinfos Complete..."))
|
||||
self.disconnect_database()
|
||||
|
||||
# 接收更新列表与信息,生成数据并插入数据库中
|
||||
def insert_info(self, mode, pkg_list=[], pkg_group=[], adjust_pkg=[], success = False, error_string = '', error_desc = ''):
|
||||
errstr = error_string + " " + error_desc
|
||||
status = " "
|
||||
status_cn = " "
|
||||
appname_cn = ""
|
||||
UpdateInfos = {}
|
||||
InstallInfos = {}
|
||||
time = datetime.datetime.now()
|
||||
timestr = datetime.datetime.strftime(time, "%Y-%m-%d %H:%M:%S")
|
||||
pkg_list = pkg_list.copy()
|
||||
pkg_group = pkg_group.copy()
|
||||
adjust_pkg = adjust_pkg.copy()
|
||||
# 更新列表空,无更新
|
||||
if not pkg_list and not pkg_group and mode != InstallBackend.MODE_INSTALL_SYSTEM:
|
||||
logging.info("There is no update.")
|
||||
return True
|
||||
|
||||
if success:
|
||||
status = 'success'
|
||||
status_cn = '成功'
|
||||
else:
|
||||
status = 'failed'
|
||||
status_cn = '失败'
|
||||
changeLog = ""
|
||||
|
||||
try:
|
||||
# 判断更新方式
|
||||
if mode == InstallBackend.MODE_INSTALL_PARTIAL: # 部分更新
|
||||
pkg_adj = ""
|
||||
# 判断更新包为单包或更新组
|
||||
if pkg_group:
|
||||
# 更新组
|
||||
pkgname = pkg_group.pop(0)
|
||||
pkgversion,pkgdescription,appname_cn = self.GetGroupmsg(pkgname)
|
||||
#更新信息update-infos
|
||||
UpdateInfos.update({"appname":str(pkgname)})
|
||||
UpdateInfos.update({"source":"Kylin System Updater"})
|
||||
UpdateInfos.update({"status":status})
|
||||
UpdateInfos.update({"errorCode":str(error_string+" "+error_desc)})
|
||||
self.window_main.collector.Upgrade_Process_Msg("finish-update", UpdateInfos.copy())
|
||||
#安装信息install-infos
|
||||
InstallInfos.update({"appname":str(pkgname)})
|
||||
if pkgname in self.window_main.update_list.upgrade_meta.versoin_pkgs['groups_upgrade'].keys():
|
||||
InstallInfos.update({"old_version":str(self.window_main.update_list.upgrade_meta.versoin_pkgs['groups_upgrade'][pkgname])})
|
||||
else:
|
||||
InstallInfos.update({"old_version":'UnKnown'})
|
||||
InstallInfos.update({"new_version":str(pkgversion)})
|
||||
InstallInfos.update({"status":status})
|
||||
InstallInfos.update({"errorCode":str(error_string+" "+error_desc)})
|
||||
self.window_main.collector.Upgrade_Process_Msg("finish-install", InstallInfos.copy())
|
||||
# 系统升级完成 ..判断版本号
|
||||
if status == "success" and "kylin-update-desktop-system" in pkgname:
|
||||
# 更新版本号
|
||||
if "=" in str(pkgversion):
|
||||
pkgversion = str(pkgversion).split('=')[-1]
|
||||
logging.info("Complete system upgrade, refresh system version ...")
|
||||
self._refresh_system_version(pkgversion)
|
||||
#移除step-two标记
|
||||
self._removal_of_marker()
|
||||
|
||||
#FIXME: 临时方案 PHP
|
||||
PHPSeverSend(_appname=pkgname, _appversion=pkgversion, _statue=status, _errorcode="10000100", _errorstring=errstr)
|
||||
file_path = os.path.join(get_config_patch(), str(pkgname) + ".yaml")
|
||||
with open(file_path, "r") as stream:
|
||||
try:
|
||||
data_yaml = yaml.safe_load(stream)
|
||||
changeLog = data_yaml['changelog']
|
||||
except yaml.YAMLError as exc:
|
||||
logging.error(exc)
|
||||
elif pkg_list:
|
||||
changeLog = " "
|
||||
# 单包更新 # 获取单包数据插入数据库
|
||||
pkgname = pkg_list.pop(0)
|
||||
for adj in adjust_pkg:
|
||||
if pkgname in adj:
|
||||
# 该部分升级的单包为调整版本,与候选版本不一致
|
||||
pkg_adj = adj
|
||||
break
|
||||
if pkg_adj: # 有调整的情况
|
||||
try:
|
||||
pkg = self.window_main.cache[pkg_adj.split("=")[0]]
|
||||
for ver in pkg.versions:
|
||||
if ver.version == pkg_adj.split("=")[1]:
|
||||
pkg_inst_ver = ver
|
||||
break
|
||||
pkgname = pkg_adj.split("=")[0]
|
||||
pkgversion = str(pkg_inst_ver.source_version)
|
||||
pkgdescription = str(pkg_inst_ver.description)
|
||||
except Exception as e:
|
||||
logging.error(_("%s could not be detected in the source because the source was changed or for other reasons."), \
|
||||
str(pkgname))
|
||||
logging.error(str(e))
|
||||
else: # 没有调整的情况
|
||||
try:
|
||||
pkg = self.window_main.cache[pkgname]
|
||||
pkgversion = str(pkg.candidate.version)
|
||||
pkgdescription = str(pkg.candidate.raw_description)
|
||||
except Exception as e:
|
||||
logging.error(str(e))
|
||||
|
||||
#更新信息update-infos
|
||||
UpdateInfos.update({"appname":str(pkgname)})
|
||||
UpdateInfos.update({"source":"Kylin System Updater"})
|
||||
UpdateInfos.update({"status":status})
|
||||
UpdateInfos.update({"errorCode":str(error_string+" "+error_desc)})
|
||||
self.window_main.collector.Upgrade_Process_Msg("finish-update", UpdateInfos.copy())
|
||||
#安装信息install-infos
|
||||
InstallInfos.update({"appname":str(pkgname)})
|
||||
if pkgname in self.window_main.update_list.upgrade_meta.versoin_pkgs['single_upgrade'].keys():
|
||||
InstallInfos.update({"old_version":str(self.window_main.update_list.upgrade_meta.versoin_pkgs['single_upgrade'][pkgname])})
|
||||
else:
|
||||
InstallInfos.update({"old_version":'UnKnown'})
|
||||
InstallInfos.update({"new_version":str(pkgversion)})
|
||||
InstallInfos.update({"status":status})
|
||||
InstallInfos.update({"errorCode":str(error_string+" "+error_desc)})
|
||||
self.window_main.collector.Upgrade_Process_Msg("finish-install", InstallInfos.copy())
|
||||
# 软件商店获取中文名
|
||||
appname_cn = self.get_cn_appname(str(pkgname))
|
||||
#FIXME: 临时方案 PHP
|
||||
PHPSeverSend(_appname=pkgname, _appversion=pkgversion, _statue=status, _errorcode="10000100", _errorstring=errstr)
|
||||
try:
|
||||
self.insert_into_updateinfo(pkgname, pkgversion, pkgdescription, timestr, status, "1", errstr, appname_cn, status_cn, changeLog)
|
||||
# FIXME: 发送插入数据库成功的信号local_upgrade_list
|
||||
self.window_main.dbusController.UpdateSqlitSingle(pkgname, timestr)
|
||||
# 数据库文件被删除或者新增字段导致需要重新初始化数据库再写入
|
||||
except Exception as e:
|
||||
self.init_sqlit()
|
||||
self.insert_into_updateinfo(pkgname, pkgversion, pkgdescription, timestr, status, "1", errstr, appname_cn, status_cn, changeLog)
|
||||
# FIXME: 这里也需要, 发送插入数据库成功的信号
|
||||
self.window_main.dbusController.UpdateSqlitSingle(pkgname, timestr)
|
||||
elif mode == InstallBackend.MODE_INSTALL_ALL: # 系统全部升级
|
||||
# # insert signal deb first
|
||||
for i in pkg_list:
|
||||
changeLog = ""
|
||||
try:
|
||||
pkg = self.window_main.cache[i]
|
||||
except Exception as e:
|
||||
logging.error(_("%s could not be detected in the source because the source was changed or for other reasons."), \
|
||||
str(i))
|
||||
continue
|
||||
if not pkg:
|
||||
continue
|
||||
pkgversion = str(pkg.candidate.version)
|
||||
pkgdescription = str(pkg.candidate.raw_description)
|
||||
|
||||
#更新信息update-infos
|
||||
UpdateInfos.update({"appname":str(pkg.name)})
|
||||
UpdateInfos.update({"source":"Kylin System Updater"})
|
||||
UpdateInfos.update({"status":status})
|
||||
UpdateInfos.update({"errorCode":str(error_string+" "+error_desc)})
|
||||
self.window_main.collector.Upgrade_Process_Msg("finish-update", UpdateInfos.copy())
|
||||
#安装信息install-infos
|
||||
InstallInfos.update({"appname":str(pkg.name)})
|
||||
if pkg.name in self.window_main.update_list.upgrade_meta.versoin_pkgs['groups_upgrade'].keys():
|
||||
InstallInfos.update({"old_version":str(self.window_main.update_list.upgrade_meta.versoin_pkgs['groups_upgrade'][pkg.name])})
|
||||
else:
|
||||
InstallInfos.update({"old_version":'UnKnown'})
|
||||
InstallInfos.update({"new_version":str(pkgversion)})
|
||||
InstallInfos.update({"status":status})
|
||||
InstallInfos.update({"errorCode":str(error_string+" "+error_desc)})
|
||||
self.window_main.collector.Upgrade_Process_Msg("finish-install", InstallInfos.copy())
|
||||
|
||||
try:
|
||||
# 软件商店获取中文名
|
||||
appname_cn = self.get_cn_appname(str(i))
|
||||
self.insert_into_updateinfo(str(i), pkgversion, pkgdescription, timestr, status, "1", errstr, appname_cn, status_cn, changeLog)
|
||||
self.window_main.dbusController.UpdateSqlitSingle(str(i), timestr)
|
||||
# 数据库文件被删除或者新增字段导致需要重新初始化数据库再写入
|
||||
except Exception as e:
|
||||
self.init_sqlit()
|
||||
self.insert_into_updateinfo(str(i), pkgversion, pkgdescription, timestr, status, "1", errstr, appname_cn, status_cn, changeLog)
|
||||
self.window_main.dbusController.UpdateSqlitSingle(str(i), timestr)
|
||||
#FIXME: 临时方案 PHP
|
||||
PHPSeverSend(_appname=pkg.name, _appversion=pkgversion, _statue=status, _errorcode="10000100", _errorstring=errstr)
|
||||
# insert group deb next
|
||||
for i in pkg_group:
|
||||
# FIXME: 获取组信息
|
||||
pkgversion,pkgdescription,appname_cn = self.GetGroupmsg(i)
|
||||
#更新信息update-infos
|
||||
UpdateInfos.update({"appname":str(i)})
|
||||
UpdateInfos.update({"source":"Kylin System Updater"})
|
||||
UpdateInfos.update({"status":status})
|
||||
UpdateInfos.update({"errorCode":str(error_string+" "+error_desc)})
|
||||
self.window_main.collector.Upgrade_Process_Msg("finish-update", UpdateInfos.copy())
|
||||
#安装信息install-infos
|
||||
InstallInfos.update({"appname":str(i)})
|
||||
if i in self.window_main.update_list.upgrade_meta.versoin_pkgs['groups_upgrade'].keys():
|
||||
InstallInfos.update({"old_version":str(self.window_main.update_list.upgrade_meta.versoin_pkgs['groups_upgrade'][i])})
|
||||
else:
|
||||
InstallInfos.update({"old_version":'UnKnown'})
|
||||
InstallInfos.update({"new_version":str(pkgversion)})
|
||||
InstallInfos.update({"status":status})
|
||||
InstallInfos.update({"errorCode":str(error_string+" "+error_desc)})
|
||||
json_file = json.dumps(InstallInfos.copy())
|
||||
try:
|
||||
self.window_main.collector.UpdateMsg("InstallInfos", json_file)
|
||||
except:
|
||||
pass
|
||||
|
||||
#FIXME: 临时方案 PHP
|
||||
PHPSeverSend(_appname=i, _appversion=pkgversion, _statue=status, _errorcode="10000100", _errorstring=errstr)
|
||||
file_path = os.path.join(get_config_patch(), str(i) + ".yaml")
|
||||
with open(file_path, "r") as stream:
|
||||
try:
|
||||
data_yaml = yaml.safe_load(stream)
|
||||
changeLog = data_yaml['changelog']
|
||||
except yaml.YAMLError as exc:
|
||||
logging.error(exc)
|
||||
try:
|
||||
self.insert_into_updateinfo(str(i), pkgversion, pkgdescription, timestr, status, "1", errstr, appname_cn, status_cn, changeLog)
|
||||
self.window_main.dbusController.UpdateSqlitSingle(str(i), timestr)
|
||||
# 数据库文件被删除或者新增字段导致需要重新初始化数据库再写入
|
||||
except Exception as e:
|
||||
self.init_sqlit()
|
||||
self.insert_into_updateinfo(str(i), pkgversion, pkgdescription, timestr, status, "1", errstr, appname_cn, status_cn, changeLog)
|
||||
self.window_main.dbusController.UpdateSqlitSingle(str(i), timestr)
|
||||
|
||||
# 系统升级完成 ..判断版本号
|
||||
if status == "success" and "kylin-update-desktop-system" in pkg_group:
|
||||
# 更新版本号
|
||||
if "=" in str(pkgversion):
|
||||
pkgversion = str(pkgversion).split('=')[-1]
|
||||
logging.info("Complete system upgrade, refresh system version ...")
|
||||
self._refresh_system_version(str(pkgversion))
|
||||
#移除step-two标记
|
||||
self._removal_of_marker()
|
||||
|
||||
elif mode == InstallBackend.MODE_INSTALL_SYSTEM: # 全盘升级
|
||||
self.insert_into_updateinfo(_("Upgrade System"), "", "This is a complete system upgrade, equivalent to the implementation of apt dist-upgrade", timestr, status, "1", errstr, str("全盘升级"), status_cn, " ")
|
||||
self.window_main.dbusController.UpdateSqlitSingle("Upgrade System", timestr)
|
||||
# 全盘更新完成 ..判断版本号
|
||||
if status == "success":
|
||||
# 更新版本号
|
||||
self._refresh_system_version(pseudo_version=True)
|
||||
#移除step-two标记
|
||||
self._removal_of_marker()
|
||||
else:
|
||||
logging.warning("Cache is None.")
|
||||
except Exception as e:
|
||||
logging.error("record update error: %s.",str(e))
|
||||
|
||||
# 获取group信息
|
||||
def GetGroupmsg(self, appname):
|
||||
jsonfile = appname+".json"
|
||||
files = os.listdir(self.config_path) #获取文件夹中所有文件
|
||||
if jsonfile in files: # 存在
|
||||
# 读取组JSON文件
|
||||
with open(self.config_path+jsonfile, "r") as f:
|
||||
try :
|
||||
data = json.load(f)
|
||||
except json.JSONDecodeError as e:
|
||||
logging.error(str(e))
|
||||
try:
|
||||
version = data['version']
|
||||
if "=" in version:
|
||||
version = version.split("=")[1].strip()
|
||||
tmpdescription = data['description']
|
||||
appname_cn = data['name']['zh_CN']
|
||||
except Exception as e:
|
||||
logging.error(str(e))
|
||||
if "zh_CN" in tmpdescription and "en_US" in tmpdescription:
|
||||
description = tmpdescription["zh_CN"] + ": " + tmpdescription["en_US"]
|
||||
return (version,description,appname_cn)
|
||||
else: # 不存在
|
||||
return (None, None, None)
|
||||
|
||||
def refreshpkglist(self):
|
||||
pkgs_install = []
|
||||
pkgs_upgrade = []
|
||||
pkgs_remove = []
|
||||
|
||||
for pkg in self.window_main.cache:
|
||||
try:
|
||||
if pkg.marked_install:
|
||||
pkgs_install.append(pkg.name)
|
||||
if pkg.marked_upgrade:
|
||||
pkgs_upgrade.append(pkg.name)
|
||||
elif pkg.marked_delete:
|
||||
pkgs_remove.append(pkg.name)
|
||||
except KeyError:
|
||||
# pkg missing from fresh_cache can't be modified
|
||||
pass
|
||||
return pkgs_install,pkgs_upgrade,pkgs_remove
|
||||
|
||||
def _removal_of_marker(self):
|
||||
try:
|
||||
marker_path = "/var/cache/kylin-update-manager/ignoreOrDelay"
|
||||
if os.path.exists(marker_path):
|
||||
with open(marker_path, 'r+') as f:
|
||||
line= f.readline()
|
||||
if "2107" in line or "2203" in line:
|
||||
f.seek(0)
|
||||
f.truncate()
|
||||
except Exception as e:
|
||||
logging.error("Removing the upgrade success mark error: %s.",str(e))
|
||||
|
||||
# #查找数据库
|
||||
# def find_msg_from_datebase(self, table, field, action = 'check', cid = 0):
|
||||
# # 查询数据
|
||||
# try:
|
||||
# sql = "select "+field+" from "+table
|
||||
# self.cursor.execute(sql)
|
||||
# update_count = self.cursor.fetchone()[0]
|
||||
# logging.info("%d history updates detected.", update_count)
|
||||
# except Exception as e:
|
||||
# logging.error("Check update error: %s", str(e))
|
||||
|
||||
def _system_version_config(self):
|
||||
self.connect_database()
|
||||
try:
|
||||
sql = "select init_version from display where id=1"
|
||||
self.cursor.execute(sql)
|
||||
_is_init_verison = self.cursor.fetchone()[0]
|
||||
if _is_init_verison == "yes":
|
||||
update_version, os_version = self.get_default_version()
|
||||
logging.info("Need to refresh version ...")
|
||||
self._refresh_system_version(update_version, os_version)
|
||||
sql = "update display set init_version = 'no'"
|
||||
self.cursor.execute(sql)
|
||||
self.connect.commit()
|
||||
except Exception as e:
|
||||
logging.error(str(e))
|
||||
self.disconnect_database()
|
||||
self.disconnect_database()
|
||||
|
||||
def _refresh_system_version(self, update_version='', os_version = '', pseudo_version = False):
|
||||
try:
|
||||
if "=" in update_version:
|
||||
update_version = str(update_version).split('=')[-1]
|
||||
if "=" in os_version:
|
||||
os_version = str(os_version).split('=')[-1]
|
||||
os_version = os_version.strip()
|
||||
update_version = update_version.strip()
|
||||
|
||||
#刷新系统版本号:os_version
|
||||
if update_version == '':
|
||||
update_version, os_version = self.get_default_version()
|
||||
if os_version == '' and os.path.isfile("/etc/os-release"):
|
||||
with open("/etc/os-release", "r+") as f:
|
||||
lines = f.readlines()
|
||||
for line in lines:
|
||||
if "KYLIN_RELEASE_ID" in line:
|
||||
os_version = line.split('=')[1]
|
||||
os_version = os_version.strip()
|
||||
if not pseudo_version:
|
||||
if len(os_version) != 0:
|
||||
self.ucconfigs.setValue("SYSTEM","os_version",str(os_version),True)
|
||||
if len(update_version) != 0:
|
||||
self.ucconfigs.setValue("SYSTEM","update_version",str(update_version),True)
|
||||
else:
|
||||
current_update_version, current_os_version = self.get_current_version()
|
||||
if current_os_version != os_version:
|
||||
os_version+='*'
|
||||
self.ucconfigs.setValue("SYSTEM","os_version",str(os_version),True)
|
||||
if current_update_version != update_version:
|
||||
update_version+='*'
|
||||
self.ucconfigs.setValue("SYSTEM","update_version",str(update_version),True)
|
||||
except Exception as e:
|
||||
logging.error("Refresh system version error: %s.",str(e))
|
||||
|
||||
def get_default_version(self):
|
||||
update_version = ""
|
||||
os_version = ""
|
||||
INPUT_CONFIG_PATH = self.config_path + 'kylin-update-desktop-system.json'
|
||||
if os.path.isfile(INPUT_CONFIG_PATH): # 存在
|
||||
# 读取JSON文件
|
||||
with open(INPUT_CONFIG_PATH, "r") as f:
|
||||
try :
|
||||
data = json.load(f)
|
||||
except json.JSONDecodeError as e:
|
||||
logging.error(str(e))
|
||||
try:
|
||||
update_version = data['version']
|
||||
if "=" in update_version:
|
||||
update_version = update_version.split('=')[-1].strip()
|
||||
except Exception as e:
|
||||
logging.error("get_default_version error: %s .",str(e))
|
||||
version_path = "/etc/os-release"
|
||||
if os.path.isfile(version_path):
|
||||
with open(version_path, "r+") as f:
|
||||
lines = f.readlines()
|
||||
for line in lines:
|
||||
if "KYLIN_RELEASE_ID" in line:
|
||||
os_version = line.split('=')[1]
|
||||
os_version = eval(os_version.strip())
|
||||
if update_version == "" and os_version != "":
|
||||
update_version = os_version
|
||||
elif update_version != "" and os_version == "":
|
||||
os_version = update_version
|
||||
return str(update_version),str(os_version)
|
||||
|
||||
def get_current_version(self):
|
||||
os_version = ''
|
||||
update_version = ''
|
||||
try:
|
||||
if not os.path.exists("/etc/kylin-version/kylin-system-version.conf"):
|
||||
logging.warning("System version file doesn't exist.")
|
||||
return os_version,update_version
|
||||
os_version = eval(str(self.window_main.sqlite3_server.ucconfigs.get("SYSTEM","os_version")))
|
||||
update_version = str(self.window_main.sqlite3_server.ucconfigs.get("SYSTEM","update_version"))
|
||||
except Exception as e:
|
||||
logging.error(str(e))
|
||||
return update_version,os_version
|
||||
logging.info('Current os_version: %s, release_id: %s .', os_version, update_version)
|
||||
return str(update_version),str(os_version)
|
||||
|
||||
def get_cn_appname(self, name):
|
||||
try:
|
||||
SC_DB_FILE = "/usr/share/kylin-software-center/data/uksc.db"
|
||||
if os.path.isfile(SC_DB_FILE):
|
||||
connect = sqlite3.connect(SC_DB_FILE, check_same_thread=False)
|
||||
cursor = connect.cursor()
|
||||
else:
|
||||
logging.warning("software center database isn't exist .")
|
||||
return ""
|
||||
sql = "select display_name_cn from application where display_name='"+name+"'"
|
||||
cursor.execute(sql)
|
||||
connect.commit()
|
||||
retval = cursor.fetchone()
|
||||
connect.close()
|
||||
if retval != None and len(retval) != 0:
|
||||
return str(retval[0])
|
||||
else:
|
||||
return ''
|
||||
except Exception as e:
|
||||
logging.error(_("Failed to initialize the database: %s"), str(e))
|
||||
return ''
|
||||
|
||||
def insert_upgrade_history(self, args, caller):
|
||||
caller_list = ['kylin-unattended-upgrade', "d-feet", "root"]
|
||||
_in_list = False
|
||||
for cl in caller_list:
|
||||
if caller in cl:
|
||||
_in_list = True
|
||||
if _in_list == False:
|
||||
logging.warning("Caller \" %s \": Operation without permission...", caller)
|
||||
return False
|
||||
# {"appname":GLib.Variant("s", "kylin-system-updater"), "version":GLib.Variant("s", "0.0")}
|
||||
# "description":GLib.Variant("s", "Update Manager for Kylin"), "date":GLib.Variant("s", "2022-07-27 15:23:51")
|
||||
# "status":GLib.Variant("s", "failed"), "keyword":GLib.Variant("s", "1")
|
||||
# "errorcode":GLib.Variant("s", "System upgrade is complete. "), "appname_cn":GLib.Variant("s", "音乐")
|
||||
upgrade_info = {}
|
||||
try:
|
||||
for it in args:
|
||||
upgrade_info[str(it)] = str(args[str(it)])
|
||||
logging.info("upgrade_info: %s", upgrade_info)
|
||||
|
||||
if "appname" in upgrade_info.keys() and "version" in upgrade_info.keys() \
|
||||
and "description" in upgrade_info.keys() \
|
||||
and "date" in upgrade_info.keys() \
|
||||
and "status" in upgrade_info.keys() \
|
||||
and "keyword" in upgrade_info.keys() \
|
||||
and "errorcode" in upgrade_info.keys() \
|
||||
and "appname_cn" in upgrade_info.keys() \
|
||||
and "status_cn" in upgrade_info.keys() \
|
||||
and "changelog" in upgrade_info.keys():
|
||||
appname = upgrade_info["appname"]
|
||||
if "kylin-unattended-upgrade" == appname:
|
||||
upgrade_info["appname"] = self.get_cn_appname(appname)
|
||||
if upgrade_info["appname"] == "":
|
||||
upgrade_info["appname"] = _("kylin-unattended-upgrade")
|
||||
if appname in self.window_main.cache and upgrade_info["description"] == "":
|
||||
pkg = self.window_main.cache[appname]
|
||||
if pkg.is_installed:
|
||||
upgrade_info["description"] = pkg.installed.description
|
||||
self.insert_into_updateinfo( upgrade_info["appname"], upgrade_info["version"], \
|
||||
upgrade_info["description"], \
|
||||
upgrade_info["date"], \
|
||||
upgrade_info["status"], \
|
||||
upgrade_info["keyword"], \
|
||||
upgrade_info["errorcode"], \
|
||||
upgrade_info["appname_cn"], \
|
||||
upgrade_info["status_cn"], \
|
||||
upgrade_info["changelog"] )
|
||||
else:
|
||||
logging.warning("Incomplete field.")
|
||||
return False
|
||||
except Exception as e:
|
||||
logging.error(e)
|
||||
return False
|
||||
return True
|
||||
|
||||
def listtojsonstr(lists):
|
||||
import json
|
||||
jsonfile = json.dumps(lists)
|
||||
return jsonfile
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,124 @@
|
|||
import os
|
||||
from gettext import gettext as _
|
||||
import apt
|
||||
import logging
|
||||
import fcntl
|
||||
import apt_pkg
|
||||
|
||||
|
||||
class LogInstallProgress(apt.progress.base.InstallProgress):
|
||||
""" Install progress that writes to self.progress_log
|
||||
(/var/run/unattended-upgrades.progress by default)
|
||||
"""
|
||||
def __init__(self,file):
|
||||
# type: (str) -> None
|
||||
apt.progress.base.InstallProgress.__init__(self)
|
||||
self.output_logfd = None # type: int
|
||||
self.filename=file
|
||||
self.error_pkg=""
|
||||
self.errormsg=""
|
||||
# raise Exception("for test!!!")
|
||||
|
||||
def error(self,pkg, errormsg):
|
||||
logging.error(("Install mode - dpkg, Install error: %s"), errormsg)
|
||||
self.error_pkg=self.filename
|
||||
self.errormsg = errormsg
|
||||
|
||||
def status_change(self, pkg, percent, status):
|
||||
# type: (str, float, str) -> None
|
||||
logging.info(("pkg:%s,percent:%s,status:%s"),pkg,percent,status)
|
||||
with open(self.progress_log, "w") as f:
|
||||
f.write(("%s")%percent)
|
||||
f.write(_("当前进度: %s ,正在安装:%s,当前状态:%s") % (percent, pkg,status))
|
||||
f.write(_("Progress: %s %% (%s)") % (percent, pkg))
|
||||
|
||||
def _fixup_fds(self):
|
||||
# () -> None
|
||||
required_fds = [0, 1, 2, # stdin, stdout, stderr
|
||||
self.writefd,
|
||||
self.write_stream.fileno(),
|
||||
self.statusfd,
|
||||
self.status_stream.fileno()
|
||||
]
|
||||
# ensure that our required fds close on exec
|
||||
for fd in required_fds[3:]:
|
||||
old_flags = fcntl.fcntl(fd, fcntl.F_GETFD)
|
||||
fcntl.fcntl(fd, fcntl.F_SETFD, old_flags | fcntl.FD_CLOEXEC)
|
||||
# close all fds
|
||||
try:
|
||||
# PEP-446 implemented in Python 3.4 made all descriptors
|
||||
# CLOEXEC, but we need to be able to pass writefd to dpkg
|
||||
# when we spawn it
|
||||
os.set_inheritable(self.writefd, True)
|
||||
except AttributeError: # if we don't have os.set_inheritable()
|
||||
pass
|
||||
proc_fd = "/proc/self/fd"
|
||||
if os.path.exists(proc_fd):
|
||||
error_count = 0
|
||||
for fdname in os.listdir(proc_fd):
|
||||
try:
|
||||
fd = int(fdname)
|
||||
except Exception:
|
||||
print("ERROR: can not get fd for %s" % fdname)
|
||||
if fd in required_fds:
|
||||
continue
|
||||
try:
|
||||
os.close(fd)
|
||||
# print("closed: ", fd)
|
||||
except OSError as e:
|
||||
# there will be one fd that can not be closed
|
||||
# as its the fd from pythons internal diropen()
|
||||
# so its ok to ignore one close error
|
||||
error_count += 1
|
||||
if error_count > 1:
|
||||
print("ERROR: os.close(%s): %s" % (fd, e))
|
||||
|
||||
def _redirect_stdin(self):
|
||||
# type: () -> None
|
||||
REDIRECT_INPUT = os.devnull
|
||||
fd = os.open(REDIRECT_INPUT, os.O_RDWR)
|
||||
os.dup2(fd, 0)
|
||||
|
||||
def _redirect_output(self):
|
||||
# type: () -> None
|
||||
# do not create log in dry-run mode, just output to stdout/stderr
|
||||
if not apt_pkg.config.find_b("Debug::pkgDPkgPM", False):
|
||||
logfd = self._get_logfile_dpkg_fd()
|
||||
os.dup2(logfd, 1)
|
||||
os.dup2(logfd, 2)
|
||||
|
||||
def _get_logfile_dpkg_fd(self):
|
||||
# type: () -> int
|
||||
logfd = os.open(
|
||||
"/var/log/kylin-system-updater/kylin-system-updater.log.1", os.O_RDWR | os.O_APPEND | os.O_CREAT, 0o640)
|
||||
try:
|
||||
import grp
|
||||
adm_gid = grp.getgrnam("adm").gr_gid
|
||||
os.fchown(logfd, 0, adm_gid)
|
||||
except (KeyError, OSError):
|
||||
pass
|
||||
return logfd
|
||||
|
||||
def update_interface(self):
|
||||
# type: () -> None
|
||||
# call super class first
|
||||
apt.progress.base.InstallProgress.update_interface(self)
|
||||
|
||||
def _log_in_dpkg_log(self, msg):
|
||||
# type: (str) -> None
|
||||
logfd = self._get_logfile_dpkg_fd()
|
||||
os.write(logfd, msg.encode("utf-8"))
|
||||
os.close(logfd)
|
||||
|
||||
def finish_update(self):
|
||||
# if error_status == 1:
|
||||
# os._exit(1)
|
||||
pass
|
||||
|
||||
def fork(self):
|
||||
pid = os.fork()
|
||||
if pid == 0:
|
||||
self._fixup_fds()
|
||||
self._redirect_stdin()
|
||||
self._redirect_output()
|
||||
return pid
|
|
@ -0,0 +1,69 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
#参考文档: https://cuiqingcai.com/6080.html
|
||||
|
||||
import os
|
||||
|
||||
path = '/var/log/kylin-system-updater/'
|
||||
|
||||
numlist = []
|
||||
|
||||
def get_FileSize(filePath):
|
||||
fsize = os.path.getsize(filePath)
|
||||
fsize = fsize / float(1024 * 1024)
|
||||
return round(fsize, 2)
|
||||
|
||||
#日志回滚
|
||||
def get_logfile():
|
||||
if not os.path.exists(path):
|
||||
os.makedirs(path)
|
||||
#优先获取当前未写满100M的日志编号文件
|
||||
for i in os.listdir(path):
|
||||
if "kylin-system-updater.log." in os.path.basename(path + i):
|
||||
numlist.append((path + i).split(".")[2])
|
||||
if get_FileSize(path + i) < 100:
|
||||
return path + i
|
||||
#获取1-5未使用的最小数字的标号作为日志文件
|
||||
for i in range(1, 6):
|
||||
if str(i) not in numlist:
|
||||
return(os.path.join(path, ("kylin-system-updater.log.%s") % i))
|
||||
try:
|
||||
#编号1-5日志文件均写满时,删除第一个,往前移动日志编号,获取最后一个编号作为日志文件
|
||||
if len(numlist) != 0:
|
||||
os.remove(os.path.join(path, "kylin-system-updater.log.1"))
|
||||
for i in range(2, 6):
|
||||
os.rename(os.path.join(path, ("kylin-system-updater.log.%s") % i),
|
||||
os.path.join(path, ("kylin-system-updater.log.%s") % (i - 1)))
|
||||
return os.path.join(path, "kylin-system-updater.log.5")
|
||||
#默认情况下未生成任何日志时使用编号1的日志文件
|
||||
else:
|
||||
return os.path.join(path, "kylin-system-updater.log.1")
|
||||
except:
|
||||
return os.path.join(path, "kylin-system-updater.log.1")
|
||||
|
||||
def upgrade_strategies_logfile():
|
||||
if not os.path.exists(path):
|
||||
os.makedirs(path)
|
||||
#优先获取当前未写满100M的日志编号文件
|
||||
for i in os.listdir(path):
|
||||
if "upgrade-strategies-daemon.log." in os.path.basename(path + i):
|
||||
numlist.append((path + i).split(".")[2])
|
||||
if get_FileSize(path + i) < 10:
|
||||
return path + i
|
||||
#获取1-5未使用的最小数字的标号作为日志文件
|
||||
for i in range(1, 6):
|
||||
if str(i) not in numlist:
|
||||
return(os.path.join(path, ("upgrade-strategies-daemon.log.%s") % i))
|
||||
try:
|
||||
#编号1-5日志文件均写满时,删除第一个,往前移动日志编号,获取最后一个编号作为日志文件
|
||||
if len(numlist) != 0:
|
||||
os.remove(os.path.join(path, "upgrade-strategies-daemon.log.1"))
|
||||
for i in range(2, 6):
|
||||
os.rename(os.path.join(path, ("upgrade-strategies-daemon.log.%s") % i),
|
||||
os.path.join(path, ("upgrade-strategies-daemon.log.%s") % (i - 1)))
|
||||
return os.path.join(path, "upgrade-strategies-daemon.log.5")
|
||||
#默认情况下未生成任何日志时使用编号1的日志文件
|
||||
else:
|
||||
return os.path.join(path, "upgrade-strategies-daemon.log.1")
|
||||
except:
|
||||
return os.path.join(path, "upgrade-strategies-daemon.log.1")
|
|
@ -0,0 +1,434 @@
|
|||
# MyCache.py
|
||||
# -*- Mode: Python; indent-tabs-mode: nil; tab-width: 4; coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2004-2008 Canonical
|
||||
#
|
||||
# Author: Michael Vogt <mvo@debian.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
# USA
|
||||
|
||||
from __future__ import absolute_import, print_function
|
||||
|
||||
import warnings
|
||||
warnings.filterwarnings("ignore", "apt API not stable yet", FutureWarning)
|
||||
import apt
|
||||
import apt_pkg
|
||||
import logging
|
||||
import os
|
||||
from urllib.error import HTTPError
|
||||
from urllib.request import urlopen
|
||||
from urllib.parse import urlsplit
|
||||
from http.client import BadStatusLine
|
||||
import socket
|
||||
import re
|
||||
import SystemUpdater.Core.DistUpgradeCache
|
||||
from gettext import gettext as _
|
||||
try:
|
||||
from launchpadlib.launchpad import Launchpad
|
||||
except ImportError:
|
||||
Launchpad = None
|
||||
|
||||
CHANGELOGS_POOL = "https://changelogs.ubuntu.com/changelogs/pool/"
|
||||
CHANGELOGS_URI = CHANGELOGS_POOL + "%s/%s/%s/%s_%s/%s"
|
||||
|
||||
|
||||
class HttpsChangelogsUnsupportedError(Exception):
|
||||
""" https changelogs with credentials are unsupported because of the
|
||||
lack of certitifcation validation in urllib2 which allows MITM
|
||||
attacks to steal the credentials
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class MyCache(SystemUpdater.Core.DistUpgradeCache.MyCache):
|
||||
|
||||
CHANGELOG_ORIGIN = "Ubuntu"
|
||||
|
||||
def __init__(self, progress, rootdir=None):
|
||||
apt.Cache.__init__(self, progress, rootdir)
|
||||
# save for later
|
||||
self.rootdir = rootdir
|
||||
# raise if we have packages in reqreinst state
|
||||
# and let the caller deal with that (runs partial upgrade)
|
||||
assert len(self.req_reinstall_pkgs) == 0
|
||||
# check if the dpkg journal is ok (we need to do that here
|
||||
# too because libapt will only do it when it tries to lock
|
||||
# the packaging system)
|
||||
if self._dpkgJournalDirty() == True:
|
||||
logging.info("dpkg was interrupted, you must manually run 'sudo dpkg --configure -a' to correct the problem.")
|
||||
# init the regular cache
|
||||
self._initDepCache()
|
||||
self.all_changes = {}
|
||||
self.all_news = {}
|
||||
# on broken packages, try to fix via saveDistUpgrade()
|
||||
# if self._depcache.broken_count > 0:
|
||||
# self.saveDistUpgrade()
|
||||
# assert (self._depcache.broken_count == 0
|
||||
# and self._depcache.del_count == 0)
|
||||
self.launchpad = None
|
||||
|
||||
def _dpkgJournalDirty(self):
|
||||
"""
|
||||
test if the dpkg journal is dirty
|
||||
(similar to debSystem::CheckUpdates)
|
||||
"""
|
||||
d = os.path.dirname(
|
||||
apt_pkg.config.find_file("Dir::State::status")) + "/updates"
|
||||
for f in os.listdir(d):
|
||||
if re.match("[0-9]+", f):
|
||||
return True
|
||||
return False
|
||||
|
||||
def _initDepCache(self):
|
||||
self._depcache.read_pinfile()
|
||||
self._depcache.init()
|
||||
|
||||
def clear(self):
|
||||
self._initDepCache()
|
||||
|
||||
@property
|
||||
def required_download(self):
|
||||
""" get the size of the packages that are required to download """
|
||||
pm = apt_pkg.PackageManager(self._depcache)
|
||||
fetcher = apt_pkg.Acquire()
|
||||
pm.get_archives(fetcher, self._list, self._records)
|
||||
return fetcher.fetch_needed
|
||||
|
||||
@property
|
||||
def install_count(self):
|
||||
return self._depcache.inst_count
|
||||
|
||||
def keep_count(self):
|
||||
return self._depcache.keep_count
|
||||
|
||||
@property
|
||||
def del_count(self):
|
||||
return self._depcache.del_count
|
||||
|
||||
def _check_dependencies(self, target, deps):
|
||||
"""Return True if any of the dependencies in deps match target."""
|
||||
# TODO: handle virtual packages
|
||||
for dep_or in deps:
|
||||
if not dep_or:
|
||||
continue
|
||||
match = True
|
||||
for base_dep in dep_or:
|
||||
if (base_dep.name != target.package.shortname
|
||||
or not apt_pkg.check_dep(
|
||||
target.version, base_dep.relation, base_dep.version)):
|
||||
match = False
|
||||
if match:
|
||||
return True
|
||||
return False
|
||||
|
||||
def find_removal_justification(self, pkg):
|
||||
target = pkg.installed
|
||||
if not target:
|
||||
return False
|
||||
for cpkg in self:
|
||||
candidate = cpkg.candidate
|
||||
if candidate is not None:
|
||||
if (self._check_dependencies(
|
||||
target, candidate.get_dependencies("Conflicts"))
|
||||
and self._check_dependencies(
|
||||
target, candidate.get_dependencies("Replaces"))):
|
||||
logging.info(
|
||||
"%s Conflicts/Replaces %s; allowing removal" % (
|
||||
candidate.package.shortname, pkg.shortname))
|
||||
return True
|
||||
return False
|
||||
|
||||
def saveDistUpgrade(self):
|
||||
""" this functions mimics a upgrade but will never remove anything """
|
||||
#upgrade(True) 为True时使用dist-upgrade进行升级
|
||||
self._depcache.upgrade(True)
|
||||
wouldDelete = self._depcache.del_count
|
||||
wouldDelete = 0
|
||||
if wouldDelete > 0:
|
||||
deleted_pkgs = [pkg for pkg in self if pkg.marked_delete]
|
||||
assert wouldDelete == len(deleted_pkgs)
|
||||
for pkg in deleted_pkgs:
|
||||
if self.find_removal_justification(pkg):
|
||||
wouldDelete -= 1
|
||||
if wouldDelete > 0:
|
||||
self.clear()
|
||||
assert (self._depcache.broken_count == 0
|
||||
and self._depcache.del_count == 0)
|
||||
# else:
|
||||
# assert self._depcache.broken_count == 0
|
||||
self._depcache.upgrade()
|
||||
return wouldDelete
|
||||
|
||||
def _strip_epoch(self, verstr):
|
||||
" strip of the epoch "
|
||||
vers_no_epoch = verstr.split(":")
|
||||
if len(vers_no_epoch) > 1:
|
||||
verstr = "".join(vers_no_epoch[1:])
|
||||
return verstr
|
||||
|
||||
def _get_changelog_or_news(self, name, fname, strict_versioning=False,
|
||||
changelogs_uri=None):
|
||||
" helper that fetches the file in question "
|
||||
# don't touch the gui in this function, it needs to be thread-safe
|
||||
pkg = self[name]
|
||||
|
||||
# get the src package name
|
||||
srcpkg = pkg.candidate.source_name
|
||||
|
||||
# assume "main" section
|
||||
src_section = "main"
|
||||
# use the section of the candidate as a starting point
|
||||
section = pkg._pcache._depcache.get_candidate_ver(pkg._pkg).section
|
||||
|
||||
# get the source version
|
||||
srcver_epoch = pkg.candidate.source_version
|
||||
srcver = self._strip_epoch(srcver_epoch)
|
||||
|
||||
split_section = section.split("/")
|
||||
if len(split_section) > 1:
|
||||
src_section = split_section[0]
|
||||
|
||||
# lib is handled special
|
||||
prefix = srcpkg[0]
|
||||
if srcpkg.startswith("lib"):
|
||||
prefix = "lib" + srcpkg[3]
|
||||
|
||||
# the changelogs_uri argument overrides the default changelogs_uri,
|
||||
# this is useful for e.g. PPAs where we construct the changelogs
|
||||
# path differently
|
||||
if changelogs_uri:
|
||||
uri = changelogs_uri
|
||||
else:
|
||||
uri = CHANGELOGS_URI % (src_section, prefix, srcpkg, srcpkg,
|
||||
srcver, fname)
|
||||
|
||||
# https uris are not supported when they contain a username/password
|
||||
# because the urllib2 https implementation will not check certificates
|
||||
# and so its possible to do a man-in-the-middle attack to steal the
|
||||
# credentials
|
||||
res = urlsplit(uri)
|
||||
if res.scheme == "https" and res.username:
|
||||
raise HttpsChangelogsUnsupportedError(
|
||||
"https locations with username/password are not"
|
||||
"supported to fetch changelogs")
|
||||
|
||||
# print("Trying: %s " % uri)
|
||||
changelog = urlopen(uri)
|
||||
#print(changelog.read())
|
||||
# do only get the lines that are new
|
||||
alllines = ""
|
||||
regexp = "^%s \\((.*)\\)(.*)$" % (re.escape(srcpkg))
|
||||
|
||||
while True:
|
||||
line = changelog.readline().decode("UTF-8", "replace")
|
||||
if line == "":
|
||||
break
|
||||
match = re.match(regexp, line)
|
||||
if match:
|
||||
# strip epoch from installed version
|
||||
# and from changelog too
|
||||
installed = getattr(pkg.installed, "version", None)
|
||||
if installed and ":" in installed:
|
||||
installed = installed.split(":", 1)[1]
|
||||
changelogver = match.group(1)
|
||||
if changelogver and ":" in changelogver:
|
||||
changelogver = changelogver.split(":", 1)[1]
|
||||
# we test for "==" here for changelogs
|
||||
# to ensure that the version
|
||||
# is actually really in the changelog - if not
|
||||
# just display it all, this catches cases like:
|
||||
# gcc-defaults with "binver=4.3.1" and srcver=1.76
|
||||
#
|
||||
# for NEWS.Debian we do require the changelogver > installed
|
||||
if strict_versioning:
|
||||
if (installed
|
||||
and apt_pkg.version_compare(changelogver,
|
||||
installed) < 0):
|
||||
break
|
||||
else:
|
||||
if (installed
|
||||
and apt_pkg.version_compare(changelogver,
|
||||
installed) == 0):
|
||||
break
|
||||
alllines = alllines + line
|
||||
return alllines
|
||||
|
||||
def _extract_ppa_changelog_uri(self, name):
|
||||
"""Return the changelog URI from the Launchpad API
|
||||
|
||||
Return None in case of an error.
|
||||
"""
|
||||
if not Launchpad:
|
||||
logging.warning("Launchpadlib not available, cannot retrieve PPA "
|
||||
"changelog")
|
||||
return None
|
||||
|
||||
cdt = self[name].candidate
|
||||
for uri in cdt.uris:
|
||||
if urlsplit(uri).hostname != 'ppa.launchpad.net':
|
||||
continue
|
||||
match = re.search('http.*/(.*)/(.*)/ubuntu/.*', uri)
|
||||
if match is not None:
|
||||
user, ppa = match.group(1), match.group(2)
|
||||
break
|
||||
else:
|
||||
logging.error("Unable to find a valid PPA candidate URL.")
|
||||
return
|
||||
|
||||
# Login on launchpad if we are not already
|
||||
if self.launchpad is None:
|
||||
self.launchpad = Launchpad.login_anonymously('update-manager',
|
||||
'production',
|
||||
version='devel')
|
||||
|
||||
archive = self.launchpad.archives.getByReference(
|
||||
reference='~%s/ubuntu/%s' % (user, ppa)
|
||||
)
|
||||
if archive is None:
|
||||
logging.error("Unable to retrieve the archive from the Launchpad "
|
||||
"API.")
|
||||
return
|
||||
|
||||
spphs = archive.getPublishedSources(source_name=cdt.source_name,
|
||||
exact_match=True,
|
||||
version=cdt.source_version)
|
||||
if not spphs:
|
||||
logging.error("No published sources were retrieved from the "
|
||||
"Launchpad API.")
|
||||
return
|
||||
|
||||
return spphs[0].changelogUrl()
|
||||
|
||||
def _guess_third_party_changelogs_uri_by_source(self, name):
|
||||
pkg = self[name]
|
||||
deb_uri = pkg.candidate.uri
|
||||
if deb_uri is None:
|
||||
return None
|
||||
srcrec = pkg.candidate.record.get("Source")
|
||||
if not srcrec:
|
||||
return None
|
||||
# srcpkg can be "apt" or "gcc-default (1.0)"
|
||||
srcpkg = srcrec.split("(")[0].strip()
|
||||
if "(" in srcrec:
|
||||
srcver = srcrec.split("(")[1].rstrip(")")
|
||||
else:
|
||||
srcver = pkg.candidate.source_version
|
||||
base_uri = deb_uri.rpartition("/")[0]
|
||||
return base_uri + "/%s_%s.changelog" % (srcpkg, srcver)
|
||||
|
||||
def _guess_third_party_changelogs_uri_by_binary(self, name):
|
||||
""" guess changelogs uri based on ArchiveURI by replacing .deb
|
||||
with .changelog
|
||||
"""
|
||||
# there is always a pkg and a pkg.candidate, no need to add
|
||||
# check here
|
||||
pkg = self[name]
|
||||
deb_uri = pkg.candidate.uri
|
||||
if deb_uri:
|
||||
return "%s.changelog" % deb_uri.rsplit(".", 1)[0]
|
||||
return None
|
||||
|
||||
def get_news_and_changelog(self, name, lock):
|
||||
self.get_news(name)
|
||||
self.get_changelog(name)
|
||||
try:
|
||||
lock.release()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def get_news(self, name):
|
||||
" get the NEWS.Debian file from the changelogs location "
|
||||
try:
|
||||
news = self._get_changelog_or_news(name, "NEWS.Debian", True)
|
||||
except Exception:
|
||||
return
|
||||
if news:
|
||||
self.all_news[name] = news
|
||||
|
||||
def _fetch_changelog_for_third_party_package(self, name, origins):
|
||||
# Special case for PPAs
|
||||
changelogs_uri_ppa = None
|
||||
for origin in origins:
|
||||
if origin.origin.startswith('LP-PPA-'):
|
||||
try:
|
||||
changelogs_uri_ppa = self._extract_ppa_changelog_uri(name)
|
||||
break
|
||||
except Exception:
|
||||
logging.exception("Unable to connect to the Launchpad "
|
||||
"API.")
|
||||
# Try non official changelog location
|
||||
changelogs_uri_binary = \
|
||||
self._guess_third_party_changelogs_uri_by_binary(name)
|
||||
changelogs_uri_source = \
|
||||
self._guess_third_party_changelogs_uri_by_source(name)
|
||||
error_message = ""
|
||||
for changelogs_uri in [changelogs_uri_ppa,
|
||||
changelogs_uri_binary,
|
||||
changelogs_uri_source]:
|
||||
if changelogs_uri:
|
||||
try:
|
||||
changelog = self._get_changelog_or_news(
|
||||
name, "changelog", False, changelogs_uri)
|
||||
self.all_changes[name] += changelog
|
||||
except (HTTPError, HttpsChangelogsUnsupportedError):
|
||||
# no changelogs_uri or 404
|
||||
error_message = _(
|
||||
"This update does not come from a "
|
||||
"source that supports changelogs.")
|
||||
except (IOError, BadStatusLine, socket.error):
|
||||
# network errors and others
|
||||
logging.exception("error on changelog fetching")
|
||||
error_message = _(
|
||||
"Failed to download the list of changes. \n"
|
||||
"Please check your Internet connection.")
|
||||
self.all_changes[name] += error_message
|
||||
|
||||
def get_changelog(self, name):
|
||||
" get the changelog file from the changelog location "
|
||||
origins = self[name].candidate.origins
|
||||
self.all_changes[name] = _("Changes for %s versions:\n"
|
||||
"Installed version: %s\n"
|
||||
"Available version: %s\n\n") % \
|
||||
(name, getattr(self[name].installed, "version", None),
|
||||
self[name].candidate.version)
|
||||
if self.CHANGELOG_ORIGIN not in [o.origin for o in origins]:
|
||||
self._fetch_changelog_for_third_party_package(name, origins)
|
||||
return
|
||||
# fixup epoch handling version
|
||||
srcpkg = self[name].candidate.source_name
|
||||
srcver_epoch = self[name].candidate.source_version.replace(':', '%3A')
|
||||
try:
|
||||
changelog = self._get_changelog_or_news(name, "changelog")
|
||||
if len(changelog) == 0:
|
||||
changelog = _("The changelog does not contain any relevant "
|
||||
"changes.\n\n"
|
||||
"Please use http://launchpad.net/ubuntu/+source/"
|
||||
"%s/%s/+changelog\n"
|
||||
"until the changes become available or try "
|
||||
"again later.") % (srcpkg, srcver_epoch)
|
||||
except HTTPError:
|
||||
changelog = _("The list of changes is not available yet.\n\n"
|
||||
"Please use http://launchpad.net/ubuntu/+source/"
|
||||
"%s/%s/+changelog\n"
|
||||
"until the changes become available or try again "
|
||||
"later.") % (srcpkg, srcver_epoch)
|
||||
except (IOError, BadStatusLine, socket.error) as e:
|
||||
print("caught exception: ", e)
|
||||
changelog = _("Failed to download the list "
|
||||
"of changes. \nPlease "
|
||||
"check your Internet "
|
||||
"connection.")
|
||||
self.all_changes[name] += changelog
|
|
@ -0,0 +1,580 @@
|
|||
#!/usr/bin/python3
|
||||
import apt
|
||||
import apt_pkg
|
||||
import fnmatch
|
||||
import logging
|
||||
import logging.handlers
|
||||
import re
|
||||
import os
|
||||
import sys
|
||||
import string
|
||||
import subprocess
|
||||
import json
|
||||
try:
|
||||
from typing import List
|
||||
from typing import Union
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
from gettext import gettext as _
|
||||
|
||||
SYSTEM_UPDATER_CORE_LIB_PATH="/usr/share/kylin-system-updater/"
|
||||
sys.path.append(SYSTEM_UPDATER_CORE_LIB_PATH)
|
||||
from SystemUpdater.Core.utils import get_config_patch
|
||||
|
||||
ImportantListPath="/var/lib/kylin-software-properties/template/important.list"
|
||||
SOURCESLIST = "/etc/apt/sources.list"
|
||||
|
||||
# no py3 lsb_release in debian :/
|
||||
DISTRO_CODENAME = subprocess.check_output(
|
||||
["lsb_release", "-c", "-s"], universal_newlines=True).strip() # type: str
|
||||
DISTRO_DESC = subprocess.check_output(
|
||||
["lsb_release", "-d", "-s"], universal_newlines=True).strip() # type: str
|
||||
DISTRO_ID = subprocess.check_output(
|
||||
["lsb_release", "-i", "-s"], universal_newlines=True).strip() # type: str
|
||||
|
||||
ARCHITECTUREMAP = ['arm64','amd64','armhf','i386','loongarch64','mips64el','sw64']
|
||||
|
||||
RELEASEOFFSET = 1
|
||||
ORIGINOFFSET = 2
|
||||
HTTPTYPE = "HTTP"
|
||||
FTPTYPE = "FTP"
|
||||
|
||||
class UpdateListFilterCache(apt.Cache):
|
||||
|
||||
def __init__(self, window_main):
|
||||
self.window_main = window_main
|
||||
# whitelist
|
||||
self.upgradeList = []
|
||||
# 必须升级的包
|
||||
self.installList = []
|
||||
|
||||
self.config_path = get_config_patch()
|
||||
|
||||
# 获取源属性
|
||||
self.origin_property = OriginProperty()
|
||||
self.origin_property.get_allowed_sources()
|
||||
self.origin_property.get_allowed_origin()
|
||||
|
||||
self.allowed_origins = get_allowed_origins(self.origin_property.allow_origin)
|
||||
|
||||
self.allowed_origins = deleteDuplicatedElementFromList(self.allowed_origins)
|
||||
logging.info(_("Allowed origins: %s"),
|
||||
self.allowed_origins)
|
||||
|
||||
# self.blacklist = apt_pkg.config.value_list(
|
||||
# "Kylin-system-updater::Package-Blacklist")
|
||||
# self.blacklist = deleteDuplicatedElementFromList(self.blacklist)
|
||||
|
||||
# self.whitelist = apt_pkg.config.value_list(
|
||||
# "Kylin-system-updater::Package-Whitelist")
|
||||
# self.whitelist = deleteDuplicatedElementFromList(self.whitelist)
|
||||
|
||||
# self.strict_whitelist = apt_pkg.config.find_b(
|
||||
# "Kylin-system-updater::Package-Whitelist-Strict", False)
|
||||
|
||||
def checkInCache(self):
|
||||
logging.info("start Check in cache")
|
||||
tmplist = []
|
||||
cache = apt.Cache()
|
||||
for i in self.upgradeList:
|
||||
try:
|
||||
cache[i]
|
||||
tmplist.append(i)
|
||||
except Exception as e:
|
||||
pass
|
||||
self.upgradeList = tmplist
|
||||
|
||||
def initLocalPackagesList(self):
|
||||
jsonfiles = []
|
||||
tmplist = []
|
||||
|
||||
# 获取importantlist 本次更新推送
|
||||
with open(ImportantListPath, 'r') as f:
|
||||
text = f.read()
|
||||
importantList = text.split()
|
||||
logging.info("importantList: %s",importantList)
|
||||
f.close()
|
||||
|
||||
if not importantList:
|
||||
logging.error("importantList is empty")
|
||||
exit(-1)
|
||||
|
||||
# 获取/usr/share/kylin-update-desktop-config/data/下所有json文件
|
||||
for root,dirs,files in os.walk(self.config_path):
|
||||
pass
|
||||
for i in files:
|
||||
if ".json" in i:
|
||||
jsonfiles.append(i.split('.')[0])
|
||||
|
||||
# 找到importantlist中对应的json文件
|
||||
for i in importantList:
|
||||
if i not in jsonfiles:
|
||||
# 说明这个是单独的包,不在分组中
|
||||
# 加入更新列表
|
||||
if i not in self.upgradeList:
|
||||
self.upgradeList.append(i)
|
||||
else:
|
||||
# 在分组中
|
||||
# 获取每个对应json文件中的upgrade_list
|
||||
if i in jsonfiles:
|
||||
filepath = os.path.join(self.config_path, i)
|
||||
filepath = filepath+".json"
|
||||
with open(filepath, 'r') as f:
|
||||
pkgdict = f.read()
|
||||
jsonfile = json.loads(pkgdict)
|
||||
tmplist = jsonfile['install_list']
|
||||
for j in tmplist:
|
||||
if j not in self.upgradeList:
|
||||
self.upgradeList.append(j)
|
||||
f.close()
|
||||
|
||||
# 更改:传入包列表,经过源过滤,返回的pkg中进行版本调整
|
||||
def check_in_allowed_origin(self, pkg_lists, _is_adjust):
|
||||
new_upgrade_pkgs = []
|
||||
adjust_candidate_pkgs = []
|
||||
for pkg in pkg_lists:
|
||||
try:
|
||||
new_ver = ver_in_allowed_origin(pkg, self.allowed_origins)
|
||||
if _is_adjust and len(new_ver) == 0:
|
||||
logging.warning("< %s > did not find a suitable version..." % pkg.name)
|
||||
continue
|
||||
if len(new_ver) == 0:
|
||||
continue
|
||||
if not pkg.installed: # 判断安装列表
|
||||
if pkg.candidate == new_ver[0] and pkg not in new_upgrade_pkgs:
|
||||
new_upgrade_pkgs.append(pkg)
|
||||
elif new_ver[0] != pkg.candidate and pkg not in new_upgrade_pkgs:
|
||||
logging.info("adjusting candidate version: %s" % new_ver[0])
|
||||
if _is_adjust == True:
|
||||
pkg.candidate = new_ver[0]
|
||||
adjust_candidate_pkgs.append(pkg.name+"="+pkg.candidate.version)
|
||||
new_upgrade_pkgs.append(pkg)
|
||||
else: # 判断升级列表
|
||||
for nv in new_ver:
|
||||
if nv > pkg.installed and nv != pkg.candidate:
|
||||
logging.info("adjusting candidate version: %s" % nv)
|
||||
if _is_adjust == True:
|
||||
pkg.candidate = nv
|
||||
adjust_candidate_pkgs.append(pkg.name+"="+pkg.candidate.version)
|
||||
break
|
||||
elif nv > pkg.installed and nv == pkg.candidate:
|
||||
new_upgrade_pkgs.append(pkg)
|
||||
break
|
||||
elif _is_adjust == True:
|
||||
logging.warning("< %s > did not find a suitable version..." % pkg.name)
|
||||
except NoAllowedOriginError:
|
||||
logging.error("Cannot found allowed version: %s", pkg.name)
|
||||
continue
|
||||
|
||||
return (new_upgrade_pkgs, adjust_candidate_pkgs)
|
||||
|
||||
def is_pkgname_in_blacklist(self, pkgs):
|
||||
blacklist_filter_pkgs = []
|
||||
for pkg in pkgs:
|
||||
if pkg.name in self.blacklist:
|
||||
pass
|
||||
else :
|
||||
blacklist_filter_pkgs.append(pkg)
|
||||
|
||||
return blacklist_filter_pkgs
|
||||
|
||||
def is_pkgname_in_whitelist(self, pkgs):
|
||||
whitelist_filter_upgrade_pkgs = []
|
||||
for pkg in pkgs:
|
||||
if pkg.name in self.upgradeList:
|
||||
whitelist_filter_upgrade_pkgs.append(pkg)
|
||||
else :
|
||||
pkg.mark_keep()
|
||||
return whitelist_filter_upgrade_pkgs
|
||||
|
||||
class OriginProperty():
|
||||
|
||||
def __init__(self):
|
||||
# 包含了本地所有源 http & ftp
|
||||
self.local_sourcelist = {"http":[],"ftp":[]}
|
||||
# 经过解析后的本地源,获取所有的分发属性
|
||||
self.local_origin = {"http":[],"ftp":[]}
|
||||
# 允许的源列表
|
||||
self.allow_sources = []
|
||||
# 允许的源+属性
|
||||
self.allow_origin = {"http":[],"ftp":[]}
|
||||
# 加载本地所有源
|
||||
self.init_local_origin()
|
||||
# 进行属性解析
|
||||
self.analytic_properties(self.local_sourcelist)
|
||||
|
||||
def init_local_origin(self):
|
||||
http_origin = {}
|
||||
ftp_orgin = {}
|
||||
#apt policy
|
||||
sh_retval = os.popen("apt-cache policy").read().split("\n")
|
||||
# policy = [ rv for rv in sh_retval if "http" in rv or "ftp" in rv or "release" in rv or "origin" in rv]
|
||||
for rv in sh_retval:
|
||||
if "http" in rv:
|
||||
http_origin['sources'] = rv
|
||||
http_origin['release'] = sh_retval[sh_retval.index(rv) + RELEASEOFFSET]
|
||||
http_origin['origin'] = sh_retval[sh_retval.index(rv) + ORIGINOFFSET]
|
||||
self.local_sourcelist['http'].append(http_origin.copy())
|
||||
elif "ftp" in rv:
|
||||
ftp_orgin['sources'] = rv
|
||||
ftp_orgin['release'] = sh_retval[sh_retval.index(rv) + RELEASEOFFSET]
|
||||
ftp_orgin['origin'] = sh_retval[sh_retval.index(rv) + ORIGINOFFSET]
|
||||
self.local_sourcelist['ftp'].append(ftp_orgin.copy())
|
||||
|
||||
def merge_origin(self, source_type, source_origin):
|
||||
is_append = True
|
||||
if source_type == HTTPTYPE:
|
||||
if self.local_origin['http']:
|
||||
for lo in self.local_origin['http']:
|
||||
if lo['origin_source'] == source_origin['origin_source'] and lo['dist'] == source_origin['dist']:
|
||||
lo['component'] = list(set(lo['component']).union(set(source_origin['component'])))
|
||||
is_append = False
|
||||
if is_append:
|
||||
self.local_origin['http'].append(source_origin.copy())
|
||||
else:
|
||||
self.local_origin['http'].append(source_origin.copy())
|
||||
elif source_type == FTPTYPE:
|
||||
if self.local_origin['ftp']:
|
||||
for lo in self.local_origin['ftp']:
|
||||
if lo['origin_source'] == source_origin['origin_source'] and lo['dist'] == source_origin['dist']:
|
||||
lo['component'] = list(set(lo['component']).union(set(source_origin['component'])))
|
||||
is_append = False
|
||||
if is_append:
|
||||
self.local_origin['ftp'].append(source_origin.copy())
|
||||
else:
|
||||
self.local_origin['ftp'].append(source_origin.copy())
|
||||
|
||||
def analytic_properties(self, local_sourcelist):
|
||||
http_origin = {"component":[],"release":{}}
|
||||
ftp_orgin = {"component":[],"release":{}}
|
||||
dist_list = []
|
||||
# 经过解析后的本地源,获取所有的分发属性
|
||||
for ls in local_sourcelist['http']:
|
||||
for item in filter(not_empty, ls['sources'].split(' ')):
|
||||
if item.isdigit():
|
||||
http_origin['policy_priority'] = item
|
||||
elif "http" in item:
|
||||
http_origin['origin_source'] = item
|
||||
elif "/" in item:
|
||||
dist_list = item.split("/")
|
||||
dist_list.pop()
|
||||
http_origin['dist'] = "/".join(dist_list)
|
||||
http_origin['component'].append(item.split("/")[1])
|
||||
elif item not in ARCHITECTUREMAP and item != "Packages":
|
||||
http_origin['component'].append(item)
|
||||
release_list = ls['release'].split(',')
|
||||
release_list = [ rl.strip() for rl in release_list ]
|
||||
if "release" in release_list[0]:
|
||||
release_list[0] = release_list[0].lstrip("release").strip()
|
||||
for rl in release_list:
|
||||
if "=" in rl:
|
||||
self.generate_dict(http_origin['release'], rl)
|
||||
for item in filter(not_empty, ls['origin'].split(' ')):
|
||||
if "origin" not in ls['origin']:
|
||||
break
|
||||
elif "origin" != item:
|
||||
http_origin['origin'] = item
|
||||
self.merge_origin(HTTPTYPE, http_origin)
|
||||
http_origin = {"component":[],"release":{}}
|
||||
|
||||
for ls in local_sourcelist['ftp']:
|
||||
for item in filter(not_empty, ls['sources'].split(' ')):
|
||||
if item.isdigit():
|
||||
ftp_orgin['policy_priority'] = item
|
||||
elif "ftp" in item:
|
||||
ftp_orgin['origin_source'] = item
|
||||
elif "/" in item:
|
||||
ftp_orgin['dist'] = item.split("/")[0]
|
||||
ftp_orgin['component'].append(item.split("/")[1])
|
||||
elif item not in ARCHITECTUREMAP and item != "Packages":
|
||||
ftp_orgin['component'].append(item)
|
||||
release_list = ls['release'].split(',')
|
||||
if "release " in release_list[0]:
|
||||
release_list[0] = release_list[0].lstrip("release ")
|
||||
for rl in release_list:
|
||||
if "=" in rl:
|
||||
self.generate_dict(ftp_orgin['release'], rl)
|
||||
for item in filter(not_empty, ls['origin'].split(' ')):
|
||||
if "origin" not in ls['origin']:
|
||||
break
|
||||
elif "origin" != item:
|
||||
ftp_orgin['origin'] = item
|
||||
self.merge_origin(FTPTYPE, ftp_orgin)
|
||||
ftp_orgin = {"component":[],"release":{}}
|
||||
|
||||
def generate_dict(self, dict, item):
|
||||
item = item.strip()
|
||||
if item == "":
|
||||
logging.warning("empty match string matches nothing")
|
||||
return False
|
||||
(what, value) = [ s for s in item.split("=")]
|
||||
if what in ('o', 'origin'):
|
||||
dict['origin'] = value
|
||||
elif what in ("l", "label"):
|
||||
dict['label'] = value
|
||||
elif what in ("a", "suite", "archive"):
|
||||
dict['archive'] = value
|
||||
elif what in ("c", "component"):
|
||||
dict['component'] = value
|
||||
elif what in ("site",):
|
||||
dict['site'] = value
|
||||
elif what in ("n", "codename",):
|
||||
dict['codename'] = value
|
||||
else:
|
||||
dict[what] = value
|
||||
# raise UnknownMatcherError(
|
||||
# "Unknown whitelist entry for matcher %s (value %s)" % (
|
||||
# what, value))
|
||||
|
||||
def get_allowed_sources(self):
|
||||
# 源地址,在本地源列表中查找. 源服务器下发source.list为允许的源, 本模块屏蔽了sources.list.d下的源
|
||||
# 获取允许的源
|
||||
try:
|
||||
old_sources_list = apt_pkg.config.find("Dir::Etc::sourcelist")
|
||||
old_sources_list_d = apt_pkg.config.find("Dir::Etc::sourceparts")
|
||||
old_cleanup = apt_pkg.config.find("APT::List-Cleanup")
|
||||
apt_pkg.config.set("Dir::Etc::sourcelist",
|
||||
os.path.abspath(SOURCESLIST))
|
||||
apt_pkg.config.set("Dir::Etc::sourceparts", "xxx")
|
||||
apt_pkg.config.set("APT::List-Cleanup", "0")
|
||||
slist = apt_pkg.SourceList()
|
||||
slist.read_main_list()
|
||||
self.allow_sources = slist.list
|
||||
except Exception as e:
|
||||
logging.error(str(e))
|
||||
finally:
|
||||
apt_pkg.config.set("Dir::Etc::sourcelist",
|
||||
old_sources_list)
|
||||
apt_pkg.config.set("Dir::Etc::sourceparts",
|
||||
old_sources_list_d)
|
||||
apt_pkg.config.set("APT::List-Cleanup",
|
||||
old_cleanup)
|
||||
|
||||
def get_allowed_origin(self):
|
||||
# 获取允许的源
|
||||
# 生成源与属性
|
||||
self.local_origin
|
||||
self.allow_sources
|
||||
self.allow_origin
|
||||
try:
|
||||
for item in self.allow_sources:
|
||||
for lo in self.local_origin['http']:
|
||||
if item.uri.strip('/') == lo['origin_source'].strip('/') and item.dist == lo['dist']:
|
||||
self.allow_origin['http'].append(lo)
|
||||
for lo in self.local_origin['ftp']:
|
||||
if item.uri.strip('/') == lo['origin_source'].strip('/') and item.dist == lo['dist']:
|
||||
self.allow_origin['ftp'].append(lo)
|
||||
except Exception as e:
|
||||
logging.error(str(e))
|
||||
|
||||
class UnattendUpgradeFilter():
|
||||
def __init__(self) -> None:
|
||||
pass
|
||||
|
||||
def GetAllowOrigins(self):
|
||||
# 获取源属性
|
||||
self.origin_property = OriginProperty()
|
||||
self.origin_property.get_allowed_sources()
|
||||
self.origin_property.get_allowed_origin()
|
||||
|
||||
self.allowed_origins = get_allowed_origins(self.origin_property.allow_origin)
|
||||
|
||||
self.allowed_origins = deleteDuplicatedElementFromList(self.allowed_origins)
|
||||
logging.info(_("Allowed origins: %s"),
|
||||
self.allowed_origins)
|
||||
return self.allowed_origins
|
||||
|
||||
|
||||
def ver_in_allowed_origin(pkg, allow_origin):
|
||||
# type: (apt.Package, List[str]) -> apt.package.Version
|
||||
allown_versions = []
|
||||
versions = _get_priority_order(pkg)
|
||||
# 获取每个优先级别中 允许源的最高版本
|
||||
allown_versions = _get_allowed_list(versions, allow_origin)
|
||||
|
||||
return allown_versions
|
||||
|
||||
def _get_priority_order(pkg):
|
||||
versions = []
|
||||
for ver in pkg.versions:
|
||||
if versions:
|
||||
for v in versions:
|
||||
if v.policy_priority >= ver.policy_priority and v == versions[-1]:
|
||||
break
|
||||
elif v.policy_priority >= ver.policy_priority and v != versions[-1]:
|
||||
continue
|
||||
else:
|
||||
index = versions.index(v)
|
||||
versions.insert(index,ver)
|
||||
break
|
||||
if v == versions[-1] and versions[-1].policy_priority >= ver.policy_priority:
|
||||
versions.append(ver)
|
||||
else:
|
||||
versions.append(ver)
|
||||
return versions
|
||||
|
||||
def _get_allowed_list(versions, allow_origin):
|
||||
current_priority = -100
|
||||
allown_versions = []
|
||||
for ver in versions:
|
||||
if current_priority != ver.policy_priority:
|
||||
if is_in_allowed_origin(ver, allow_origin):
|
||||
allown_versions.append(ver)
|
||||
current_priority = ver.policy_priority
|
||||
else:
|
||||
continue
|
||||
return allown_versions
|
||||
|
||||
def get_allowed_origins(allow_origin):
|
||||
""" return a list of allowed origins
|
||||
"""
|
||||
allowed_origins = []
|
||||
origin = ''
|
||||
archive = ''
|
||||
uri = ''
|
||||
label = ''
|
||||
for ao in (allow_origin['http']+allow_origin['ftp']):
|
||||
if 'origin' in ao['release']:
|
||||
origin = 'o='+ao['release']['origin']
|
||||
else:
|
||||
origin = 'o='
|
||||
if 'archive' in ao['release']:
|
||||
archive = 'a='+ao['release']['archive']
|
||||
else:
|
||||
archive = 'a='
|
||||
if 'label' in ao['release']:
|
||||
label = 'l='+ao['release']['label']
|
||||
else:
|
||||
label = 'l='
|
||||
if 'origin_source' in ao:
|
||||
uri = 'uri='+ao['origin_source']
|
||||
else:
|
||||
uri = 'uri='
|
||||
allowed_origins.append(origin+","+archive+","+label+","+uri)
|
||||
return allowed_origins
|
||||
|
||||
def get_allowed_origins_legacy():
|
||||
# type: () -> List[str]
|
||||
""" legacy support for old Allowed-Origins var """
|
||||
allowed_origins = [] # type: List[str]
|
||||
key = "Kylin-system-updater::Allowed-Origins"
|
||||
try:
|
||||
for s in apt_pkg.config.value_list(key):
|
||||
# if there is a ":" use that as seperator, else use spaces
|
||||
if re.findall(r'(?<!\\):', s):
|
||||
(distro_id, distro_codename) = re.split(r'(?<!\\):', s)
|
||||
else:
|
||||
(distro_id, distro_codename) = s.split()
|
||||
# unescape "\:" back to ":"
|
||||
distro_id = re.sub(r'\\:', ':', distro_id)
|
||||
# escape "," (see LP: #824856) - can this be simpler?
|
||||
distro_id = re.sub(r'([^\\]),', r'\1\\,', distro_id)
|
||||
distro_codename = re.sub(r'([^\\]),', r'\1\\,', distro_codename)
|
||||
# convert to new format
|
||||
allowed_origins.append("o=%s,a=%s" % (substitute(distro_id),
|
||||
substitute(distro_codename)))
|
||||
except ValueError:
|
||||
logging.error(_("Unable to parse %s." % key))
|
||||
raise
|
||||
return allowed_origins
|
||||
|
||||
def substitute(line):
|
||||
# type: (str) -> str
|
||||
""" substitude known mappings and return a new string
|
||||
|
||||
Currently supported ${distro-release}
|
||||
"""
|
||||
mapping = {"distro_codename": get_distro_codename(),
|
||||
"distro_id": get_distro_id()}
|
||||
return string.Template(line).substitute(mapping)
|
||||
|
||||
|
||||
def get_distro_codename():
|
||||
# type: () -> str
|
||||
return DISTRO_CODENAME
|
||||
|
||||
|
||||
def get_distro_id():
|
||||
# type: () -> str
|
||||
return DISTRO_ID
|
||||
|
||||
def is_in_allowed_origin(ver, allowed_origins):
|
||||
# type: (apt.package.Version, List[str]) -> bool
|
||||
if not ver:
|
||||
return False
|
||||
for origin in ver.origins:
|
||||
if is_allowed_origin(origin, allowed_origins):
|
||||
return True
|
||||
return False
|
||||
|
||||
def is_allowed_origin(origin, allowed_origins):
|
||||
# type: (Union[apt.package.Origin, apt_pkg.PackageFile], List[str]) -> bool
|
||||
for allowed in allowed_origins:
|
||||
if match_whitelist_string(allowed, origin):
|
||||
return True
|
||||
return False
|
||||
|
||||
def match_whitelist_string(whitelist, origin):
|
||||
# type: (str, Union[apt.package.Origin, apt_pkg.PackageFile]) -> bool
|
||||
"""
|
||||
take a whitelist string in the form "origin=Debian,label=Debian-Security"
|
||||
and match against the given python-apt origin. A empty whitelist string
|
||||
never matches anything.
|
||||
"""
|
||||
whitelist = whitelist.strip()
|
||||
if whitelist == "":
|
||||
logging.warning("empty match string matches nothing")
|
||||
return False
|
||||
res = True
|
||||
# make "\," the html quote equivalent
|
||||
whitelist = whitelist.replace("\\,", "%2C")
|
||||
for token in whitelist.split(","):
|
||||
# strip and unquote the "," back
|
||||
(what, value) = [s.strip().replace("%2C", ",")
|
||||
for s in token.split("=")]
|
||||
# logging.debug("matching %s=%s against %s" % (
|
||||
# what, value, origin))
|
||||
# support substitution here as well
|
||||
value = substitute(value)
|
||||
# first char is apt-cache policy output, send is the name
|
||||
# in the Release file
|
||||
if what in ("o", "origin"):
|
||||
match = fnmatch.fnmatch(origin.origin, value)
|
||||
elif what in ("l", "label"):
|
||||
match = fnmatch.fnmatch(origin.label, value)
|
||||
elif what in ("a", "suite", "archive"):
|
||||
match = fnmatch.fnmatch(origin.archive, value)
|
||||
elif what in ("c", "component"):
|
||||
match = fnmatch.fnmatch(origin.component, value)
|
||||
elif what in ("site",):
|
||||
match = fnmatch.fnmatch(origin.site, value)
|
||||
elif what in ("n", "codename",):
|
||||
match = fnmatch.fnmatch(origin.codename, value)
|
||||
elif what in ("uri",):
|
||||
match = True
|
||||
else:
|
||||
raise UnknownMatcherError(
|
||||
"Unknown whitelist entry for matcher %s (token %s)" % (
|
||||
what, token))
|
||||
# update res
|
||||
res = res and match
|
||||
# logging.debug("matching %s=%s against %s" % (
|
||||
# what, value, origin))
|
||||
return res
|
||||
|
||||
def deleteDuplicatedElementFromList(list):
|
||||
resultList = []
|
||||
for item in list:
|
||||
if not item in resultList:
|
||||
resultList.append(item)
|
||||
return resultList
|
||||
|
||||
def not_empty(s):
|
||||
return s and s.strip()
|
||||
|
||||
class UnknownMatcherError(ValueError):
|
||||
pass
|
||||
|
||||
class NoAllowedOriginError(ValueError):
|
||||
pass
|
|
@ -0,0 +1,633 @@
|
|||
# UpdateList.py
|
||||
|
||||
from gettext import gettext as _
|
||||
import logging
|
||||
import os
|
||||
import json
|
||||
import yaml
|
||||
import shutil
|
||||
from gi.repository import Gio
|
||||
from .OriginFilter import UpdateListFilterCache
|
||||
from .errors import *
|
||||
from .enums import *
|
||||
from SystemUpdater.Core.utils import get_config_patch
|
||||
|
||||
class LocalUpgradeDataList:
|
||||
"""
|
||||
Represent the (potentially partial) results of an unattended-upgrades
|
||||
run
|
||||
"""
|
||||
def __init__(self,
|
||||
groups_pkgs={},
|
||||
upgrade_groups=[],
|
||||
single_pkgs=[],
|
||||
adjust_pkgs=[],
|
||||
):
|
||||
#可升级的组列表
|
||||
self.upgrade_groups = upgrade_groups
|
||||
#组列表中包含的包
|
||||
self.groups_pkgs = groups_pkgs
|
||||
#推送的可升级的单包
|
||||
self.single_pkgs = single_pkgs
|
||||
#调整版本列表 源过滤
|
||||
self.adjust_pkgs = adjust_pkgs
|
||||
#加版本号的升级包
|
||||
self.versoin_pkgs = {'single_upgrade':{}, 'groups_upgrade':{}}
|
||||
|
||||
class UpdateList():
|
||||
OUTPUT_CONFIG_PATH = '/var/lib/kylin-system-updater/json/'
|
||||
IMPORTANT_LIST_PATH = '/var/lib/kylin-software-properties/template/important.list'
|
||||
|
||||
def __init__(self,parent):
|
||||
self.parent = parent
|
||||
|
||||
#所有的组升级安装列表
|
||||
self.upgrade_meta = LocalUpgradeDataList({},[],[],[])
|
||||
|
||||
if 'XDG_CURRENT_DESKTOP' in os.environ:
|
||||
self.current_desktop = os.environ.get('XDG_CURRENT_DESKTOP')
|
||||
else:
|
||||
self.current_desktop = ''
|
||||
|
||||
if 'XDG_DATA_DIRS' in os.environ and os.environ['XDG_DATA_DIRS']:
|
||||
data_dirs = os.environ['XDG_DATA_DIRS']
|
||||
else:
|
||||
data_dirs = '/usr/local/share/:/usr/share/'
|
||||
|
||||
self.application_dirs = [os.path.join(base, 'applications')
|
||||
for base in data_dirs.split(':')]
|
||||
|
||||
self.config_path = get_config_patch()
|
||||
|
||||
if self.parent.install_mode.check_filter() == True:
|
||||
#开启原过滤
|
||||
self.fu = UpdateListFilterCache(self.parent)
|
||||
else:
|
||||
self.fu = None
|
||||
logging.info("Close to Allowed origin fiter...")
|
||||
|
||||
|
||||
#清空上次输出的分组JSON文件
|
||||
def _empty_output_dir(self):
|
||||
#清空 升级列表
|
||||
if not os.path.exists(self.OUTPUT_CONFIG_PATH):
|
||||
os.makedirs(self.OUTPUT_CONFIG_PATH)
|
||||
logging.info('making the ConfigPath(%s) is complete...',self.OUTPUT_CONFIG_PATH)
|
||||
else:
|
||||
shutil.rmtree(self.OUTPUT_CONFIG_PATH)
|
||||
os.makedirs(self.OUTPUT_CONFIG_PATH)
|
||||
logging.info('Emptying the ConfigPath(%s) is complete...',self.OUTPUT_CONFIG_PATH)
|
||||
|
||||
#读取推送列表,判断分组和单包推送,再进行源过滤
|
||||
def _make_important_list(self,cache,pkgs_upgrade,important_list = []):
|
||||
upgradeable_pkgs = []
|
||||
tmp = []
|
||||
upgradeable_groups = []
|
||||
|
||||
logging.info("The Server Push List: %a",important_list)
|
||||
|
||||
for pkg_name in important_list:
|
||||
#检查是否在cache 没有在cache中属于组
|
||||
if pkg_name in cache:
|
||||
pkg_obj = cache[pkg_name]
|
||||
#在可升级的列表当中 此步骤为了排除已安装不需要升级的
|
||||
if pkg_obj.is_installed:
|
||||
if pkg_name in pkgs_upgrade:
|
||||
pkgs_upgrade.remove(pkg_name)
|
||||
tmp.append(pkg_obj)
|
||||
else:
|
||||
tmp.append(pkg_obj)
|
||||
else:
|
||||
upgradeable_groups.append(pkg_name)
|
||||
|
||||
if tmp != []:
|
||||
install_list,upgrade_list,adjust_pkgs = self._make_fiter_origin(tmp,True)
|
||||
self.upgrade_meta.adjust_pkgs.extend(adjust_pkgs)
|
||||
upgradeable_pkgs = install_list + upgrade_list
|
||||
|
||||
logging.info("Push Single Packages: %a, Push Groups:%a",upgradeable_pkgs,upgradeable_groups)
|
||||
return upgradeable_groups,upgradeable_pkgs
|
||||
|
||||
def _make_pkg_info_json(self,cache,pkgs_list):
|
||||
total_download_size = 0
|
||||
total_installed_size = 0
|
||||
pkgs_info_json = {}
|
||||
|
||||
for pkg_name in pkgs_list:
|
||||
pkg = cache[pkg_name]
|
||||
#当前版本
|
||||
cur_version = getattr(pkg.installed, "version", '')
|
||||
new_version = getattr(pkg.candidate, "version", '')
|
||||
|
||||
#获取下载大小
|
||||
download_size = getattr(pkg.candidate, "size", 0)
|
||||
installed_size = getattr(pkg.candidate, "installed_size", 0)
|
||||
|
||||
total_download_size = total_download_size + download_size
|
||||
total_installed_size = total_installed_size + installed_size
|
||||
|
||||
pkgs_info_json.update({pkg_name:{"cur_version":cur_version,"new_version":new_version,\
|
||||
"download_size":str(download_size),"install_size":str(installed_size)}})
|
||||
|
||||
pkgs_info_json.update({"total_download_size":str(total_download_size)})
|
||||
pkgs_info_json.update({"total_install_size":str(total_installed_size)})
|
||||
return pkgs_info_json
|
||||
|
||||
#检查包是否在cache中 返回新得列表没 有安装的话才添加到列表
|
||||
def _check_pkg_in_cache(self,cache,pkgs_list):
|
||||
new_pkgs_list = []
|
||||
for pkg_name in pkgs_list:
|
||||
#检查是否在cache 以及 是否安装检查
|
||||
if pkg_name in cache and not cache[pkg_name].is_installed:
|
||||
new_pkgs_list.append(pkg_name)
|
||||
else:
|
||||
pass
|
||||
return new_pkgs_list
|
||||
|
||||
def _make_group_output_json(self,data,data_yaml,upgrade_pkgs_json,install_pkgs_json):
|
||||
groups_base_info = {}
|
||||
output_json = {}
|
||||
|
||||
#FIXME: 确定输出文件的文件名 以及放置位置
|
||||
output_config_name = self.OUTPUT_CONFIG_PATH + data['package'] + '.json'
|
||||
|
||||
#4、添加一些基础信息
|
||||
groups_base_info.update({"package":data['package']})
|
||||
groups_base_info.update({"new_version":data['version']})
|
||||
groups_base_info.update({"name":data['name']})
|
||||
groups_base_info.update({"description":data['description']})
|
||||
groups_base_info.update({"icon":data['icon']})
|
||||
|
||||
#添加读yaml文件
|
||||
groups_base_info.update({"changelog":data_yaml['changelog']})
|
||||
|
||||
#5、添加升级的内容
|
||||
output_json.update(groups_base_info)
|
||||
output_json.update({"upgrade_list":upgrade_pkgs_json})
|
||||
output_json.update({"install_list":install_pkgs_json})
|
||||
# output_json.update({"hold_list":hold_pkgs_list})
|
||||
# output_json.update({"remove_list":remove_pkgs_list})
|
||||
|
||||
#6 产生JSON文件
|
||||
with open(output_config_name, 'w', encoding='utf-8') as f:
|
||||
json.dump(output_json, f, ensure_ascii=False, indent=4)
|
||||
logging.info("Generate Jsonfile(%s) to complete... ",output_config_name)
|
||||
|
||||
#进行源过滤,is_adjust 是否调整cache中的候选版本,单包推送会调整保持控制面板显示正确的版本
|
||||
def _make_fiter_origin(self,pkgs_list,adjust_versions):
|
||||
install_pkgs = []
|
||||
upgrade_pkgs = []
|
||||
adjust_pkgs = []
|
||||
|
||||
#是否进行源过滤的选项
|
||||
if self.fu != None:
|
||||
try:
|
||||
after_pkgs_list,adjust_pkgs = self.fu.check_in_allowed_origin(pkgs_list,adjust_versions)
|
||||
except Exception as e:
|
||||
after_pkgs_list = pkgs_list
|
||||
logging.error("Check Allowed origin is occur error:" + str(e))
|
||||
else:
|
||||
after_pkgs_list = pkgs_list
|
||||
adjust_pkgs = []
|
||||
|
||||
for pkg_obj in after_pkgs_list:
|
||||
if pkg_obj.is_installed:
|
||||
upgrade_pkgs.append(pkg_obj.name)
|
||||
else:
|
||||
install_pkgs.append(pkg_obj.name)
|
||||
|
||||
return install_pkgs,upgrade_pkgs,adjust_pkgs
|
||||
|
||||
#从本地中获取本次升级需要升级的包 部分升级和全部升级使用 全盘升级不适用
|
||||
def _make_pkgs_list(self,cache,groups_pkgs,groups_list,pkg_list):
|
||||
pkgs_install = []
|
||||
pkgs_upgrade = []
|
||||
|
||||
#单包的升级方式
|
||||
for pkg in pkg_list:
|
||||
if cache[pkg].is_installed:
|
||||
pkgs_upgrade.append(pkg)
|
||||
else:
|
||||
pkgs_install.append(pkg)
|
||||
|
||||
#遍历升级组列表
|
||||
for group_name in groups_list:
|
||||
pkgs_install += groups_pkgs.get(group_name,[]).get('pkgs_install',[])
|
||||
pkgs_upgrade += groups_pkgs.get(group_name,[]).get('pkgs_upgrade',[])
|
||||
|
||||
return pkgs_install,pkgs_upgrade
|
||||
|
||||
#输出白名单的配置
|
||||
def _make_autoupgrade_config(self,cache,upgrade_data,_adjust_pkgs):
|
||||
pkgs_install,pkgs_upgrade = self._make_pkgs_list(cache,upgrade_data.groups_pkgs,upgrade_data.upgrade_groups,upgrade_data.single_pkgs)
|
||||
split_adjust_pkgs = [i.split("=")[0] for i in _adjust_pkgs]
|
||||
|
||||
output_config_name = self.OUTPUT_CONFIG_PATH + 'auto-upgrade-list.json'
|
||||
output_json = {}
|
||||
install_info = {}
|
||||
for pkg in pkgs_install:
|
||||
pkg_cache = cache[pkg]
|
||||
pkgs_json = {}
|
||||
pkgs_json.update({"cur_version":getattr(pkg_cache.installed, "version", '')})
|
||||
|
||||
if pkg in split_adjust_pkgs:
|
||||
version_adjust = _adjust_pkgs[split_adjust_pkgs.index(pkg)].split("=")[1]
|
||||
pkgs_json.update({"new_version":version_adjust})
|
||||
else:
|
||||
pkgs_json.update({"new_version":getattr(pkg_cache.candidate, "version", '')})
|
||||
install_info.update({pkg:pkgs_json})
|
||||
|
||||
upgrade_json = {}
|
||||
for pkg in pkgs_upgrade:
|
||||
pkg_cache = cache[pkg]
|
||||
pkgs_json = {}
|
||||
pkgs_json.update({"cur_version":getattr(pkg_cache.installed, "version", '')})
|
||||
|
||||
if pkg in split_adjust_pkgs:
|
||||
version_adjust = _adjust_pkgs[split_adjust_pkgs.index(pkg)].split("=")[1]
|
||||
pkgs_json.update({"new_version":version_adjust})
|
||||
else:
|
||||
pkgs_json.update({"new_version":getattr(pkg_cache.candidate, "version", '')})
|
||||
|
||||
upgrade_json.update({pkg:pkgs_json})
|
||||
|
||||
group_json = {}
|
||||
for ug in self.upgrade_meta.groups_pkgs:
|
||||
pkgs_json = {}
|
||||
with open(self.config_path + str(ug) + ".yaml", "r") as stream:
|
||||
try:
|
||||
data_yaml = yaml.safe_load(stream)
|
||||
pkgs_json.update({"cur_version":""})
|
||||
pkgs_json.update({"new_version":data_yaml["version"]})
|
||||
pkgs_json.update({"changelog":data_yaml["changelog"]})
|
||||
except yaml.YAMLError as exc:
|
||||
logging.error(exc)
|
||||
group_json.update({ug:pkgs_json})
|
||||
|
||||
single_json = {}
|
||||
for us in self.upgrade_meta.single_pkgs:
|
||||
pkg_cache = cache[us]
|
||||
pkgs_json = {}
|
||||
pkgs_json.update({"cur_version":getattr(pkg_cache.installed, "version", '')})
|
||||
|
||||
if pkg in split_adjust_pkgs:
|
||||
version_adjust = _adjust_pkgs[split_adjust_pkgs.index(pkg)].split("=")[1]
|
||||
pkgs_json.update({"new_version":version_adjust})
|
||||
else:
|
||||
pkgs_json.update({"new_version":getattr(pkg_cache.candidate, "version", '')})
|
||||
pkgs_json.update({"changelog":""})
|
||||
single_json.update({us:pkgs_json})
|
||||
|
||||
output_json.update({"upgrade_list":upgrade_json})
|
||||
output_json.update({"install_list":install_info})
|
||||
output_json.update({"group_json":group_json})
|
||||
output_json.update({"single_json":single_json})
|
||||
|
||||
#产生JSON文件
|
||||
with open(output_config_name, 'w', encoding='utf-8') as f:
|
||||
json.dump(output_json, f, ensure_ascii=False, indent=4)
|
||||
logging.info("Generate AutoUpgrade Configfile to Complete and Jsonfile(%s) to complete... ",output_config_name)
|
||||
|
||||
def _split_package_id(self,package):
|
||||
"""Return the name, the version number and the release of the
|
||||
specified package."""
|
||||
if "=" in package:
|
||||
name, version = package.split("=", 1)
|
||||
release = None
|
||||
elif "/" in package:
|
||||
name, release = package.split("/", 1)
|
||||
version = None
|
||||
else:
|
||||
name = package
|
||||
version = release = None
|
||||
return name, version, release
|
||||
|
||||
def _make_downgrade(self,cache,downgrade_pkgs):
|
||||
output_downgrade = []
|
||||
adjust_pkgs = []
|
||||
for pkg_name, pkg_ver, pkg_rel in [self._split_package_id(pkg)
|
||||
for pkg in downgrade_pkgs]:
|
||||
try:
|
||||
pkg = cache[pkg_name]
|
||||
except KeyError:
|
||||
logging.warning("Package %s isn't available",pkg_name)
|
||||
continue
|
||||
if not pkg.is_installed:
|
||||
logging.warning("Package %s isn't installed",pkg_name)
|
||||
|
||||
if pkg_ver:
|
||||
if pkg.installed and pkg.installed.version < pkg_ver:
|
||||
logging.warning("The former version %s of %s is already installed",pkg.installed.version, pkg.name)
|
||||
continue
|
||||
elif pkg.installed and pkg.installed.version == pkg_ver:
|
||||
logging.warning("The version %s of %s is already installed",pkg.installed.version, pkg.name)
|
||||
continue
|
||||
|
||||
try:
|
||||
pkg.candidate = pkg.versions[pkg_ver]
|
||||
except KeyError:
|
||||
logging.warning("The version %s of %s isn't available",pkg_ver, pkg_name)
|
||||
continue
|
||||
|
||||
output_downgrade.append(pkg_name)
|
||||
adjust_pkgs.append(pkg_name+'='+pkg_ver)
|
||||
|
||||
return output_downgrade,adjust_pkgs
|
||||
|
||||
def _get_downgrade_list(self,cache,data):
|
||||
downgrade_pkgs = []
|
||||
|
||||
try:
|
||||
downgrade_raw = data['force_install_list']
|
||||
except Exception as e:
|
||||
downgrade_raw = []
|
||||
|
||||
for pkg_name, pkg_ver, pkg_rel in [self._split_package_id(pkg)
|
||||
for pkg in downgrade_raw]:
|
||||
|
||||
if pkg_name in cache:
|
||||
downgrade_pkgs.append(pkg_name)
|
||||
else:
|
||||
logging.warning("Package %s isn't available",pkg_name)
|
||||
continue
|
||||
|
||||
return downgrade_raw,downgrade_pkgs
|
||||
|
||||
def _make_groups_pkgs(self,cache,data,pkgs_upgrade = []):
|
||||
|
||||
upgrade_pkgs_list = data['upgrade_list']
|
||||
#检查包是否在cache中 以及是否已经安装 没有安装的话才添加到列表
|
||||
new_install_list = self._check_pkg_in_cache(cache,data['install_list'])
|
||||
|
||||
downgrade_raw,downgrade_pkgs = self._get_downgrade_list(cache,data)
|
||||
#被降级的软件包优先级最高
|
||||
for pkg in downgrade_pkgs:
|
||||
if pkg in upgrade_pkgs_list:
|
||||
upgrade_pkgs_list.remove(pkg)
|
||||
if pkg in new_install_list:
|
||||
new_install_list.remove(pkg)
|
||||
if pkg in self.upgrade_meta.single_pkgs:
|
||||
self.upgrade_meta.single_pkgs.remove(pkg)
|
||||
|
||||
#进行交集 升级列表
|
||||
new_upgrade_list = list(set(pkgs_upgrade) & set(upgrade_pkgs_list))
|
||||
|
||||
#进行源过滤
|
||||
new_install_list,new_upgrade_list,adjust_pkgs = self._make_fiter_origin([cache[pkg] for pkg in new_install_list + new_upgrade_list],False)
|
||||
self.upgrade_meta.adjust_pkgs.extend(adjust_pkgs)
|
||||
|
||||
#在总升级列表中移除这些包
|
||||
for pkg in new_upgrade_list:
|
||||
pkgs_upgrade.remove(pkg)
|
||||
|
||||
downgrade_pkg,adjust_pkgs = self._make_downgrade(cache,downgrade_raw)
|
||||
self.upgrade_meta.adjust_pkgs.extend(adjust_pkgs)
|
||||
new_upgrade_list.extend(downgrade_pkg)
|
||||
|
||||
#单包的优先级最高 从组中剔除此包
|
||||
for pkg in self.upgrade_meta.single_pkgs:
|
||||
if pkg in new_install_list:
|
||||
new_install_list.remove(pkg)
|
||||
|
||||
return new_install_list,new_upgrade_list
|
||||
|
||||
|
||||
def _make_groups_upgrade(self,cache,group_list,is_openkylin,pkgs_install,pkgs_upgrade):
|
||||
upgrade_list = []
|
||||
install_list = []
|
||||
|
||||
if os.path.isdir(self.config_path) == False:
|
||||
logging.warning("configPath(%s) is not exists...",self.config_path)
|
||||
return
|
||||
|
||||
files = os.listdir(self.config_path) #获得文件夹中所有文件的名称列表
|
||||
|
||||
for ifile in files:
|
||||
#判是否是目录以及是否以JSON结尾
|
||||
if ifile.endswith('.json'):
|
||||
#读取组JSON文件
|
||||
with open(self.config_path+ifile,'r') as f:
|
||||
try:
|
||||
data = json.load(f)
|
||||
except Exception as exc:
|
||||
logging.error(exc)
|
||||
raise UpdateBaseError(ERROR_LOAD_CONFIG_FAILED)
|
||||
|
||||
group_name = data['package']
|
||||
#读取组的yaml 文件的changelog的信息
|
||||
with open(self.config_path + group_name + ".yaml", "r") as stream:
|
||||
try:
|
||||
data_yaml = yaml.safe_load(stream)
|
||||
except Exception as exc:
|
||||
logging.error(exc)
|
||||
raise UpdateBaseError(ERROR_LOAD_CONFIG_FAILED)
|
||||
|
||||
#过滤没有推送的配置文件
|
||||
if not group_name in group_list:
|
||||
continue
|
||||
|
||||
if is_openkylin == True:
|
||||
install_list,upgrade_list = pkgs_install,pkgs_upgrade
|
||||
else:
|
||||
install_list,upgrade_list = self._make_groups_pkgs(cache,data,pkgs_upgrade)
|
||||
|
||||
#判断当前是否可升级或者新装的包
|
||||
if len(install_list) == 0 and len(upgrade_list) == 0:
|
||||
continue
|
||||
|
||||
#3、生成升级的包列表JSON
|
||||
upgrade_pkgs_json = self._make_pkg_info_json(cache,upgrade_list)
|
||||
#2、生成安装的软件列表
|
||||
install_pkgs_json = self._make_pkg_info_json(cache,install_list)
|
||||
#输出JSON配置文件
|
||||
self._make_group_output_json(data,data_yaml,upgrade_pkgs_json,install_pkgs_json)
|
||||
|
||||
#保存分组版本号,好像没有
|
||||
self.upgrade_meta.versoin_pkgs['groups_upgrade'].update({group_name:''})
|
||||
|
||||
#添加到字典维护的升级列表
|
||||
self.upgrade_meta.upgrade_groups.append(group_name)
|
||||
self.upgrade_meta.groups_pkgs.update({group_name:{"pkgs_upgrade":upgrade_list,"pkgs_install":install_list}})
|
||||
logging.info("Group(%s) upgrade:%d install:%d",group_name,len(upgrade_list),len(install_list))
|
||||
else:
|
||||
pass
|
||||
|
||||
def _make_openkylin_output_json(self,upgrade_pkgs_json,install_pkgs_json):
|
||||
groups_base_info = {}
|
||||
output_json = {}
|
||||
|
||||
#FIXME: 确定输出文件的文件名 以及放置位置
|
||||
output_config_name = self.OUTPUT_CONFIG_PATH + "kylin-update-desktop-system.json"
|
||||
|
||||
#4、添加一些基础信息
|
||||
groups_base_info.update({"package":"kylin-update-desktop-system"})
|
||||
groups_base_info.update({"new_version":"33797.0001"})
|
||||
groups_base_info.update({"name":{"zh_CN": "系统更新","en_US": "Kylin OS"}})
|
||||
groups_base_info.update({"description":{"zh_CN": "Openkylin-系统更新包","en_US": "Openkylin-System Update Package"}})
|
||||
groups_base_info.update({"icon":" "})
|
||||
|
||||
#添加读yaml文件
|
||||
groups_base_info.update({"changelog":"Openkylin-系统更新包\n"})
|
||||
|
||||
#5、添加升级的内容
|
||||
output_json.update(groups_base_info)
|
||||
output_json.update({"upgrade_list":upgrade_pkgs_json})
|
||||
output_json.update({"install_list":install_pkgs_json})
|
||||
|
||||
#6 产生JSON文件
|
||||
with open(output_config_name, 'w', encoding='utf-8') as f:
|
||||
json.dump(output_json, f, ensure_ascii=False, indent=4)
|
||||
logging.info("Generate Jsonfile(%s) to complete... ",output_config_name)
|
||||
|
||||
def _rate_application_for_package(self, application, pkg):
|
||||
score = 0
|
||||
desktop_file = os.path.basename(application.get_filename())
|
||||
application_id = os.path.splitext(desktop_file)[0]
|
||||
|
||||
if application.should_show():
|
||||
score += 1
|
||||
|
||||
if application_id == pkg.name:
|
||||
score += 5
|
||||
|
||||
return score
|
||||
|
||||
def _file_is_application(self, file_path):
|
||||
# WARNING: This is called often if there's a lot of updates. A poor
|
||||
# performing call here has a huge impact on the overall performance!
|
||||
if not file_path.endswith(".desktop"):
|
||||
# First the obvious case: If the path doesn't end in a .desktop
|
||||
# extension, this isn't a desktop file.
|
||||
return False
|
||||
|
||||
file_path = os.path.abspath(file_path)
|
||||
for app_dir in self.application_dirs:
|
||||
if file_path.startswith(app_dir):
|
||||
return True
|
||||
return False
|
||||
|
||||
def get_application_for_package(self, pkg):
|
||||
desktop_files = []
|
||||
rated_applications = []
|
||||
|
||||
for installed_file in pkg.installed_files:
|
||||
if self._file_is_application(installed_file):
|
||||
desktop_files.append(installed_file)
|
||||
|
||||
for desktop_file in desktop_files:
|
||||
try:
|
||||
application = Gio.DesktopAppInfo.new_from_filename(
|
||||
desktop_file)
|
||||
application.set_desktop_env(self.current_desktop)
|
||||
except Exception as e:
|
||||
logging.warning("Error loading .desktop file %s: %s" %
|
||||
(desktop_file, e))
|
||||
continue
|
||||
score = self._rate_application_for_package(application, pkg)
|
||||
if score > 0:
|
||||
rated_applications.append((score, application))
|
||||
|
||||
rated_applications.sort(key=lambda app: app[0], reverse=True)
|
||||
if len(rated_applications) > 0:
|
||||
return rated_applications[0][1]
|
||||
else:
|
||||
return None
|
||||
|
||||
def _make_single_upgrade(self,cache,pkg_list):
|
||||
for pkg in pkg_list:
|
||||
zh_name = ''
|
||||
base_info = {}
|
||||
output_json = {}
|
||||
output_config_name = self.OUTPUT_CONFIG_PATH + pkg + '.json'
|
||||
|
||||
pkg_cache = cache[pkg]
|
||||
|
||||
#获取包的软件名称,从主题中读取,只有可升级,是软件的包才可以读取
|
||||
if pkg_cache.is_installed:
|
||||
app = self.get_application_for_package(pkg_cache)
|
||||
if app is not None:
|
||||
zh_name = app.get_display_name()
|
||||
|
||||
pkgs_json = self._make_pkg_info_json(cache,[pkg])
|
||||
en_name = getattr(pkg_cache.candidate, "summary", '')
|
||||
description_str = getattr(pkg_cache.candidate, "description", '')
|
||||
|
||||
#4、添加一些基础信息
|
||||
base_info.update({"package":pkg})
|
||||
|
||||
base_info.update({"cur_version":getattr(pkg_cache.installed, "version", '')})
|
||||
base_info.update({"new_version":getattr(pkg_cache.candidate, "version", '')})
|
||||
base_info.update({"name":{"zh_CN":zh_name,"en_US":en_name}})
|
||||
base_info.update({"description":{"zh_CN":description_str,"en_US":description_str}})
|
||||
base_info.update({"icon":''})
|
||||
|
||||
#5、添加升级的内容
|
||||
output_json.update(base_info)
|
||||
if pkg_cache.is_installed:
|
||||
output_json.update({"upgrade_list":pkgs_json})
|
||||
output_json.update({"install_list":{}})
|
||||
else:
|
||||
output_json.update({"upgrade_list":{}})
|
||||
output_json.update({"install_list":pkgs_json})
|
||||
|
||||
#产生JSON文件
|
||||
with open(output_config_name, 'w', encoding='utf-8') as f:
|
||||
json.dump(output_json, f, ensure_ascii=False, indent=4)
|
||||
logging.info("Generate Jsonfile(%s) to complete... ",output_config_name)
|
||||
|
||||
#6、保存单包版本号
|
||||
self.upgrade_meta.versoin_pkgs['single_upgrade'].update({pkg_cache.name:getattr(pkg_cache.installed, "version", '')})
|
||||
|
||||
def _make_distupgrade(self,cache):
|
||||
pkgs_upgrade = []
|
||||
pkgs_install = []
|
||||
if cache.get_changes():
|
||||
cache.clear()
|
||||
cache._depcache.upgrade(True)
|
||||
|
||||
#查找所有可升级的包
|
||||
for pkg in cache:
|
||||
try:
|
||||
if pkg.marked_install:
|
||||
pkgs_install.append(pkg.name)
|
||||
elif pkg.marked_upgrade:
|
||||
pkgs_upgrade.append(pkg.name)
|
||||
except KeyError:
|
||||
pass
|
||||
return pkgs_install,pkgs_upgrade
|
||||
|
||||
def update_kylin(self,cache,important_data,is_openkylin = False):
|
||||
pkgs_install = []
|
||||
pkgs_upgrade = []
|
||||
|
||||
#查找所有可升级的包
|
||||
if is_openkylin == True:
|
||||
pkgs_install,pkgs_upgrade = self._make_distupgrade(cache)
|
||||
else:
|
||||
for pkg in cache:
|
||||
if pkg.is_upgradable and pkg.is_installed:
|
||||
pkgs_upgrade.append(pkg.name)
|
||||
|
||||
logging.info("System all upgradeable packages:upgrade:%d install:%d ",len(pkgs_upgrade),len(pkgs_install))
|
||||
|
||||
group_important_list,self.upgrade_meta.single_pkgs = self._make_important_list(cache,pkgs_upgrade,important_data)
|
||||
|
||||
#清空输出的目录
|
||||
self._empty_output_dir()
|
||||
|
||||
#important_list 为空时此次不需要升级
|
||||
if not group_important_list and not self.upgrade_meta.single_pkgs:
|
||||
self.parent.dbusController.UpdateDetectFinished(True,[],'','')
|
||||
return
|
||||
|
||||
#产生单包的JSON
|
||||
self._make_single_upgrade(cache,self.upgrade_meta.single_pkgs)
|
||||
|
||||
#分组的包的JSON
|
||||
self._make_groups_upgrade(cache,group_important_list,is_openkylin,pkgs_install,pkgs_upgrade)
|
||||
|
||||
self._make_autoupgrade_config(cache,self.upgrade_meta,self.upgrade_meta.adjust_pkgs)
|
||||
|
||||
self.parent.dbusController.UpdateDetectFinished(True,self.upgrade_meta.upgrade_groups + self.upgrade_meta.single_pkgs,'','')
|
||||
|
||||
return
|
|
@ -0,0 +1,105 @@
|
|||
#!/usr/bin/python3
|
||||
# DistUpgradeConfigParser.py
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
# USA
|
||||
|
||||
|
||||
from configparser import NoOptionError
|
||||
from configparser import ConfigParser as SafeConfigParser
|
||||
import os.path
|
||||
import logging
|
||||
|
||||
class UpgradeConfig(SafeConfigParser):
|
||||
def __init__(self, datadir="/var/lib/kylin-system-updater/", name="system-updater.conf",defaults_dir=None):
|
||||
SafeConfigParser.__init__(self)
|
||||
self.datadir = datadir
|
||||
maincfg = os.path.join(datadir, name)
|
||||
# defaults are read first
|
||||
self.config_files = []
|
||||
if defaults_dir:
|
||||
self.config_files.append(os.path.join(datadir, defaults_dir))
|
||||
# our config file
|
||||
self.config_files += [maincfg]
|
||||
self.read(self.config_files)
|
||||
logging.info("Initialize Upgrade ConfigFile(%s) to success",str(self.config_files))
|
||||
|
||||
def optionxform(self, optionstr):
|
||||
return optionstr
|
||||
|
||||
def reReadConfigFiles(self):
|
||||
self.read(self.config_files)
|
||||
|
||||
def setValue(self, section, option, value=None,is_write = True):
|
||||
if option != 'upgradelist':
|
||||
logging.info("SetValue Section:%s Option:%s Value:%s",section, option, value)
|
||||
try:
|
||||
self.reReadConfigFiles()
|
||||
|
||||
self.set(section, option,value)
|
||||
except Exception as e:
|
||||
logging.error("Error: setValue section:%s option:%s value:%s",section, option, value)
|
||||
logging.error(str(e))
|
||||
return False
|
||||
if is_write == True:
|
||||
with open(self.config_files[-1], 'w+') as configfile:
|
||||
self.write(configfile)
|
||||
return True
|
||||
|
||||
def getWithDefault(self, section, option, default,re_read=False):
|
||||
try:
|
||||
if re_read == True:
|
||||
self.reReadConfigFiles()
|
||||
|
||||
if type(default) == bool:
|
||||
return self.getboolean(section, option)
|
||||
elif type(default) == float:
|
||||
return self.getfloat(section, option)
|
||||
elif type(default) == int:
|
||||
return self.getint(section, option)
|
||||
return self.get(section, option)
|
||||
except Exception as e:
|
||||
logging.error(str(e))
|
||||
return default
|
||||
|
||||
def getlist(self, section, option):
|
||||
try:
|
||||
tmp = self.get(section, option)
|
||||
except Exception as e:
|
||||
logging.error(str(e))
|
||||
return []
|
||||
items = [x.strip() for x in tmp.split(" ")]
|
||||
if '' in items and len(items):
|
||||
return []
|
||||
return items
|
||||
|
||||
def setListValue(self, section, option, value=None,is_write = True):
|
||||
tmp = str(value).replace('[', '').replace(']', '')
|
||||
tmp = tmp.replace("'", '').replace(',', '')
|
||||
try:
|
||||
self.set(section, option,tmp)
|
||||
except Exception as e:
|
||||
logging.error("setListValue section:%s option:%s",section, option)
|
||||
logging.error(str(e))
|
||||
return
|
||||
if is_write == True:
|
||||
with open(self.config_files[-1], 'w+') as configfile:
|
||||
self.write(configfile)
|
||||
|
||||
def getListFromFile(self, section, option):
|
||||
try:
|
||||
filename = self.get(section, option)
|
||||
except NoOptionError:
|
||||
return []
|
||||
p = os.path.join(self.datadir, filename)
|
||||
if not os.path.exists(p):
|
||||
logging.error("getListFromFile: no '%s' found" % p)
|
||||
with open(p) as f:
|
||||
items = [x.strip() for x in f]
|
||||
return [s for s in items if not s.startswith("#") and not s == ""]
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# c = UpgradeConfig("/home/x/share/kylin-system-updater/backend/data/")
|
||||
# print(c.setValue("SystemStatus", "abnormal_reboot", str(False)),True)
|
||||
# print(c.getWithDefault("SystemStatus", "abnormal_reboot", False))
|
||||
pass
|
|
@ -0,0 +1,169 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""enums - Enumerates for apt daemon dbus messages"""
|
||||
|
||||
__all__ = (
|
||||
"ERROR_UPDATE_DEFAULT_FAILED",
|
||||
"ERROR_UPDATE_SOURCE_FAILED","ERROR_NETWORK_FAILED","ERROR_NOT_GROUPS_CONFIG","ERROR_SOFTWARE_INDEX_RROKEN",
|
||||
"ERROR_NOT_INIT_PACKAGESINFIO","ERROR_READ_IMPORTANTLIST_FAILED","ERROR_RESOLVER_FAILED","ERROR_NOT_UPGRADE_PACKAGES",
|
||||
"ERROR_REMOVE_ESSENTIAL_PACKAGES","ERROR_NOT_DISK_SPACE","ERROR_NOT_CONFIGPKG_DEPENDENCIES","ERROR_NOT_SELFPKG_DEPENDENCIES",
|
||||
"ERROR_NOT_FIX_SYSTEM","ERROR_READ_LOCAL_DEB","ERROR_LOCAL_DEB_FORMAT","ERROR_INSTALL_DEB_BASE","ERROR_LOAD_CONFIG_FAILED",
|
||||
"ERROR_UPDATE_KEY_SIGNATURES","ERROR_UPDATE_NET_AUTHENTICATION","ERROR_UPDATE_NOTREAD_SOURCES","PRIORITY_UPGRADE_SUCCCESSED",
|
||||
"ERROR_UPDATE_INVALID_TIME",
|
||||
|
||||
"get_error_description_from_enum", "get_error_string_from_enum", "get_source_name_from_enum", "get_caller_from_enum")
|
||||
|
||||
import gettext
|
||||
gettext.bindtextdomain('kylin-system-updater', '/usr/share/locale')
|
||||
gettext.textdomain('kylin-system-updater')
|
||||
_ = gettext.gettext
|
||||
|
||||
PRIORITY_UPGRADE_SUCCCESSED = "priority-upgrade-successed"
|
||||
|
||||
#apt update阶段出现的错误解析
|
||||
ERROR_UPDATE_DEFAULT_FAILED = "error-update-default-failed"
|
||||
ERROR_UPDATE_KEY_SIGNATURES = "The following signatures"
|
||||
ERROR_UPDATE_NET_AUTHENTICATION ="does the network require authentication?"
|
||||
ERROR_UPDATE_NOTREAD_SOURCES = "The list of sources could not be read"
|
||||
ERROR_UPDATE_INVALID_TIME = "(invalid for another"
|
||||
|
||||
ERROR_UPDATE_SOURCE_FAILED = "error-update-source-failed"
|
||||
ERROR_NETWORK_FAILED = "error-network-failed"
|
||||
ERROR_NOT_GROUPS_CONFIG = "error-not-groups-config"
|
||||
ERROR_NOT_CONFIGPKG_DEPENDENCIES = "error-not-configpkg-dependencies"
|
||||
ERROR_NOT_SELFPKG_DEPENDENCIES = "error-not-selfpkg-dependencies"
|
||||
|
||||
ERROR_NOT_FIX_SYSTEM = "error-not-fix-system"
|
||||
|
||||
ERROR_LOAD_CONFIG_FAILED = "error-load-config-failed"
|
||||
|
||||
#自己的
|
||||
ERROR_SOFTWARE_INDEX_RROKEN = "error-software-index-broken"
|
||||
ERROR_NOT_INIT_PACKAGESINFIO = "error-not-init-packagesinfo"
|
||||
ERROR_READ_IMPORTANTLIST_FAILED = "error-read-importantlist-failed"
|
||||
ERROR_RESOLVER_FAILED = "error-resolver-failed"
|
||||
ERROR_NOT_UPGRADE_PACKAGES = "error-not-upgrade-packages"
|
||||
ERROR_REMOVE_ESSENTIAL_PACKAGES = "error-remove-essential-packages"
|
||||
ERROR_NOT_DISK_SPACE = "error-not-disk-space"
|
||||
ERROR_READ_LOCAL_DEB = "error-read-local-deb"
|
||||
ERROR_LOCAL_DEB_FORMAT = "error-local-deb-format"
|
||||
ERROR_INSTALL_DEB_BASE = "error-install-deb-base"
|
||||
|
||||
_STRINGS_ERROR = {
|
||||
PRIORITY_UPGRADE_SUCCCESSED: _("Update Manager upgrade is complete, please restart the setting panel before performing the system update."),
|
||||
|
||||
#update
|
||||
ERROR_UPDATE_DEFAULT_FAILED: _("Check for update exceptions!"),
|
||||
ERROR_UPDATE_SOURCE_FAILED: _("Check for update exceptions!"),
|
||||
ERROR_NETWORK_FAILED: _("Network anomaly, can't check for updates!"),
|
||||
ERROR_UPDATE_KEY_SIGNATURES: _("Check for update exceptions!"),
|
||||
ERROR_READ_IMPORTANTLIST_FAILED: _("Check for update exceptions!"),
|
||||
ERROR_SOFTWARE_INDEX_RROKEN: _("Check for update exceptions!"),
|
||||
ERROR_NOT_INIT_PACKAGESINFIO: _("Check for update exceptions!"),
|
||||
ERROR_NOT_FIX_SYSTEM: _("Check for update exceptions!"),
|
||||
ERROR_LOAD_CONFIG_FAILED: _("Check for update exceptions!"),
|
||||
|
||||
#优先升级
|
||||
ERROR_NOT_GROUPS_CONFIG: _("Upgrade configuration acquisition exception."),
|
||||
ERROR_NOT_CONFIGPKG_DEPENDENCIES: _("Upgrade configuration acquisition exception."),
|
||||
ERROR_NOT_SELFPKG_DEPENDENCIES: _("Priority upgrade status exception."),
|
||||
|
||||
#install
|
||||
ERROR_RESOLVER_FAILED: _("Could not calculate the upgrade"),
|
||||
ERROR_NOT_UPGRADE_PACKAGES: _("There is an exception in the update package."),
|
||||
ERROR_REMOVE_ESSENTIAL_PACKAGES: _("There is an exception in the update package."),
|
||||
ERROR_NOT_DISK_SPACE: _("Disk space is insufficient, please clean the disk and then upgrade"),
|
||||
ERROR_READ_LOCAL_DEB:_(" "),
|
||||
ERROR_LOCAL_DEB_FORMAT:_(" "),
|
||||
ERROR_INSTALL_DEB_BASE:_(" ")}
|
||||
|
||||
_DESCS_ERROR = {
|
||||
#update
|
||||
ERROR_UPDATE_SOURCE_FAILED: _("Unable to access the source management server"),
|
||||
ERROR_NETWORK_FAILED: _("Please check your network connection and retry."),
|
||||
ERROR_UPDATE_KEY_SIGNATURES: _("Check your source public key signature"),
|
||||
ERROR_UPDATE_NOTREAD_SOURCES: _("Please check your source list and retry."),
|
||||
ERROR_UPDATE_INVALID_TIME: _("Please check the system time and synchronize the system time before updating."),
|
||||
ERROR_UPDATE_NET_AUTHENTICATION: _("Check if your network requires authentication?"),
|
||||
ERROR_NOT_GROUPS_CONFIG: _("Unable to get group configuration package, Please check if the configuration package exists in the software source repository."),
|
||||
ERROR_NOT_INIT_PACKAGESINFIO: _("An unresolvable problem occurred while initializing the package."),
|
||||
ERROR_SOFTWARE_INDEX_RROKEN: _("Software index is broken") + _("It is impossible to install or remove any software. "
|
||||
"Please use the package manager \"Synaptic\" or run "
|
||||
"\"sudo apt-get install -f\" in a terminal to fix "
|
||||
"this issue at first."),
|
||||
ERROR_READ_IMPORTANTLIST_FAILED: _("read important list failed"),
|
||||
ERROR_NOT_CONFIGPKG_DEPENDENCIES: _("Unable to install group configuration package, Please check the configuration package related dependencies."),
|
||||
ERROR_NOT_SELFPKG_DEPENDENCIES: _("Unable to perform priority upgrade, please check the dependency related to the priority upgrade package."),
|
||||
|
||||
ERROR_LOAD_CONFIG_FAILED: _("The system update configuration file is read abnormally, please check if the system update configuration file format is correct."),
|
||||
ERROR_NOT_FIX_SYSTEM: _("The system APT environment is abnormal, please check the system APT environment."),
|
||||
|
||||
#install
|
||||
ERROR_RESOLVER_FAILED: _("nothing"),
|
||||
ERROR_NOT_UPGRADE_PACKAGES: _("This update cannot detect the upgradeable package."),
|
||||
ERROR_REMOVE_ESSENTIAL_PACKAGES: _("You request the removal of a system-essential package."),
|
||||
ERROR_NOT_DISK_SPACE: _("test"),
|
||||
ERROR_READ_LOCAL_DEB:_("Deb format exception, read local deb file error."),
|
||||
ERROR_LOCAL_DEB_FORMAT:_("Deb format exception, failed to parse package file."),
|
||||
ERROR_INSTALL_DEB_BASE:_("Install deb error.")
|
||||
}
|
||||
|
||||
#UPGRADE MONITOR STATUS
|
||||
MONIT_DETECT = "step-updatedetect"
|
||||
MONIT_DEPRESOLUT = "step-depresolution"
|
||||
MONIT_DOWNLOAD = "step-downloading"
|
||||
MONIT_INSTALL = "step-installing"
|
||||
MONIT_FINISH = "step-finish"
|
||||
MONIT_INSTALLDEB = "step-installdeb"
|
||||
|
||||
SOURCE_NAME = {
|
||||
'kylin-installer':_("Kylin Installer"),
|
||||
'kylin-uninstaller':_("Kylin Uninstaller"),
|
||||
'kylin-background-upgrade':_("Kylin Background Upgrade"),
|
||||
'kylin-software-center':_("Kylin Software Center"),
|
||||
}
|
||||
|
||||
CALLER = {
|
||||
'kylin-installer':"Kylin Installer",
|
||||
'kylin-uninstaller':"Kylin Uninstaller",
|
||||
'kylin-background-upgrade':"Kylin Background Upgrade",
|
||||
'kylin-software-center':"Kylin Software Center",
|
||||
}
|
||||
|
||||
def get_error_description_from_enum(enum):
|
||||
"""Get a long description of an error.
|
||||
|
||||
:param enum: The transaction error enum, e.g. :data:`ERROR_NO_LOCK`.
|
||||
:returns: The description string.
|
||||
"""
|
||||
try:
|
||||
return _DESCS_ERROR[enum]
|
||||
except KeyError:
|
||||
return None
|
||||
|
||||
|
||||
def get_error_string_from_enum(enum):
|
||||
"""Get a short description of an error.
|
||||
|
||||
:param enum: The transaction error enum, e.g. :data:`ERROR_NO_LOCK`.
|
||||
:returns: The description string.
|
||||
"""
|
||||
try:
|
||||
return _STRINGS_ERROR[enum]
|
||||
except KeyError:
|
||||
return None
|
||||
|
||||
|
||||
def get_source_name_from_enum(enum):
|
||||
try:
|
||||
return SOURCE_NAME[enum]
|
||||
except KeyError:
|
||||
return _("Kylin System Updater")
|
||||
|
||||
def get_caller_from_enum(enum):
|
||||
try:
|
||||
return CALLER[enum]
|
||||
except KeyError:
|
||||
return _("Kylin System Updater")
|
||||
|
||||
# vim:ts=4:sw=4:et
|
|
@ -0,0 +1,65 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Exception classes"""
|
||||
|
||||
# __all__ = ("UpdateBaseError")
|
||||
|
||||
import logging
|
||||
from selectors import EpollSelector
|
||||
import sys
|
||||
from .enums import *
|
||||
|
||||
PY3K = sys.version_info.major > 2
|
||||
|
||||
class UpdateBaseError(Exception):
|
||||
|
||||
"""Internal error if a transaction could not be processed successfully."""
|
||||
|
||||
_dbus_error_name = "org.debian.apt.TransactionFailed"
|
||||
|
||||
def __init__(self, code,header=None,desc=None,details="",*args):
|
||||
if not args:
|
||||
# Avoid string replacements if not used
|
||||
details = details.replace("%", "%%")
|
||||
args = tuple([_convert_unicode(arg) for arg in args])
|
||||
details = _convert_unicode(details)
|
||||
self.code = code
|
||||
self.details = details
|
||||
self.details_args = args
|
||||
if header == None:
|
||||
self.header = get_error_string_from_enum(self.code)
|
||||
else:
|
||||
self.header = header
|
||||
|
||||
if desc == None:
|
||||
self.desc = get_error_description_from_enum(self.code)
|
||||
else:
|
||||
self.desc = desc
|
||||
|
||||
Exception.__init__(self, *args)
|
||||
# AptDaemonError.__init__(self, "%s: %s" % (code, details % args))
|
||||
|
||||
def __unicode__(self):
|
||||
return "%s" % \
|
||||
(get_error_string_from_enum(self.code))
|
||||
|
||||
def __str__(self):
|
||||
if PY3K:
|
||||
return self.__unicode__()
|
||||
else:
|
||||
return self.__unicode__().encode("utf-8")
|
||||
|
||||
class UpdateProgressExit(Exception):
|
||||
def __init__(self,*args):
|
||||
Exception.__init__(self, *args)
|
||||
logging.info("Update Progress wiil be Exit...")
|
||||
|
||||
def _convert_unicode(text, encoding="UTF-8"):
|
||||
"""Always return an unicode."""
|
||||
if PY3K and not isinstance(text, str):
|
||||
text = str(text, encoding, errors="ignore")
|
||||
elif not PY3K and not isinstance(text, unicode):
|
||||
text = unicode(text, encoding, errors="ignore")
|
||||
return text
|
||||
|
||||
# vim:ts=4:sw=4:et
|
|
@ -0,0 +1,13 @@
|
|||
#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Main loop for aptdaemon."""
|
||||
|
||||
__all__ = ("mainloop", "get_main_loop")
|
||||
|
||||
from gi.repository import GLib
|
||||
|
||||
mainloop = GLib.MainLoop()
|
||||
|
||||
def get_main_loop():
|
||||
"""Return the glib main loop as a singleton."""
|
||||
return mainloop
|
|
@ -0,0 +1,809 @@
|
|||
# utils.py
|
||||
# -*- Mode: Python; indent-tabs-mode: nil; tab-width: 4; coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (c) 2004-2013 Canonical
|
||||
#
|
||||
# Authors: Michael Vogt <mvo@debian.org>
|
||||
# Michael Terry <michael.terry@canonical.com>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
# USA
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
from gettext import gettext as _
|
||||
from gettext import ngettext
|
||||
from stat import (S_IMODE, ST_MODE, S_IXUSR)
|
||||
from math import ceil
|
||||
|
||||
import apt
|
||||
import dbus
|
||||
import apt_pkg
|
||||
apt_pkg.init_config()
|
||||
|
||||
import shutil
|
||||
import locale
|
||||
import logging
|
||||
import re
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
import fcntl
|
||||
from urllib.request import (
|
||||
ProxyHandler,
|
||||
Request,
|
||||
build_opener,
|
||||
install_opener,
|
||||
urlopen,
|
||||
)
|
||||
import dbus
|
||||
from urllib.parse import urlsplit
|
||||
|
||||
from copy import copy
|
||||
import psutil
|
||||
import ctypes
|
||||
from ctypes import *
|
||||
import struct
|
||||
|
||||
# 禁止关机锁文件路径
|
||||
VERIFY_SO = "libkylin_signtool.so"
|
||||
|
||||
class ExecutionTime(object):
|
||||
"""
|
||||
Helper that can be used in with statements to have a simple
|
||||
measure of the timing of a particular block of code, e.g.
|
||||
with ExecutionTime("db flush"):
|
||||
db.flush()
|
||||
"""
|
||||
def __init__(self, info=""):
|
||||
self.info = info
|
||||
|
||||
def __enter__(self):
|
||||
self.now = time.time()
|
||||
|
||||
def __exit__(self, type, value, stack):
|
||||
print("%s: %s" % (self.info, time.time() - self.now))
|
||||
|
||||
|
||||
def get_string_with_no_auth_from_source_entry(entry):
|
||||
tmp = copy(entry)
|
||||
url_parts = urlsplit(tmp.uri)
|
||||
if url_parts.username:
|
||||
tmp.uri = tmp.uri.replace(url_parts.username, "hidden-u")
|
||||
if url_parts.password:
|
||||
tmp.uri = tmp.uri.replace(url_parts.password, "hidden-p")
|
||||
return str(tmp)
|
||||
|
||||
|
||||
def is_unity_running():
|
||||
""" return True if Unity is currently running """
|
||||
unity_running = False
|
||||
try:
|
||||
import dbus
|
||||
bus = dbus.SessionBus()
|
||||
unity_running = bus.name_has_owner("com.canonical.Unity")
|
||||
except Exception:
|
||||
logging.exception("could not check for Unity dbus service")
|
||||
return unity_running
|
||||
|
||||
|
||||
def is_child_of_process_name(processname, pid=None):
|
||||
if not pid:
|
||||
pid = os.getpid()
|
||||
while pid > 0:
|
||||
stat_file = "/proc/%s/stat" % pid
|
||||
with open(stat_file) as stat_f:
|
||||
stat = stat_f.read()
|
||||
# extract command (inside ())
|
||||
command = stat.partition("(")[2].rpartition(")")[0]
|
||||
if command == processname:
|
||||
return True
|
||||
# get parent (second to the right of command) and check that next
|
||||
pid = int(stat.rpartition(")")[2].split()[1])
|
||||
return False
|
||||
|
||||
|
||||
def inside_chroot():
|
||||
""" returns True if we are inside a chroot
|
||||
"""
|
||||
# if there is no proc or no pid 1 we are very likely inside a chroot
|
||||
if not os.path.exists("/proc") or not os.path.exists("/proc/1"):
|
||||
return True
|
||||
# if the inode is differnt for pid 1 "/" and our "/"
|
||||
return os.stat("/") != os.stat("/proc/1/root")
|
||||
|
||||
|
||||
def wrap(t, width=70, subsequent_indent=""):
|
||||
""" helpers inspired after textwrap - unfortunately
|
||||
we can not use textwrap directly because it break
|
||||
packagenames with "-" in them into new lines
|
||||
"""
|
||||
out = ""
|
||||
for s in t.split():
|
||||
if (len(out) - out.rfind("\n")) + len(s) > width:
|
||||
out += "\n" + subsequent_indent
|
||||
out += s + " "
|
||||
return out
|
||||
|
||||
|
||||
def twrap(s, **kwargs):
|
||||
msg = ""
|
||||
paras = s.split("\n")
|
||||
for par in paras:
|
||||
s = wrap(par, **kwargs)
|
||||
msg += s + "\n"
|
||||
return msg
|
||||
|
||||
|
||||
def lsmod():
|
||||
" return list of loaded modules (or [] if lsmod is not found) "
|
||||
modules = []
|
||||
# FIXME raise?
|
||||
if not os.path.exists("/sbin/lsmod"):
|
||||
return []
|
||||
p = subprocess.Popen(["/sbin/lsmod"], stdout=subprocess.PIPE,
|
||||
universal_newlines=True)
|
||||
lines = p.communicate()[0].split("\n")
|
||||
# remove heading line: "Modules Size Used by"
|
||||
del lines[0]
|
||||
# add lines to list, skip empty lines
|
||||
for line in lines:
|
||||
if line:
|
||||
modules.append(line.split()[0])
|
||||
return modules
|
||||
|
||||
|
||||
def check_and_fix_xbit(path):
|
||||
" check if a given binary has the executable bit and if not, add it"
|
||||
if not os.path.exists(path):
|
||||
return
|
||||
mode = S_IMODE(os.stat(path)[ST_MODE])
|
||||
if not ((mode & S_IXUSR) == S_IXUSR):
|
||||
os.chmod(path, mode | S_IXUSR)
|
||||
|
||||
|
||||
def country_mirror():
|
||||
" helper to get the country mirror from the current locale "
|
||||
# special cases go here
|
||||
lang_mirror = {'c': ''}
|
||||
# no lang, no mirror
|
||||
if 'LANG' not in os.environ:
|
||||
return ''
|
||||
lang = os.environ['LANG'].lower()
|
||||
# check if it is a special case
|
||||
if lang[:5] in lang_mirror:
|
||||
return lang_mirror[lang[:5]]
|
||||
# now check for the most comon form (en_US.UTF-8)
|
||||
if "_" in lang:
|
||||
country = lang.split(".")[0].split("_")[1]
|
||||
if "@" in country:
|
||||
country = country.split("@")[0]
|
||||
return country + "."
|
||||
else:
|
||||
return lang[:2] + "."
|
||||
return ''
|
||||
|
||||
|
||||
def get_dist():
|
||||
" return the codename of the current runing distro "
|
||||
# then check the real one
|
||||
from subprocess import Popen, PIPE
|
||||
p = Popen(["lsb_release", "-i", "-s"], stdout=PIPE,
|
||||
universal_newlines=True)
|
||||
res = p.wait()
|
||||
if res != 0:
|
||||
sys.stderr.write("lsb_release returned exitcode: %i\n" % res)
|
||||
return "unknown distribution"
|
||||
dist = p.stdout.readline().strip()
|
||||
p.stdout.close()
|
||||
return dist
|
||||
|
||||
|
||||
def get_dist_version():
|
||||
" return the version of the current running distro "
|
||||
# then check the real one
|
||||
from subprocess import Popen, PIPE
|
||||
p = Popen(["lsb_release", "-r", "-s"], stdout=PIPE,
|
||||
universal_newlines=True)
|
||||
res = p.wait()
|
||||
if res != 0:
|
||||
sys.stderr.write("lsb_release returned exitcode: %i\n" % res)
|
||||
return "unknown distribution"
|
||||
desc = p.stdout.readline().strip()
|
||||
p.stdout.close()
|
||||
return desc
|
||||
|
||||
|
||||
class HeadRequest(Request):
|
||||
def get_method(self):
|
||||
return "HEAD"
|
||||
|
||||
|
||||
def url_downloadable(uri, debug_func=None):
|
||||
"""
|
||||
helper that checks if the given uri exists and is downloadable
|
||||
(supports optional debug_func function handler to support
|
||||
e.g. logging)
|
||||
|
||||
Supports http (via HEAD) and ftp (via size request)
|
||||
"""
|
||||
if not debug_func:
|
||||
lambda x: True
|
||||
debug_func("url_downloadable: %s" % uri)
|
||||
(scheme, netloc, path, querry, fragment) = urlsplit(uri)
|
||||
debug_func("s='%s' n='%s' p='%s' q='%s' f='%s'" % (scheme, netloc, path,
|
||||
querry, fragment))
|
||||
if scheme in ("http", "https"):
|
||||
try:
|
||||
http_file = urlopen(HeadRequest(uri))
|
||||
http_file.close()
|
||||
if http_file.code == 200:
|
||||
return True
|
||||
return False
|
||||
except Exception as e:
|
||||
debug_func("error from httplib: '%s'" % e)
|
||||
return False
|
||||
elif scheme == "ftp":
|
||||
import ftplib
|
||||
try:
|
||||
f = ftplib.FTP(netloc)
|
||||
f.login()
|
||||
f.cwd(os.path.dirname(path))
|
||||
size = f.size(os.path.basename(path))
|
||||
f.quit()
|
||||
if debug_func:
|
||||
debug_func("ftplib.size() returned: %s" % size)
|
||||
if size != 0:
|
||||
return True
|
||||
except Exception as e:
|
||||
if debug_func:
|
||||
debug_func("error from ftplib: '%s'" % e)
|
||||
return False
|
||||
return False
|
||||
|
||||
def is_chinese(string):
|
||||
"""
|
||||
检查整个字符串是否包含中文
|
||||
:param string: 需要检查的字符串
|
||||
:return: bool
|
||||
"""
|
||||
for ch in string:
|
||||
if u'\u4e00' <= ch <= u'\u9fff':
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def init_proxy(gsettings=None):
|
||||
""" init proxy settings
|
||||
|
||||
* use apt.conf http proxy if present,
|
||||
* otherwise look into synaptics config file,
|
||||
* otherwise the default behavior will use http_proxy environment
|
||||
if present
|
||||
"""
|
||||
SYNAPTIC_CONF_FILE = "/root/.synaptic/synaptic.conf"
|
||||
proxies = {}
|
||||
# generic apt config wins
|
||||
if apt_pkg.config.find("Acquire::http::Proxy") != '':
|
||||
proxies["http"] = apt_pkg.config.find("Acquire::http::Proxy")
|
||||
# then synaptic
|
||||
elif os.path.exists(SYNAPTIC_CONF_FILE):
|
||||
cnf = apt_pkg.Configuration()
|
||||
apt_pkg.read_config_file(cnf, SYNAPTIC_CONF_FILE)
|
||||
use_proxy = cnf.find_b("Synaptic::useProxy", False)
|
||||
if use_proxy:
|
||||
proxy_host = cnf.find("Synaptic::httpProxy")
|
||||
proxy_port = str(cnf.find_i("Synaptic::httpProxyPort"))
|
||||
if proxy_host and proxy_port:
|
||||
proxies["http"] = "http://%s:%s/" % (proxy_host, proxy_port)
|
||||
if apt_pkg.config.find("Acquire::https::Proxy") != '':
|
||||
proxies["https"] = apt_pkg.config.find("Acquire::https::Proxy")
|
||||
elif "http" in proxies:
|
||||
proxies["https"] = proxies["http"]
|
||||
# if we have a proxy, set it
|
||||
if proxies:
|
||||
# basic verification
|
||||
for proxy in proxies.values():
|
||||
if not re.match("https?://\\w+", proxy):
|
||||
print("proxy '%s' looks invalid" % proxy, file=sys.stderr)
|
||||
return
|
||||
proxy_support = ProxyHandler(proxies)
|
||||
opener = build_opener(proxy_support)
|
||||
install_opener(opener)
|
||||
if "http" in proxies:
|
||||
os.putenv("http_proxy", proxies["http"])
|
||||
if "https" in proxies:
|
||||
os.putenv("https_proxy", proxies["https"])
|
||||
return proxies
|
||||
|
||||
|
||||
def on_battery():
|
||||
"""
|
||||
Check via dbus if the system is running on battery.
|
||||
This function is using UPower per default, if UPower is not
|
||||
available it falls-back to DeviceKit.Power.
|
||||
"""
|
||||
try:
|
||||
import dbus
|
||||
bus = dbus.Bus(dbus.Bus.TYPE_SYSTEM)
|
||||
try:
|
||||
devobj = bus.get_object('org.freedesktop.UPower',
|
||||
'/org/freedesktop/UPower')
|
||||
dev = dbus.Interface(devobj, 'org.freedesktop.DBus.Properties')
|
||||
return dev.Get('org.freedesktop.UPower', 'OnBattery')
|
||||
except dbus.exceptions.DBusException as e:
|
||||
error_unknown = 'org.freedesktop.DBus.Error.ServiceUnknown'
|
||||
if e._dbus_error_name != error_unknown:
|
||||
raise
|
||||
devobj = bus.get_object('org.freedesktop.DeviceKit.Power',
|
||||
'/org/freedesktop/DeviceKit/Power')
|
||||
dev = dbus.Interface(devobj, "org.freedesktop.DBus.Properties")
|
||||
return dev.Get("org.freedesktop.DeviceKit.Power", "on_battery")
|
||||
except Exception:
|
||||
#import sys
|
||||
#print("on_battery returned error: ", e, file=sys.stderr)
|
||||
return False
|
||||
|
||||
|
||||
def str_to_bool(str):
|
||||
if str == "0" or str.upper() == "FALSE":
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def get_lang():
|
||||
import logging
|
||||
try:
|
||||
(locale_s, encoding) = locale.getdefaultlocale()
|
||||
return locale_s
|
||||
except Exception:
|
||||
logging.exception("gedefaultlocale() failed")
|
||||
return None
|
||||
|
||||
|
||||
def get_ubuntu_flavor(cache=None):
|
||||
""" try to guess the flavor based on the running desktop """
|
||||
# this will (of course) not work in a server environment,
|
||||
# but the main use case for this is to show the right
|
||||
# release notes.
|
||||
pkg = get_ubuntu_flavor_package(cache=cache)
|
||||
return pkg.split('-', 1)[0]
|
||||
|
||||
|
||||
# def _load_meta_pkg_list():
|
||||
# # This could potentially introduce a circular dependency, but the config
|
||||
# # parser logic is simple, and doesn't rely on any UpdateManager code.
|
||||
# from DistUpgrade.DistUpgradeConfigParser import DistUpgradeConfig
|
||||
# parser = DistUpgradeConfig('/usr/share/ubuntu-release-upgrader')
|
||||
# return parser.getlist('Distro', 'MetaPkgs')
|
||||
|
||||
|
||||
def get_ubuntu_flavor_package(cache=None):
|
||||
""" try to guess the flavor metapackage based on the running desktop """
|
||||
# From spec, first if ubuntu-desktop is installed, use that.
|
||||
# Second, grab first installed one from DistUpgrade.cfg.
|
||||
# Lastly, fallback to ubuntu-desktop again.
|
||||
meta_pkgs = ['ubuntu-desktop']
|
||||
|
||||
# try:
|
||||
# meta_pkgs.extend(sorted(_load_meta_pkg_list()))
|
||||
# except Exception as e:
|
||||
# print('Could not load list of meta packages:', e)
|
||||
|
||||
if cache is None:
|
||||
cache = apt.Cache()
|
||||
for meta_pkg in meta_pkgs:
|
||||
cache_pkg = cache[meta_pkg] if meta_pkg in cache else None
|
||||
if cache_pkg and cache_pkg.is_installed:
|
||||
return meta_pkg
|
||||
return 'ubuntu-desktop'
|
||||
|
||||
|
||||
def get_ubuntu_flavor_name(cache=None):
|
||||
""" try to guess the flavor name based on the running desktop """
|
||||
pkg = get_ubuntu_flavor_package(cache=cache)
|
||||
lookup = {'ubuntustudio-desktop': 'Ubuntu Studio'}
|
||||
if pkg in lookup:
|
||||
return lookup[pkg]
|
||||
elif pkg.endswith('-desktop'):
|
||||
return capitalize_first_word(pkg.rsplit('-desktop', 1)[0])
|
||||
elif pkg.endswith('-netbook'):
|
||||
return capitalize_first_word(pkg.rsplit('-netbook', 1)[0])
|
||||
else:
|
||||
return 'Ubuntu'
|
||||
|
||||
|
||||
# Unused by update-manager, but still used by ubuntu-release-upgrader
|
||||
def error(parent, summary, message):
|
||||
import gi
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, Gdk
|
||||
d = Gtk.MessageDialog(parent=parent,
|
||||
flags=Gtk.DialogFlags.MODAL,
|
||||
type=Gtk.MessageType.ERROR,
|
||||
buttons=Gtk.ButtonsType.CLOSE)
|
||||
d.set_markup("<big><b>%s</b></big>\n\n%s" % (summary, message))
|
||||
d.realize()
|
||||
d.get_window().set_functions(Gdk.WMFunction.MOVE)
|
||||
d.set_title("")
|
||||
d.run()
|
||||
d.destroy()
|
||||
return False
|
||||
|
||||
def _split_package_id(package):
|
||||
"""Return the name, the version number and the release of the
|
||||
specified package."""
|
||||
if ":" in package:
|
||||
name, arch = package.split(":", 1)
|
||||
# release = None
|
||||
# elif "/" in package:
|
||||
# name, release = package.split("/", 1)
|
||||
# version = None
|
||||
else:
|
||||
name = package
|
||||
arch = None
|
||||
return name, arch
|
||||
|
||||
|
||||
def get_config_patch():
|
||||
#检查组配置文件当前的目录
|
||||
NOW_UPDATE_CONFIG = '/usr/share/kylin-update-desktop-config/config/'
|
||||
OLD_UPDATE_CONFIG = '/usr/share/kylin-update-desktop-config/data/'
|
||||
if os.path.exists(NOW_UPDATE_CONFIG):
|
||||
return NOW_UPDATE_CONFIG
|
||||
elif os.path.exists(OLD_UPDATE_CONFIG):
|
||||
return NOW_UPDATE_CONFIG
|
||||
else:
|
||||
return NOW_UPDATE_CONFIG
|
||||
|
||||
def get_broken_details(cache,now=True):
|
||||
"""Return a message which provides debugging information about
|
||||
broken packages.
|
||||
|
||||
This method is basically a Python implementation of apt-get.cc's
|
||||
ShowBroken.
|
||||
|
||||
Keyword arguments:
|
||||
trans -- the corresponding transaction
|
||||
#表示当前系统apt已经破损的话是True 如果是安装软件包讲导致破损的话是False
|
||||
now -- if we check currently broken dependecies or the installation
|
||||
candidate
|
||||
"""
|
||||
msg = _("The following packages have unmet dependencies:")
|
||||
msg += "\n\n"
|
||||
for pkg in cache:
|
||||
if not ((now and pkg.is_now_broken) or
|
||||
(not now and pkg.is_inst_broken)):
|
||||
continue
|
||||
msg += "%s: " % pkg.name
|
||||
#获取出现问题的包的版本
|
||||
if now:
|
||||
version = pkg.installed
|
||||
else:
|
||||
version = pkg.candidate
|
||||
indent = " " * (len(pkg.name) + 2)
|
||||
dep_msg = ""
|
||||
#拿取依赖关系
|
||||
for dep in version.dependencies:
|
||||
or_msg = ""
|
||||
for base_dep in dep.or_dependencies:
|
||||
if or_msg:
|
||||
or_msg += "or\n"
|
||||
or_msg += indent
|
||||
# Check if it's an important dependency
|
||||
# See apt-pkg/depcache.cc IsImportantDep
|
||||
# See apt-pkg/pkgcache.cc IsCritical()
|
||||
if not (base_dep.rawtype in ["Depends","PreDepends",
|
||||
"Obsoletes", "DpkgBreaks",
|
||||
"Conflicts"] or
|
||||
(apt_pkg.config.find_b("APT::Install-Recommends",
|
||||
False) and
|
||||
base_dep.rawtype == "Recommends") or
|
||||
(apt_pkg.config.find_b("APT::Install-Suggests",
|
||||
False) and
|
||||
base_dep.rawtype == "Suggests")):
|
||||
continue
|
||||
# Get the version of the target package
|
||||
try:
|
||||
pkg_name,pkg_arch = _split_package_id(base_dep.name)
|
||||
pkg_dep = cache[pkg_name]
|
||||
except KeyError:
|
||||
dep_version = None
|
||||
else:
|
||||
if now:
|
||||
dep_version = pkg_dep.installed
|
||||
else:
|
||||
dep_version = pkg_dep.candidate
|
||||
# We only want to display dependencies which cannot
|
||||
# be satisfied
|
||||
if dep_version and not apt_pkg.check_dep(base_dep.version,
|
||||
base_dep.relation,
|
||||
dep_version.version):
|
||||
break
|
||||
or_msg = "%s: %s " % (base_dep.rawtype, base_dep.name)
|
||||
if base_dep.version:
|
||||
or_msg += "(%s %s) " % (base_dep.relation,
|
||||
base_dep.version)
|
||||
if cache.is_virtual_package(base_dep.name):
|
||||
or_msg += _("but it is a virtual package")
|
||||
#表示这个依赖包没有安装 源里面没有
|
||||
elif not dep_version:
|
||||
if now:
|
||||
or_msg += _("but it is not installed")
|
||||
else:
|
||||
#要依赖包 不存在时走此
|
||||
or_msg += _("but it is not going to "
|
||||
"be installed")
|
||||
#表示安装的版本与需要的版本不一致 在这个地方来再进行递归安装判断 具体那些包造成的不能安装
|
||||
elif now:
|
||||
# TRANSLATORS: %s is a version number
|
||||
or_msg += (_("but %s is installed") %
|
||||
dep_version.version)
|
||||
else:
|
||||
#安装之后出现破损的话走这里
|
||||
# TRANSLATORS: %s is a version number
|
||||
or_msg += (_("but %s is to be installed") %
|
||||
dep_version.version)
|
||||
else:
|
||||
# Only append an or-group if at least one of the
|
||||
# dependencies cannot be satisfied
|
||||
if dep_msg:
|
||||
dep_msg += indent
|
||||
dep_msg += or_msg
|
||||
dep_msg += "\n"
|
||||
msg += dep_msg
|
||||
return msg
|
||||
|
||||
|
||||
def humanize_size(bytes):
|
||||
"""
|
||||
Convert a given size in bytes to a nicer better readable unit
|
||||
"""
|
||||
|
||||
if bytes < 1000 * 1000:
|
||||
# to have 0 for 0 bytes, 1 for 0-1000 bytes and for 1 and above
|
||||
# round up
|
||||
size_in_kb = int(ceil(bytes / float(1000)))
|
||||
# TRANSLATORS: download size of small updates, e.g. "250 kB"
|
||||
return ngettext("%(size).0f kB", "%(size).0f kB", size_in_kb) % {
|
||||
"size": size_in_kb}
|
||||
else:
|
||||
# TRANSLATORS: download size of updates, e.g. "2.3 MB"
|
||||
return locale.format_string(_("%.1f MB"), bytes / 1000.0 / 1000.0)
|
||||
|
||||
|
||||
def get_arch():
|
||||
return apt_pkg.config.find("APT::Architecture")
|
||||
|
||||
|
||||
def is_port_already_listening(port):
|
||||
""" check if the current system is listening on the given tcp port """
|
||||
# index in the line
|
||||
INDEX_LOCAL_ADDR = 1
|
||||
#INDEX_REMOTE_ADDR = 2
|
||||
INDEX_STATE = 3
|
||||
# state (st) that we care about
|
||||
STATE_LISTENING = '0A'
|
||||
# read the data
|
||||
with open("/proc/net/tcp") as net_tcp:
|
||||
for line in net_tcp.readlines():
|
||||
line = line.strip()
|
||||
if not line:
|
||||
continue
|
||||
# split, values are:
|
||||
# sl local_address rem_address st tx_queue rx_queue tr
|
||||
# tm->when retrnsmt uid timeout inode
|
||||
values = line.split()
|
||||
state = values[INDEX_STATE]
|
||||
if state != STATE_LISTENING:
|
||||
continue
|
||||
local_port_str = values[INDEX_LOCAL_ADDR].split(":")[1]
|
||||
local_port = int(local_port_str, 16)
|
||||
if local_port == port:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def iptables_active():
|
||||
""" Return True if iptables is active """
|
||||
# FIXME: is there a better way?
|
||||
iptables_empty = """Chain INPUT (policy ACCEPT)
|
||||
target prot opt source destination
|
||||
|
||||
Chain FORWARD (policy ACCEPT)
|
||||
target prot opt source destination
|
||||
|
||||
Chain OUTPUT (policy ACCEPT)
|
||||
target prot opt source destination
|
||||
"""
|
||||
if os.getuid() != 0:
|
||||
raise OSError("Need root to check the iptables state")
|
||||
if not os.path.exists("/sbin/iptables"):
|
||||
return False
|
||||
out = subprocess.Popen(["iptables", "-nL"],
|
||||
stdout=subprocess.PIPE,
|
||||
universal_newlines=True).communicate()[0]
|
||||
if out == iptables_empty:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def capitalize_first_word(string):
|
||||
""" this uppercases the first word's first letter
|
||||
"""
|
||||
if len(string) > 1 and string[0].isalpha() and not string[0].isupper():
|
||||
return string[0].capitalize() + string[1:]
|
||||
return string
|
||||
|
||||
|
||||
def get_package_label(pkg):
|
||||
""" this takes a package synopsis and uppercases the first word's
|
||||
first letter
|
||||
"""
|
||||
name = getattr(pkg.candidate, "summary", "")
|
||||
return capitalize_first_word(name)
|
||||
|
||||
# 查看uu进程是否需要kill
|
||||
def kill_process(path):
|
||||
try:
|
||||
# 判断文件是否存在
|
||||
if (os.path.exists(path)):
|
||||
with open(path, "r") as f:
|
||||
pid = f.read()
|
||||
if len(pid) == 0:
|
||||
return False
|
||||
logging.info("Unattended Upgrades run path: %d. ", int(pid))
|
||||
os.kill(int(pid), 9)
|
||||
logging.info('Unattended Upgrades is running, kill pid: %d. ', int(pid))
|
||||
else:
|
||||
logging.warning('%s is not exist.', path)
|
||||
except Exception as e:
|
||||
logging.error(e)
|
||||
return False
|
||||
return True
|
||||
|
||||
def whether_to_quit_uu():
|
||||
osreleasedict={}
|
||||
try:
|
||||
with open('/etc/os-release') as f:
|
||||
lines = f.readlines()
|
||||
for line in lines:
|
||||
ls = line.strip().split('=',1)
|
||||
osreleasedict.update({ls[0]:ls[1].strip('"')})
|
||||
except Exception as e:
|
||||
pass
|
||||
if 'SUB_PROJECT_CODENAME' not in osreleasedict.keys():
|
||||
osreleasedict.update({'SUB_PROJECT_CODENAME':''})
|
||||
if 'PROJECT_CODENAME' in osreleasedict:
|
||||
if osreleasedict['PROJECT_CODENAME']=='V10SP1-edu':
|
||||
if 'SUB_PROJECT_CODENAME' in osreleasedict:
|
||||
if osreleasedict['SUB_PROJECT_CODENAME']=='mavis':
|
||||
return False
|
||||
else:
|
||||
logging.info("SUB_PROJECT_CODENAME != mavis")
|
||||
else:
|
||||
logging.info("no SUB_PROJECT_CODENAME")
|
||||
else:
|
||||
logging.info("PROJECT_CODENAME != V10SP1-edu")
|
||||
else:
|
||||
logging.info("no PROJECT_CODENAME")
|
||||
|
||||
return True
|
||||
|
||||
def get_proc_from_dbus_name(dbus_name, bus=None):
|
||||
"""Return a deferred that gets the id of process owning the given
|
||||
system D-Bus name.
|
||||
"""
|
||||
|
||||
if not bus:
|
||||
bus = dbus.SystemBus()
|
||||
bus_obj = bus.get_object("org.freedesktop.DBus",
|
||||
"/org/freedesktop/DBus/Bus")
|
||||
pid = bus_obj.GetConnectionUnixProcessID(dbus_name,
|
||||
dbus_interface="org.freedesktop.DBus")
|
||||
proc = psutil.Process(int(pid))
|
||||
|
||||
# with open("/proc/%s/status" % pid) as process:
|
||||
# values = [v for v in process.readlines() if v.startswith("Uid:")]
|
||||
# uid = int(values[0].split()[1])
|
||||
|
||||
# #检查是否root用户执行
|
||||
# if uid == 0:
|
||||
# return "root"
|
||||
|
||||
return proc.name()
|
||||
|
||||
def deb_verify(deb_path, _isinstall = False):
|
||||
logging.info("Verify pkg:%s.",deb_path)
|
||||
_deb_path = str(deb_path)
|
||||
try:
|
||||
# # 加载验证签名库 , 验签接口暂时无法调用
|
||||
# args = ["dpkg-architecture", "-qDEB_TARGET_MULTIARCH"]
|
||||
# ret = subprocess.run(args, stdout=subprocess.PIPE,stderr=subprocess.STDOUT,text=True)
|
||||
# verifyso_path = os.path.join("/usr/lib/",str(ret.stdout).strip(),VERIFY_SO)
|
||||
# logging.info("Load verify interface:%s.",verifyso_path)
|
||||
# verifyso = ctypes.CDLL(verifyso_path)
|
||||
# #环境初始化
|
||||
# ret = verifyso.SOF_Initialize(ctx_obj)
|
||||
# if (ret) :
|
||||
# logging.info("SOF_InitializeEx error!")
|
||||
# return 2
|
||||
# if os.path.isfile(_deb_path):
|
||||
# ret = verifyso.BJCA_dodebverify(None, bytes(_deb_path, encoding='utf8'), _isinstall)
|
||||
if not os.path.isfile("/usr/bin/kylinsigntool"):
|
||||
logging.error("SOF_InitializeEx error!")
|
||||
return 1
|
||||
args = ["/usr/bin/kylinsigntool", "-v", _deb_path]
|
||||
ret = subprocess.run(args, stdout=subprocess.PIPE,stderr=subprocess.STDOUT,text=True)
|
||||
if "Signature Verified failed" in str(ret.stdout).strip() or "签名验证失败" in str(ret.stdout).strip():
|
||||
logging.info("Signature Verified failed!")
|
||||
return 2
|
||||
elif "Signature Verified Ok" in str(ret.stdout).strip() or "签名验证成功" in str(ret.stdout).strip():
|
||||
logging.info("Signature Verified Ok!")
|
||||
return 0
|
||||
except Exception as e:
|
||||
logging.error(e)
|
||||
return 3
|
||||
|
||||
def PolicyKit_Authority(details = '', sender = None):
|
||||
_allow_kylinsign = False
|
||||
_verify_kylinsign = False
|
||||
try:
|
||||
#获取未知来源应用安装策略Unknown sources apply installation policies
|
||||
inst_policies_path = "/etc/dpkg/dpkg.cfg"
|
||||
if os.path.isfile(inst_policies_path):
|
||||
with open(inst_policies_path, "r") as f:
|
||||
lines = f.readlines()
|
||||
for line in lines:
|
||||
if "allow-kylinsign" in line:
|
||||
_allow_kylinsign = True
|
||||
if "verify-kylinsign" in line:
|
||||
_verify_kylinsign = True
|
||||
if _allow_kylinsign == True and _verify_kylinsign == False: #策略: 阻止
|
||||
logging.debug("unknown sources apply installation policies: deter")
|
||||
return False,_("The package is unsigned, refuses to install.")
|
||||
elif _allow_kylinsign == True and _verify_kylinsign == True: #策略: 警告
|
||||
logging.debug("unknown sources apply installation policies: warning")
|
||||
elif _allow_kylinsign == False and _verify_kylinsign == False: #策略: 关闭
|
||||
logging.debug("unknown sources apply installation policies: close")
|
||||
else:
|
||||
logging.warning("Unknown sources apply installation policies get failed.")
|
||||
|
||||
#用户鉴权
|
||||
details = {'polkit.message':details}
|
||||
cancel_id = ''
|
||||
action = "cn.kylinos.KylinSystemUpdater.action"
|
||||
kit = dbus.SystemBus().get_object('org.freedesktop.PolicyKit1', '/org/freedesktop/PolicyKit1/Authority')
|
||||
kit = dbus.Interface(kit, 'org.freedesktop.PolicyKit1.Authority')
|
||||
(granted, notused , details) = kit.CheckAuthorization(
|
||||
('system-bus-name', {'name': sender}),
|
||||
action, details, dbus.UInt32(1),cancel_id, timeout=60*60*24*7)
|
||||
if granted:
|
||||
logging.info("Authentication success ...")
|
||||
return True,_("Authentication success.")
|
||||
else:
|
||||
logging.info("Authentication failure ...")
|
||||
return False,_("Authentication failure.")
|
||||
except Exception as e:
|
||||
logging.error(e)
|
||||
return False,str(e)
|
||||
|
||||
if __name__ == "__main__":
|
||||
#print(mirror_from_sources_list())
|
||||
#print(on_battery())
|
||||
#print(inside_chroot())
|
||||
#print(iptables_active())
|
||||
error(None, "bar", "baz")
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,101 @@
|
|||
# UpdateManager.py
|
||||
# -*- Mode: Python; indent-tabs-mode: nil; tab-width: 4; coding: utf-8 -*-
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import dbus
|
||||
import logging
|
||||
import dbus.service
|
||||
import traceback
|
||||
from gettext import gettext as _
|
||||
from dbus.mainloop.glib import DBusGMainLoop
|
||||
from gi.repository import GLib
|
||||
DBusGMainLoop(set_as_default=True)
|
||||
|
||||
from .UpgradeStrategiesDbus import UpgradeStrategiesDbusController,UPDATER_DBUS_INTERFACE,UPDATER_DBUS_PATH,UPDATER_DBUS_SERVICE
|
||||
from .Core.Database import Sqlite3Server
|
||||
from .Core.loop import mainloop
|
||||
|
||||
from SystemUpdater.Core.UpdaterConfigParser import UpgradeConfig
|
||||
|
||||
STRATEGY_IDLE_INTERVAL = 2*60
|
||||
STRATEGY_IDLE_TIMEOUT = 6*60
|
||||
class UpgradeStrategies():
|
||||
def __init__(self,options):
|
||||
try:
|
||||
self.options = options
|
||||
#dbus
|
||||
self.dbusController = self._setup_dbus()
|
||||
#config
|
||||
self.uuconfigs = UpgradeConfig(datadir = "/var/lib/unattended-upgrades/", name = "unattended-upgrades-policy.conf")
|
||||
self.sqlite3_server = Sqlite3Server(self)
|
||||
#策略配置接口的超时退出机制
|
||||
self.strategy_timestamp = 0
|
||||
GLib.timeout_add_seconds(STRATEGY_IDLE_INTERVAL,
|
||||
self._check_strategy_inactivity)
|
||||
except Exception as e:
|
||||
logging.error(e)
|
||||
traceback.print_exc()
|
||||
|
||||
def run(self):
|
||||
"""Start the daemon and listen for calls."""
|
||||
logging.info("Waiting for calls...")
|
||||
try:
|
||||
mainloop.run()
|
||||
except KeyboardInterrupt:
|
||||
self.dbusController.Quit(None)
|
||||
|
||||
def _setup_dbus(self):
|
||||
# check if there is another g-a-i already and if not setup one
|
||||
# listening on dbus
|
||||
bus = dbus.SystemBus()
|
||||
try:
|
||||
bus_name = dbus.service.BusName(UPDATER_DBUS_SERVICE,
|
||||
bus,
|
||||
do_not_queue=True)
|
||||
logging.info("Initiate dbus success ...")
|
||||
return UpgradeStrategiesDbusController(self, bus_name)
|
||||
except dbus.exceptions.NameExistsException:
|
||||
if self.options.replace is False:
|
||||
logging.critical("Another daemon is already running")
|
||||
sys.exit(1)
|
||||
logging.warning("Replacing already running daemon")
|
||||
|
||||
retry_reboot_times = 0
|
||||
the_other_guy = bus.get_object(UPDATER_DBUS_SERVICE,
|
||||
UPDATER_DBUS_PATH)
|
||||
the_other_guy.Quit(dbus_interface=UPDATER_DBUS_INTERFACE,
|
||||
timeout=300)
|
||||
time.sleep(1)
|
||||
while True:
|
||||
retry_reboot_times = retry_reboot_times + 1
|
||||
#当重试次数超过5次时退出程序
|
||||
if retry_reboot_times > 5:
|
||||
logging.critical("Reboot backend is Failed...")
|
||||
sys.exit(1)
|
||||
try:
|
||||
bus_name = dbus.service.BusName(UPDATER_DBUS_SERVICE,
|
||||
bus,
|
||||
do_not_queue=True)
|
||||
logging.warning("Replacing already running daemon to Success...")
|
||||
return UpgradeStrategiesDbusController(self, bus_name)
|
||||
except dbus.exceptions.NameExistsException:
|
||||
the_other_guy = bus.get_object(UPDATER_DBUS_SERVICE,
|
||||
UPDATER_DBUS_PATH)
|
||||
the_other_guy.Quit(dbus_interface=UPDATER_DBUS_INTERFACE,
|
||||
timeout=300)
|
||||
logging.error("Dbus has not withdrawn and retry reboot times:%d...",retry_reboot_times)
|
||||
time.sleep(1)
|
||||
|
||||
def _check_strategy_inactivity(self):
|
||||
logging.info("Checking for inactivity in Strategies daemon ...")
|
||||
timestamp = self.strategy_timestamp
|
||||
if timestamp == 0:
|
||||
self.strategy_timestamp = time.time()
|
||||
return True
|
||||
#超时退出
|
||||
if self.strategy_timestamp != 0 and time.time() - self.strategy_timestamp > STRATEGY_IDLE_TIMEOUT:
|
||||
logging.warning("Quitting due to inactivity")
|
||||
self.dbusController.Quit(None)
|
||||
return False
|
||||
return True
|
|
@ -0,0 +1,604 @@
|
|||
#!/usr/bin/python3
|
||||
import os
|
||||
import dbus
|
||||
import dbus.service
|
||||
import logging
|
||||
import subprocess
|
||||
from gettext import gettext as _
|
||||
from .Core.loop import mainloop
|
||||
from SystemUpdater.Core.utils import get_proc_from_dbus_name
|
||||
|
||||
UPDATER_DBUS_INTERFACE = 'com.kylin.UpgradeStrategies.interface'
|
||||
UPDATER_DBUS_PATH = '/com/kylin/UpgradeStrategies'
|
||||
UPDATER_DBUS_SERVICE = 'com.kylin.UpgradeStrategies'
|
||||
RUN_UNATTENDED_UPGRADE = '/var/run/unattended-upgrades.pid'
|
||||
SYSTEM_VERSION = '/etc/kylin-version/kylin-system-version.conf'
|
||||
|
||||
#颜色设置
|
||||
COLORLOG_SUFFIX = "\033[0m"
|
||||
|
||||
# Define some foreground colors
|
||||
BLACK = 30
|
||||
RED = 31
|
||||
GREEN = 32
|
||||
YELLOW = 33
|
||||
BLUE = 34
|
||||
MAGENTA = 35
|
||||
CYAN = 36
|
||||
WHITE = 37
|
||||
|
||||
#字体颜色
|
||||
FRONT_COLOR_SEQ = "\033[1;%dm"
|
||||
#背景颜色
|
||||
BACK_COLOR_SEQ = "\033[%d;1m"
|
||||
|
||||
COLORLOG_PREFIX = FRONT_COLOR_SEQ % GREEN
|
||||
COLORMETHOR_PREFIX = FRONT_COLOR_SEQ % CYAN
|
||||
|
||||
UU_UPGRADE_MODE_AUTOMATIC_DOWNLOAD = 0
|
||||
UU_UPGRADE_MODE_MANUAL = 1
|
||||
UU_UPGRADE_MODE_AUTOMATIC_INSTALL = 2
|
||||
UU_UPGRADE_MODE_BEFORE_SHUTDOWN = 3
|
||||
|
||||
|
||||
#dbus 建立
|
||||
class UpgradeStrategiesDbusController(dbus.service.Object):
|
||||
""" this is a helper to provide the UpdateManagerIFace """
|
||||
|
||||
P2P_DEDAULT_PATH = "/etc/default/apt-p2p"
|
||||
RETURN_SUCCESS_CODE = 0
|
||||
RETURN_SUCCESS_DESC = ""
|
||||
|
||||
RETURN_UNKNOWN_CODE = -1
|
||||
RETURN_UNKNOWN_DESC = ""
|
||||
|
||||
def __init__(self, parent, bus_name,
|
||||
object_path=UPDATER_DBUS_PATH):
|
||||
dbus.service.Object.__init__(self, bus_name, object_path)
|
||||
self.parent = parent
|
||||
self.bus = dbus.SystemBus()
|
||||
|
||||
self.transaction = None
|
||||
|
||||
def __check_change__(self, _config = None, _section = "", _option = "", _value = ""):
|
||||
if _config == None:
|
||||
return False
|
||||
if _value == _config.getWithDefault(_section,_option,_value," "):
|
||||
return True
|
||||
return False
|
||||
|
||||
@dbus.service.method(UPDATER_DBUS_INTERFACE,
|
||||
in_signature="", out_signature="",
|
||||
sender_keyword="caller_name")
|
||||
def Quit(self, caller_name):
|
||||
"""Request a shutdown of the daemon."""
|
||||
#如果在下载就请求 取消
|
||||
logging.info("Quitting was requested")
|
||||
logging.debug("Quitting main loop...")
|
||||
mainloop.quit()
|
||||
logging.debug("Exit")
|
||||
|
||||
## dbus接口: 开启或关闭预下载功能
|
||||
@dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='s', out_signature='is',sender_keyword='sender')
|
||||
def ChangingP2PStatus(self,_status,sender = None):
|
||||
status = str(_status)
|
||||
sender_name = get_proc_from_dbus_name(sender)
|
||||
logging.info(COLORMETHOR_PREFIX+'method'+COLORLOG_SUFFIX+' ChangingP2PStatus, _status = %s , sender name: %s',status,sender_name)
|
||||
|
||||
if os.path.exists(self.P2P_DEDAULT_PATH):
|
||||
if status == "enable":
|
||||
with open(self.P2P_DEDAULT_PATH, 'w+') as configfile:
|
||||
configfile.write("#enable=true\n")
|
||||
#第一次进行检查是否已经开启
|
||||
args = ["systemctl","is-enabled","apt-p2p.service"]
|
||||
p = subprocess.run(args, stdout=subprocess.PIPE,stderr=subprocess.STDOUT,text=True)
|
||||
if p.returncode != 0:
|
||||
logging.info("Apt-p2p service is not runing and will be enable...")
|
||||
#第二次进行重启
|
||||
args = ["systemctl","enable","apt-p2p.service"]
|
||||
p = subprocess.run(args, stdout=subprocess.PIPE,stderr=subprocess.STDOUT,text=True)
|
||||
if p.returncode == 0:
|
||||
logging.info("Service Enable Execute successfully")
|
||||
#第三次进行重启
|
||||
args = ["systemctl","restart","apt-p2p.service"]
|
||||
p = subprocess.run(args, stdout=subprocess.PIPE,stderr=subprocess.STDOUT,text=True)
|
||||
if p.returncode == 0:
|
||||
logging.info("Restart Execute successfully")
|
||||
return self.RETURN_SUCCESS_CODE,self.RETURN_SUCCESS_DESC
|
||||
else:
|
||||
logging.error(str(p.stdout))
|
||||
logging.error("Failed to execute reboot")
|
||||
return self.RETURN_UNKNOWN_CODE,str(p.stdout)
|
||||
else:
|
||||
logging.error(str(p.stdout))
|
||||
logging.error("Failed to execute enable")
|
||||
return self.RETURN_UNKNOWN_CODE,str(p.stdout)
|
||||
else:
|
||||
logging.info("Apt-p2p service has been enabled and not need to reabled...")
|
||||
return self.RETURN_SUCCESS_CODE,self.RETURN_SUCCESS_DESC
|
||||
|
||||
elif status == "disable":
|
||||
with open(self.P2P_DEDAULT_PATH, 'w+') as configfile:
|
||||
configfile.write("enable=false\n")
|
||||
|
||||
args = ["systemctl","is-enabled","apt-p2p.service"]
|
||||
p = subprocess.run(args, stdout=subprocess.PIPE,stderr=subprocess.STDOUT,text=True)
|
||||
if p.returncode == 0:
|
||||
logging.info("Apt-p2p service is runing and will be disable...")
|
||||
args = ["systemctl","disable","apt-p2p.service"]
|
||||
p = subprocess.run(args, stdout=subprocess.PIPE,stderr=subprocess.STDOUT,text=True)
|
||||
if p.returncode == 0:
|
||||
logging.info("Service disable Execute successfully")
|
||||
|
||||
args = ["systemctl","stop","apt-p2p.service"]
|
||||
p = subprocess.run(args, stdout=subprocess.PIPE,stderr=subprocess.STDOUT,text=True)
|
||||
|
||||
if p.returncode == 0:
|
||||
logging.info("Stop Execute successfully")
|
||||
return self.RETURN_SUCCESS_CODE,self.RETURN_SUCCESS_DESC
|
||||
else:
|
||||
logging.error(str(p.stdout))
|
||||
logging.error("Failed to execute Stop")
|
||||
return self.RETURN_UNKNOWN_CODE,str(p.stdout)
|
||||
else:
|
||||
logging.error(str(p.stdout))
|
||||
logging.error("Failed to execute disable")
|
||||
return self.RETURN_UNKNOWN_CODE,str(p.stdout)
|
||||
else:
|
||||
logging.info("Apt-p2p service has been disabled and not need to redisabled...")
|
||||
return self.RETURN_SUCCESS_CODE,self.RETURN_SUCCESS_DESC
|
||||
else:
|
||||
logging.waring("error: input value _status=%s",status)
|
||||
else:
|
||||
logging.waring("apt-p2p function is not install...")
|
||||
|
||||
## dbus接口: 开启或关闭预下载功能
|
||||
@dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='bs', out_signature='b',sender_keyword='sender')
|
||||
def SetPreDownloadState(self, _state, _time, sender = None):
|
||||
state = bool(_state)
|
||||
time = str(_time)
|
||||
sender_name = get_proc_from_dbus_name(sender)
|
||||
logging.info(COLORMETHOR_PREFIX+'method'+COLORLOG_SUFFIX+' SetPreDownloadState, state is %r, time: %s, sender name: %s .',state,time,sender_name)
|
||||
try:
|
||||
if state:
|
||||
if not self.__check_change__(self.parent.uuconfigs, "autoUpgradePolicy", "preDownload", "on"):
|
||||
self.parent.uuconfigs.setValue("autoUpgradePolicy", "preDownload", "on", True)
|
||||
self.PropertyChanged("preDownload","on")
|
||||
if not self.__check_change__(self.parent.uuconfigs, "autoUpgradePolicy", "preDownloadTime", time):
|
||||
self.parent.uuconfigs.setValue("autoUpgradePolicy", "preDownloadTime", time, True)
|
||||
self.PropertyChanged("preDownloadTime",time)
|
||||
else:
|
||||
if not self.__check_change__(self.parent.uuconfigs, "autoUpgradePolicy", "preDownload", "off"):
|
||||
self.parent.uuconfigs.setValue("autoUpgradePolicy", "preDownload", "off", True)
|
||||
self.PropertyChanged("preDownload","off")
|
||||
except Exception as e:
|
||||
logging.error(str(e))
|
||||
return False
|
||||
return True
|
||||
|
||||
## 设置更新周期
|
||||
@dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='i', out_signature='b',sender_keyword='sender')
|
||||
def SetUpdateDays(self, days, sender = None):
|
||||
_days = int(days)
|
||||
sender_name = get_proc_from_dbus_name(sender)
|
||||
logging.info(COLORMETHOR_PREFIX+'method'+COLORLOG_SUFFIX+' SetUpdateDays, days: %d , sender:%s .'\
|
||||
,_days,sender_name)
|
||||
try:
|
||||
if not self.__check_change__(self.parent.uuconfigs, "autoUpgradePolicy", "updateDays", _days):
|
||||
self.parent.uuconfigs.setValue("autoUpgradePolicy", "updateDays", str(_days), True)
|
||||
self.PropertyChanged("updateDays",str(_days))
|
||||
except Exception as e:
|
||||
logging.error(str(e))
|
||||
return False
|
||||
return True
|
||||
|
||||
# 设置自动更新时间
|
||||
@dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='s', out_signature='bs',sender_keyword='sender')
|
||||
def SetAutoUpgradeRandomRange(self,randomRange,sender=None):
|
||||
_randomRange = str(randomRange)
|
||||
sender_name = get_proc_from_dbus_name(sender)
|
||||
logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' SetAutoUpgradeRandomRange will be set value %s, sender: %s .',\
|
||||
_randomRange,sender_name)
|
||||
try:
|
||||
if not self.__check_change__(self.parent.uuconfigs, "autoUpgradePolicy", "randomRange", _randomRange):
|
||||
self.parent.uuconfigs.setValue("autoUpgradePolicy", "randomRange", _randomRange, True)
|
||||
self.PropertyChanged("randomRange",_randomRange)
|
||||
except Exception as e:
|
||||
logging.error(str(e))
|
||||
return True,"success"
|
||||
|
||||
## 设置是否开启自动重启,以及设置自动重启的时间
|
||||
@dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='bs', out_signature='b',sender_keyword='sender')
|
||||
def SetAutomaticReboot(self, status, reboot_time, sender = None):
|
||||
_state = bool(status)
|
||||
_reboot_time = str(reboot_time)
|
||||
sender_name = get_proc_from_dbus_name(sender)
|
||||
logging.info(COLORMETHOR_PREFIX+'method'+COLORLOG_SUFFIX+' SetAutomaticReboot, status is %r, reboot_time: %s, sender name: %s .'\
|
||||
,_state,_reboot_time,sender_name)
|
||||
try:
|
||||
if _state:
|
||||
if not self.__check_change__(self.parent.uuconfigs, "autoUpgradePolicy", "automaticReboot", "on"):
|
||||
self.parent.uuconfigs.setValue("autoUpgradePolicy", "automaticReboot", "on", True)
|
||||
self.PropertyChanged("automaticReboot","on")
|
||||
if not self.__check_change__(self.parent.uuconfigs, "autoUpgradePolicy", "automaticRebootTime", _reboot_time):
|
||||
self.parent.uuconfigs.setValue("autoUpgradePolicy", "automaticRebootTime", _reboot_time, True)
|
||||
self.PropertyChanged("automaticRebootTime",_reboot_time)
|
||||
else:
|
||||
if not self.__check_change__(self.parent.uuconfigs, "autoUpgradePolicy", "automaticReboot", "off"):
|
||||
self.parent.uuconfigs.setValue("autoUpgradePolicy", "automaticReboot", "off", True)
|
||||
self.PropertyChanged("automaticReboot","off")
|
||||
except Exception as e:
|
||||
logging.error(str(e))
|
||||
return False
|
||||
return True
|
||||
|
||||
## dbus接口: 开启关闭自动更新功能
|
||||
@dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='b', out_signature='b')
|
||||
def SetAutoUpgradeState(self, _state):
|
||||
state = bool(_state)
|
||||
logging.info(COLORMETHOR_PREFIX+'method'+COLORLOG_SUFFIX+' SetAutoUpgradeState, state is %r ...',state)
|
||||
try:
|
||||
if state:
|
||||
if not self.__check_change__(self.parent.uuconfigs, "autoUpgradePolicy", "autoUpgradeState", "on"):
|
||||
self.parent.uuconfigs.setValue("autoUpgradePolicy", "autoUpgradeState", "on", True)
|
||||
self.parent.sqlite3_server.insert_into_display("autoupdate_allow", "true")
|
||||
self.PropertyChanged("autoUpgradeState","on")
|
||||
self.ButtonStatusChange("autoUpgradeStatus", "true")
|
||||
else :
|
||||
if not self.__check_change__(self.parent.uuconfigs, "autoUpgradePolicy", "autoUpgradeState", "off"):
|
||||
self.parent.uuconfigs.setValue("autoUpgradePolicy", "autoUpgradeState", "off", True)
|
||||
self.parent.sqlite3_server.insert_into_display("autoupdate_allow", "false")
|
||||
self.PropertyChanged("autoUpgradeState","off")
|
||||
self.ButtonStatusChange("autoUpgradeStatus", "false")
|
||||
except Exception as e:
|
||||
logging.error(str(e))
|
||||
return False
|
||||
return True
|
||||
|
||||
## dbus接口: 设置自动更新策略
|
||||
@dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='is', out_signature='b')
|
||||
def SetAutoUpgradeMode(self, mode, time):
|
||||
_time = str(time)
|
||||
logging.info(COLORMETHOR_PREFIX+'method'+COLORLOG_SUFFIX+' SetAutoUpgradeMode, mode is %s, time is %s ...',mode,_time)
|
||||
try:
|
||||
if mode == UU_UPGRADE_MODE_AUTOMATIC_DOWNLOAD:
|
||||
if not self.__check_change__(self.parent.uuconfigs, "autoUpgradePolicy", "downloadMode", "timing"):
|
||||
self.parent.uuconfigs.setValue("autoUpgradePolicy", "downloadMode", "timing", True)
|
||||
self.PropertyChanged("downloadMode","timing")
|
||||
if not self.__check_change__(self.parent.uuconfigs, "autoUpgradePolicy", "downloadTime", str(_time)):
|
||||
self.parent.uuconfigs.setValue("autoUpgradePolicy", "downloadTime", str(_time), True)
|
||||
self.PropertyChanged("downloadTime",str(_time))
|
||||
self.ButtonStatusChange("autoUpgradeTime", str(_time))
|
||||
elif mode == UU_UPGRADE_MODE_AUTOMATIC_INSTALL:
|
||||
if not self.__check_change__(self.parent.uuconfigs, "autoUpgradePolicy", "installMode", "timing"):
|
||||
self.parent.uuconfigs.setValue("autoUpgradePolicy", "installMode", "timing", True)
|
||||
self.PropertyChanged("installMode","timing")
|
||||
if not self.__check_change__(self.parent.uuconfigs, "autoUpgradePolicy", "installTime", str(_time)):
|
||||
self.parent.uuconfigs.setValue("autoUpgradePolicy", "installTime", str(_time), True)
|
||||
self.PropertyChanged("installTime",str(_time))
|
||||
elif mode == UU_UPGRADE_MODE_BEFORE_SHUTDOWN:
|
||||
if not self.__check_change__(self.parent.uuconfigs, "autoUpgradePolicy", "installTime", "bshutdown"):
|
||||
self.parent.uuconfigs.setValue("autoUpgradePolicy", "installMode", "bshutdown", True)
|
||||
self.PropertyChanged("installMode","bshutdown")
|
||||
elif mode == UU_UPGRADE_MODE_MANUAL:
|
||||
if not self.__check_change__(self.parent.uuconfigs, "autoUpgradePolicy", "downloadMode", "manual"):
|
||||
self.parent.uuconfigs.setValue("autoUpgradePolicy", "downloadMode", "manual", True)
|
||||
self.PropertyChanged("downloadMode","manual")
|
||||
except Exception as e:
|
||||
logging.error(str(e))
|
||||
return False
|
||||
return True
|
||||
|
||||
# # dbus接口:改变apt下载速度
|
||||
@dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='sb', out_signature='b',sender_keyword='sender')
|
||||
def SetDownloadspeedMax(self, speed, set,sender = None):
|
||||
sender_name = get_proc_from_dbus_name(sender)
|
||||
logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' SetDownloadspeedMax, speed:%s, set:%r, sender name: %s .'%(speed, set, sender_name))
|
||||
#来重启Aptdeamon
|
||||
self.parent.init_config_aptdeamon = True
|
||||
if set:
|
||||
with open("/etc/apt/apt.conf.d/80apt-download", "w+") as f:
|
||||
try:
|
||||
f.write("Acquire::http::Dl-Limit" + " \"" + "%s" % str(speed) + "\";\n")
|
||||
f.write("Acquire::https::Dl-Limit" + " \"" + "%s" % str(speed) + "\";\n")
|
||||
#更改数据库值
|
||||
self.parent.sqlite3_server.insert_into_display("download_limit","true")
|
||||
self.parent.sqlite3_server.insert_into_display("download_limit_value",str(speed))
|
||||
#发送信号
|
||||
self.ButtonStatusChange("speed" , str(speed))
|
||||
return True
|
||||
except Exception as e:
|
||||
logging.error(e)
|
||||
return False
|
||||
else:
|
||||
if os.path.exists("/etc/apt/apt.conf.d/80apt-download"):
|
||||
os.remove("/etc/apt/apt.conf.d/80apt-download")
|
||||
self.parent.sqlite3_server.insert_into_display("download_limit","false")
|
||||
self.ButtonStatusChange("speed", "0")
|
||||
return True
|
||||
else:
|
||||
self.parent.sqlite3_server.insert_into_display("download_limit","false")
|
||||
self.ButtonStatusChange("speed", "0")
|
||||
return True
|
||||
|
||||
# # dbus接口:获取apt下载速度
|
||||
@dbus.service.method(UPDATER_DBUS_INTERFACE, out_signature='bs',sender_keyword='sender')
|
||||
def GetDownloadspeedLimitValue(self,sender = None):
|
||||
sender_name = get_proc_from_dbus_name(sender)
|
||||
logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' GetDownloadspeedLimitValue sender: %s .', sender_name)
|
||||
try:
|
||||
download_limit = self.parent.sqlite3_server.select_from_display("download_limit")
|
||||
if download_limit == "true":
|
||||
download_limit_value = self.parent.sqlite3_server.select_from_display("download_limit_value")
|
||||
return True,str(download_limit_value)
|
||||
else:
|
||||
return False,str("0")
|
||||
except:
|
||||
return False, "0"
|
||||
|
||||
# 是否允许关机前更新
|
||||
@dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='ss', out_signature='bs', sender_keyword='sender')
|
||||
def UnattendedUpgradeValue(self, operation, value="false", sender=None):
|
||||
sender_name = get_proc_from_dbus_name(sender)
|
||||
logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' UnattendedUpgradeValue sender:%s ', sender_name)
|
||||
if operation.lower() != "get" and operation.lower() != "set":
|
||||
return False, 'Please input [\"set\", \"value\"] to set. \nor [\"get\"] to get whether updates are allowed before shutdown.'
|
||||
if operation == "set":
|
||||
try:
|
||||
logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' UnattendedUpgradeValue is going to %s [allow_unattended_upgrades_shutdown] value to %s.'%(operation,value))
|
||||
self.parent.sqlite3_server.insert_into_display("allow_unattended_upgrades_shutdown", value.lower())
|
||||
except Exception as e:
|
||||
logging.error(str(e))
|
||||
return False,str(e)
|
||||
else:
|
||||
logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' UnattendedUpgradeValue is going to %s [allow_unattended_upgrades_shutdown] value.'%(operation))
|
||||
try:
|
||||
value = self.parent.sqlite3_server.select_from_display("allow_unattended_upgrades_shutdown")
|
||||
logging.info("[allow_unattended_upgrades_shutdown] value is %s."%(value))
|
||||
except Exception as e:
|
||||
logging.error(str(e))
|
||||
return False,str(e)
|
||||
return True,"success"
|
||||
|
||||
# 设置自动更新时间
|
||||
@dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='s', out_signature='bs',sender_keyword='sender')
|
||||
def SetAutoUpgradePeriod(self, period, sender = None):
|
||||
sender_name = get_proc_from_dbus_name(sender)
|
||||
logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' SetAutoUpgradePeriod will be set value %s, SetAutoUpgradePeriod sender: %s.'%(period, sender_name))
|
||||
try:
|
||||
self.parent.sqlite3_server.insert_into_display("update_period", period.lower())
|
||||
except Exception as e:
|
||||
logging.error(str(e))
|
||||
return True,"success"
|
||||
|
||||
# 获取数据库值
|
||||
@dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='bss', out_signature='s')
|
||||
def GetSetDatabaseInfo(self, gs, table, field):
|
||||
Text = 'NULL'
|
||||
try:
|
||||
if gs: #get
|
||||
if table == 'display':
|
||||
Text = self.parent.sqlite3_server.select_from_display(str(field))
|
||||
logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' GetDatabaseInfo Table:%s Field:%s Text:%s',table,field,Text)
|
||||
else: #set
|
||||
if table == 'display' and "=" in field:
|
||||
field, value = str(field).split("=")
|
||||
logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' SetDatabaseInfo Table:%s Field:%s', table, field)
|
||||
self.parent.sqlite3_server.insert_into_display(field, value)
|
||||
return "success"
|
||||
except Exception as e:
|
||||
logging.error(str(e))
|
||||
return Text
|
||||
return Text
|
||||
|
||||
## dbus接口: 发送立即更新的信号
|
||||
@dbus.service.method(UPDATER_DBUS_INTERFACE, out_signature='b')
|
||||
def AutoUpgradeAllNow(self):
|
||||
logging.info(COLORMETHOR_PREFIX+'method'+COLORLOG_SUFFIX+' AutoUpgradeAllNow ...')
|
||||
try:
|
||||
self.UpgradeAllNow()
|
||||
except Exception as e:
|
||||
logging.error(str(e))
|
||||
return False
|
||||
return True
|
||||
|
||||
# kill 进程
|
||||
@dbus.service.method(UPDATER_DBUS_INTERFACE, in_signature='i', out_signature='b')
|
||||
def KillProcessSignal(self, pid):
|
||||
logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' KillProcessSignal is %d', pid)
|
||||
try:
|
||||
# 判断文件是否存在
|
||||
if (os.path.exists(RUN_UNATTENDED_UPGRADE)):
|
||||
os.kill(int(pid), 9)
|
||||
logging.info('%s has been killed', pid)
|
||||
else:
|
||||
logging.warning('%s is not exist.', RUN_UNATTENDED_UPGRADE)
|
||||
except Exception as e:
|
||||
logging.error(str(e))
|
||||
return False
|
||||
return True
|
||||
|
||||
#设置数据库配置信息
|
||||
@dbus.service.method(UPDATER_DBUS_INTERFACE,in_signature='ss',out_signature='b',sender_keyword='sender')
|
||||
def DatabaseInfoSet(self,field_name,field_value,sender=None):
|
||||
Status = False
|
||||
sender_name = get_proc_from_dbus_name(sender)
|
||||
logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' SetDatabaseInfo,field_name:%s,field_value:%s,caller:%s .',\
|
||||
field_name,field_value,sender_name)
|
||||
Status = self.parent.sqlite3_server.insert_into_display(field_name,field_value)
|
||||
return bool(Status)
|
||||
|
||||
#数据库获取配置信息
|
||||
@dbus.service.method(UPDATER_DBUS_INTERFACE,in_signature='s',out_signature='s',sender_keyword='sender')
|
||||
def DatabaseInfoGet(self,field_name,sender=None):
|
||||
field_value = ''
|
||||
sender_name = get_proc_from_dbus_name(sender)
|
||||
logging.info(COLORMETHOR_PREFIX+'Method'+COLORLOG_SUFFIX+' GetDatabaseInfo field_name:%s caller:%s',field_name,sender_name)
|
||||
field_value = self.parent.sqlite3_server.select_from_display(str(field_name))
|
||||
logging.info("Get field_value:%s",field_value)
|
||||
return field_value
|
||||
|
||||
#限速修改信号
|
||||
@dbus.service.signal(UPDATER_DBUS_INTERFACE,signature='ss')
|
||||
def ButtonStatusChange(self, signal_types = '', value=''):
|
||||
logging.info(COLORLOG_PREFIX + "Emitting"+ COLORLOG_SUFFIX + " ButtonStatusChange signal_types = %s, value = %s.",signal_types, value)
|
||||
|
||||
# dbus 信号:用于发送立即更新信号
|
||||
@dbus.service.signal(UPDATER_DBUS_INTERFACE)
|
||||
def UpgradeAllNow(self):
|
||||
logging.info(COLORLOG_PREFIX + "Emitting" + COLORLOG_SUFFIX +" UpgradeAllNow")
|
||||
|
||||
# dbus 信号:用于发送自动更新配置更改信号
|
||||
@dbus.service.signal(UPDATER_DBUS_INTERFACE)
|
||||
def ChangeUpgradePolicy(self):
|
||||
logging.info(COLORLOG_PREFIX + "Emitting" + COLORLOG_SUFFIX +" ChangeUpgradePolicy")
|
||||
|
||||
|
||||
#限速修改信号
|
||||
@dbus.service.signal(UPDATER_DBUS_INTERFACE,signature='ss')
|
||||
def ButtonStatusChange(self, signal_types = '', value=''):
|
||||
logging.info(COLORLOG_PREFIX + "Emitting"+ COLORLOG_SUFFIX + " ButtonStatusChange signal_types = %s, value = %s.",signal_types, value)
|
||||
|
||||
|
||||
# signal:属性发生改变
|
||||
@dbus.service.signal(dbus_interface=UPDATER_DBUS_INTERFACE,
|
||||
signature="ss")
|
||||
def PropertyChanged(self, property, value):
|
||||
logging.info(COLORLOG_PREFIX + "Emitting" + COLORLOG_SUFFIX +" PropertyChanged: ( %s, %s )" % (property, value))
|
||||
|
||||
|
||||
# WRITABLE_PROPERTIES = ()
|
||||
|
||||
# # pylint: disable-msg=C0103,C0322
|
||||
# @dbus.service.signal(dbus_interface=dbus.PROPERTIES_IFACE,
|
||||
# signature="sa{sv}as")
|
||||
# def PropertiesChanged(self, interface, changed_properties,
|
||||
# invalidated_properties):
|
||||
# """The signal gets emitted if a property of the object's
|
||||
# interfaces changed.
|
||||
|
||||
# :param property: The name of the interface.
|
||||
# :param changed_properties: A dictrionary of changed
|
||||
# property/value pairs
|
||||
# :param invalidated_properties: An array of property names which
|
||||
# changed but the value isn't conveyed.
|
||||
|
||||
# :type interface: s
|
||||
# :type changed_properties: a{sv}
|
||||
# :type invalidated_properties: as
|
||||
# """
|
||||
# logging.info("Emitting PropertiesChanged: %s, %s, %s" %
|
||||
# (interface, changed_properties, invalidated_properties))
|
||||
|
||||
# # pylint: disable-msg=C0103,C0322
|
||||
# @dbus.service.method(dbus.INTROSPECTABLE_IFACE,
|
||||
# in_signature='', out_signature='s',
|
||||
# path_keyword='object_path',
|
||||
# connection_keyword='connection')
|
||||
# def Introspect(self, object_path, connection):
|
||||
# # Inject the properties into the introspection xml data
|
||||
# data = dbus.service.Object.Introspect(self, object_path, connection)
|
||||
# xml = ElementTree.fromstring(data)
|
||||
# for iface in xml.findall("interface"):
|
||||
# props = self._get_properties(iface.attrib["name"])
|
||||
# for key, value in props.items():
|
||||
# attrib = {"name": key}
|
||||
# if key in self.WRITABLE_PROPERTIES:
|
||||
# attrib["access"] = "readwrite"
|
||||
# else:
|
||||
# attrib["access"] = "read"
|
||||
# if isinstance(value, dbus.String):
|
||||
# attrib["type"] = "s"
|
||||
# elif isinstance(value, dbus.UInt32):
|
||||
# attrib["type"] = "u"
|
||||
# elif isinstance(value, dbus.Int32):
|
||||
# attrib["type"] = "i"
|
||||
# elif isinstance(value, dbus.UInt64):
|
||||
# attrib["type"] = "t"
|
||||
# elif isinstance(value, dbus.Int64):
|
||||
# attrib["type"] = "x"
|
||||
# elif isinstance(value, dbus.Boolean):
|
||||
# attrib["type"] = "b"
|
||||
# elif isinstance(value, dbus.Struct):
|
||||
# attrib["type"] = "(%s)" % value.signature
|
||||
# elif isinstance(value, dbus.Dictionary):
|
||||
# attrib["type"] = "a{%s}" % value.signature
|
||||
# elif isinstance(value, dbus.Array):
|
||||
# attrib["type"] = "a%s" % value.signature
|
||||
# else:
|
||||
# raise Exception("Type %s of property %s isn't "
|
||||
# "convertable" % (type(value), key))
|
||||
# iface.append(ElementTree.Element("property", attrib))
|
||||
# new_data = ElementTree.tostring(xml, encoding="UTF-8")
|
||||
# return new_data
|
||||
|
||||
# # pylint: disable-msg=C0103,C0322
|
||||
# @dbus.service.method(dbus.PROPERTIES_IFACE,
|
||||
# in_signature="ssv", out_signature="",
|
||||
# sender_keyword="sender")
|
||||
# def Set(self, iface, name, value, sender):
|
||||
# """Set a property.
|
||||
|
||||
# Only the user who intiaited the transaction is
|
||||
# allowed to modify it.
|
||||
|
||||
# :param iface: The interface which provides the property.
|
||||
# :param name: The name of the property which should be modified.
|
||||
# :param value: The new value of the property.
|
||||
|
||||
# :type iface: s
|
||||
# :type name: s
|
||||
# :type value: v
|
||||
# """
|
||||
# logging.info("Set() was called: %s, %s" % (name, value))
|
||||
# return self._set_property(iface, name, value, sender)
|
||||
|
||||
# # pylint: disable-msg=C0103,C0322
|
||||
# @dbus.service.method(dbus.PROPERTIES_IFACE,
|
||||
# in_signature="s", out_signature="a{sv}")
|
||||
# def GetAll(self, iface):
|
||||
# """Get all available properties of the given interface."""
|
||||
# logging.info("GetAll() was called: %s" % iface)
|
||||
# return self._get_properties(iface)
|
||||
|
||||
# # pylint: disable-msg=C0103,C0322
|
||||
# @dbus.service.method(dbus.PROPERTIES_IFACE,
|
||||
# in_signature="ss", out_signature="v")
|
||||
# def Get(self, iface, property):
|
||||
# """Return the value of the given property provided by the given
|
||||
# interface.
|
||||
# """
|
||||
# logging.info("Get() was called: %s, %s" % (iface, property))
|
||||
# return self._get_properties(iface)[property]
|
||||
|
||||
# def _set_property(self, iface, name, value, sender):
|
||||
# """Helper to set a property on the properties D-Bus interface."""
|
||||
# if iface == UPDATER_DBUS_INTERFACE:
|
||||
# if name == "ShutdownInstall":
|
||||
# self.parent.configs_uncover.setValue("InstallMode","shutdown_install",str(bool(value)))
|
||||
# elif name == "UploadUpgradeLog":
|
||||
# self.parent.configs_uncover.setValue("SystemStatus","upload_upgrade_log",str(bool(value)))
|
||||
# elif name == "UploadInstallerLog":
|
||||
# self.parent.configs_uncover.setValue("SystemStatus","upload_installer_log",str(bool(value)))
|
||||
# else:
|
||||
# raise dbus.exceptions.DBusException("Unknown or read only "
|
||||
# "property: %s" % name)
|
||||
# else:
|
||||
# raise dbus.exceptions.DBusException("Unknown interface: %s" %
|
||||
# iface)
|
||||
|
||||
# def _get_properties(self, iface):
|
||||
# """Helper get the properties of a D-Bus interface."""
|
||||
# if iface == UPDATER_DBUS_INTERFACE:
|
||||
# return {
|
||||
# "ShutdownInstall": dbus.Boolean(
|
||||
# self.parent.configs_uncover.getWithDefault("InstallMode", "shutdown_install", False)),
|
||||
|
||||
# "UploadUpgradeLog": dbus.Boolean(
|
||||
# self.parent.configs_uncover.getWithDefault("SystemStatus", "upload_upgrade_log", True)),
|
||||
|
||||
# "UploadInstallerLog": dbus.Boolean(
|
||||
# self.parent.configs_uncover.getWithDefault("SystemStatus", "upload_installer_log", False))
|
||||
# }
|
||||
# else:
|
||||
# return {}
|
|
@ -0,0 +1,529 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import aptdaemon.client as client
|
||||
import aptdaemon.errors as errors
|
||||
import aptdaemon.enums as enums
|
||||
from aptdaemon.enums import (
|
||||
EXIT_SUCCESS,
|
||||
EXIT_FAILED,
|
||||
EXIT_CANCELLED,
|
||||
STATUS_FINISHED,
|
||||
get_error_description_from_enum,
|
||||
get_error_string_from_enum,
|
||||
get_status_string_from_enum
|
||||
)
|
||||
from defer import inline_callbacks
|
||||
from SystemUpdater.backend import InstallBackend
|
||||
import logging
|
||||
from gettext import gettext as _
|
||||
from SystemUpdater.Core.utils import humanize_size
|
||||
import dbus,time
|
||||
from gi.repository import GLib
|
||||
import traceback
|
||||
from importlib import reload
|
||||
|
||||
# 超时检测 秒单位
|
||||
UPDATER_IDLE_CHECK_INTERVAL = 5
|
||||
#安装的超时检查20分钟 按照5秒检查一次
|
||||
INSTALL_IDLE_TIMEOUT = 4 * 60
|
||||
#更新超时检查 5分钟
|
||||
UPDATE_IDLE_TIMEOUT = 5 * 60
|
||||
|
||||
class InstallBackendAptdaemon(InstallBackend):
|
||||
"""Makes use of aptdaemon to refresh the cache and to install updates."""
|
||||
|
||||
def __init__(self, window_main, action,mode = InstallBackend.MODE_DEFAULT_STATUS):
|
||||
InstallBackend.__init__(self, window_main, action,mode)
|
||||
self.window_main = window_main
|
||||
#切换aptdaemon的语言 重新导入模块就可以进行切换
|
||||
if self.window_main.aptd_lang_switch == True:
|
||||
self.window_main.aptd_lang_switch = False
|
||||
reload(client)
|
||||
reload(errors)
|
||||
reload(enums)
|
||||
|
||||
#客户端连接aptdeamon的dbus接口
|
||||
self.client = client.AptClient()
|
||||
self.trans_failed_msg = None
|
||||
|
||||
#是否在安装状态 判断依据进度>50
|
||||
self.on_install_stage = False
|
||||
if self.action == self.ACTION_INSTALL_SHUTDOWN:
|
||||
self.on_install_stage = True
|
||||
|
||||
if self.action == self.ACTION_UPDATE:
|
||||
#更新的超时检查机制 超时时取消下载
|
||||
self.update_timestamp = 0
|
||||
GLib.timeout_add_seconds(UPDATER_IDLE_CHECK_INTERVAL,
|
||||
self._check_update_inactivity)
|
||||
|
||||
#定时模拟发送进度 为了让进度更加线性
|
||||
self.simulation_progress = 0
|
||||
GLib.timeout_add_seconds(1,self._check_simulation_progress)
|
||||
|
||||
elif self.action == self.ACTION_INSTALL or self.action == self.ACTION_INSTALL_SHUTDOWN:
|
||||
#安装的超时间检查 超时解除禁止关机
|
||||
self.install_timestamp = INSTALL_IDLE_TIMEOUT
|
||||
self.check_progress = 0
|
||||
GLib.timeout_add_seconds(UPDATER_IDLE_CHECK_INTERVAL,
|
||||
self._check_install_inactivity)
|
||||
|
||||
def _check_simulation_progress(self):
|
||||
self.simulation_progress += 20
|
||||
|
||||
if self.aptd_base.progress >= 90 or self.simulation_progress > 80:
|
||||
return False
|
||||
else:
|
||||
self._dist_status_changed(self.action,[],self.simulation_progress,self.aptd_base.status,self.aptd_base.details)
|
||||
return True
|
||||
|
||||
def _check_install_inactivity(self):
|
||||
"""Shutdown the daemon if it has been inactive for time specified
|
||||
in INSTALL_IDLE_TIMEOUT.
|
||||
"""
|
||||
logging.info("Checking for inactivity in Installing Time:%d...",self.install_timestamp)
|
||||
|
||||
if self.window_main.now_working != self.ACTION_INSTALL and self.window_main.now_working != self.ACTION_INSTALL_SHUTDOWN:
|
||||
logging.info("Installing to exit and timeout check quit...")
|
||||
return False
|
||||
|
||||
# 进度不同时 更新时间戳
|
||||
if self.aptd_base.progress != self.check_progress:
|
||||
self.check_progress = self.aptd_base.progress
|
||||
self.install_timestamp = INSTALL_IDLE_TIMEOUT
|
||||
|
||||
#只有安装的时候启用 下载时候不使用
|
||||
if (self.install_timestamp <= 0 and self.on_install_stage == True):
|
||||
logging.error("Quitting due to inactivity(%s)",self.aptd_base.details)
|
||||
if self.action == self.ACTION_INSTALL_SHUTDOWN:
|
||||
#关机安装模式 解除禁止关机锁
|
||||
self.window_main.inhibit_lock.close()
|
||||
logging.info("Installtion timeout to exit Due to inactivity and Releasing the shutdown lock...")
|
||||
else:
|
||||
#超时只单独进行解锁关机
|
||||
self.inhibit_shutdown.unlock()
|
||||
self._action_done(self.ACTION_INSTALL,
|
||||
is_cancelled=False, success=False,
|
||||
#FIXME: 安装超时退出
|
||||
error_string=_("Could not install the upgrades"),
|
||||
error_desc=_("Installtion timeout to exit Due to inactivity") + self.aptd_base.details)
|
||||
|
||||
# self.window_main.dbusController.Quit(None)
|
||||
return False
|
||||
else:
|
||||
self.install_timestamp = self.install_timestamp - 1
|
||||
|
||||
return True
|
||||
|
||||
def _check_update_inactivity(self):
|
||||
logging.info("Checking for inactivity in Updating...")
|
||||
#退出定时器 当更新完毕的时候
|
||||
if (self.aptd_base.cancelable == False and self.aptd_base.progress >= 90) or self.window_main.now_working != self.ACTION_UPDATE:
|
||||
logging.info("Updating to exit and timeout check quit...")
|
||||
return False
|
||||
|
||||
#当更新进入下载状态时 记录进去的时间
|
||||
timestamp = self.update_timestamp
|
||||
if self.aptd_base.cancelable == True and timestamp == 0:
|
||||
self.update_timestamp = time.time()
|
||||
return True
|
||||
|
||||
#超时设置
|
||||
if self.update_timestamp != 0 and time.time() - self.update_timestamp > UPDATE_IDLE_TIMEOUT \
|
||||
and self.aptd_base.cancelable == True:
|
||||
|
||||
logging.error("Quitting due to inactivity")
|
||||
self.window_main.dbusController.transaction.cancel()
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
@inline_callbacks
|
||||
def update(self):
|
||||
"""刷新包cache"""
|
||||
try:
|
||||
trans = yield self.client.update_cache(defer=True)
|
||||
self.window_main.dbusController.transaction = trans
|
||||
# 注册回调函数 接收更新的状态
|
||||
yield self._show_transaction(trans, self.ACTION_UPDATE,
|
||||
_("Checking for updates…"), False)
|
||||
except errors.NotAuthorizedError:
|
||||
self._action_done(self.ACTION_UPDATE,
|
||||
authorized=False, success=False,
|
||||
error_string='', error_desc='')
|
||||
except Exception:
|
||||
self._action_done(self.ACTION_UPDATE,
|
||||
is_cancelled=False, success=False,
|
||||
error_string='', error_desc='')
|
||||
raise
|
||||
|
||||
@inline_callbacks
|
||||
def commit(self,model,pkgs_install, pkgs_upgrade, pkgs_remove,pkgs_downgrade = []):
|
||||
"""Commit a list of package adds and removes"""
|
||||
try:
|
||||
reinstall = purge = []
|
||||
trans = yield self.client.commit_packages(
|
||||
pkgs_install, reinstall, pkgs_remove, purge = purge, upgrade = pkgs_upgrade,
|
||||
downgrade = pkgs_downgrade,defer=True)
|
||||
self.window_main.dbusController.transaction = trans
|
||||
|
||||
yield self._show_transaction(trans, self.action,
|
||||
_("Installing updates…"), True)
|
||||
except errors.NotAuthorizedError:
|
||||
self._action_done(self.action,
|
||||
authorized=False, success=False,
|
||||
error_string='', error_desc='')
|
||||
except errors.TransactionFailed as e:
|
||||
self.trans_failed_msg = str(e)
|
||||
except dbus.DBusException as e:
|
||||
if e.get_dbus_name() != "org.freedesktop.DBus.Error.NoReply":
|
||||
raise
|
||||
self._action_done(self.action,
|
||||
authorized=False, success=False,
|
||||
error_string='', error_desc='')
|
||||
except Exception:
|
||||
self._action_done(self.action,
|
||||
is_cancelled=False, success=False,
|
||||
error_string='', error_desc='')
|
||||
raise
|
||||
|
||||
@inline_callbacks
|
||||
def commit_only(self,model,pkgs_install, pkgs_upgrade, pkgs_remove,pkgs_downgrade = []):
|
||||
"""Commit a list of package adds and removes"""
|
||||
try:
|
||||
reinstall = purge = []
|
||||
trans = yield self.client.commit_only(
|
||||
pkgs_install, reinstall, pkgs_remove, purge = purge, upgrade = pkgs_upgrade,
|
||||
downgrade = pkgs_downgrade,download = model, defer=True)
|
||||
self.window_main.dbusController.transaction = trans
|
||||
|
||||
yield self._show_transaction(trans, self.action,
|
||||
_("Installing updates…"), True)
|
||||
except errors.NotAuthorizedError:
|
||||
self._action_done(self.action,
|
||||
authorized=False, success=False,
|
||||
error_string='', error_desc='')
|
||||
except errors.TransactionFailed as e:
|
||||
self.trans_failed_msg = str(e)
|
||||
except dbus.DBusException as e:
|
||||
if e.get_dbus_name() != "org.freedesktop.DBus.Error.NoReply":
|
||||
raise
|
||||
self._action_done(self.action,
|
||||
authorized=False, success=False,
|
||||
error_string='', error_desc='')
|
||||
except Exception:
|
||||
self._action_done(self.action,
|
||||
is_cancelled=False, success=False,
|
||||
error_string='', error_desc='')
|
||||
raise
|
||||
|
||||
@inline_callbacks
|
||||
def install_deb(self,install_path,install_force):
|
||||
"""安装deb包 """
|
||||
try:
|
||||
trans = yield self.client.install_file(path = install_path,force = install_force,defer=True)
|
||||
# 注册回调函数 接收更新的状态
|
||||
yield self._show_transaction(trans, self.ACTION_INSTALL_DEB,
|
||||
_("Installing deb packages…"), False)
|
||||
except errors.NotAuthorizedError:
|
||||
self._action_done(self.ACTION_INSTALL_DEB,
|
||||
authorized=False, success=False,
|
||||
error_string='', error_desc='')
|
||||
except Exception as e:
|
||||
self._action_done(self.ACTION_INSTALL_DEB,
|
||||
is_cancelled=False, success=False,
|
||||
error_string=str(e), error_desc='')
|
||||
# raise
|
||||
|
||||
@inline_callbacks
|
||||
def fix_broken(self):
|
||||
"""安装deb包 """
|
||||
try:
|
||||
trans = yield self.client.fix_broken_depends(defer=True)
|
||||
self.window_main.dbusController.transaction = trans
|
||||
# 注册回调函数 接收更新的状态
|
||||
yield self._show_transaction(trans, self.ACTION_FIX_BROKEN,
|
||||
_("Installing deb packages…"), False)
|
||||
except errors.NotAuthorizedError:
|
||||
self._action_done(self.ACTION_FIX_BROKEN,
|
||||
authorized=False, success=False,
|
||||
error_string='', error_desc='')
|
||||
except Exception:
|
||||
self._action_done(self.ACTION_FIX_BROKEN,
|
||||
is_cancelled=False, success=False,
|
||||
error_string='', error_desc='')
|
||||
raise
|
||||
|
||||
@inline_callbacks
|
||||
def fix_incomplete(self):
|
||||
"""修复未完成的安装 """
|
||||
try:
|
||||
trans = yield self.client.fix_incomplete_install(defer=True)
|
||||
self.window_main.dbusController.transaction = trans
|
||||
# 注册回调函数 接收更新的状态
|
||||
yield self._show_transaction(trans, self.ACTION_FIX_INCOMPLETE,
|
||||
_("fix incomplete install"), False)
|
||||
except errors.NotAuthorizedError:
|
||||
self._action_done(self.ACTION_FIX_INCOMPLETE,
|
||||
authorized=False, success=False,
|
||||
error_string='', error_desc='')
|
||||
except Exception:
|
||||
self._action_done(self.ACTION_FIX_INCOMPLETE,
|
||||
is_cancelled=False, success=False,
|
||||
error_string='', error_desc='')
|
||||
raise
|
||||
|
||||
@inline_callbacks
|
||||
def clean(self):
|
||||
"""清空所有下载的文件 """
|
||||
try:
|
||||
trans = yield self.client.clean(defer=True)
|
||||
self.window_main.dbusController.transaction = trans
|
||||
# 注册回调函数 接收更新的状态
|
||||
yield self._show_transaction(trans, self.ACTION_CLEAN,
|
||||
_("Remove all downloaded files."), False)
|
||||
except errors.NotAuthorizedError:
|
||||
self._action_done(self.ACTION_CLEAN,
|
||||
authorized=False, success=False,
|
||||
error_string='', error_desc='')
|
||||
except Exception:
|
||||
self._action_done(self.ACTION_CLEAN,
|
||||
is_cancelled=False, success=False,
|
||||
error_string='', error_desc='')
|
||||
raise
|
||||
|
||||
@inline_callbacks
|
||||
def purge_packages(self,pkgs_purge):
|
||||
"""卸载deb包 """
|
||||
try:
|
||||
# trans = yield self.client.remove_packages(package_names = pkgs_purge,defer=True)
|
||||
trans = yield self.client.commit_packages([],[],[],pkgs_purge,[],[],defer=True)
|
||||
self.window_main.dbusController.transaction = trans
|
||||
# 注册回调函数 接收更新的状态
|
||||
yield self._show_transaction(trans, self.ACTION_REMOVE_PACKAGES,
|
||||
_("Installing deb packages…"), False)
|
||||
except errors.NotAuthorizedError:
|
||||
self._action_done(self.ACTION_REMOVE_PACKAGES,
|
||||
authorized=False, success=False,
|
||||
error_string='', error_desc='')
|
||||
except Exception as e:
|
||||
logging.error(str(e))
|
||||
# self._action_done(self.ACTION_REMOVE_PACKAGES,
|
||||
# is_cancelled=False, success=False,
|
||||
# error_string=str(e), error_desc='')
|
||||
|
||||
#进度回调
|
||||
def _on_progress_changed(self, trans,progress,action):
|
||||
#不要101这种未知状态
|
||||
if progress == 101:
|
||||
return
|
||||
|
||||
#过滤掉不是线性的进度
|
||||
if progress > self.aptd_base.progress:
|
||||
self.aptd_base.progress = progress
|
||||
else:
|
||||
return
|
||||
|
||||
self.aptd_base.progress = progress
|
||||
self._dist_status_changed(action,self.now_upgrade.upgrade_content,self.aptd_base.progress,self.aptd_base.status,self.aptd_base.details)
|
||||
|
||||
|
||||
#同步状态回调
|
||||
def _on_status_changed(self, trans, status,action):
|
||||
if action == self.ACTION_UPDATE and status == STATUS_FINISHED:
|
||||
return
|
||||
|
||||
#转化词条
|
||||
self.aptd_base.status = get_status_string_from_enum(status)
|
||||
if self.aptd_base.status == None:
|
||||
return
|
||||
|
||||
self._dist_status_changed(action,self.now_upgrade.upgrade_content,\
|
||||
self.aptd_base.progress,self.aptd_base.status,self.aptd_base.details)
|
||||
|
||||
#分发进度状态和细节信息
|
||||
def _dist_status_changed(self,action,upgrade_content = [],progress = 0,status = '',details = ''):
|
||||
if action == self.ACTION_UPDATE: # 更新进度100后推迟发出100%的信号 -- 等待源过滤完成
|
||||
if progress == 11:
|
||||
progress = 15
|
||||
|
||||
if progress != 100:
|
||||
self.window_main.dbusController.UpdateDetectStatusChanged(progress,status)
|
||||
elif action == self.ACTION_INSTALL:
|
||||
#50%时候 属于下载状态切换到安装状态的过程 下面的代码只执行一次
|
||||
if progress >= 50 and progress < 90 and self.on_install_stage == False:
|
||||
logging.info("The process is now in the installtion phase")
|
||||
self.on_install_stage = True
|
||||
self.safe_manager.shutdown_safe()
|
||||
self._start_install_lock(_("Kylin System Updater"))
|
||||
|
||||
#只处理从下载切换到安装时出现的网络问题
|
||||
#当网络波动时下载某些软件包失败时属于异常状态进行重试时 不发送后续进度 等待重试正常是 进行下载安装
|
||||
if self.now_upgrade.version_upgrade == True and progress >= 48 and self.on_install_stage != True and 'Failed to fetch' in self.aptd_base.error_details:
|
||||
logging.warning("Arise Failed to fetch and Need retry Upgrade...")
|
||||
self.now_upgrade.need_retry = True
|
||||
return
|
||||
|
||||
#在下载阶段发送取消信号
|
||||
if self.on_install_stage == False:
|
||||
self.window_main.dbusController.Cancelable(self.aptd_base.cancelable)
|
||||
|
||||
self.window_main.dbusController.UpdateDloadAndInstStaChanged(upgrade_content,progress,status,details)
|
||||
elif action == self.ACTION_INSTALL_SHUTDOWN:
|
||||
# 写入进度 到plymouth
|
||||
self._progress_to_plymouth(progress)
|
||||
self.window_main.dbusController.UpdateDloadAndInstStaChanged(upgrade_content,progress,status,details)
|
||||
|
||||
elif action == self.ACTION_DOWNLOADONLY:
|
||||
#只处理从下载切换到安装时出现的网络问题
|
||||
#当网络波动时下载某些软件包失败时属于异常状态进行重试时 不发送后续进度 等待重试正常是 进行下载安装
|
||||
if self.now_upgrade.version_upgrade == True and progress >= 48 and 'Failed to fetch' in self.aptd_base.error_details:
|
||||
logging.warning("Arise Failed to fetch and Need retry Upgrade...")
|
||||
self.now_upgrade.need_retry = True
|
||||
return
|
||||
|
||||
self.window_main.dbusController.Cancelable(self.aptd_base.cancelable)
|
||||
self.window_main.dbusController.UpdateDloadAndInstStaChanged(upgrade_content,progress,status,details)
|
||||
|
||||
elif action == self.ACTION_FIX_BROKEN:
|
||||
self.window_main.dbusController.FixBrokenStatusChanged(False,True,progress,status,'','')
|
||||
elif action == self.ACTION_REMOVE_PACKAGES:
|
||||
self.window_main.dbusController.PurgePkgStatusChanged(progress,status,details)
|
||||
elif action == self.ACTION_INSTALL_DEB or action == self.ACTION_BACKGROUND_UPGRADE:
|
||||
self.window_main.dbusController.InstalldebStatusChanged(progress,status,details)
|
||||
else:
|
||||
logging.info("Other Action:progress = %d , status = %s ,details = %s",progress,status,details)
|
||||
|
||||
def _on_details_changed(self, trans, details,action):
|
||||
self.aptd_base.details = details
|
||||
self._dist_status_changed(action,self.now_upgrade.upgrade_groups+self.now_upgrade.single_pkgs,\
|
||||
self.aptd_base.progress,self.aptd_base.status,self.aptd_base.details)
|
||||
|
||||
def _on_download_changed(self, trans, details):
|
||||
logging.info(details)
|
||||
|
||||
# eta 剩余时间不正确,取消掉
|
||||
def _on_progress_download_changed(self,trans,current_items, total_items, currenty_bytes, total_bytes, current_cps, eta):
|
||||
if self.action == self.ACTION_INSTALL or self.action == self.ACTION_DOWNLOADONLY or self.action == self.ACTION_BACKGROUND_UPGRADE:
|
||||
self.window_main.dbusController.UpdateDownloadInfo(\
|
||||
self.now_upgrade.upgrade_groups+self.now_upgrade.single_pkgs,\
|
||||
current_items, total_items, \
|
||||
currenty_bytes, total_bytes, \
|
||||
current_cps)
|
||||
else:
|
||||
if self.action == self.ACTION_UPDATE or self.action == self.ACTION_REMOVE_PACKAGES:
|
||||
return
|
||||
logging.info("Other Action:current_items = %d, total_items = %d, currenty_bytes = %s, total_bytes = %s, current_cps = %s/s",\
|
||||
current_items, total_items, \
|
||||
humanize_size(currenty_bytes), humanize_size(total_bytes),\
|
||||
humanize_size(current_cps))
|
||||
|
||||
def _on_cancellable_changed(self, trans, Cancelable):
|
||||
#下面的这些 不发送取消信号
|
||||
if self.action == self.ACTION_REMOVE_PACKAGES:
|
||||
return
|
||||
|
||||
if self.action != self.ACTION_UPDATE:
|
||||
logging.info("\033[1;32m" + "Emitting" + "\033[0m" +" Cancelable: %r",Cancelable)
|
||||
self.window_main.dbusController.Cancelable(Cancelable)
|
||||
#增加取消信号的频发机制
|
||||
self.aptd_base.cancelable = Cancelable
|
||||
|
||||
def _on_config_file_conflict(self, transaction, old, new):
|
||||
logging.info("Config file conflict oldconf = %s , newconf = %s...",str(old),str(new))
|
||||
logging.info("Default To Replace Old Configfile...")
|
||||
#默认替换旧的配置文件
|
||||
transaction.resolve_config_file_conflict(old, "keep")
|
||||
# transaction.resolve_config_file_conflict(old, "keep")
|
||||
|
||||
#增加记录当产生错误的时候 详细信息
|
||||
def _on_error_changed(self, trans,error_code, error_details):
|
||||
# error_string = get_error_string_from_enum(error_code)
|
||||
self.aptd_base.error_details = str(error_details)
|
||||
logging.error(str(error_details))
|
||||
|
||||
@inline_callbacks
|
||||
def _show_transaction(self, trans, action, header, show_details):
|
||||
#更新和升级最后完成和失败都会走此在此进行完成之后的处理
|
||||
trans.connect("finished", self._on_finished, action)
|
||||
#升级和更新的状态信息和进度
|
||||
trans.connect("status-changed", self._on_status_changed,action)
|
||||
trans.connect("progress-changed", self._on_progress_changed,action)
|
||||
#取消升级
|
||||
trans.connect("cancellable-changed", self._on_cancellable_changed)
|
||||
#下载的进度信息
|
||||
trans.connect("progress-details-changed", self._on_progress_download_changed)
|
||||
trans.connect("status-details-changed", self._on_details_changed,action)
|
||||
trans.connect("error", self._on_error_changed)
|
||||
|
||||
trans.connect("config-file-conflict", self._on_config_file_conflict)
|
||||
|
||||
# yield trans.set_debconf_frontend("ukui")
|
||||
# yield trans.set_locale(os.environ["LANGUAGE"] + ".UTF-8")
|
||||
yield trans.run()
|
||||
|
||||
def _on_finished(self, trans, status, action):
|
||||
try:
|
||||
error_string = ''
|
||||
error_desc = ''
|
||||
#退出
|
||||
self.on_install_stage = False
|
||||
if status == EXIT_FAILED:
|
||||
# self.log_audit(str(trans.error.code))
|
||||
error_string = get_error_string_from_enum(trans.error.code)
|
||||
error_desc = get_error_description_from_enum(trans.error.code)
|
||||
if self.trans_failed_msg:
|
||||
error_desc = error_desc + "\n" + self.trans_failed_msg
|
||||
#取消下载
|
||||
elif status == EXIT_CANCELLED:
|
||||
error_string = _("Failed to fetch")
|
||||
error_desc = _("_Cancel Upgrade")
|
||||
elif status == EXIT_SUCCESS and action == self.ACTION_INSTALL:
|
||||
error_string = _("System upgrade is complete.")
|
||||
elif status == EXIT_SUCCESS and action == self.ACTION_REMOVE_PACKAGES:
|
||||
error_string = _("Uninstallation completed")
|
||||
|
||||
is_success = (status == EXIT_SUCCESS)
|
||||
self._action_done(action,
|
||||
is_cancelled=(status == EXIT_CANCELLED), success=is_success,
|
||||
error_string=error_string, error_desc=error_desc)
|
||||
except Exception as e:
|
||||
logging.error(e)
|
||||
traceback.print_exc()
|
||||
|
||||
# def log_audit(self,error_code):
|
||||
# if error_code == "error-package-manager-failed":
|
||||
# error_msg = self.check_install_error()
|
||||
|
||||
# with open("/var/log/kylin-system-updater/error_details.log", 'w+') as configfile:
|
||||
# configfile.write(str(error_msg))
|
||||
|
||||
# def check_install_error(self):
|
||||
# locate_error = ''
|
||||
# with open("/var/log/apt/term.log", "r+") as f:
|
||||
# log_start = None
|
||||
# log_end = None
|
||||
# aptterm_log = f.readlines()
|
||||
|
||||
# reverse_log = aptterm_log[::-1]
|
||||
|
||||
# for logstr in reverse_log:
|
||||
# if log_end == None and "Log ended:" in logstr:
|
||||
# log_end = aptterm_log.index(logstr)
|
||||
# if log_start == None and "Log started:" in logstr:
|
||||
# log_start = aptterm_log.index(logstr)
|
||||
|
||||
# if log_end != None and log_start != None:
|
||||
# break
|
||||
|
||||
# latest_log = aptterm_log[log_start:log_end+1]
|
||||
# error_deb = latest_log[-2].strip()
|
||||
|
||||
# error_msg_line = None
|
||||
# for log_msg in latest_log:
|
||||
# if error_deb in log_msg:
|
||||
# error_msg_line = latest_log.index(log_msg)
|
||||
# locate_error = latest_log[error_msg_line-5:error_msg_line+5]
|
||||
# break
|
||||
|
||||
# return locate_error
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1 @@
|
|||
Dir::Bin::Methods::ftp "ftp";
|
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE policyconfig PUBLIC
|
||||
"-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
|
||||
"http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
|
||||
<policyconfig>
|
||||
|
||||
<vendor>Kylin System Updater</vendor>
|
||||
<vendor_url>www.kylinos.cn</vendor_url>
|
||||
<icon_name>kylin-system-updater</icon_name>
|
||||
|
||||
<action id="cn.kylinos.KylinSystemUpdater.action">
|
||||
<_description>
|
||||
system level settings
|
||||
</_description>
|
||||
<_message>
|
||||
To Change the settings, you need to authenticate.
|
||||
</_message>
|
||||
<defaults>
|
||||
<allow_any>auth_admin_keep</allow_any>
|
||||
<allow_inactive>auth_admin_keep</allow_inactive>
|
||||
<allow_active>auth_admin_keep</allow_active>
|
||||
</defaults>
|
||||
</action>
|
||||
|
||||
</policyconfig>
|
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE policyconfig PUBLIC
|
||||
"-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
|
||||
"http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
|
||||
<policyconfig>
|
||||
|
||||
<vendor>Kylin System Updater Config Manager</vendor>
|
||||
<vendor_url>www.kylinos.cn</vendor_url>
|
||||
<icon_name>kylin-upgrade-strategies</icon_name>
|
||||
|
||||
<action id="com.kylin.UpgradeStrategies.action">
|
||||
<_description>
|
||||
system level settings
|
||||
</_description>
|
||||
<_message>
|
||||
To Change the settings, you need to authenticate.
|
||||
</_message>
|
||||
<defaults>
|
||||
<allow_any>auth_admin_keep</allow_any>
|
||||
<allow_inactive>auth_admin_keep</allow_inactive>
|
||||
<allow_active>auth_admin_keep</allow_active>
|
||||
</defaults>
|
||||
</action>
|
||||
|
||||
</policyconfig>
|
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?> <!-- -*- XML -*- -->
|
||||
|
||||
<!DOCTYPE busconfig PUBLIC
|
||||
"-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
|
||||
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
|
||||
<busconfig>
|
||||
<!-- Only root can own the service -->
|
||||
<policy user="root">
|
||||
<allow own="com.kylin.UpgradeStrategies"/>
|
||||
<allow send_interface="com.kylin.UpgradeStrategies.interface"/>
|
||||
</policy>
|
||||
|
||||
<!-- Allow anyone to invoke methods on the interfaces -->
|
||||
<policy context="default">
|
||||
<allow send_destination="com.kylin.UpgradeStrategies"
|
||||
send_interface="com.kylin.UpgradeStrategies.interface"/>
|
||||
<allow send_destination="com.kylin.UpgradeStrategies"
|
||||
send_interface="org.freedesktop.DBus.Introspectable"/>
|
||||
<allow send_destination="com.kylin.UpgradeStrategies"
|
||||
send_interface="org.freedesktop.DBus.Properties"/>
|
||||
|
||||
</policy>
|
||||
</busconfig>
|
|
@ -0,0 +1,4 @@
|
|||
[D-BUS Service]
|
||||
Name=com.kylin.UpgradeStrategies
|
||||
Exec=/bin/python3 /usr/share/kylin-system-updater/kylin-upgrade-strategies -r -d
|
||||
User=root
|
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?> <!-- -*- XML -*- -->
|
||||
|
||||
<!DOCTYPE busconfig PUBLIC
|
||||
"-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
|
||||
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
|
||||
<busconfig>
|
||||
<!-- Only root can own the service -->
|
||||
<policy user="root">
|
||||
<allow own="com.kylin.systemupgrade"/>
|
||||
<allow send_interface="com.kylin.systemupgrade.interface"/>
|
||||
</policy>
|
||||
|
||||
<!-- Allow anyone to invoke methods on the interfaces -->
|
||||
<policy context="default">
|
||||
<allow send_destination="com.kylin.systemupgrade"
|
||||
send_interface="com.kylin.systemupgrade.interface"/>
|
||||
<allow send_destination="com.kylin.systemupgrade"
|
||||
send_interface="org.freedesktop.DBus.Introspectable"/>
|
||||
<allow send_destination="com.kylin.systemupgrade"
|
||||
send_interface="org.freedesktop.DBus.Properties"/>
|
||||
|
||||
</policy>
|
||||
</busconfig>
|
|
@ -0,0 +1,14 @@
|
|||
[whitelist]
|
||||
key1 = /usr/bin/kylin-background-upgrade
|
||||
key2 = /usr/bin/ukui-control-center
|
||||
key3 = /usr/bin/kylin-installer
|
||||
key4 = /usr/bin/kylin-uninstaller
|
||||
key5 = /usr/bin/kylin-software-properties-service
|
||||
key6 = /usr/bin/kylin-source-update
|
||||
key7 = /usr/bin/kylin-source-manager
|
||||
key8 = /usr/bin/kylin-unattended-upgrade
|
||||
key9 = /usr/bin/kylin-software-center
|
||||
key10 = /usr/bin/kylin-printer
|
||||
key11 = /usr/bin/kylin-printer-applet
|
||||
key12 = /usr/bin/hedron-client
|
||||
key13 = /usr/bin/kylin-software-center-plugin-synchrodata
|
|
@ -0,0 +1,26 @@
|
|||
#!/bin/sh
|
||||
|
||||
# a) it breaks if its not available
|
||||
# b) the string we have here does not need it (because it has no vars)
|
||||
eval_gettext() {
|
||||
if [ -x /usr/bin/gettext ]; then
|
||||
echo $(gettext "$1")
|
||||
else
|
||||
echo "$1"
|
||||
fi
|
||||
}
|
||||
export TEXTDOMAIN=update-notifier
|
||||
export TEXTDOMAINDIR=/usr/share/locale
|
||||
|
||||
case "$DPKG_MAINTSCRIPT_PACKAGE::$DPKG_MAINTSCRIPT_NAME" in
|
||||
linux-image-extra*::postrm)
|
||||
exit 0;;
|
||||
esac
|
||||
|
||||
if [ "$0" = "/etc/kernel/postinst.d/update-notifier" ]; then
|
||||
DPKG_MAINTSCRIPT_PACKAGE=linux-base
|
||||
fi
|
||||
|
||||
# Wake the applet up
|
||||
echo "*** $(eval_gettext "System logout required") ***" > /var/run/logout-required
|
||||
echo "$DPKG_MAINTSCRIPT_PACKAGE" >> /var/run/logout-required.pkgs
|
|
@ -0,0 +1,26 @@
|
|||
#!/bin/sh
|
||||
|
||||
# a) it breaks if its not available
|
||||
# b) the string we have here does not need it (because it has no vars)
|
||||
eval_gettext() {
|
||||
if [ -x /usr/bin/gettext ]; then
|
||||
echo $(gettext "$1")
|
||||
else
|
||||
echo "$1"
|
||||
fi
|
||||
}
|
||||
export TEXTDOMAIN=update-notifier
|
||||
export TEXTDOMAINDIR=/usr/share/locale
|
||||
|
||||
case "$DPKG_MAINTSCRIPT_PACKAGE::$DPKG_MAINTSCRIPT_NAME" in
|
||||
linux-image-extra*::postrm)
|
||||
exit 0;;
|
||||
esac
|
||||
|
||||
if [ "$0" = "/etc/kernel/postinst.d/update-notifier" ]; then
|
||||
DPKG_MAINTSCRIPT_PACKAGE=linux-base
|
||||
fi
|
||||
|
||||
# Wake the applet up
|
||||
echo "*** $(eval_gettext "System restart required") ***" > /var/run/reboot-required
|
||||
echo "$DPKG_MAINTSCRIPT_PACKAGE" >> /var/run/reboot-required.pkgs
|
|
@ -0,0 +1,10 @@
|
|||
/var/log/kylin-system-updater/kylin-system-updater.log.1
|
||||
{
|
||||
weekly
|
||||
missingok
|
||||
rotate 3
|
||||
compress
|
||||
notifempty
|
||||
minsize 10M
|
||||
copytruncate
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,13 @@
|
|||
[Unit]
|
||||
Description=kylin-system-updater dbus daemon
|
||||
StartLimitIntervalSec=0
|
||||
|
||||
[Service]
|
||||
Type=dbus
|
||||
Restart=always
|
||||
RestartSec=3
|
||||
BusName=com.kylin.systemupgrade
|
||||
ExecStart=/usr/share/kylin-system-updater/kylin-system-updater
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
|
@ -0,0 +1,3 @@
|
|||
[SYSTEM]
|
||||
os_version =
|
||||
update_version =
|
|
@ -0,0 +1,12 @@
|
|||
#此配置文件内的所有配置项,在新装时都会被替换掉
|
||||
[SystemStatusCover]
|
||||
close_source_filter = False
|
||||
priority_upgrade_restart = True
|
||||
|
||||
[ConfigPkgStatus]
|
||||
check_resover_remove = False
|
||||
check_frontend_pkg = True
|
||||
|
||||
[AutoUpgradeConfig]
|
||||
upgradeInterval = 7
|
||||
downloadRandom = 180
|
|
@ -0,0 +1,9 @@
|
|||
[SystemStatus]
|
||||
abnormal_reboot = False
|
||||
upload_upgrade_log = True
|
||||
upload_installer_log = False
|
||||
|
||||
[InstallMode]
|
||||
shutdown_install = False
|
||||
manual_install = False
|
||||
auto_install = False
|
|
@ -0,0 +1,30 @@
|
|||
[autoUpgradePolicy]
|
||||
#自动更新的开关
|
||||
autoUpgradeState = off
|
||||
|
||||
#预下载开关
|
||||
preDownload = off
|
||||
|
||||
# 预下载的时间为时间段 例如:10:00-11:00
|
||||
preDownloadTime = 10:00
|
||||
|
||||
#添加检查更新的周期 以天为单位
|
||||
updateDays = 1
|
||||
|
||||
# timing 为定时下载 manaual手动下载
|
||||
downloadMode = timing
|
||||
|
||||
# 下载的时间为时间段 例如:10:00-11:00
|
||||
downloadTime = 10:00
|
||||
|
||||
#安装存在定时timing 手动:manual 关机安装bshutdown
|
||||
installMode = timing
|
||||
|
||||
#安装也为时间段 例如:00:00
|
||||
installTime = 10:00
|
||||
|
||||
#是否开启自动重启 以及自动重启时间可以调节
|
||||
automaticReboot = off
|
||||
|
||||
#自动重启时间的调节 now为立即重启 重启时间调节 例如00:00
|
||||
automaticRebootTime = now
|
|
@ -0,0 +1 @@
|
|||
0
|
|
@ -0,0 +1,657 @@
|
|||
## DBUS接口
|
||||
|
||||
[TOC]
|
||||
|
||||
|
||||
|
||||
### 对应版本信息
|
||||
|
||||
| 软件包 | 目前版本 | 备注 |
|
||||
| :------------------: | :-----------------------------: | :--: |
|
||||
| kylin-system-updater | kylin-system-updater 1.4.16kord | |
|
||||
| aptdaemon | 1.1.1+bzr982-0kylin32.3 | |
|
||||
| | | |
|
||||
|
||||
|
||||
|
||||
### 描述
|
||||
|
||||
实现系统升级以python apt库和aptdeamon的形式
|
||||
|
||||
|
||||
|
||||
### Dbus接口信息
|
||||
|
||||
| 名称 | 含义 |
|
||||
| -------------- | --------------------------------- |
|
||||
| BUS类型 | SYSTEM BUS |
|
||||
| DBUS名称 | com.kylin.systemupgrade |
|
||||
| OBJECT路径 | /com/kylin/systemupgrade |
|
||||
| INTERFACES名称 | com.kylin.systemupgrade.interface |
|
||||
| 属性名称 | org.freedesktop.DBus.Properties |
|
||||
|
||||
|
||||
|
||||
### Apt-p2p配置项设置
|
||||
|
||||
### Dbus接口信息
|
||||
|
||||
| 名称 | 含义 |
|
||||
| -------------- | --------------------------------- |
|
||||
| BUS类型 | SYSTEM BUS |
|
||||
| DBUS名称 | com.kylin.systemupgrade |
|
||||
| OBJECT路径 | /com/kylin/systemupgrade |
|
||||
| INTERFACES名称 | com.kylin.systemupgrade.interface |
|
||||
| 属性名称 | org.freedesktop.DBus.Properties |
|
||||
|
||||
|
||||
|
||||
#### Get
|
||||
|
||||
- `简介:`获取属性的值
|
||||
|
||||
- `入参:` `s`iface:要设置的属性的接口, `s`property:要设置的属性名称
|
||||
|
||||
- `出参:` `Variant`变量
|
||||
|
||||
- `示例:`
|
||||
|
||||
```
|
||||
#获取p2p的配置
|
||||
|
||||
Get(com.kylin.systemupgrade.interface,P2pBootstrap)
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#### Set
|
||||
|
||||
- `简介:`设置属性的值
|
||||
|
||||
- `入参:` `s`iiface:要设置的属性的接口, `s`iproperty:要设置的属性名称 `Variant`value:要设置的值
|
||||
|
||||
- `出参:`
|
||||
|
||||
- `示例:`
|
||||
|
||||
```
|
||||
#设置p2p的配置
|
||||
|
||||
set("com.kylin.systemupgrade.interface","P2pBootstrap",GLib.Variant('s', "test"))
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### 方法列表
|
||||
|
||||
| Method Name | Input Args | Output Args | means | 异步任务 |
|
||||
| ------------------ | ---------- | ----------- | --------------------------------- | ------------------ |
|
||||
| UpdateDetect | 无 | b | 更新cache,产生组升级列表JSON文件 | |
|
||||
| DistUpgradeAll | b | b | 全部升级 | |
|
||||
| DistUpgradePartial | b,as | b | 部分升级 | |
|
||||
| DistUpgradeSystem | b | b | 全盘升级 | |
|
||||
| CancelDownload | 无 | b | 取消升级 | |
|
||||
| InsertInstallState | ss | b | 向display表插入数据 | |
|
||||
| GtDownloadspeedLimitValue | 无 | b | 获取当前限速 | |
|
||||
| SetDownloadspeedMax | sb | b | 设置限速 | |
|
||||
| GetBackendStatus | 无 | i | 控制获取后端状态 | |
|
||||
| UnattendedUpgradeValue | ss | bs | 获取是否允许关机前更新 | |
|
||||
| PurgePackages | as | b | 卸载软件包 | |
|
||||
| InstalldebFile | ssbb | b | 安装本地deb包 | |
|
||||
| DataBackendCollect | ss | b | | |
|
||||
| CheckRebootRequired | s | b | 检查是否需要重启的方法,以及弹窗提示 | |
|
||||
|
||||
|
||||
### Method分析
|
||||
|
||||
#### UpdateDetect
|
||||
|
||||
- `简介:`更新cache对象,完成从之后拿到系统中所有可升级的包再经过源过滤、白名单等等的过滤,最后输出当前`可升级的包以及分组(JSON配置 输出目录: /var/lib/kylin-system-updater)
|
||||
|
||||
- `入参:`无
|
||||
- `出参:`True or False 注意:不通过返回值来判断有没有执行成功 通过下面的信号
|
||||
- `对应信号:`
|
||||
- `UpdateDetectStatusChanged:` 更新的进度信息和状态信息
|
||||
- `UpdateDetectFinished:`更新的完成的信号
|
||||
|
||||
|
||||
|
||||
#### DistUpgradePartial
|
||||
|
||||
- `简介:` 升级部分软件包或者分组
|
||||
|
||||
- `入参:` `b:` False模式:只进行获取升级列表以及计算修复依赖关系,以及计算是否存在删除的包,`True模式:`直接进行安装的操作 注意:必须选使用False模式获取升级列表以及计算依赖关系再进行True模式
|
||||
|
||||
`as:` 输入需要升级或者安装的分组 例如 升级系统组:["kylin-update-desktop-system"]
|
||||
|
||||
- `出参:`True or False 注意:不通过返回值来判断有没有执行成功 通过下面的信号
|
||||
|
||||
- `对应信号:`
|
||||
|
||||
- `UpdateDependResloveStatus:` 升级计算依赖修复反馈信号
|
||||
- `UpdateDloadAndInstStaChanged:`升级安装过程的进度信号以及状态
|
||||
- `UpdateInstallFinished:` 升级安装完成的信号
|
||||
|
||||
|
||||
|
||||
#### DistUpgradeAll
|
||||
|
||||
- `简介:`升级全部可升级的分组
|
||||
|
||||
- `入参:` `b:` False模式:只进行获取升级列表以及计算修复依赖关系,以及计算是否存在删除的包,`True模式:`直接进行安装的操作 注意:必须选使用False模式获取升级列表以及计算依赖关系再进行True模式
|
||||
- `出参:`True or False 注意:不通过返回值来判断有没有执行成功 通过下面的信号
|
||||
- `对应信号:`
|
||||
- `UpdateDependResloveStatus:` 升级计算依赖修复反馈信号
|
||||
- `UpdateDloadAndInstStaChanged:`升级安装过程的进度信号以及状态
|
||||
- `UpdateInstallFinished:` 升级安装完成的信号
|
||||
|
||||
|
||||
|
||||
|
||||
#### UpdateDownloadInfo
|
||||
|
||||
- `介绍:` 发送下载包信息信号
|
||||
|
||||
- `出参`: `i:`当前正在下载的项,`i:`所有下载的项,`i:`当前下载的字节,`i:`总的需要下载的字节,`i:`下载速度
|
||||
|
||||
- `示例:`
|
||||
|
||||
```sh
|
||||
current_items = 1, total_items = 1, currenty_bytes = 45 kB, total_bytes = 45 kB, current_cps = 0 kB/s
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### GetBackendStatus
|
||||
|
||||
- `介绍:` 获取后端的状态,现在正在处理那些任务
|
||||
|
||||
- `入参:` `s:`当前用户的语言变量 例如传入语言环境变量`LANG` 的值`zh_CN.UTF-8` 就会将升级的语言切换为中文 同理其他也能相应设置
|
||||
|
||||
- `出参`: `i:`当前任务ID,整型数字
|
||||
|
||||
- `状态示例列表:`
|
||||
|
||||
```python
|
||||
ACTION_DEFUALT_STATUS = -1 #默认状态空闲状态
|
||||
ACTION_UPDATE = 0 #处于更新cache状态
|
||||
ACTION_INSTALL = 1 #包括部分升级、全部升级、q
|
||||
ACTION_INSTALL_DEB = 2 #处于安装deb的状态
|
||||
ACTION_CHECK_RESOLVER = 3 #处于计算依赖过程
|
||||
ACTION_DOWNLOADONLY = 4 #单独下载软件包过程
|
||||
ACTION_FIX_BROKEN = 5 #修复依赖的过程
|
||||
ACTION_REMOVE_PACKAGES = 6 #卸载包的状态中
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### UnattendedUpgradeValue
|
||||
|
||||
- `介绍:` 设置或获取是否允许关机前更新
|
||||
|
||||
- `入参`: `s:`operation("get"/"set"),`s:`value将要设置的值
|
||||
|
||||
- `示例:`
|
||||
|
||||
```sh
|
||||
operation = "set", value = "false"
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### InstalldebFile
|
||||
|
||||
- `简介:`安装本地deb包
|
||||
|
||||
- `入参:` `source:(string)` 安装来源,`path:(string)`本地deb包绝对路径,`_check_local_dep:(bool)`出现依赖问题时是否查询本路径下是否存在满足的包,`_auto_satisfy:(bool)`出现依赖问题时是否通过网络下载并安装依赖包
|
||||
- `出参:`True or False
|
||||
- `对应信号:`
|
||||
- `InstalldebStatusChanged`:安装过程的进度信号以及状态
|
||||
- `InstalldebFinished`:安装完成的信号
|
||||
- `示例:`
|
||||
|
||||
```sh
|
||||
source = 'kylin-installer', path = '/home/kylin/kylin-video_3.1.0-94.5_amd64.deb', _check_local_dep = 0, _auto_satisfy = 1
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### PurgePackages
|
||||
|
||||
- `简介:`卸载系统中的软件包
|
||||
|
||||
- `入参:` `as:` 需要卸载的包列表 `s:`当前用户的用户名 例如:kylin用户就传入`kylin`字符串
|
||||
|
||||
- `出参:`True or False 出参值不做任何参考意义 `注意:`其中False的时候表示后端正在处理其他任务会报错,其中完成信号也会反馈结果,故不采用方法的返回值来判断错误类型
|
||||
|
||||
- `对应信号:`
|
||||
|
||||
- `PurgePkgStatusChanged:`卸载过程的进度信号以及状态
|
||||
- `PurgePackagesFinished:` 卸载完成的信号
|
||||
|
||||
- `示例:`
|
||||
|
||||
```sh
|
||||
_purge_list = ['kylin-video','tree'] cur_user = 'kylin'
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### DataBackendCollect
|
||||
|
||||
- `介绍:` 后端数据采集
|
||||
|
||||
- `入参`: `messageType: ` 消息埋点(string), `uploadMessage: ` 上传数据(json格式字符串),必须包含的字段: "packageName"
|
||||
|
||||
- `示例:`
|
||||
|
||||
```sh
|
||||
messageType = "UpdateInfos", uploadMessage = "{\"packageName\":\"kylin-system-updater\",\"source\":\"kylin-system-updater\",\"status\":\"True\",\"errorCode\":\"\",\"versionOld\":\"1.2.13.2kord\",\"versionNew\":\"1.2.17.1kord\"}"
|
||||
|
||||
messageType: 消息埋点(string) "UpdateInfos"、"InstallInfos"、"RemoveInfos"...
|
||||
source: 安装来源 "kylin-installer"、"unattented-upgrade"、"kylin-software-center"、"kylin-system-updater"...
|
||||
status: 安装或卸载状态 "True"/"False"
|
||||
errorCode: 错误信息 ""/"..."
|
||||
versionOld: 旧版本号 "1.2.13.2kord"
|
||||
versionNew: 新版本号 "1.2.17.1kord"
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### CheckRebootRequired
|
||||
|
||||
- `介绍:` 检查是否需要重启的方法,以及弹窗提示
|
||||
- `入参`: `s:`标识那个应用调的此接口(如自动更新可填入字符串“autoyupgrade”)
|
||||
- `出参:`True or False 执行的结果
|
||||
|
||||
|
||||
|
||||
#### SetConfigValue
|
||||
|
||||
- `简介:`设置配置文件的值 配置文件的目录`/var/lib/kylin-system-updater/system-updater.conf`
|
||||
|
||||
- `入参:` `section`, `option`,` value` 不管布尔、列表的数据类型都转化成字符串类型来写入
|
||||
|
||||
- 例如传入"InstallModel","shutdown_install","False"
|
||||
|
||||
```
|
||||
[InstallMode]
|
||||
shutdown_install = True
|
||||
manual_install = False
|
||||
auto_install = False
|
||||
pkgs_install =
|
||||
pkgs_upgrade =
|
||||
pkgs_remove =
|
||||
```
|
||||
|
||||
- `出参:`True :设置值成功 False: 设置失败
|
||||
|
||||
#### GetConfigValue
|
||||
|
||||
- `简介:`获取配置文件的值 配置文件的目录`/var/lib/kylin-system-updater/system-updater.conf`
|
||||
|
||||
- `入参:` `section`,` option` 例如传入"InstallModel","shutdown_install"
|
||||
|
||||
- `出参:` `bool:`True :获取值成功 False: 获取失败 `Value:`值都以字符串类型来返回
|
||||
|
||||
```
|
||||
[InstallMode]
|
||||
shutdown_install = True
|
||||
manual_install = False
|
||||
auto_install = False
|
||||
pkgs_install =
|
||||
pkgs_upgrade =
|
||||
pkgs_remove =
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### CheckInstallRequired
|
||||
|
||||
- `简介:`检查当前系统是否需要关机安装或者重启安装
|
||||
- `入参:` 无
|
||||
- `出参:` `int:` 类型返回值 表示当前系统是否需要安装 返回值数值含义如下。简要为0时不需要安装,不为零时需要进行提示安装
|
||||
- `1` 手动更新请求当前系统在关机时进行安装软件包
|
||||
- `2` 自动更新请求当前系统在关机时进行安装软件包
|
||||
- `0` 当前系统不需要进行安装
|
||||
|
||||
|
||||
|
||||
#### FixBrokenDepends
|
||||
|
||||
- `简介:` 修复当前的系统Apt环境,收到`UpdateFixBrokenStatus`后进行调用,类似于调用apt install -f 来进行修复
|
||||
- `入参:` 无
|
||||
- `出参:` True or False 执行的结果 无实际意义
|
||||
- `对应信号:`
|
||||
- `FixBrokenStatusChanged:` 修复依赖的状态信号 可不使用
|
||||
|
||||
|
||||
|
||||
#### MountSquashfsSource
|
||||
|
||||
- `简介:` 挂载离线源squashfs
|
||||
- `入参:` `s:` 挂载文件的位置
|
||||
- `出参:` `b:` True or False 执行的结果,`s:` 字符类型错误信息描述
|
||||
|
||||
|
||||
|
||||
### Signal列表
|
||||
|
||||
| Signal Name | Output Args | means |
|
||||
| ---------------------------- | ----------- | ------------------------ |
|
||||
| UpdateDetectStatusChanged | i,s | 更新进度信息以及状态信息 |
|
||||
| UpdateDetectFinished | b,as,s,s | 更新完成信号 |
|
||||
| UpdateDloadAndInstStaChanged | as,i,s,s | 升级的进度信号以及状态 |
|
||||
| UpdateInstallFinished | b,as,s,s | 升级完成的信号 |
|
||||
| UpdateDownloadInfo | i,i,u,u,i | 发送下载包信息信号 |
|
||||
| UpdateDependResloveStatus | b,b,s | 更新依赖修复信息 |
|
||||
| DistupgradeDependResloveStatus | b,s | 更新全盘修复信息 |
|
||||
| Cancelable | b | 是否可取消 |
|
||||
| UpdateSqlitSingle | | |
|
||||
| FixBrokenStatusChanged | iiisss | 修复依赖的状态信号 |
|
||||
| PurgePackagesFinished | iss | 卸载完成信号 |
|
||||
| PurgePkgStatusChanged | bss | 卸载进度信息以及状态信息 |
|
||||
| RebootLogoutRequired | s | 请求重启或者注销的信号 |
|
||||
| UpdateInstallFinished | b,as,s,s | 下载完成的信号 |
|
||||
|
||||
|
||||
|
||||
### Signal分析
|
||||
|
||||
#### UpdateDetectStatusChanged
|
||||
|
||||
- `介绍:`更新的进度信息和状态信息
|
||||
|
||||
- `出参`:`i:`更新的进度信息从0-100%,`s:`更新的状态信息,
|
||||
|
||||
- `示例:`
|
||||
|
||||
```sh
|
||||
progress = 9 , status = 正在解决依赖关系
|
||||
progress = 92 , status = 正在载入软件列表
|
||||
progress = 92 , status = 完成
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### UpdateDetectFinished
|
||||
|
||||
- `介绍:`更新的完成的信号
|
||||
|
||||
- `出参`: `b:`更新是否成功,`as:`可升级的组列表,`s:`产生错误的结果,`s:`产生错误的原因
|
||||
|
||||
- `示例:`
|
||||
|
||||
```sh
|
||||
success = True , upgrade_group = ['kylin-update-desktop-system', 'tree', 'texinfo', 'kylin-update-manager', 'dnsmasq-base', 'vino', 'dpkg-dev', 'ghostscript', 'atril', 'wpasupplicant', 'eom', 'eom-common', 'fcitx-bin', 'fcitx-data', 'fcitx-frontend-gtk2', 'wps-office'], error_string = , error_desc =
|
||||
|
||||
error_string = 获取更新软件推送失败,请稍后再进行尝试更新 , error_desc = 推送服务器连接异常
|
||||
|
||||
```
|
||||
|
||||
#### UpdateDependResloveStatus
|
||||
|
||||
- `介绍:`升级计算依赖修复反馈信号
|
||||
|
||||
- `出参`: `b:`修复依赖关系是否成功,`b:`是否存在升级需要卸载的包,`as:`卸载的包列表,`as:`卸载的包的描述信息,`as:`卸载此包的原因 升级安装那些包导致的,`s:`产生错误的结果,`s:`产生错误的原因
|
||||
|
||||
- `示例:`
|
||||
|
||||
```sh
|
||||
UpdateDependResloveStatus:resolver_status = True , remove_status = True , remove_pkgs = ['kylin-burner-i18n'],pkg_raw_description = ['Sophisticated CD/DVD burning application - localizations files'] ,delete_desc = ['kylin-burner-i18n 将要被删除,由于升级 kylin-burner'],error_string = , error_desc =
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
#### UpdateFixBrokenStatus
|
||||
|
||||
- `介绍:`更新检查过程中是否需要修复系统Apt的环境,提示是否存在卸载软件包的情况
|
||||
|
||||
- `出参`: `b:`是否能修复系统环境,`b:`是否存在修复需要卸载的包,`as:`卸载的包列表,`as:`卸载的包的描述信息,`as:`卸载此包的原因,`s:`产生错误的结果,`s:`产生错误的原因
|
||||
|
||||
- `示例:`
|
||||
|
||||
```sh
|
||||
UpdateDependResloveStatus:resolver_status = True , remove_status = True , remove_pkgs = ['kylin-burner-i18n'],pkg_raw_description = ['Sophisticated CD/DVD burning application - localizations files'] ,delete_desc = ['kylin-burner-i18n 将要被删除,由于升级 kylin-burner'],error_string = , error_desc =
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
#### UpdateDloadAndInstStaChanged
|
||||
|
||||
- `介绍:` 升级安装过程的进度信号以及状态
|
||||
|
||||
- `出参`: `as:`当前那些组在升级安装 `i:`更新的进度信息从0-100%,`s:`更新的状态信息 `s:`下载的细节信息
|
||||
|
||||
- ` 示例:`
|
||||
|
||||
```sh
|
||||
groups_list = ['kylin-update-desktop-system'] progress = 15 , status = 下载中 current_details = 下载中 tree
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### UpdateInstallFinished
|
||||
|
||||
- `介绍:` 升级安装完成的信号
|
||||
|
||||
- `出参`: `b:`升级是否成功,`as:`可升级的组列表,`s:`产生错误的结果,`s:`产生错误的原因
|
||||
|
||||
- `示例:`
|
||||
|
||||
```sh
|
||||
pdateInstallFinished success = True , upgrade_group = ['tree'], error_string = 系统升级完成。 , error_desc =
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### UpdateDownloadFinished
|
||||
|
||||
- `介绍:` 下载完成的信号
|
||||
|
||||
- `出参`: `b:`下载是否成功,`as:`可升级的组列表,`s:`产生错误的结果,`s:`产生错误的原因
|
||||
|
||||
- `示例:`
|
||||
|
||||
```sh
|
||||
pdateInstallFinished success = True , upgrade_group = ['tree'], error_string = 系统升级完成。 , error_desc =
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### FixBrokenStatusChanged
|
||||
|
||||
- `介绍:` 修复依赖过程中的状态反馈信号
|
||||
|
||||
- `出参`: `i:`修复依赖是否完成 `i:`修复依赖过程是否成功`注意:只有修复完成时,修复依赖是否成功才有意义`,`i:`修复的进度信息 `s:`修复的状态信息 `s:`产生错误的结果,`s:`产生错误的原因
|
||||
|
||||
- ` 示例:`
|
||||
|
||||
```sh
|
||||
emit FixBrokenStatusChanged finished = False , success = True,progress = 66 , status = 正在应用更改,error_string = , error_desc =
|
||||
```
|
||||
|
||||
-
|
||||
|
||||
|
||||
|
||||
#### PurgePkgStatusChanged
|
||||
|
||||
- `介绍:`卸载的进度信息和状态信息以及状态的细节信息
|
||||
|
||||
- `出参`:`i:`卸载的进度信息从0-100%,`s:`卸载的状态信息,`s:`卸载的细节信息
|
||||
|
||||
- `示例:`
|
||||
|
||||
```sh
|
||||
INFO:emit PurgePkgStatusChanged progress = 63 , status = 正在应用更改 ,current_details = 正在准备删除 kylin-video
|
||||
INFO:emit PurgePkgStatusChanged progress = 76 , status = 正在应用更改 ,current_details = 正在卸载 kylin-video
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
#### PurgePackagesFinished
|
||||
|
||||
- `介绍:`卸载的完成的信号
|
||||
|
||||
- `出参`: `b:`卸载是否成功,`s:`产生错误的结果,`s:`产生错误的原因
|
||||
|
||||
- `示例:`
|
||||
|
||||
```sh
|
||||
#卸载完成
|
||||
PurgePackagesFinished success = True , error_string = 卸载完成。 , error_desc =
|
||||
|
||||
#卸载失败
|
||||
PurgePackagesFinished success = False , error_string = 软件包不存在 , error_desc = 检查包名的拼写是否正确,以及是否启用了相应的仓库。
|
||||
PurgePackagesFinished success = False , error_string = 软件包没有安装 , error_desc = 不需要进行卸载。
|
||||
|
||||
#卸载失败 由于正在处理其他任务也同样会报错
|
||||
PurgePackagesFinished success = False , error_string = 其他任务正在更新升级中,请稍后再卸载。 , error_desc =
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### InstalldebStatusChanged
|
||||
|
||||
- `介绍:`安装的进度信息和状态信息以及状态的细节信息
|
||||
|
||||
- `出参`:`i:`安装的进度信息从0-100%,`s:`安装的状态信息,`s:`安装的细节信息
|
||||
|
||||
- `示例:`
|
||||
|
||||
```sh
|
||||
InstalldebStatusChanged progress = 57 , status = 正在应用更改 ,current_details = 正在配置 python3-bandit
|
||||
InstalldebStatusChanged progress = 57 , status = 正在应用更改 ,current_details = python3-bandit 已安装
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
#### InstalldebFinished
|
||||
|
||||
- `介绍:`安装的完成的信号
|
||||
|
||||
- `出参`: `b:`安装是否成功,`s:`产生错误的结果,`s:`产生错误的原因
|
||||
|
||||
- `示例:`
|
||||
|
||||
```sh
|
||||
#安装完成
|
||||
InstalldebFinished success = True , error_string = , error_desc =
|
||||
|
||||
#安装失败 缺少依赖的
|
||||
InstalldebFinished success = False , error_string = bandit dependency is not satisfied , error_desc = python3-bandit
|
||||
|
||||
#安装失败 选择从网络拉依赖 网络断开 报网络错误
|
||||
InstalldebFinished success = False , error_string = 下载软件包文件失败 , error_desc = 检查您的网络连接。
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
#### RebootLogoutRequired
|
||||
|
||||
- `介绍:`请求重启和注销的信号
|
||||
|
||||
- `出参`: `s:` "reboot" 表示重启 "logout"表示注销
|
||||
|
||||
- `示例:`
|
||||
|
||||
```sh
|
||||
Emitting RebootLogoutRequired required_status = reboot
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### InstallDetectStatus
|
||||
|
||||
- `介绍:`下载安装前的状态检查
|
||||
|
||||
- `出参`: `b:`检查出错时为`False`,没有错误`success`,`s:`产生错误的码
|
||||
|
||||
- 错误码示例:
|
||||
|
||||
```python
|
||||
ERROR_NOT_DISK_SPACE = "error-not-disk-space"
|
||||
```
|
||||
|
||||
- `示例:`
|
||||
|
||||
```sh
|
||||
#表示出现磁盘已满的错误z
|
||||
InstallDetectStatus success = False , error_code = "error-not-disk-space"
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
后端日志:`/var/log/kylin-system-updater/kylin-system-updater.log.1`
|
||||
|
||||
### 更新过程报错信息总结
|
||||
|
||||
| 错误信息 | 错误原因 | 解决办法 |
|
||||
| -------------------- | ------------------------------------------------------------ | ---------------------------------------- |
|
||||
| 下载软件仓库信息失败 | 源存在问题,使用apt update检查,若存在报错则更新管理器无问题 | 检查源是否可以使用 |
|
||||
| 无法访问源管理服务器 | 源管理服务器存在问题 | 源管理服务器是否可用或者检查源服务器配置 |
|
||||
| 软件索引已经损坏 | 当前系统中cache被破坏,apt无法使用 | 终端检查错误原因进行解决 |
|
||||
| 无法初始化软件包信息 | apt存在某些问题 | 具体错误原因查看日志相应解决 |
|
||||
| 无法获取组配置软件包 | 源中不存在kylin-update-desktop-config | 将此包放入源仓库或者写配置文件不强制安装 |
|
||||
| 无法读取推送升级列表 | 读取推送列表出现问题 | 检查important.list是否存在 |
|
||||
| 获取软件推送失败 | 老版本文案同 无法访问源管理服务器解决 | |
|
||||
|
||||
|
||||
|
||||
### 安装过程报错信息总结
|
||||
|
||||
| 错误信息 | 错误原因 | 解决办法 |
|
||||
| ------------------ | ------------------------------ | ---------------------------------- |
|
||||
| 软件包操作失败 | 被升级的软件包有问题 | 检查后端log日志查看那个包存在问题 |
|
||||
| 下载软件包文件失败 | 网络原因的或者这个软件包的仓库 | 检查网络以及源仓库 |
|
||||
| 磁盘空间不足 | 磁盘的空间不足 | 查看日志那些目录空间不足 |
|
||||
| 不能计算升级 | 无法计算依赖关系 | 检查日志那个包出现的问题,相应解决 |
|
||||
| | | |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
from SystemUpdater.UpdateManager import UpdateManager
|
||||
from gettext import gettext as _
|
||||
import logging
|
||||
from optparse import OptionParser
|
||||
import dbus
|
||||
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
|
||||
import signal
|
||||
import os
|
||||
import sys
|
||||
import gettext
|
||||
|
||||
from SystemUpdater.Core.LogManager import get_logfile as logfile
|
||||
|
||||
gettext.bindtextdomain('kylin-system-updater', '/usr/share/locale')
|
||||
gettext.textdomain('kylin-system-updater')
|
||||
_ = gettext.gettext
|
||||
|
||||
#定义日志的格式
|
||||
FORMAT = "%(asctime)s [%(levelname)s]: %(message)s"
|
||||
|
||||
FORMAT_DEBUG = '%(asctime)-15s %(levelname)s(%(filename)s:%(lineno)d):%(message)s'
|
||||
|
||||
def signal_handler_term(signal, frame):
|
||||
# type: (int, object) -> None
|
||||
logging.warning("SIGTERM received, will stop")
|
||||
app.dbusController.Quit(None)
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Begin parsing of options
|
||||
parser = OptionParser()
|
||||
parser.add_option ("-d", "--debug", action="store_true", default=False,
|
||||
help=_("Show debug messages"))
|
||||
parser.add_option("-r", "--replace",
|
||||
default=False,
|
||||
action="store_true", dest="replace",
|
||||
help=_("Quit and replace an already running "
|
||||
"daemon"))
|
||||
parser.add_option ("-n","--no-update-source", action="store_true",
|
||||
dest="no_update_source", default=False,
|
||||
help=_("Do not check for updates source when updating"))
|
||||
parser.add_option ("--no-update", action="store_true",
|
||||
dest="no_update", default=False,
|
||||
help="Do not check for updates when starting")
|
||||
parser.add_option("-c", "--close-filter",
|
||||
default=False,
|
||||
action="store_true", dest="close_filter",
|
||||
help=_("Quit and close allowed origin"))
|
||||
parser.add_option("--no-check-network",
|
||||
default=False,
|
||||
action="store_true", dest="no_check_network",
|
||||
help=_("Quit and close check network"))
|
||||
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
if os.getuid() != 0:
|
||||
print(_("You need to be root to run this application"))
|
||||
sys.exit(1)
|
||||
|
||||
# set debconf to NON_INTERACTIVE
|
||||
os.environ["DEBIAN_FRONTEND"] = "noninteractive"
|
||||
os.environ["TERM"] = "xterm"
|
||||
os.environ["PATH"] = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
|
||||
#当不存在语言变量时 默认显示中文
|
||||
if not "LANGUAGE" in os.environ:
|
||||
os.environ["LANGUAGE"] = "zh_CN.UTF-8"
|
||||
|
||||
#当不存在语言变量时 默认显示中文
|
||||
if not "LANG" in os.environ:
|
||||
os.environ["LANG"] = "zh_CN.UTF-8"
|
||||
|
||||
#做一些规范处理
|
||||
if os.environ["LANGUAGE"] == "en":
|
||||
os.environ["LANGUAGE"] = "en_US.UTF-8"
|
||||
if os.environ["LANGUAGE"] == "zh_CN:en" or os.environ["LANGUAGE"] == "zh_CN:zh":
|
||||
os.environ["LANGUAGE"] = "zh_CN.UTF-8"
|
||||
|
||||
# ensure that we are not killed when the terminal goes away e.g. on
|
||||
# shutdown
|
||||
signal.signal(signal.SIGHUP, signal.SIG_IGN)
|
||||
signal.signal(signal.SIGINT,signal_handler_term)
|
||||
|
||||
if options.debug:
|
||||
logging.basicConfig(format=FORMAT,level=logging.INFO,datefmt='%m-%d,%H:%M:%S')
|
||||
else:
|
||||
logging.basicConfig(format=FORMAT,level=logging.DEBUG,datefmt='%m-%d,%H:%M:%S',filename = logfile(),filemode = 'a')
|
||||
|
||||
logging.info('kylin-system-updater(LANGUAGE:%s LANG:%s) starting ...',os.environ["LANGUAGE"],os.environ["LANG"])
|
||||
|
||||
app = UpdateManager(options)
|
||||
|
||||
#当出现安装过程中异常的重启时 开机直接进行修复操作
|
||||
# if app.configs_cover.getWithDefault("ConfigPkgStatus", "check_frontend_pkg", False) == True:
|
||||
# app.configs_cover.setValue("ConfigPkgStatus","check_frontend_pkg",str(False),True)
|
||||
# app.check_frontend_pkg()
|
||||
|
||||
#当出现安装过程中异常的重启时 开机直接进行修复操作
|
||||
if app.configs_uncover.getWithDefault("SystemStatus", "abnormal_reboot", False) == True:
|
||||
app.start_update()
|
||||
|
||||
app.run()
|
|
@ -0,0 +1,81 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
from SystemUpdater.UpgradeStrategies import UpgradeStrategies
|
||||
from gettext import gettext as _
|
||||
import logging
|
||||
from optparse import OptionParser
|
||||
import dbus
|
||||
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
|
||||
import signal
|
||||
import os
|
||||
import sys
|
||||
import gettext
|
||||
|
||||
from SystemUpdater.Core.LogManager import upgrade_strategies_logfile as logfile
|
||||
|
||||
gettext.bindtextdomain('kylin-system-updater', '/usr/share/locale')
|
||||
gettext.textdomain('kylin-system-updater')
|
||||
_ = gettext.gettext
|
||||
|
||||
#定义日志的格式
|
||||
FORMAT = "%(asctime)s [%(levelname)s]: %(message)s"
|
||||
|
||||
FORMAT_DEBUG = '%(asctime)-15s %(levelname)s(%(filename)s:%(lineno)d):%(message)s'
|
||||
|
||||
def signal_handler_term(signal, frame):
|
||||
# type: (int, object) -> None
|
||||
logging.warning("SIGTERM received, will stop")
|
||||
app.dbusController.Quit(None)
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Begin parsing of options
|
||||
parser = OptionParser()
|
||||
parser.add_option ("-d", "--debug", action="store_true", default=False,
|
||||
help=_("Show debug messages"))
|
||||
parser.add_option("-r", "--replace",
|
||||
default=False,
|
||||
action="store_true", dest="replace",
|
||||
help=_("Quit and replace an already running "
|
||||
"daemon"))
|
||||
|
||||
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
if os.getuid() != 0:
|
||||
print(_("You need to be root to run this application"))
|
||||
sys.exit(1)
|
||||
|
||||
# set debconf to NON_INTERACTIVE
|
||||
os.environ["DEBIAN_FRONTEND"] = "noninteractive"
|
||||
os.environ["TERM"] = "xterm"
|
||||
os.environ["PATH"] = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
|
||||
#当不存在语言变量时 默认显示中文
|
||||
if not "LANGUAGE" in os.environ:
|
||||
os.environ["LANGUAGE"] = "zh_CN.UTF-8"
|
||||
|
||||
#当不存在语言变量时 默认显示中文
|
||||
if not "LANG" in os.environ:
|
||||
os.environ["LANG"] = "zh_CN.UTF-8"
|
||||
|
||||
#做一些规范处理
|
||||
if os.environ["LANGUAGE"] == "en":
|
||||
os.environ["LANGUAGE"] = "en_US.UTF-8"
|
||||
if os.environ["LANGUAGE"] == "zh_CN:en" or os.environ["LANGUAGE"] == "zh_CN:zh":
|
||||
os.environ["LANGUAGE"] = "zh_CN.UTF-8"
|
||||
|
||||
# ensure that we are not killed when the terminal goes away e.g. on
|
||||
# shutdown
|
||||
signal.signal(signal.SIGHUP, signal.SIG_IGN)
|
||||
signal.signal(signal.SIGINT,signal_handler_term)
|
||||
|
||||
if options.debug:
|
||||
logging.basicConfig(format=FORMAT,level=logging.INFO,datefmt='%m-%d,%H:%M:%S')
|
||||
else:
|
||||
logging.basicConfig(format=FORMAT,level=logging.DEBUG,datefmt='%m-%d,%H:%M:%S',filename = logfile(),filemode = 'a')
|
||||
|
||||
|
||||
logging.info('Updater Config Manager Daemon(LANGUAGE:%s LANG:%s) starting ...',os.environ["LANGUAGE"],os.environ["LANG"])
|
||||
|
||||
app = UpgradeStrategies(options)
|
||||
app.run()
|
|
@ -0,0 +1,6 @@
|
|||
2021-09-16 XueYi Luo <luoxueyi@kylinos.cn>
|
||||
|
||||
* zh_CN.po: Updated Simplified Chinese translation.
|
||||
* zh_HK.po: Updated translation for HongKong,china.
|
||||
* zh_TW.po: Updated translation for Taiwan,China.
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
|
||||
top_srcdir=`pwd`/..
|
||||
|
||||
DOMAIN=kylin-system-updater
|
||||
PO_FILES := $(wildcard *.po)
|
||||
CONTACT=sebastian.heinlein@web.de
|
||||
XGETTEXT_ARGS = --msgid-bugs-address=$(CONTACT)
|
||||
XGETTEXT_ARGS += --keyword=unicode_gettext:2 --keyword=unicode_ngettext:2,3
|
||||
XGETTEXT_ARGS += --language=python
|
||||
|
||||
all: update-po
|
||||
|
||||
# update the pot
|
||||
$(DOMAIN).pot:
|
||||
XGETTEXT_ARGS="$(XGETTEXT_ARGS)" intltool-update -p -g $(DOMAIN)
|
||||
|
||||
# merge the new stuff into the po files
|
||||
merge-po: $(PO_FILES)
|
||||
XGETTEXT_ARGS="$(XGETTEXT_ARGS)" intltool-update -r -g $(DOMAIN);
|
||||
|
||||
# create mo from the pos
|
||||
%.mo : %.po
|
||||
mkdir -p mo/$(subst .po,,$<)/LC_MESSAGES/
|
||||
msgfmt $< -o mo/$(subst .po,,$<)/LC_MESSAGES/$(DOMAIN).mo
|
||||
|
||||
# dummy target
|
||||
update-po: $(DOMAIN).pot merge-po $(patsubst %.po,%.mo,$(wildcard *.po))
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
[encoding: UTF-8]
|
||||
SystemUpdater/backend/InstallBackendAptdaemon.py
|
||||
SystemUpdater/backend/__init__.py
|
||||
SystemUpdater/UpdateManager.py
|
||||
SystemUpdater/Core/MyCache.py
|
||||
SystemUpdater/Core/UpdateList.py
|
||||
SystemUpdater/Core/OriginFilter.py
|
||||
SystemUpdater/Core/Database.py
|
||||
SystemUpdater/UpdateManagerDbus.py
|
||||
SystemUpdater/Core/utils.py
|
||||
SystemUpdater/Core/enums.py
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,50 @@
|
|||
#!/bin/sh
|
||||
#系统升级收集bug日志使用
|
||||
echo "系统升级收集BUG日志使用..."
|
||||
|
||||
#建立收集的log目录
|
||||
mkdir updaterlog
|
||||
#记录一些基本信息
|
||||
date >> updaterlog/base-info
|
||||
dpkg -l | grep kylin-system-updater >> updaterlog/base-info
|
||||
dpkg -l | grep ukui-control-center >> updaterlog/base-info
|
||||
dpkg -l | grep aptdaemon >> updaterlog/base-info
|
||||
echo $1 >> updaterlog/base-info
|
||||
echo "记录BUG产生时间(系统当前时间)以及升级相关的版本信息:"
|
||||
cat updaterlog/base-info
|
||||
|
||||
cp /etc/apt/sources.list updaterlog || true
|
||||
|
||||
cp -r /usr/share/kylin-update-desktop-config/config/ updaterlog || true
|
||||
#复制后端的日志
|
||||
cp -r /var/log/kylin-system-updater/ updaterlog || true
|
||||
|
||||
#收集apt的日志
|
||||
cp -r /var/log/apt/term.log updaterlog || true
|
||||
|
||||
cp -r /var/log/apt/history.log updaterlog || true
|
||||
|
||||
#收集aptdamon的日志
|
||||
cp -r /var/log/kylin-unattended-upgrades/ updaterlog || true
|
||||
|
||||
outputName="$(date +%m-%d,%H-%M-%S)-updaterLog.tar.gz"
|
||||
|
||||
#将所有的日志进行打包
|
||||
tar -czvf updaterLog.tar.gz updaterlog >/dev/null
|
||||
|
||||
#删除收集的日志目录
|
||||
rm -rf updaterlog
|
||||
|
||||
#将文件存储到桌面
|
||||
if [ ! -d ~/桌面 ]; then
|
||||
mv updaterLog.tar.gz ~/Desktop/$outputName
|
||||
echo 输出位置:~/Desktop/$outputName
|
||||
else
|
||||
mv updaterLog.tar.gz ~/桌面/$outputName
|
||||
echo 输出位置:~/桌面/$outputName
|
||||
fi
|
||||
|
||||
echo "系统更新日志收集完毕..."
|
||||
echo "\033[1;31m注意:\033[0m 1、请确保Bug复现的时间与执行脚本收集日志时间相近,以此能根据脚本执行时间快速定位到问题的相关日志..."
|
||||
echo " 2、若Bug复现的时间与现在时间相差较远时,请手动输入大概复现时间。例如 report-updater-bug 月-日,时-分"
|
||||
echo "请将桌面下\033[5;32;49;1m $outputName \033[0m日志文件提交到禅道... "
|
|
@ -0,0 +1,15 @@
|
|||
[build_i18n]
|
||||
domain=kylin-system-updater
|
||||
|
||||
# xml_files=[("share/metainfo/",
|
||||
# ("data/update-manager.appdata.xml.in",)),
|
||||
# ]
|
||||
|
||||
[sdist]
|
||||
formats = bztar
|
||||
|
||||
[nosetests]
|
||||
match=test
|
||||
|
||||
# [install]
|
||||
# skip-build=0
|
|
@ -0,0 +1,21 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- Mode: Python; indent-tabs-mode: nil; tab-width: 4; coding: utf-8 -*-
|
||||
from distutils.core import setup
|
||||
from DistUtilsExtra.command import (
|
||||
build_extra, build_i18n, build_help)
|
||||
|
||||
disabled = []
|
||||
class CustomBuild(build_extra.build_extra):
|
||||
def run(self):
|
||||
build_extra.build_extra.run(self)
|
||||
|
||||
setup(
|
||||
packages=[ 'SystemUpdater',
|
||||
'SystemUpdater.backend',
|
||||
'SystemUpdater.Core'
|
||||
],
|
||||
cmdclass={ "build": CustomBuild,
|
||||
"build_i18n": build_i18n.build_i18n
|
||||
# "build_help": build_help.build_help
|
||||
}
|
||||
)
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1 @@
|
|||
9
|
|
@ -0,0 +1,52 @@
|
|||
Source: kylin-system-updater
|
||||
Section: misc
|
||||
Priority: optional
|
||||
Maintainer: Kylin Development Team <cp@kylinos.cn>
|
||||
Build-Depends: debhelper (>= 9),
|
||||
python3,
|
||||
python3-setuptools,
|
||||
dh-python,
|
||||
python3-all (>= 3.3.0-2),
|
||||
python3-distutils-extra (>= 2.38),
|
||||
python3-dbus,
|
||||
python3-distro-info,
|
||||
python3-gi (>= 3.8),
|
||||
python3-yaml,
|
||||
lsb-release,
|
||||
apt-clone (>= 0.2.3~ubuntu1)
|
||||
Build-Depends-Indep: intltool,
|
||||
python3-coverage,
|
||||
python3-distro-info,
|
||||
pycodestyle | pep8,
|
||||
pyflakes3,
|
||||
python3-apt (>= 1.9.6~),
|
||||
python3-mock,
|
||||
lsb-release,
|
||||
python3-psutil
|
||||
Standards-Version: 3.8.0
|
||||
Homepage: https://www.kylinos.cn
|
||||
Vcs-Browser: https://www.kylinos.cn
|
||||
X-Python3-Version: >= 3.2
|
||||
|
||||
Package: kylin-system-updater
|
||||
Architecture: all
|
||||
Depends: ${python3:Depends},
|
||||
${misc:Depends},
|
||||
policykit-1,
|
||||
python3-dbus,
|
||||
python3-psutil,
|
||||
python3-gi (>= 3.8),
|
||||
python3-yaml,
|
||||
aptdaemon (>=1.1.1+bzr982-0kylin32.3k5.2),
|
||||
python3-distro-info,
|
||||
python3-apscheduler,
|
||||
python3-pyqt5,
|
||||
python3-crypto,
|
||||
sqlite3,
|
||||
kylin-update-frontend
|
||||
Breaks:
|
||||
Recommends: python3-launchpadlib
|
||||
Suggests: gir1.2-dbusmenu-glib-0.4,
|
||||
gir1.2-unity-5.0,
|
||||
Description: dbus daemon that manages apt updates.
|
||||
dbus daemon that manages apt updates. Provides DBUS interfaces to UKCC.
|
|
@ -0,0 +1,22 @@
|
|||
This package was debianized by Michiel Sikkes <michiel@eyesopened.nl> on
|
||||
Mon, 25 Oct 2004 21:49:07 +0200.
|
||||
|
||||
It was downloaded from http://code.launchpad.net/~ubuntu-core-dev/update-manager/main
|
||||
|
||||
Upstream Authors:
|
||||
Michiel Sikkes <michiel@eyesopened.nl>
|
||||
Michael Vogt <michael.vogt@ubuntu.com>
|
||||
Sebastian Heinlein <glatzor@ubuntu.com>
|
||||
Jonathan Riddell <jriddell@ubuntu.com>
|
||||
|
||||
Copyright:
|
||||
2004-2008 Canonical Ltd.
|
||||
2004-2005 Michiel Sikkes
|
||||
|
||||
All code released under the GPL, see /usr/share/common-licenses/GPL
|
||||
|
||||
|
||||
With the exception of
|
||||
UpdateManager/SimpleGladeApp.py
|
||||
which is released under the LGPL, see /usr/share/common-licenses/LGPL
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
#!/usr/bin/dh-exec
|
||||
#backend
|
||||
backend/data/kylin-system-updater.db /usr/share/kylin-system-updater/
|
||||
backend/report-updater-bug /usr/bin
|
||||
backend/data/30kylin-system-updater /etc/apt/apt.conf.d/
|
||||
backend/data/com.kylin.systemupgrade.conf /etc/dbus-1/system.d/
|
||||
#backend/data/com.kylin.systemupgrade.limit /etc/dbus-1/conf/
|
||||
backend/data/kylin-system-updater.service /usr/lib/systemd/system/
|
||||
backend/data/kylin-logout-required /usr/share/kylin-system-updater/
|
||||
backend/data/kylin-reboot-required /usr/share/kylin-system-updater/
|
||||
backend/kylin-system-updater /usr/share/kylin-system-updater/
|
||||
backend/SystemUpdater/*.py /usr/share/kylin-system-updater/SystemUpdater/
|
||||
backend/SystemUpdater/backend/*.py /usr/share/kylin-system-updater/SystemUpdater/backend/
|
||||
backend/SystemUpdater/Core/*.py /usr/share/kylin-system-updater/SystemUpdater/Core/
|
||||
backend/build/mo/* /usr/share/locale/
|
||||
backend/data/system-updater-defaults.conf /var/lib/kylin-system-updater/
|
||||
backend/data/system-updater-coverable.conf /var/lib/kylin-system-updater/
|
||||
backend/data/unattended-upgrades-policy.conf /var/lib/unattended-upgrades/
|
||||
backend/data/unattended-upgrades-timestamp /var/lib/unattended-upgrades/
|
||||
backend/data/cn.kylinos.KylinSystemUpdater.policy /usr/share/polkit-1/actions/
|
||||
backend/data/kylin-system-version.conf /etc/kylin-version/
|
||||
|
||||
#configDaemon
|
||||
backend/kylin-upgrade-strategies /usr/share/kylin-system-updater/
|
||||
backend/data/com.kylin.UpgradeStrategies.conf /etc/dbus-1/system.d/
|
||||
backend/data/com.kylin.UpgradeStrategies.service /usr/share/dbus-1/system-services/
|
||||
backend/data/cn.kylinos.UpgradeStrategies.policy /usr/share/polkit-1/actions/
|
||||
backend/data/kylin-system-updater /etc/logrotate.d
|
||||
|
||||
#uu
|
||||
unattended-upgrades/*.service /lib/systemd/system/
|
||||
unattended-upgrades/notify /usr/bin/
|
||||
unattended-upgrades/*.desktop /etc/xdg/autostart/
|
||||
unattended-upgrades/kylin-unattended-upgrade /usr/bin
|
||||
unattended-upgrades/kylin-unattended-upgrade-shutdown /usr/bin
|
||||
unattended-upgrades/kylin-unattended-upgrades /etc/apt/apt.conf.d/
|
||||
unattended-upgrades/logrotate.d/* /etc/logrotate.d/
|
|
@ -0,0 +1,24 @@
|
|||
#!/bin/bash
|
||||
if [ ! -d /var/cache/kylin-system-updater ];then
|
||||
mkdir -p /var/cache/kylin-system-updater
|
||||
fi
|
||||
if [ ! -f /var/cache/kylin-system-updater/kylin-system-updater.db ];then
|
||||
echo "Copying database to the specified path ..."
|
||||
cp -r /usr/share/kylin-system-updater/kylin-system-updater.db /var/cache/kylin-system-updater/
|
||||
fi
|
||||
systemctl enable kylin-system-updater.service
|
||||
|
||||
mkdir -p /var/lib/unattended-upgrades
|
||||
chmod +x /usr/bin/kylin-unattended-upgrade
|
||||
chmod +x /usr/bin/kylin-unattended-upgrade-shutdown
|
||||
systemctl enable kylin-unattended-upgrades.service
|
||||
|
||||
if [ -f /usr/share/kylin-system-updater/SystemUpdater/Core/DataMigration.py ];then
|
||||
# echo "Database record migration"
|
||||
# /usr/share/kylin-system-updater/SystemUpdater/Core/DataMigration.py -m
|
||||
/usr/share/kylin-system-updater/SystemUpdater/Core/DataMigration.py -u appname_cn=
|
||||
/usr/share/kylin-system-updater/SystemUpdater/Core/DataMigration.py -t=tid_search
|
||||
/usr/share/kylin-system-updater/SystemUpdater/Core/DataMigration.py -u status_cn=
|
||||
/usr/share/kylin-system-updater/SystemUpdater/Core/DataMigration.py -u changelog=
|
||||
/usr/share/kylin-system-updater/SystemUpdater/Core/DataMigration.py -f init_version="yes"
|
||||
fi
|
|
@ -0,0 +1,7 @@
|
|||
#!/usr/bin/make -f
|
||||
#export PYBUILD_INTERPRETERS=python3
|
||||
|
||||
%:
|
||||
dh $@
|
||||
#override_dh_makeshlibs:
|
||||
#--with=python3 --buildsystem=pybuild
|
|
@ -0,0 +1 @@
|
|||
3.0 (quilt)
|
|
@ -0,0 +1 @@
|
|||
debian/tmp/usr/share/man/man8/kylin-system-updater.8
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,153 @@
|
|||
// Automatically upgrade packages from these (origin:archive) pairs
|
||||
//
|
||||
// Note that in Ubuntu security updates may pull in new dependencies
|
||||
// from non-security sources (e.g. chromium). By allowing the release
|
||||
// pocket these get automatically pulled in.
|
||||
Unattended-Upgrade::Allowed-Origins {
|
||||
"Kylin:10.1";
|
||||
":default";
|
||||
//"${distro_id}:${distro_codename}";
|
||||
//"${distro_id}:${distro_codename}-security";
|
||||
// Extended Security Maintenance; doesn't necessarily exist for
|
||||
// every release and this system may not have it installed, but if
|
||||
// available, the policy for updates is such that unattended-upgrades
|
||||
// should also install from here by default.
|
||||
//"${distro_id}ESMApps:${distro_codename}-apps-security";
|
||||
//"${distro_id}ESM:${distro_codename}-infra-security";
|
||||
// "${distro_id}:${distro_codename}-updates";
|
||||
// "${distro_id}:${distro_codename}-proposed";
|
||||
// "${distro_id}:${distro_codename}-backports";
|
||||
};
|
||||
|
||||
// Python regular expressions, matching packages to exclude from upgrading
|
||||
Unattended-Upgrade::Package-Blacklist {
|
||||
// The following matches all packages starting with linux-
|
||||
// "linux-";
|
||||
|
||||
// Use $ to explicitely define the end of a package name. Without
|
||||
// the $, "libc6" would match all of them.
|
||||
// "libc6$";
|
||||
// "libc6-dev$";
|
||||
// "libc6-i686$";
|
||||
|
||||
// Special characters need escaping
|
||||
// "libstdc\+\+6$";
|
||||
|
||||
// The following matches packages like xen-system-amd64, xen-utils-4.1,
|
||||
// xenstore-utils and libxenstore3.0
|
||||
// "(lib)?xen(store)?";
|
||||
|
||||
// For more information about Python regular expressions, see
|
||||
// https://docs.python.org/3/howto/regex.html
|
||||
};
|
||||
|
||||
// This option controls whether the development release of Ubuntu will be
|
||||
// upgraded automatically. Valid values are "true", "false", and "auto".
|
||||
Unattended-Upgrade::DevRelease "false";
|
||||
|
||||
// This option allows you to control if on a unclean dpkg exit
|
||||
// unattended-upgrades will automatically run
|
||||
// dpkg --force-confold --configure -a
|
||||
// The default is true, to ensure updates keep getting installed
|
||||
//Unattended-Upgrade::AutoFixInterruptedDpkg "true";
|
||||
|
||||
//tell dpkg not to cause conffile prompts
|
||||
DPkg:Options{
|
||||
"--force-confnew";
|
||||
};
|
||||
|
||||
// Split the upgrade into the smallest possible chunks so that
|
||||
// they can be interrupted with SIGTERM. This makes the upgrade
|
||||
// a bit slower but it has the benefit that shutdown while a upgrade
|
||||
// is running is possible (with a small delay)
|
||||
//Unattended-Upgrade::MinimalSteps "false";
|
||||
|
||||
// Install all updates when the machine is shutting down
|
||||
// instead of doing it in the background while the machine is running.
|
||||
// This will (obviously) make shutdown slower.
|
||||
// Unattended-upgrades increases logind's InhibitDelayMaxSec to 30s.
|
||||
// This allows more time for unattended-upgrades to shut down gracefully
|
||||
// or even install a few packages in InstallOnShutdown mode, but is still a
|
||||
// big step back from the 30 minutes allowed for InstallOnShutdown previously.
|
||||
// Users enabling InstallOnShutdown mode are advised to increase
|
||||
// InhibitDelayMaxSec even further, possibly to 30 minutes.
|
||||
//Unattended-Upgrade::InstallOnShutdown "False";
|
||||
|
||||
// Send email to this address for problems or packages upgrades
|
||||
// If empty or unset then no email is sent, make sure that you
|
||||
// have a working mail setup on your system. A package that provides
|
||||
// 'mailx' must be installed. E.g. "user@example.com"
|
||||
//Unattended-Upgrade::Mail "";
|
||||
|
||||
// Set this value to one of:
|
||||
// "always", "only-on-error" or "on-change"
|
||||
// If this is not set, then any legacy MailOnlyOnError (boolean) value
|
||||
// is used to chose between "only-on-error" and "on-change"
|
||||
//Unattended-Upgrade::MailReport "on-change";
|
||||
|
||||
// Remove unused automatically installed kernel-related packages
|
||||
// (kernel images, kernel headers and kernel version locked tools).
|
||||
//Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
|
||||
|
||||
// Do automatic removal of newly unused dependencies after the upgrade
|
||||
//Unattended-Upgrade::Remove-New-Unused-Dependencies "true";
|
||||
|
||||
// Do automatic removal of unused packages after the upgrade
|
||||
// (equivalent to apt-get autoremove)
|
||||
//Unattended-Upgrade::Remove-Unused-Dependencies "false";
|
||||
|
||||
// Automatically reboot *WITHOUT CONFIRMATION* if
|
||||
// the file /var/run/reboot-required is found after the upgrade
|
||||
//Unattended-Upgrade::Automatic-Reboot "false";
|
||||
|
||||
// Automatically reboot even if there are users currently logged in
|
||||
// when Unattended-Upgrade::Automatic-Reboot is set to true
|
||||
//Unattended-Upgrade::Automatic-Reboot-WithUsers "true";
|
||||
|
||||
// If automatic reboot is enabled and needed, reboot at the specific
|
||||
// time instead of immediately
|
||||
// Default: "now"
|
||||
//Unattended-Upgrade::Automatic-Reboot-Time "02:00";
|
||||
|
||||
// Use apt bandwidth limit feature, this example limits the download
|
||||
// speed to 70kb/sec
|
||||
//Acquire::http::Dl-Limit "70";
|
||||
|
||||
//Retry times after each download failure
|
||||
Unattended-Upgrade::RetryTimes 3;
|
||||
|
||||
// Enable logging to syslog. Default is False
|
||||
//Unattended-Upgrade::SyslogEnable "True";
|
||||
|
||||
// Specify syslog facility. Default is daemon
|
||||
// Unattended-Upgrade::SyslogFacility "daemon";
|
||||
|
||||
// Download and install upgrades only on AC power
|
||||
// (i.e. skip or gracefully stop updates on battery)
|
||||
Unattended-Upgrade::OnlyOnACPower "True";
|
||||
|
||||
// Download and install upgrades only on non-metered connection
|
||||
// (i.e. skip or gracefully stop updates on a metered connection)
|
||||
// Unattended-Upgrade::Skip-Updates-On-Metered-Connections "true";
|
||||
|
||||
// Verbose logging
|
||||
//Unattended-Upgrade::Verbose "True";
|
||||
|
||||
// Print debugging information both in unattended-upgrades and
|
||||
// in unattended-upgrade-shutdown
|
||||
Unattended-Upgrade::Debug "True";
|
||||
|
||||
// Allow package downgrade if Pin-Priority exceeds 1000
|
||||
// Unattended-Upgrade::Allow-downgrade "false";
|
||||
|
||||
// When APT fails to mark a package to be upgraded or installed try adjusting
|
||||
// candidates of related packages to help APT's resolver in finding a solution
|
||||
// where the package can be upgraded or installed.
|
||||
// This is a workaround until APT's resolver is fixed to always find a
|
||||
// solution if it exists. (See Debian bug #711128.)
|
||||
// The fallback is enabled by default, except on Debian's sid release because
|
||||
// uninstallable packages are frequent there.
|
||||
// Disabling the fallback speeds up unattended-upgrades when there are
|
||||
// uninstallable packages at the expense of rarely keeping back packages which
|
||||
// could be upgraded or installed.
|
||||
// Unattended-Upgrade::Allow-APT-Mark-Fallback "true";
|
|
@ -0,0 +1,14 @@
|
|||
[Unit]
|
||||
Description=Unattended Upgrades Shutdown
|
||||
After=network.target local-fs.target systemd-logind.service kylin-system-updater.service
|
||||
RequiresMountsFor=/run /var/log /var/run /var/lib /boot
|
||||
Documentation=man:unattended-upgrade(8)
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/bin/kylin-unattended-upgrade-shutdown --wait-for-signal
|
||||
Type=idle
|
||||
#KillMode=process
|
||||
#TimeoutStopSec=1800
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
|
@ -0,0 +1,10 @@
|
|||
/var/log/unattended-upgrades/unattended-upgrades.log
|
||||
/var/log/unattended-upgrades/unattended-upgrades-dpkg.log
|
||||
/var/log/unattended-upgrades/unattended-upgrades-shutdown.log
|
||||
{
|
||||
rotate 6
|
||||
monthly
|
||||
compress
|
||||
missingok
|
||||
notifempty
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
#!/usr/bin/python3
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import dbus
|
||||
import re
|
||||
import atexit
|
||||
import logging
|
||||
import signal
|
||||
|
||||
NOTIFICATION_PIPE = '/tmp/notification.pipe'
|
||||
PID_FILE = '/tmp/notify.pid'
|
||||
|
||||
def signal_handler_term():
|
||||
logging.warning("SIGTERM received, will stop")
|
||||
sys.exit(1)
|
||||
|
||||
def signal_handler_int():
|
||||
logging.warning("SIGINT received, will stop")
|
||||
sys.exit(1)
|
||||
|
||||
def translate(text):
|
||||
env = os.environ['LANG']
|
||||
if re.match('zh_CN',env):
|
||||
if text == 'install start':
|
||||
return '安装开始'
|
||||
elif text == 'install finish':
|
||||
return '安装结束'
|
||||
else:
|
||||
return text
|
||||
|
||||
def notify(iface,msg):
|
||||
msg = msg.rstrip()
|
||||
title = ' '
|
||||
content = ' '
|
||||
if msg =='install start':
|
||||
title = translate('install start')
|
||||
content = translate('install start')
|
||||
elif msg == 'install finish':
|
||||
title = translate('install finish')
|
||||
content = translate('install start')
|
||||
#print(title,content)
|
||||
iface.Notify(' ',1,' ',title,content,[],{},3)
|
||||
|
||||
def main():
|
||||
bus = dbus.SessionBus()
|
||||
proxy_object = bus.get_object('org.freedesktop.Notifications','/org/freedesktop/Notifications')
|
||||
iface = dbus.Interface(proxy_object,dbus_interface='org.freedesktop.Notifications')
|
||||
f=open(NOTIFICATION_PIPE,'r')
|
||||
while True:
|
||||
msg = f.read()
|
||||
if len(msg)>0:
|
||||
bus = dbus.SessionBus()
|
||||
proxy_object = bus.get_object('org.freedesktop.Notifications','/org/freedesktop/Notifications')
|
||||
iface = dbus.Interface(proxy_object,dbus_interface='org.freedesktop.Notifications')
|
||||
notify(iface,msg)
|
||||
f.flush()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
signal.signal(signal.SIGTERM, signal_handler_term)
|
||||
signal.signal(signal.SIGINT,signal_handler_int)
|
||||
if os.path.exists(PID_FILE):
|
||||
logging.info("notify already exists, exiting...")
|
||||
sys.exit(0)
|
||||
else:
|
||||
# clean up pid file on exit
|
||||
with open(PID_FILE, "w+") as fp:
|
||||
fp.write("%s" % os.getpid())
|
||||
atexit.register(os.remove, PID_FILE)
|
||||
|
||||
main()
|
|
@ -0,0 +1,7 @@
|
|||
[Desktop Entry]
|
||||
Name=update-notify
|
||||
Exec=/usr/bin/notify
|
||||
Type=Application
|
||||
NoDisplay=true
|
||||
Comment=update-notify
|
||||
|
Loading…
Reference in New Issue