From: Michael Tremer Date: Sat, 11 Feb 2012 12:01:56 +0000 (+0100) Subject: Add experimental support for package signatures. X-Git-Tag: 0.9.22~60^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=68c0e769cbb267f5c449334f151f089b5f1459d7;p=pakfire.git Add experimental support for package signatures. --- diff --git a/po/pakfire.pot b/po/pakfire.pot index 58419eb63..5bac065ff 100644 --- a/po/pakfire.pot +++ b/po/pakfire.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-01-26 22:46+0100\n" +"POT-Creation-Date: 2012-02-11 12:47+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -74,520 +74,629 @@ msgstr "" msgid "Downgrading" msgstr "" -#: ../python/pakfire/base.py:211 ../python/pakfire/base.py:241 -#: ../python/pakfire/base.py:287 ../python/pakfire/base.py:338 -#: ../python/pakfire/base.py:404 ../python/pakfire/base.py:441 -#: ../python/pakfire/base.py:494 ../python/pakfire/base.py:514 +#: ../python/pakfire/base.py:214 ../python/pakfire/base.py:244 +#: ../python/pakfire/base.py:290 ../python/pakfire/base.py:341 +#: ../python/pakfire/base.py:407 ../python/pakfire/base.py:444 +#: ../python/pakfire/base.py:497 ../python/pakfire/base.py:517 msgid "Nothing to do" msgstr "" -#: ../python/pakfire/base.py:273 +#: ../python/pakfire/base.py:276 msgid "There are no packages to install." msgstr "" -#: ../python/pakfire/base.py:328 +#: ../python/pakfire/base.py:331 #, python-format msgid "Could not find any installed package providing \"%s\"." msgstr "" -#: ../python/pakfire/base.py:334 +#: ../python/pakfire/base.py:337 #, python-format msgid "Multiple reinstall candidates for \"%s\": %s" msgstr "" -#: ../python/pakfire/base.py:363 +#: ../python/pakfire/base.py:366 #, python-format msgid "Could not find package %s in a remote repository." msgstr "" -#: ../python/pakfire/base.py:432 +#: ../python/pakfire/base.py:435 #, python-format msgid "Excluding %s." msgstr "" -#: ../python/pakfire/base.py:482 +#: ../python/pakfire/base.py:485 #, python-format msgid "\"%s\" package does not seem to be installed." msgstr "" -#: ../python/pakfire/base.py:626 +#: ../python/pakfire/base.py:629 msgid "Build command has failed." msgstr "" -#: ../python/pakfire/base.py:706 +#: ../python/pakfire/base.py:713 msgid "Everything is fine." msgstr "" +#: ../python/pakfire/builder.py:128 +#, python-format +msgid "Cannot build for %s on this host." +msgstr "" + #. Log the package information. -#: ../python/pakfire/builder.py:155 +#: ../python/pakfire/builder.py:159 msgid "Package information:" msgstr "" #. Install all packages. -#: ../python/pakfire/builder.py:326 +#: ../python/pakfire/builder.py:330 msgid "Install packages needed for build..." msgstr "" -#: ../python/pakfire/builder.py:331 +#: ../python/pakfire/builder.py:335 msgid "Extracting" msgstr "" -#: ../python/pakfire/builder.py:600 +#: ../python/pakfire/builder.py:604 msgid "You cannot run a build when no package was given." msgstr "" -#: ../python/pakfire/builder.py:605 +#: ../python/pakfire/builder.py:609 #, python-format msgid "Could not find makefile in build root: %s" msgstr "" -#: ../python/pakfire/builder.py:619 +#: ../python/pakfire/builder.py:623 msgid "The build command failed. See logfile for details." msgstr "" #. Walk through the whole tree and collect all files #. that are on the same disk (not crossing mountpoints). -#: ../python/pakfire/builder.py:677 +#: ../python/pakfire/builder.py:681 msgid "Creating filelist..." msgstr "" #. Create a nice progressbar. -#: ../python/pakfire/builder.py:696 +#: ../python/pakfire/builder.py:700 msgid "Compressing files..." msgstr "" -#: ../python/pakfire/builder.py:715 +#: ../python/pakfire/builder.py:719 #, python-format msgid "Cache file was successfully created at %s." msgstr "" -#: ../python/pakfire/builder.py:716 +#: ../python/pakfire/builder.py:720 #, python-format msgid " Containing %(files)s files, it has a size of %(size)s." msgstr "" #. Make a nice progress bar as always. -#: ../python/pakfire/builder.py:727 +#: ../python/pakfire/builder.py:731 msgid "Extracting files..." msgstr "" #. Update all packages. -#: ../python/pakfire/builder.py:747 +#: ../python/pakfire/builder.py:751 msgid "Updating packages from cache..." msgstr "" #. Package the result. #. Make all these little package from the build environment. -#: ../python/pakfire/builder.py:875 +#: ../python/pakfire/builder.py:879 msgid "Creating packages:" msgstr "" #. Execute the buildscript of this stage. -#: ../python/pakfire/builder.py:895 +#: ../python/pakfire/builder.py:899 #, python-format msgid "Running stage %s:" msgstr "" -#: ../python/pakfire/builder.py:913 +#: ../python/pakfire/builder.py:917 #, python-format msgid "Could not remove static libraries: %s" msgstr "" -#: ../python/pakfire/builder.py:919 +#: ../python/pakfire/builder.py:923 msgid "Compressing man pages did not complete successfully." msgstr "" -#: ../python/pakfire/builder.py:939 +#: ../python/pakfire/builder.py:943 msgid "Extracting debuginfo did not complete with success. Aborting build." msgstr "" -#: ../python/pakfire/cli.py:47 +#: ../python/pakfire/cli.py:48 msgid "Pakfire command line interface." msgstr "" -#: ../python/pakfire/cli.py:54 +#: ../python/pakfire/cli.py:55 msgid "The path where pakfire should operate in." msgstr "" -#: ../python/pakfire/cli.py:121 +#: ../python/pakfire/cli.py:122 msgid "Enable verbose output." msgstr "" -#: ../python/pakfire/cli.py:124 +#: ../python/pakfire/cli.py:125 msgid "Path to a configuration file to load." msgstr "" -#: ../python/pakfire/cli.py:128 +#: ../python/pakfire/cli.py:129 msgid "Disable a repository temporarily." msgstr "" -#: ../python/pakfire/cli.py:131 +#: ../python/pakfire/cli.py:132 msgid "Enable a repository temporarily." msgstr "" -#: ../python/pakfire/cli.py:135 +#: ../python/pakfire/cli.py:136 msgid "Run pakfire in offline mode." msgstr "" -#: ../python/pakfire/cli.py:140 +#: ../python/pakfire/cli.py:141 msgid "Install one or more packages to the system." msgstr "" -#: ../python/pakfire/cli.py:142 +#: ../python/pakfire/cli.py:143 msgid "Give name of at least one package to install." msgstr "" -#: ../python/pakfire/cli.py:148 +#: ../python/pakfire/cli.py:149 msgid "Install one or more packages from the filesystem." msgstr "" -#: ../python/pakfire/cli.py:150 +#: ../python/pakfire/cli.py:151 msgid "Give filename of at least one package." msgstr "" -#: ../python/pakfire/cli.py:156 +#: ../python/pakfire/cli.py:157 msgid "Reinstall one or more packages." msgstr "" -#: ../python/pakfire/cli.py:158 +#: ../python/pakfire/cli.py:159 msgid "Give name of at least one package to reinstall." msgstr "" -#: ../python/pakfire/cli.py:164 +#: ../python/pakfire/cli.py:165 msgid "Remove one or more packages from the system." msgstr "" -#: ../python/pakfire/cli.py:166 +#: ../python/pakfire/cli.py:167 msgid "Give name of at least one package to remove." msgstr "" -#: ../python/pakfire/cli.py:172 +#: ../python/pakfire/cli.py:173 msgid "Give a name of a package to update or leave emtpy for all." msgstr "" -#: ../python/pakfire/cli.py:174 +#: ../python/pakfire/cli.py:175 msgid "Exclude package from update." msgstr "" -#: ../python/pakfire/cli.py:176 ../python/pakfire/cli.py:201 +#: ../python/pakfire/cli.py:177 ../python/pakfire/cli.py:202 msgid "Allow changing the vendor of packages." msgstr "" -#: ../python/pakfire/cli.py:178 ../python/pakfire/cli.py:203 +#: ../python/pakfire/cli.py:179 ../python/pakfire/cli.py:204 msgid "Allow changing the architecture of packages." msgstr "" -#: ../python/pakfire/cli.py:183 +#: ../python/pakfire/cli.py:184 msgid "Update the whole system or one specific package." msgstr "" -#: ../python/pakfire/cli.py:190 +#: ../python/pakfire/cli.py:191 msgid "Check, if there are any updates available." msgstr "" -#: ../python/pakfire/cli.py:197 +#: ../python/pakfire/cli.py:198 msgid "Downgrade one or more packages." msgstr "" -#: ../python/pakfire/cli.py:199 +#: ../python/pakfire/cli.py:200 msgid "Give a name of a package to downgrade." msgstr "" -#: ../python/pakfire/cli.py:209 +#: ../python/pakfire/cli.py:210 msgid "Print some information about the given package(s)." msgstr "" -#: ../python/pakfire/cli.py:211 +#: ../python/pakfire/cli.py:212 msgid "Give at least the name of one package." msgstr "" -#: ../python/pakfire/cli.py:217 +#: ../python/pakfire/cli.py:218 msgid "Search for a given pattern." msgstr "" -#: ../python/pakfire/cli.py:219 +#: ../python/pakfire/cli.py:220 msgid "A pattern to search for." msgstr "" -#: ../python/pakfire/cli.py:225 +#: ../python/pakfire/cli.py:226 msgid "Get a list of packages that provide a given file or feature." msgstr "" -#: ../python/pakfire/cli.py:227 +#: ../python/pakfire/cli.py:228 msgid "File or feature to search for." msgstr "" -#: ../python/pakfire/cli.py:233 +#: ../python/pakfire/cli.py:234 msgid "Get list of packages that belong to the given group." msgstr "" -#: ../python/pakfire/cli.py:235 +#: ../python/pakfire/cli.py:236 msgid "Group name to search for." msgstr "" -#: ../python/pakfire/cli.py:241 +#: ../python/pakfire/cli.py:242 msgid "Install all packages that belong to the given group." msgstr "" -#: ../python/pakfire/cli.py:243 +#: ../python/pakfire/cli.py:244 msgid "Group name." msgstr "" -#: ../python/pakfire/cli.py:249 +#: ../python/pakfire/cli.py:250 msgid "List all currently enabled repositories." msgstr "" -#: ../python/pakfire/cli.py:253 +#: ../python/pakfire/cli.py:254 msgid "Cleanup commands." msgstr "" -#: ../python/pakfire/cli.py:261 +#: ../python/pakfire/cli.py:262 msgid "Cleanup all temporary files." msgstr "" -#: ../python/pakfire/cli.py:267 +#: ../python/pakfire/cli.py:268 msgid "Check the system for any errors." msgstr "" -#: ../python/pakfire/cli.py:273 +#: ../python/pakfire/cli.py:274 msgid "Check the dependencies for a particular package." msgstr "" -#: ../python/pakfire/cli.py:275 +#: ../python/pakfire/cli.py:276 msgid "Give name of at least one package to check." msgstr "" -#: ../python/pakfire/cli.py:351 ../python/pakfire/transaction.py:352 +#: ../python/pakfire/cli.py:352 ../python/pakfire/transaction.py:352 msgid "Repository" msgstr "" -#: ../python/pakfire/cli.py:351 +#: ../python/pakfire/cli.py:352 msgid "Enabled" msgstr "" -#: ../python/pakfire/cli.py:351 +#: ../python/pakfire/cli.py:352 msgid "Priority" msgstr "" -#: ../python/pakfire/cli.py:351 +#: ../python/pakfire/cli.py:352 msgid "Packages" msgstr "" -#: ../python/pakfire/cli.py:363 +#: ../python/pakfire/cli.py:364 msgid "Cleaning up everything..." msgstr "" -#: ../python/pakfire/cli.py:379 +#: ../python/pakfire/cli.py:380 msgid "You cannot run pakfire-builder in a pakfire chroot." msgstr "" -#: ../python/pakfire/cli.py:382 ../python/pakfire/cli.py:719 +#: ../python/pakfire/cli.py:383 ../python/pakfire/cli.py:726 msgid "Pakfire builder command line interface." msgstr "" -#: ../python/pakfire/cli.py:440 +#: ../python/pakfire/cli.py:441 msgid "Update the package indexes." msgstr "" -#: ../python/pakfire/cli.py:446 ../python/pakfire/cli.py:739 +#: ../python/pakfire/cli.py:447 ../python/pakfire/cli.py:746 msgid "Build one or more packages." msgstr "" -#: ../python/pakfire/cli.py:448 ../python/pakfire/cli.py:633 -#: ../python/pakfire/cli.py:741 +#: ../python/pakfire/cli.py:449 ../python/pakfire/cli.py:635 +#: ../python/pakfire/cli.py:748 msgid "Give name of at least one package to build." msgstr "" -#: ../python/pakfire/cli.py:452 ../python/pakfire/cli.py:745 -#: ../python/pakfire/cli.py:815 +#: ../python/pakfire/cli.py:453 ../python/pakfire/cli.py:752 +#: ../python/pakfire/cli.py:822 msgid "Build the package for the given architecture." msgstr "" -#: ../python/pakfire/cli.py:454 ../python/pakfire/cli.py:482 -#: ../python/pakfire/cli.py:747 +#: ../python/pakfire/cli.py:455 ../python/pakfire/cli.py:483 +#: ../python/pakfire/cli.py:754 msgid "Path were the output files should be copied to." msgstr "" -#: ../python/pakfire/cli.py:456 ../python/pakfire/cli.py:471 -#: ../python/pakfire/cli.py:749 +#: ../python/pakfire/cli.py:457 ../python/pakfire/cli.py:472 +#: ../python/pakfire/cli.py:756 msgid "Mode to run in. Is either 'release' or 'development' (default)." msgstr "" -#: ../python/pakfire/cli.py:458 +#: ../python/pakfire/cli.py:459 msgid "Run a shell after a successful build." msgstr "" -#: ../python/pakfire/cli.py:463 +#: ../python/pakfire/cli.py:464 msgid "Go into a shell." msgstr "" -#: ../python/pakfire/cli.py:465 +#: ../python/pakfire/cli.py:466 msgid "Give name of a package." msgstr "" -#: ../python/pakfire/cli.py:469 +#: ../python/pakfire/cli.py:470 msgid "Emulated architecture in the shell." msgstr "" -#: ../python/pakfire/cli.py:476 +#: ../python/pakfire/cli.py:477 msgid "Generate a source package." msgstr "" -#: ../python/pakfire/cli.py:478 +#: ../python/pakfire/cli.py:479 msgid "Give name(s) of a package(s)." msgstr "" -#: ../python/pakfire/cli.py:487 +#: ../python/pakfire/cli.py:489 msgid "Create a build environment cache." msgstr "" -#: ../python/pakfire/cli.py:497 +#: ../python/pakfire/cli.py:499 msgid "Create a new build environment cache." msgstr "" -#: ../python/pakfire/cli.py:502 +#: ../python/pakfire/cli.py:504 msgid "Remove all cached build environments." msgstr "" -#: ../python/pakfire/cli.py:580 +#: ../python/pakfire/cli.py:582 #, python-format msgid "Removing environment cache file: %s..." msgstr "" -#: ../python/pakfire/cli.py:586 +#: ../python/pakfire/cli.py:588 #, python-format msgid "Could not remove file: %s" msgstr "" -#: ../python/pakfire/cli.py:592 +#: ../python/pakfire/cli.py:594 msgid "Pakfire server command line interface." msgstr "" -#: ../python/pakfire/cli.py:631 +#: ../python/pakfire/cli.py:633 msgid "Send a scrach build job to the server." msgstr "" -#: ../python/pakfire/cli.py:635 +#: ../python/pakfire/cli.py:637 msgid "Limit build to only these architecture(s)." msgstr "" -#: ../python/pakfire/cli.py:641 +#: ../python/pakfire/cli.py:643 msgid "Send a keepalive to the server." msgstr "" -#: ../python/pakfire/cli.py:648 +#: ../python/pakfire/cli.py:650 msgid "Update all repositories." msgstr "" -#: ../python/pakfire/cli.py:654 +#: ../python/pakfire/cli.py:656 msgid "Repository management commands." msgstr "" -#: ../python/pakfire/cli.py:662 +#: ../python/pakfire/cli.py:664 msgid "Create a new repository index." msgstr "" -#: ../python/pakfire/cli.py:663 +#: ../python/pakfire/cli.py:666 msgid "Path to the packages." msgstr "" -#: ../python/pakfire/cli.py:664 +#: ../python/pakfire/cli.py:668 msgid "Path to input packages." msgstr "" -#: ../python/pakfire/cli.py:669 +#: ../python/pakfire/cli.py:670 +msgid "Key to sign the repository with." +msgstr "" + +#: ../python/pakfire/cli.py:675 msgid "Dump some information about this machine." msgstr "" -#: ../python/pakfire/cli.py:751 +#: ../python/pakfire/cli.py:758 msgid "Do not verify build dependencies." msgstr "" -#: ../python/pakfire/cli.py:775 +#: ../python/pakfire/cli.py:782 msgid "Pakfire client command line interface." msgstr "" -#: ../python/pakfire/cli.py:809 +#: ../python/pakfire/cli.py:816 msgid "Build a package remotely." msgstr "" -#: ../python/pakfire/cli.py:811 +#: ../python/pakfire/cli.py:818 msgid "Give name of a package to build." msgstr "" -#: ../python/pakfire/cli.py:820 +#: ../python/pakfire/cli.py:827 msgid "Print some information about this host." msgstr "" -#: ../python/pakfire/cli.py:826 +#: ../python/pakfire/cli.py:833 msgid "Check the connection to the hub." msgstr "" -#: ../python/pakfire/cli.py:853 ../python/pakfire/server.py:302 +#: ../python/pakfire/cli.py:860 ../python/pakfire/server.py:302 msgid "Hostname" msgstr "" -#: ../python/pakfire/cli.py:854 +#: ../python/pakfire/cli.py:861 msgid "Pakfire hub" msgstr "" -#: ../python/pakfire/cli.py:857 +#: ../python/pakfire/cli.py:864 msgid "Username" msgstr "" #. Hardware information -#: ../python/pakfire/cli.py:861 ../python/pakfire/server.py:306 +#: ../python/pakfire/cli.py:868 ../python/pakfire/server.py:306 msgid "Hardware information" msgstr "" -#: ../python/pakfire/cli.py:862 ../python/pakfire/server.py:307 +#: ../python/pakfire/cli.py:869 ../python/pakfire/server.py:307 msgid "CPU model" msgstr "" -#: ../python/pakfire/cli.py:863 ../python/pakfire/server.py:308 +#: ../python/pakfire/cli.py:870 ../python/pakfire/server.py:308 msgid "Memory" msgstr "" -#: ../python/pakfire/cli.py:865 ../python/pakfire/server.py:310 +#: ../python/pakfire/cli.py:872 ../python/pakfire/server.py:310 msgid "Native arch" msgstr "" -#: ../python/pakfire/cli.py:867 ../python/pakfire/server.py:312 +#: ../python/pakfire/cli.py:874 +msgid "Default arch" +msgstr "" + +#: ../python/pakfire/cli.py:876 ../python/pakfire/server.py:312 msgid "Supported arches" msgstr "" -#: ../python/pakfire/cli.py:880 +#: ../python/pakfire/cli.py:889 msgid "Your IP address" msgstr "" -#: ../python/pakfire/cli.py:885 +#: ../python/pakfire/cli.py:894 msgid "You are authenticated to the build service:" msgstr "" -#: ../python/pakfire/cli.py:891 +#: ../python/pakfire/cli.py:900 msgid "User name" msgstr "" -#: ../python/pakfire/cli.py:892 +#: ../python/pakfire/cli.py:901 msgid "Real name" msgstr "" -#: ../python/pakfire/cli.py:893 +#: ../python/pakfire/cli.py:902 msgid "Email address" msgstr "" -#: ../python/pakfire/cli.py:894 +#: ../python/pakfire/cli.py:903 msgid "Registered" msgstr "" -#: ../python/pakfire/cli.py:901 +#: ../python/pakfire/cli.py:910 msgid "You could not be authenticated to the build service." msgstr "" -#: ../python/pakfire/cli.py:910 +#: ../python/pakfire/cli.py:919 msgid "Pakfire daemon command line interface." msgstr "" +#: ../python/pakfire/cli.py:952 +msgid "Pakfire key command line interface." +msgstr "" + +#: ../python/pakfire/cli.py:996 +msgid "Initialize the local keyring." +msgstr "" + +#: ../python/pakfire/cli.py:1002 ../python/pakfire/cli.py:1012 +msgid "Import a key from file." +msgstr "" + +#: ../python/pakfire/cli.py:1004 +msgid "The real name of the owner of this key." +msgstr "" + +#: ../python/pakfire/cli.py:1006 +msgid "The email address of the owner of this key." +msgstr "" + +#: ../python/pakfire/cli.py:1014 +msgid "Filename of that key to import." +msgstr "" + +#: ../python/pakfire/cli.py:1020 +msgid "Export a key to a file." +msgstr "" + +#: ../python/pakfire/cli.py:1022 +msgid "The ID of the key to export." +msgstr "" + +#: ../python/pakfire/cli.py:1024 +msgid "Write the key to this file." +msgstr "" + +#: ../python/pakfire/cli.py:1030 +msgid "List all imported keys." +msgstr "" + +#: ../python/pakfire/cli.py:1036 +msgid "Sign one or more packages." +msgstr "" + +#: ../python/pakfire/cli.py:1038 +msgid "Key that is used sign the package(s)." +msgstr "" + +#: ../python/pakfire/cli.py:1040 +msgid "Package(s) to sign." +msgstr "" + +#: ../python/pakfire/cli.py:1046 +msgid "Verify one or more packages." +msgstr "" + +#: ../python/pakfire/cli.py:1050 +msgid "Package(s) to verify." +msgstr "" + +#: ../python/pakfire/cli.py:1061 +msgid "Generating the key may take a moment..." +msgstr "" + +#: ../python/pakfire/cli.py:1108 +#, python-format +msgid "Signing %s..." +msgstr "" + +#: ../python/pakfire/cli.py:1125 +#, python-format +msgid "Verifying %s..." +msgstr "" + +#: ../python/pakfire/cli.py:1135 +msgid "This signature is valid." +msgstr "" + +#: ../python/pakfire/cli.py:1138 +msgid "Unknown key" +msgstr "" + +#: ../python/pakfire/cli.py:1139 +msgid "Could not check if this signature is valid." +msgstr "" + +#: ../python/pakfire/cli.py:1142 ../python/pakfire/keyring.py:94 +#, python-format +msgid "Created: %s" +msgstr "" + +#: ../python/pakfire/cli.py:1146 ../python/pakfire/keyring.py:97 +#, python-format +msgid "Expires: %s" +msgstr "" + #: ../python/pakfire/client/transport.py:55 #, python-format msgid "Socket error: %s" @@ -662,6 +771,37 @@ msgstr "" msgid "%(commas)s and %(last)s" msgstr "" +#: ../python/pakfire/keyring.py:67 +msgid "Initializing local keyring..." +msgstr "" + +#: ../python/pakfire/keyring.py:82 +#, python-format +msgid "Fingerprint: %s" +msgstr "" + +#: ../python/pakfire/keyring.py:86 +#, python-format +msgid "Subkey: %s" +msgstr "" + +#: ../python/pakfire/keyring.py:88 +msgid "This key has expired!" +msgstr "" + +#: ../python/pakfire/keyring.py:91 +msgid "This is a secret key." +msgstr "" + +#: ../python/pakfire/keyring.py:99 +msgid "This key does not expire." +msgstr "" + +#: ../python/pakfire/keyring.py:146 +#, python-format +msgid "Successfully import key %s." +msgstr "" + #: ../python/pakfire/packages/base.py:99 msgid "Name" msgstr "" @@ -801,15 +941,15 @@ msgstr "" msgid "Searching for automatic dependencies for %s..." msgstr "" -#: ../python/pakfire/packages/make.py:463 +#: ../python/pakfire/packages/make.py:464 #, python-format msgid "Regular experession is invalid and has been skipped: %s" msgstr "" #. Let the user know what has been done. -#: ../python/pakfire/packages/make.py:479 +#: ../python/pakfire/packages/make.py:480 #, python-format -msgid "Filter %s filtered %s." +msgid "Filter '%s' filtered %s." msgstr "" #. Load progressbar. @@ -836,31 +976,36 @@ msgstr "" msgid "Migrating database from format %s to %s." msgstr "" -#: ../python/pakfire/repository/index.py:237 +#: ../python/pakfire/repository/index.py:234 #, python-format msgid "" "I cannot be forced to re-download the metadata for the repository '%s' when " "running in offline mode." msgstr "" -#: ../python/pakfire/repository/index.py:287 +#: ../python/pakfire/repository/index.py:284 #, python-format msgid "%s: package database" msgstr "" #. Create progress bar. -#: ../python/pakfire/repository/index.py:395 +#: ../python/pakfire/repository/index.py:392 #, python-format msgid "Loading from %s" msgstr "" #. Add all packages from the database to the index. -#: ../python/pakfire/repository/index.py:458 +#: ../python/pakfire/repository/index.py:455 msgid "Loading installed packages" msgstr "" +#. Create progressbar. +#: ../python/pakfire/repository/local.py:104 +msgid "Signing packages..." +msgstr "" + #. Make a nice progress bar. -#: ../python/pakfire/repository/local.py:149 +#: ../python/pakfire/repository/local.py:163 msgid "Compressing database..." msgstr "" @@ -899,7 +1044,7 @@ msgstr "" msgid " Solutions:" msgstr "" -#: ../python/pakfire/server.py:278 ../python/pakfire/system.py:114 +#: ../python/pakfire/server.py:278 ../python/pakfire/system.py:125 msgid "Could not be determined" msgstr "" @@ -997,16 +1142,16 @@ msgstr "" msgid "%s [y/N]" msgstr "" -#: ../python/pakfire/util.py:254 +#: ../python/pakfire/util.py:260 msgid "Killing orphans..." msgstr "" -#: ../python/pakfire/util.py:261 +#: ../python/pakfire/util.py:267 #, python-format msgid "Process ID %s is still running in chroot. Killing..." msgstr "" -#: ../python/pakfire/util.py:273 +#: ../python/pakfire/util.py:279 msgid "Waiting for processes to terminate..." msgstr "" @@ -1195,14 +1340,14 @@ msgstr "" msgid "The error that lead to this:" msgstr "" -#: ../tools/pakfire-multicall.py:69 +#: ../tools/pakfire-multicall.py:70 msgid "An error has occured when running Pakfire." msgstr "" -#: ../tools/pakfire-multicall.py:72 +#: ../tools/pakfire-multicall.py:73 msgid "Error message:" msgstr "" -#: ../tools/pakfire-multicall.py:76 +#: ../tools/pakfire-multicall.py:77 msgid "Further description:" msgstr "" diff --git a/python/pakfire/api.py b/python/pakfire/api.py index c8bff043f..87886ca2e 100644 --- a/python/pakfire/api.py +++ b/python/pakfire/api.py @@ -113,10 +113,10 @@ def requires(patterns, **pakfire_args): return pakfire.requires(requires) -def repo_create(path, input_paths, type="binary", **pakfire_args): +def repo_create(path, input_paths, key_id=None, type="binary", **pakfire_args): pakfire = Pakfire(**pakfire_args) - return pakfire.repo_create(path, input_paths, type=type) + return pakfire.repo_create(path, input_paths, key_id=key_id, type=type) def repo_list(**pakfire_args): pakfire = Pakfire(**pakfire_args) @@ -136,3 +136,31 @@ def check(**pakfire_args): # Cache functions def cache_create(**pakfire_args): return Pakfire.cache_create(**pakfire_args) + + +# Key functions. + +def key_init(**pakfire_args): + pakfire = Pakfire(**pakfire_args) + + return pakfire.keyring.init() + +def key_generate(realname, email, **pakfire_args): + pakfire = Pakfire(**pakfire_args) + + return pakfire.keyring.gen_key(realname, email) + +def key_import(keyfile, **pakfire_args): + pakfire = Pakfire(**pakfire_args) + + return pakfire.keyring.import_key(keyfile) + +def key_export(keyid, keyfile, **pakfire_args): + pakfire = Pakfire(**pakfire_args) + + return pakfire.keyring.export_key(keyid, keyfile) + +def key_list(**pakfire_args): + pakfire = Pakfire(**pakfire_args) + + return pakfire.keyring.list_keys() diff --git a/python/pakfire/base.py b/python/pakfire/base.py index 47d3c1c1e..951041746 100644 --- a/python/pakfire/base.py +++ b/python/pakfire/base.py @@ -28,6 +28,7 @@ import builder import config import distro import filelist +import keyring import logger import packages import repository @@ -85,6 +86,9 @@ class Pakfire(object): logger.setup_logging(self.config) self.config.dump() + # Initialize the keyring. + self.keyring = keyring.Keyring(self) + # Get more information about the distribution we are running # or building self.distro = distro.Distribution(self, distro_config) @@ -181,9 +185,8 @@ class Pakfire(object): raise BuildError, arch + @staticmethod def check_is_ipfire(self): - return # XXX disabled for now - ret = os.path.exists("/etc/ipfire-release") if not ret: @@ -657,7 +660,7 @@ class Pakfire(object): return sorted(pkgs) - def repo_create(self, path, input_paths, type="binary"): + def repo_create(self, path, input_paths, key_id=None, type="binary"): assert type in ("binary", "source",) repo = repository.RepositoryDir( @@ -671,6 +674,10 @@ class Pakfire(object): for input_path in input_paths: repo.collect_packages(input_path) + # Sign the repository with the given key. + if key_id: + repo.sign(key_id) + repo.save() return repo diff --git a/python/pakfire/cli.py b/python/pakfire/cli.py index 6d19e97fc..f611c9f61 100644 --- a/python/pakfire/cli.py +++ b/python/pakfire/cli.py @@ -20,6 +20,7 @@ ############################################################################### import argparse +import datetime import os import sys @@ -481,6 +482,7 @@ class CliBuilder(Cli): sub_dist.add_argument("--resultdir", nargs="?", help=_("Path were the output files should be copied to.")) + def parse_command_cache(self): # Implement the "cache" command. sub_cache = self.sub_commands.add_parser("cache", @@ -660,8 +662,12 @@ class CliServer(Cli): def parse_command_repo_create(self, sub_commands): sub_create = sub_commands.add_parser("create", help=_("Create a new repository index.")) - sub_create.add_argument("path", nargs=1, help=_("Path to the packages.")) - sub_create.add_argument("inputs", nargs="+", help=_("Path to input packages.")) + sub_create.add_argument("path", nargs=1, + help=_("Path to the packages.")) + sub_create.add_argument("inputs", nargs="+", + help=_("Path to input packages.")) + sub_create.add_argument("--key", "-k", nargs="?", + help=_("Key to sign the repository with.")) sub_create.add_argument("action", action="store_const", const="repo_create") def parse_command_info(self): @@ -705,7 +711,8 @@ class CliServer(Cli): def handle_repo_create(self): path = self.args.path[0] - pakfire.repo_create(path, self.args.inputs, **self.pakfire_args) + pakfire.repo_create(path, self.args.inputs, key_id=self.args.key, + **self.pakfire_args) def handle_info(self): info = self.server.info() @@ -937,3 +944,205 @@ class CliDaemon(Cli): # We cannot just kill the daemon, it needs a smooth shutdown. except (SystemExit, KeyboardInterrupt): d.shutdown() + + +class CliKey(Cli): + def __init__(self): + self.parser = argparse.ArgumentParser( + description = _("Pakfire key command line interface."), + ) + + self.parse_common_arguments(repo_manage_switches=False, + offline_switch=True) + + # Add sub-commands. + self.sub_commands = self.parser.add_subparsers() + + self.parse_command_init() + self.parse_command_generate() + self.parse_command_import() + self.parse_command_export() + self.parse_command_list() + self.parse_command_sign() + self.parse_command_verify() + + # Finally parse all arguments from the command line and save them. + self.args = self.parser.parse_args() + + # Create a pakfire instance. + self.pakfire = pakfire.Pakfire(**self.pakfire_args) + + self.action2func = { + "init" : self.handle_init, + "generate" : self.handle_generate, + "import" : self.handle_import, + "export" : self.handle_export, + "list" : self.handle_list, + "sign" : self.handle_sign, + "verify" : self.handle_verify, + } + + @property + def pakfire_args(self): + ret = { + "mode" : "server", + } + + return ret + + def parse_command_init(self): + # Parse "init" command. + sub_init = self.sub_commands.add_parser("init", + help=_("Initialize the local keyring.")) + sub_init.add_argument("action", action="store_const", const="init") + + def parse_command_generate(self): + # Parse "generate" command. + sub_gen = self.sub_commands.add_parser("generate", + help=_("Import a key from file.")) + sub_gen.add_argument("--realname", nargs=1, + help=_("The real name of the owner of this key.")) + sub_gen.add_argument("--email", nargs=1, + help=_("The email address of the owner of this key.")) + sub_gen.add_argument("action", action="store_const", const="generate") + + def parse_command_import(self): + # Parse "import" command. + sub_import = self.sub_commands.add_parser("import", + help=_("Import a key from file.")) + sub_import.add_argument("filename", nargs=1, + help=_("Filename of that key to import.")) + sub_import.add_argument("action", action="store_const", const="import") + + def parse_command_export(self): + # Parse "export" command. + sub_export = self.sub_commands.add_parser("export", + help=_("Export a key to a file.")) + sub_export.add_argument("keyid", nargs=1, + help=_("The ID of the key to export.")) + sub_export.add_argument("filename", nargs=1, + help=_("Write the key to this file.")) + sub_export.add_argument("action", action="store_const", const="export") + + def parse_command_list(self): + # Parse "list" command. + sub_list = self.sub_commands.add_parser("list", + help=_("List all imported keys.")) + sub_list.add_argument("action", action="store_const", const="list") + + def parse_command_sign(self): + # Implement the "sign" command. + sub_sign = self.sub_commands.add_parser("sign", + help=_("Sign one or more packages.")) + sub_sign.add_argument("--key", "-k", nargs=1, + help=_("Key that is used sign the package(s).")) + sub_sign.add_argument("package", nargs="+", + help=_("Package(s) to sign.")) + sub_sign.add_argument("action", action="store_const", const="sign") + + def parse_command_verify(self): + # Implement the "verify" command. + sub_verify = self.sub_commands.add_parser("verify", + help=_("Verify one or more packages.")) + #sub_verify.add_argument("--key", "-k", nargs=1, + # help=_("Key that is used verify the package(s).")) + sub_verify.add_argument("package", nargs="+", + help=_("Package(s) to verify.")) + sub_verify.add_argument("action", action="store_const", const="verify") + + def handle_init(self): + # Initialize the keyring... + pakfire.key_init(**self.pakfire_args) + + def handle_generate(self): + realname = self.args.realname[0] + email = self.args.email[0] + + print _("Generating the key may take a moment...") + print + + # Generate the key. + fpr = pakfire.key_generate(realname, email, **self.pakfire_args) + + # Dump all information about the new key. + for line in self.dump_key(fpr): + print line + + def handle_import(self): + filename = self.args.filename[0] + + # Simply import the file. + pakfire.key_import(filename, **self.pakfire_args) + + def handle_export(self): + keyid = self.args.keyid[0] + filename = self.args.filename[0] + + pakfire.key_export(keyid, filename, **self.pakfire_args) + + def handle_list(self): + lines = pakfire.key_list(**self.pakfire_args) + + for line in lines: + print line + + def handle_sign(self): + # Get the files from the command line options + files = [] + + for file in self.args.package: + # Check, if we got a regular file + if os.path.exists(file): + file = os.path.abspath(file) + files.append(file) + + else: + raise FileNotFoundError, file + + key = self.args.key[0] + + for file in files: + # Open the package. + pkg = packages.open(self.pakfire, None, file) + + print _("Signing %s...") % pkg.friendly_name + pkg.sign(key) + + def handle_verify(self): + # Get the files from the command line options + files = [] + + for file in self.args.package: + # Check, if we got a regular file + if os.path.exists(file) and not os.path.isdir(file): + file = os.path.abspath(file) + files.append(file) + + for file in files: + # Open the package. + pkg = packages.open(self.pakfire, None, file) + + print _("Verifying %s...") % pkg.friendly_name + sigs = pkg.verify() + + for sig in sigs: + key = self.pakfire.keyring.get_key(sig.fpr) + if key: + subkey = key.subkeys[0] + + print " %s %s" % (subkey.fpr[-16:], key.uids[0].uid) + if sig.validity: + print " %s" % _("This signature is valid.") + + else: + print " %s <%s>" % (sig.fpr, _("Unknown key")) + print " %s" % _("Could not check if this signature is valid.") + + created = datetime.datetime.fromtimestamp(sig.timestamp) + print " %s" % _("Created: %s") % created + + if sig.exp_timestamp: + expires = datetime.datetime.fromtimestamp(sig.exp_timestamp) + print " %s" % _("Expires: %s") % expires + + print # Empty line diff --git a/python/pakfire/constants.py b/python/pakfire/constants.py index 082eb27e4..4c380fefc 100644 --- a/python/pakfire/constants.py +++ b/python/pakfire/constants.py @@ -34,6 +34,8 @@ CONFIG_DIR = os.path.join(SYSCONFDIR, "pakfire.repos.d") CONFIG_DIR_EXT = ".repo" CONFIG_FILE = os.path.join(SYSCONFDIR, "pakfire.conf") +KEYRING_DIR = os.path.join(SYSCONFDIR, "pakfire.d", "gnupg") + CACHE_DIR = "/var/cache/pakfire" CCACHE_CACHE_DIR = os.path.join(CACHE_DIR, "ccache") CACHE_ENVIRON_DIR = os.path.join(CACHE_DIR, "environments") diff --git a/python/pakfire/keyring.py b/python/pakfire/keyring.py new file mode 100644 index 000000000..492591d60 --- /dev/null +++ b/python/pakfire/keyring.py @@ -0,0 +1,195 @@ +#!/usr/bin/python +############################################################################### +# # +# Pakfire - The IPFire package management system # +# Copyright (C) 2012 Pakfire development team # +# # +# 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 3 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, see . # +# # +############################################################################### + +import datetime +import gpgme +import io +import os + +import logging +log = logging.getLogger("pakfire") + +from constants import * +from i18n import _ +from system import system + +class Keyring(object): + def __init__(self, pakfire): + self.pakfire = pakfire + + # Configure the environment. + os.environ["GNUPGHOME"] = self.path + self.create_path() + + def __del__(self): + del os.environ["GNUPGHOME"] + + @property + def path(self): + return KEYRING_DIR + + def create_path(self): + filename = os.path.join(self.path, "gnupg.conf") + + if os.path.exists(filename): + return + + if not os.path.exists(self.path): + os.makedirs(self.path) + # XXX chmod 700 + + # Create a default gnupg.conf. + f = open(filename, "w") + f.write("# This is a default gnupg configuration file create by\n") + f.write("# Pakfire %s.\n" % PAKFIRE_VERSION) + f.close() + # XXX chmod 600 + + def init(self): + log.info(_("Initializing local keyring...")) + + hostname, domainname = system.hostname.split(".", 1) + + self.gen_key(system.hostname, "%s@%s" % (hostname, domainname)) + + def dump_key(self, keyfp): + ret = [] + + ctx = gpgme.Context() + key = ctx.get_key(keyfp) + + for uid in key.uids: + ret.append(uid.uid) + + ret.append(" " + _("Fingerprint: %s") % keyfp) + ret.append("") + + for subkey in key.subkeys: + ret.append(" " + _("Subkey: %s") % subkey.keyid) + if subkey.expired: + ret.append(" %s" % _("This key has expired!")) + + if subkey.secret: + ret.append(" %s" % _("This is a secret key.")) + + created = datetime.datetime.fromtimestamp(subkey.timestamp) + ret.append(" %s" % _("Created: %s") % created) + if subkey.expires: + expires = datetime.datetime.fromtimestamp(subkey.expires) + ret.append(" %s" % _("Expires: %s") % expires) + else: + ret.append(" %s" % _("This key does not expire.")) + + if subkey.pubkey_algo == gpgme.PK_RSA: + ret.append(" RSA/%s" % subkey.length) + + ret.append("") + + return ret + + def get_key(self, keyid): + ctx = gpgme.Context() + + try: + return ctx.get_key(keyid) + except gpgme.GpgmeError: + return None + + def gen_key(self, realname, email): + params = """ + + Key-Type: RSA + Key-Usage: sign + Key-Length: 2048 + Name-Real: %s + Name-Email: %s + Expire-Date: 0 + + """ % (realname, email) + + # Create a new context. + ctx = gpgme.Context() + + # Generate the key. + result = ctx.genkey(params) + + # Return the fingerprint of the generated key. + return result.fpr + + def import_key(self, keyfile): + ret = [] + + ctx = gpgme.Context() + + f = open(keyfile, "rb") + res = ctx.import_(f) + f.close() + + log.info(_("Successfully import key %s.") % keyfile) + + def export_key(self, keyid, keyfile): + ctx = gpgme.Context() + ctx.armor = True + + keydata = io.BytesIO() + ctx.export(keyid, keydata) + + f = open(keyfile, "wb") + f.write(keydata.getvalue()) + f.close() + + def list_keys(self): + ret = [] + + ctx = gpgme.Context() + + keys = [k.subkeys[0].keyid for k in ctx.keylist(None, True)] + + for key in keys: + ret += self.dump_key(key) + + return ret + + def sign(self, keyid, cleartext): + ctx = gpgme.Context() + ctx.armor = True + + key = ctx.get_key(keyid) + ctx.signers = [key,] + + cleartext = io.BytesIO(cleartext) + signature = io.BytesIO() + + ctx.sign(cleartext, signature, gpgme.SIG_MODE_DETACH) + + return signature.getvalue() + + def verify(self, signature, cleartext): + # Create context. + ctx = gpgme.Context() + + signature = io.BytesIO(signature) + cleartext = io.BytesIO(cleartext) + + # Verify the data. + sigs = ctx.verify(signature, cleartext, None) + + return sigs diff --git a/python/pakfire/packages/__init__.py b/python/pakfire/packages/__init__.py index dc5fdaded..c1c8cb022 100644 --- a/python/pakfire/packages/__init__.py +++ b/python/pakfire/packages/__init__.py @@ -21,7 +21,7 @@ import tarfile -from file import BinaryPackage, InnerTarFile, SourcePackage +from file import BinaryPackage, FilePackage, InnerTarFile, SourcePackage from installed import DatabasePackage, InstalledPackage from solv import SolvPackage diff --git a/python/pakfire/packages/file.py b/python/pakfire/packages/file.py index e1f7238ed..12e144236 100644 --- a/python/pakfire/packages/file.py +++ b/python/pakfire/packages/file.py @@ -194,8 +194,8 @@ class FilePackage(Package): # A file package is always local. return True - def open_archive(self): - return tarfile.open(self.filename, format=tarfile.PAX_FORMAT) + def open_archive(self, mode="r"): + return tarfile.open(self.filename, mode=mode, format=tarfile.PAX_FORMAT) def extract(self, message=None, prefix=None): log.debug("Extracting package %s" % self.friendly_name) @@ -521,28 +521,187 @@ class FilePackage(Package): return self.__payload_compression or "none" + ### SIGNATURE STUFF + @property - def signature(self): - # XXX needs to be replaced + def signatures(self): """ - Read the signature from the archive or return None if no - signature does exist. + Read the signatures from the archive. """ - ret = None - try: - a = self.open_archive() - f = a.extractfile("signature") + ret = {} + + # Open the archive for reading. + a = self.open_archive() + + for member in a.getmembers(): + # Skip all files that are not a signature. + if not member.name.startswith("signatures/"): + continue + + # Get the ID of the key. + key_id = os.path.basename(member.name) + + # Get the content of the signature file. + f = a.extractfile(member.name) + ret[key_id] = f.read() + f.close() + + # Close the archive. + a.close() + + return ret + + def has_signature(self, key_id): + """ + Check if the file a signature of the given key. + """ + return self.signatures.has_key(key_id) + + def __has_hardlinks(self): + """ + Returns True when a file has a hardlink. + """ + res = os.stat(self.filename) + + return res.st_nlink > 1 + + def __remove_hardlinks(self): + """ + Remove all hardlinks from this file that we can alter it in place. + """ + if not self.__has_hardlinks(): + return + + # Open a file descriptor to the old file and remove the link from + # the filesystem. + f = open(self.filename, "rb") + os.unlink(self.filename) + + # Create a new file with the exact same name for copying the data + # to. + g = open(self.filename, "wb") + + # Copy the data. + while True: + buf = f.read(BUFFER_SIZE) + if not buf: + break + + g.write(buf) + + # Close all files. + f.close() + g.close() + + # Make sure the whole process above worked fine. + assert self.__has_hardlinks() is False + + def sign(self, key_id): + """ + Sign the package with the given key. + """ + # First check if the package has already been signed with this key. + # If true, we do not have anything to do here. + if self.has_signature(key_id): + return + + # Remove all hardlinks. + self.__remove_hardlinks() + + # XXX verify the content of the file here. + + # Open the archive and read the checksum file. + a = self.open_archive() + + f = a.extractfile("chksums") + cleartext = f.read() + + f.close() + a.close() + + # Create the signature. + signature = self.pakfire.keyring.sign(key_id, cleartext) - ret = f.read() + # Write the signature to a temporary file. + trash, signature_file = tempfile.mkstemp() + try: + f = open(signature_file, mode="w") + f.write(signature) f.close() + + # Reopen the outer tarfile in write mode and append + # the new signature. + a = self.open_archive("a") + a.add(signature_file, "signatures/%s" % key_id) a.close() - except KeyError: - # signature file could not be found - pass + finally: + if os.path.exists(signature_file): + os.unlink(signature_file) + + def verify(self): + """ + Verify the tarball against the given key. + + If not key is given, only the checksums are compared to + the actual data. + """ + + # XXX replace Exception + + # Read the data of the checksum file. + a = self.open_archive() + f = a.extractfile("chksums") + chksums = f.read() + f.close() + a.close() + + sigs = [] + for signature in self.signatures.values(): + sigs += self.pakfire.keyring.verify(signature, chksums) + + # Open the archive to access all files we will need. + a = self.open_archive() + + # Read the chksums file. + chksums = {} + f = a.extractfile("chksums") + for line in f.readlines(): + filename, chksum = line.split() + chksums[filename] = chksum + f.close() + a.close() + + for filename, chksum in chksums.items(): + ret = self.check_chksum(filename, chksum) + + if ret: + log.debug("Checksum of %s matches." % filename) + continue + else: + log.debug("Checksum of %s does not match." % filename) + + raise Exception, "Checksum does not match: %s" % filename + + return sigs + + def check_chksum(self, filename, chksum, algo="sha512"): + a = self.open_archive() + f = a.extractfile(filename) + + h = hashlib.new(algo) + while True: + buf = f.read(BUFFER_SIZE) + if not buf: + break + + h.update(buf) + + f.close() + a.close() - return ret or None + return h.hexdigest() == chksum @property def hash1(self): diff --git a/python/pakfire/repository/index.py b/python/pakfire/repository/index.py index c319814da..9dda6bb96 100644 --- a/python/pakfire/repository/index.py +++ b/python/pakfire/repository/index.py @@ -52,9 +52,6 @@ class Index(object): def __repr__(self): return "<%s %s>" % (self.__class__.__name__, self.repo) - def __len(self): - return len(self.repo) - @property def cache(self): return self.repo.cache diff --git a/python/pakfire/repository/local.py b/python/pakfire/repository/local.py index 800019e52..a2936e32e 100644 --- a/python/pakfire/repository/local.py +++ b/python/pakfire/repository/local.py @@ -75,38 +75,53 @@ class RepositoryDir(base.RepositoryFactory): # The path of the package in the repository repo_filename = os.path.join(self.path, os.path.basename(pkg.filename)) - # Do we need to copy the package files? - copy = True - # Check, if the package does already exists and check if the # files are really equal. if os.path.exists(repo_filename): pkg_exists = packages.open(self.pakfire, self, repo_filename) - copy = False - - # Check UUID at first (faster) and check the file hash to be - # absolutely sure. - # Otherwise, unlink the existing file and replace it with the - # new one. - if pkg.uuid != pkg_exists.uuid and pkg.hash1 != pkg_exists.hash1: - # Do not copy the file if it is already okay. - copy = True - os.unlink(repo_filename) - - del pkg_exists - - if copy: - log.debug("Copying package '%s' to repository." % pkg) - repo_dirname = os.path.dirname(repo_filename) - if not os.path.exists(repo_dirname): - os.makedirs(repo_dirname) - - # Try to use a hard link if possible, if we cannot do that we simply - # copy the file. - try: - os.link(pkg.filename, repo_filename) - except OSError: - shutil.copy2(pkg.filename, repo_filename) + + # Check UUID to see if the file needs to be copied. + if pkg.uuid == pkg_exists.uuid: + continue + + log.debug("Copying package '%s' to repository." % pkg) + repo_dirname = os.path.dirname(repo_filename) + if not os.path.exists(repo_dirname): + os.makedirs(repo_dirname) + + # Try to use a hard link if possible, if we cannot do that we simply + # copy the file. + try: + os.link(pkg.filename, repo_filename) + except OSError: + shutil.copy2(pkg.filename, repo_filename) + + def sign(self, key_id): + """ + Sign all packages with the given key. + """ + # Create progressbar. + pb = util.make_progress(_("Signing packages..."), len(self), eta=True) + i = 0 + + # Create a new index (because package checksums will change). + for pkg in self: + if pb: + i += 1 + pb.update(i) + + # Create the full path to the file. + filename = os.path.join(self.path, pkg.filename) + pkg = packages.open(self.pakfire, self, filename) + + # Sign the package. + pkg.sign(key_id) + + if pb: + pb.finish() + + # Recreate the index because file checksums may have changed. + self.index.update(force=True) def save(self, path=None, algo="xz"): """ @@ -123,7 +138,6 @@ class RepositoryDir(base.RepositoryFactory): # Remove all pre-existing metadata. if os.path.exists(metapath): - print "Removing", metapath util.rm(metapath) # Create directory for metdadata. diff --git a/tools/Makefile b/tools/Makefile index eb1315acb..4448b69f5 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -53,6 +53,7 @@ install: $(SCRIPTS) ln -svf ../..$(SCRIPT_DIR)/pakfire-multicall.py $(DESTDIR)/usr/bin/pakfire-builder ln -svf ../..$(SCRIPT_DIR)/pakfire-multicall.py $(DESTDIR)/usr/bin/pakfire-client ln -svf ../..$(SCRIPT_DIR)/pakfire-multicall.py $(DESTDIR)/usr/bin/pakfire-daemon + ln -svf ../..$(SCRIPT_DIR)/pakfire-multicall.py $(DESTDIR)/usr/bin/pakfire-key ln -svf ../..$(SCRIPT_DIR)/pakfire-multicall.py $(DESTDIR)/usr/bin/pakfire-server ln -svf pakfire-multicall.py $(DESTDIR)$(SCRIPT_DIR)/builder diff --git a/tools/pakfire-multicall.py b/tools/pakfire-multicall.py index 0e5ab8073..b7547c198 100755 --- a/tools/pakfire-multicall.py +++ b/tools/pakfire-multicall.py @@ -38,6 +38,7 @@ basename2cls = { "pakfire-builder" : CliBuilder, "pakfire-client" : CliClient, "pakfire-daemon" : CliDaemon, + "pakfire-key" : CliKey, "pakfire-server" : CliServer, "builder" : CliBuilderIntern, }