{"id":16101452,"url":"https://github.com/mendhak/grub-reboot-picker","last_synced_at":"2025-10-15T10:27:10.603Z","repository":{"id":41957926,"uuid":"265699406","full_name":"mendhak/grub-reboot-picker","owner":"mendhak","description":"Helps with dual booting. Ubuntu tray application to reboot into different OSes or UEFI/BIOS","archived":false,"fork":false,"pushed_at":"2025-10-04T08:47:04.000Z","size":655,"stargazers_count":61,"open_issues_count":4,"forks_count":7,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-10-04T10:11:25.198Z","etag":null,"topics":["appindicator","dual-boot","grub-reboot","grub2","gtk3","tray-application","ubuntu","ubuntu2004"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mendhak.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2020-05-20T22:29:57.000Z","updated_at":"2025-09-23T08:48:43.000Z","dependencies_parsed_at":"2024-08-08T08:28:19.574Z","dependency_job_id":"1698f3bf-4425-4b17-a8d0-4a7d25fa28f0","html_url":"https://github.com/mendhak/grub-reboot-picker","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/mendhak/grub-reboot-picker","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mendhak%2Fgrub-reboot-picker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mendhak%2Fgrub-reboot-picker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mendhak%2Fgrub-reboot-picker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mendhak%2Fgrub-reboot-picker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mendhak","download_url":"https://codeload.github.com/mendhak/grub-reboot-picker/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mendhak%2Fgrub-reboot-picker/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279073177,"owners_count":26097341,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-15T02:00:07.814Z","response_time":56,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["appindicator","dual-boot","grub-reboot","grub2","gtk3","tray-application","ubuntu","ubuntu2004"],"created_at":"2024-10-09T18:49:58.502Z","updated_at":"2025-10-15T10:27:10.598Z","avatar_url":"https://github.com/mendhak.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Grub Reboot Picker  [![CI](https://github.com/mendhak/grub-reboot-picker/workflows/CI/badge.svg)](https://github.com/mendhak/grub-reboot-picker/actions)\n\nThis utility is an app indicator (tray icon) to help you reboot into other OSes, or UEFI/BIOS, or the same OS.  \nInstead of picking the OS you want during reboot at the grub menu, you can just preselect it from the menu here.  \nBasically it's a wrapper around `grub-reboot`. \n\n![screenshot](assets/screenshot.png) \n\n## Install it\n\nYou can apt install it [from the PPA](https://launchpad.net/~mendhak/+archive/ubuntu/ppa).\n\n```\nsudo add-apt-repository ppa:mendhak/ppa\nsudo apt update\nsudo apt install grub-reboot-picker\n```\n\nYou can also download the .deb file from the Releases page and install it.\n\n```\nsudo apt install ./grub-reboot-picker_0.0.10+noble_all.deb \n```\n\n\n## Run it\n\nThe application will auto start the next time you log in to Ubuntu.  \nYou can also launch it directly by searching for `Grub Reboot Picker` in Activities\n\n\n## Use it\n\nClick on the application icon. \u003cimg src=\"./assets/grub-reboot-picker.svg\" width=\"20\" height=\"20\" /\u003e  \nA menu with grub entries will appear.  \nClick one of the entries.  \nAfter a moment, Ubuntu will reboot.  \nThe grub menu item you chose should be preselected. \n\n\n## TODO\n\nConfiguration file or Configuration screen: \n* Top level or double level menu items\n* Nicknames for menu items  \n\nStartupNotify = true might be causing 'wait' cursor to appear\n\nRun a single instance of the application\n\n\n\n## Running it locally from this repo\n\n\nYou can run this application directly from this git repo.  \n\nFirst get the dependencies\n\n```\nsudo apt install python3-gi python3-gi-cairo gir1.2-gtk-3.0 gir1.2-appindicator3-0.1\n```\n\nClone this repo, then run the python script. \n\n```\ncd grub-reboot-picker\nsudo ./grub-reboot-picker.py\n```\n\nYou'll get prompted because the script wants to run `grub-mkconfig` which generates the grub config output. \nAlternatively run the script with sudo so that you don't get prompted.  \n\n### Running it with molly-guard\n\nmolly-guard is a package that prompts you before reboot/shutdown, preventing accidental reboots. \nThis script will run the .no-molly-guard version of reboot/shutdown to bypass molly-guard.  \n\nTo test it locally, need to install molly-guard then add two environment variables to /etc/environment. \n\n```\nsudo apt install molly-guard\necho \"ALWAYS_QUERY_HOSTNAME=1\" | sudo tee -a /etc/environment\necho \"PRETEND_SSH=1\" | sudo tee -a /etc/environment\n```\n\nThen run the script as before\n\n```\ncd grub-reboot-picker\nsudo ./grub-reboot-picker.py\n```\n\n\n## Building a distributable\n\nThis project uses pybuild to create a .deb file. The pyproject.toml file holds the information needed to do the build, and there are additional configuration files in debian folder such as control, links, install, changelog. All of these get used by pybuild to create the .deb.  \n\nThe `debian` directory contains the files needed to build the .deb, but the .deb appears in the parent directory for some reason. It's messy which is why I prefer the Docker way. \n\n\n### Build using Docker\n\n```\n# Set the version and suite (noble, jammy, etc)\nnano version.sh\n# Update the changelog, carefully\nnano CHANGELOG.md\n\n# Read the version\nsource version.sh\n\n# Build the image which will build the deb\ndocker build --build-arg version=$version --build-arg suite=$suite --progress=plain -t docker-deb-builder .\n# Alternately: docker buildx bake deb-builder\n\n# Now grab the deb and dsc files\nmkdir -p output\ncd output\ndocker create --name docker-deb-builder docker-deb-builder\ndocker cp docker-deb-builder:/build/grub-reboot-picker_${version}.dsc ./\ndocker cp docker-deb-builder:/build/grub-reboot-picker_${version}.tar.xz ./\ndocker cp docker-deb-builder:/build/grub-reboot-picker_${version}_all.deb ./\ndocker rm docker-deb-builder\nls -lah \n```\n\n### Build on a local machine\n\nFirst, some build dependencies:\n\n```\nsudo apt install dpkg-dev fakeroot debhelper python3-all dh-python lintian devscripts python3-hatchling pybuild-plugin-pyproject build-essential\n```\n\nThen to build:\n\n```\n# Set the version and suite (noble, jammy, etc)\nnano version.sh\n# Update the changelog, carefully\nnano CHANGELOG.md\n# Read the version\nsource version.sh\n# Clean everything\ngit clean -fdx\n\n# Generate and test changelog\npython3 other/generate_changelog.py\ndpkg-parsechangelog -l debian/changelog\n\n# Build the package\ndpkg-buildpackage -uc -us\n\n# Grab the deb and dsc files\nmkdir -p output; mv ../grub-reboot-picker_${version}* output/\n\n```\n\n## Inspecting the deb\n\nEither way, once the .deb is built, it's good to inspect it.  \n\n```\ncd output\n\n# Run a lint against this deb, check for errors\nlintian grub-reboot-picker_${version}_all.deb\n\n# Look at information about this deb\ndpkg -I grub-reboot-picker_${version}_all.deb\n\n# List all the files in the deb\ndpkg -c grub-reboot-picker_${version}_all.deb\n\n# Extract contents to a dir\ndpkg-deb -R grub-reboot-picker_${version}_all.deb extracted/\n\n# View changelog\nzless extracted/usr/share/doc/grub-reboot-picker/changelog.gz\nrm -rf extracted/\n\n# View its dependencies\ndpkg-deb -f grub-reboot-picker_${version}_all.deb Depends\n```\n\n\n## Uploading to Launchpad\n\n\nAfter building, to upload to launchpad, I have to extract the sources, then GPG sign, then use dput to push up.  \nThen wait for launchpad to build the code, which can take up to an hour. \n\n```\ncd output\n# Extract the source into a subdirectory\ndpkg-source -x grub-reboot-picker_${version}.dsc\ncd grub-reboot-picker-${version}/\n# Build a debian package and GPG sign it - it uses the key id from the changelog\ndebuild -S -sa\n# Also possible to specify the key id: debuild -S -sa -k6989CF77490369CFFDCBCD8995E7D75C76CBE9A9\n# Upload to launchpad\ndput ppa:mendhak/ppa ../grub-reboot-picker_${version}_source.changes\n```\n\n\n## Application structure\n\nThere's a lot happening in a .deb file.  For my own benefit, here are the files it creates, and their purpose. \n\n![diagram](assets/diagram.drawio.svg)\n\n### .desktop file\n\nThe `com.mendhak.grubrebootpicker.desktop` file goes in two places. \n\n`/etc/xdg/autostart/` -  ensures that the app is launched when the user logs in  \n`/usr/share/applications/` - ensures that the app can be found when searching through Activities. \n\n### .policy file\n\nThe `com.mendhak.grubrebootpicker.policy` is a [polkit policy file](https://wiki.archlinux.org/index.php/Polkit) goes in `/usr/share/polkit-1/actions/`.  \nThis in turn allows the application to run `pkexec reboot` without a password prompt.  \n\n### The script\n\nAs part of the build the `.py` extension is removed.  During install, the executable, extensionless Python script is put in `/usr/sbin` so that it's on the user's $PATH.  \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmendhak%2Fgrub-reboot-picker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmendhak%2Fgrub-reboot-picker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmendhak%2Fgrub-reboot-picker/lists"}