12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package jdk.jpackage.internal; 27 28 import javax.imageio.ImageIO; 29 import java.awt.image.BufferedImage; 30 import java.io.*; 31 import java.nio.charset.StandardCharsets; 32 import java.nio.file.Files; 33 import java.nio.file.Path; 34 import java.nio.file.attribute.PosixFilePermission; 35 import java.nio.file.attribute.PosixFilePermissions; 36 import java.text.MessageFormat; 37 import java.util.*; 38 import java.util.regex.Pattern; 39 import java.util.stream.Stream; 40 41 import static jdk.jpackage.internal.StandardBundlerParam.*; 42 import static jdk.jpackage.internal.LinuxAppBundler.ICON_PNG; 43 import static jdk.jpackage.internal.LinuxAppBundler.LINUX_INSTALL_DIR; 44 import static jdk.jpackage.internal.LinuxAppBundler.LINUX_PACKAGE_DEPENDENCIES; 45 46 public class LinuxDebBundler extends AbstractBundler { 47 48 private static final ResourceBundle I18N = ResourceBundle.getBundle( 49 "jdk.jpackage.internal.resources.LinuxResources"); 50 51 public static final BundlerParamInfo<LinuxAppBundler> APP_BUNDLER = 52 new StandardBundlerParam<>( 53 "linux.app.bundler", 298 } 299 300 // bundle name has some restrictions 301 // the string converter will throw an exception if invalid 302 BUNDLE_NAME.getStringConverter().apply( 303 BUNDLE_NAME.fetchFrom(params), params); 304 305 return true; 306 } catch (RuntimeException re) { 307 if (re.getCause() instanceof ConfigException) { 308 throw (ConfigException) re.getCause(); 309 } else { 310 throw new ConfigException(re); 311 } 312 } 313 } 314 315 private boolean prepareProto(Map<String, ? super Object> params) 316 throws PackagerException, IOException { 317 File appImage = StandardBundlerParam.getPredefinedAppImage(params); 318 File appDir = null; 319 320 // we either have an application image or need to build one 321 if (appImage != null) { 322 appDir = new File(APP_IMAGE_ROOT.fetchFrom(params), 323 APP_NAME.fetchFrom(params)); 324 // copy everything from appImage dir into appDir/name 325 IOUtils.copyRecursive(appImage.toPath(), appDir.toPath()); 326 } else { 327 appDir = APP_BUNDLER.fetchFrom(params).doBundle(params, 328 APP_IMAGE_ROOT.fetchFrom(params), true); 329 } 330 return appDir != null; 331 } 332 333 public File bundle(Map<String, ? super Object> params, 334 File outdir) throws PackagerException { 335 336 IOUtils.writableOutputDir(outdir.toPath()); 337 338 // we want to create following structure 339 // <package-name> 340 // DEBIAN 341 // control (file with main package details) 342 // menu (request to create menu) 343 // ... other control files if needed .... 344 // opt (by default) 345 // AppFolder (this is where app image goes) 346 // launcher executable 347 // app 348 // runtime 349 350 File imageDir = DEB_IMAGE_DIR.fetchFrom(params); 351 File configDir = CONFIG_DIR.fetchFrom(params); 352 353 try { 354 355 imageDir.mkdirs(); 356 configDir.mkdirs(); 357 if (prepareProto(params) && prepareProjectConfig(params)) { 358 return buildDeb(params, outdir); 359 } 360 return null; 361 } catch (IOException ex) { 362 Log.verbose(ex); 363 throw new PackagerException(ex); 364 } 365 } 366 367 /* 368 * set permissions with a string like "rwxr-xr-x" 369 * 370 * This cannot be directly backport to 22u which is built with 1.6 371 */ 372 private void setPermissions(File file, String permissions) { 373 Set<PosixFilePermission> filePermissions = 374 PosixFilePermissions.fromString(permissions); 375 try { 376 if (file.exists()) { 377 Files.setPosixFilePermissions(file.toPath(), filePermissions); 395 private long getInstalledSizeKB(Map<String, ? super Object> params) { 396 return getInstalledSizeKB(APP_IMAGE_ROOT.fetchFrom(params)) >> 10; 397 } 398 399 private long getInstalledSizeKB(File dir) { 400 long count = 0; 401 File[] children = dir.listFiles(); 402 if (children != null) { 403 for (File file : children) { 404 if (file.isFile()) { 405 count += file.length(); 406 } 407 else if (file.isDirectory()) { 408 count += getInstalledSizeKB(file); 409 } 410 } 411 } 412 return count; 413 } 414 415 private boolean prepareProjectConfig(Map<String, ? super Object> params) 416 throws IOException { 417 Map<String, String> data = createReplacementData(params); 418 File rootDir = LinuxAppBundler.getRootDir(APP_IMAGE_ROOT.fetchFrom( 419 params), params); 420 File binDir = new File(rootDir, "bin"); 421 422 File iconTarget = getConfig_IconFile(binDir, params); 423 File icon = ICON_PNG.fetchFrom(params); 424 if (!StandardBundlerParam.isRuntimeInstaller(params)) { 425 // prepare installer icon 426 if (icon == null || !icon.exists()) { 427 fetchResource(iconTarget.getName(), 428 I18N.getString("resource.menu-icon"), 429 DEFAULT_ICON, 430 iconTarget, 431 VERBOSE.fetchFrom(params), 432 RESOURCE_DIR.fetchFrom(params)); 433 } else { 434 fetchResource(iconTarget.getName(), 435 I18N.getString("resource.menu-icon"), 436 icon, 437 iconTarget, 438 VERBOSE.fetchFrom(params), 439 RESOURCE_DIR.fetchFrom(params)); 559 if (description != null && !description.isEmpty()) { 560 mimeInfo.append(" <comment>") 561 .append(description) 562 .append("</comment>\n"); 563 } 564 565 if (extensions != null) { 566 for (String ext : extensions) { 567 mimeInfo.append(" <glob pattern='*.") 568 .append(ext) 569 .append("'/>\n"); 570 } 571 } 572 573 mimeInfo.append(" </mime-type>\n"); 574 if (!addedEntry) { 575 registrations.append(" xdg-mime install ") 576 .append(LINUX_INSTALL_DIR.fetchFrom(params)) 577 .append("/") 578 .append(data.get("APPLICATION_FS_NAME")) 579 .append("/") 580 .append(mimeInfoFile) 581 .append("\n"); 582 583 deregistrations.append(" xdg-mime uninstall ") 584 .append(LINUX_INSTALL_DIR.fetchFrom(params)) 585 .append("/") 586 .append(data.get("APPLICATION_FS_NAME")) 587 .append("/") 588 .append(mimeInfoFile) 589 .append("\n"); 590 addedEntry = true; 591 } else { 592 desktopMimes.append(";"); 593 } 594 desktopMimes.append(thisMime); 595 596 if (faIcon != null && faIcon.exists()) { 597 int size = getSquareSizeOfImage(faIcon); 598 599 if (size > 0) { 600 File target = new File(binDir, 601 APP_NAME.fetchFrom(params) 602 + "_fa_" + faIcon.getName()); 603 IOUtils.copyFile(faIcon, target); 604 605 // xdg-icon-resource install --context mimetypes 606 // --size 64 awesomeapp_fa_1.png 607 // application-x.vnd-awesome 742 String content = preprocessTextResource( 743 getConfig_CopyrightFile(params).getName(), 744 I18N.getString("resource.copyright-file"), 745 DEFAULT_COPYRIGHT_TEMPLATE, 746 data, 747 VERBOSE.fetchFrom(params), 748 RESOURCE_DIR.fetchFrom(params)); 749 w.write(content); 750 } 751 } 752 753 return true; 754 } 755 756 private Map<String, String> createReplacementData( 757 Map<String, ? super Object> params) throws IOException { 758 Map<String, String> data = new HashMap<>(); 759 String launcher = LinuxAppImageBuilder.getLauncherRelativePath(params); 760 761 data.put("APPLICATION_NAME", APP_NAME.fetchFrom(params)); 762 data.put("APPLICATION_FS_NAME", APP_NAME.fetchFrom(params)); 763 data.put("APPLICATION_PACKAGE", BUNDLE_NAME.fetchFrom(params)); 764 data.put("APPLICATION_VENDOR", VENDOR.fetchFrom(params)); 765 data.put("APPLICATION_MAINTAINER", MAINTAINER.fetchFrom(params)); 766 data.put("APPLICATION_VERSION", VERSION.fetchFrom(params)); 767 data.put("APPLICATION_RELEASE", RELEASE.fetchFrom(params)); 768 data.put("APPLICATION_SECTION", SECTION.fetchFrom(params)); 769 data.put("APPLICATION_LAUNCHER_FILENAME", launcher); 770 data.put("INSTALLATION_DIRECTORY", LINUX_INSTALL_DIR.fetchFrom(params)); 771 data.put("XDG_PREFIX", XDG_FILE_PREFIX.fetchFrom(params)); 772 data.put("DEPLOY_BUNDLE_CATEGORY", MENU_GROUP.fetchFrom(params)); 773 data.put("APPLICATION_DESCRIPTION", DESCRIPTION.fetchFrom(params)); 774 data.put("APPLICATION_COPYRIGHT", COPYRIGHT.fetchFrom(params)); 775 data.put("APPLICATION_LICENSE_TEXT", LICENSE_TEXT.fetchFrom(params)); 776 data.put("APPLICATION_ARCH", getDebArch()); 777 data.put("APPLICATION_INSTALLED_SIZE", 778 Long.toString(getInstalledSizeKB(params))); 779 String deps = LINUX_PACKAGE_DEPENDENCIES.fetchFrom(params); 780 data.put("PACKAGE_DEPENDENCIES", 781 deps.isEmpty() ? "" : "Depends: " + deps); 782 data.put("RUNTIME_INSTALLER", "" + 783 StandardBundlerParam.isRuntimeInstaller(params)); 784 785 return data; 786 } 787 788 private File getConfig_DesktopShortcutFile(File rootDir, 789 Map<String, ? super Object> params) { 790 return new File(rootDir, APP_NAME.fetchFrom(params) + ".desktop"); 791 } 792 793 private File getConfig_IconFile(File rootDir, 794 Map<String, ? super Object> params) { 795 return new File(rootDir, APP_NAME.fetchFrom(params) + ".png"); 796 } 797 798 private File getConfig_ControlFile(Map<String, ? super Object> params) { 799 return new File(CONFIG_DIR.fetchFrom(params), "control"); 800 } 801 802 private File getConfig_PreinstallFile(Map<String, ? super Object> params) { 803 return new File(CONFIG_DIR.fetchFrom(params), "preinst"); 804 } 805 806 private File getConfig_PrermFile(Map<String, ? super Object> params) { 807 return new File(CONFIG_DIR.fetchFrom(params), "prerm"); 808 } 809 810 private File getConfig_PostinstallFile(Map<String, ? super Object> params) { 811 return new File(CONFIG_DIR.fetchFrom(params), "postinst"); 812 } 813 814 private File getConfig_PostrmFile(Map<String, ? super Object> params) { 815 return new File(CONFIG_DIR.fetchFrom(params), "postrm"); 816 } 817 818 private File getConfig_CopyrightFile(Map<String, ? super Object> params) { 819 return Path.of(DEB_IMAGE_DIR.fetchFrom(params).getAbsolutePath(), "usr", 820 "share", "doc", BUNDLE_NAME.fetchFrom(params), "copyright").toFile(); 821 } 822 823 private File buildDeb(Map<String, ? super Object> params, 824 File outdir) throws IOException { 825 File outFile = new File(outdir, 826 FULL_PACKAGE_NAME.fetchFrom(params)+".deb"); 827 Log.verbose(MessageFormat.format(I18N.getString( 828 "message.outputting-to-location"), outFile.getAbsolutePath())); 829 830 outFile.getParentFile().mkdirs(); 831 832 // run dpkg 833 ProcessBuilder pb = new ProcessBuilder( 834 "fakeroot", TOOL_DPKG_DEB, "-b", 835 FULL_PACKAGE_NAME.fetchFrom(params), 836 outFile.getAbsolutePath()); 837 pb = pb.directory(DEB_IMAGE_DIR.fetchFrom(params).getParentFile()); 838 IOUtils.exec(pb); 839 840 Log.verbose(MessageFormat.format(I18N.getString( | 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package jdk.jpackage.internal; 27 28 import javax.imageio.ImageIO; 29 import java.awt.image.BufferedImage; 30 import java.io.*; 31 import java.nio.charset.StandardCharsets; 32 import java.nio.file.FileVisitResult; 33 import java.nio.file.Files; 34 import java.nio.file.Path; 35 import java.nio.file.SimpleFileVisitor; 36 import java.nio.file.StandardCopyOption; 37 import java.nio.file.attribute.BasicFileAttributes; 38 39 import java.nio.file.attribute.PosixFilePermission; 40 import java.nio.file.attribute.PosixFilePermissions; 41 import java.text.MessageFormat; 42 import java.util.*; 43 import java.util.regex.Pattern; 44 import java.util.stream.Stream; 45 46 import static jdk.jpackage.internal.StandardBundlerParam.*; 47 import static jdk.jpackage.internal.LinuxAppBundler.ICON_PNG; 48 import static jdk.jpackage.internal.LinuxAppBundler.LINUX_INSTALL_DIR; 49 import static jdk.jpackage.internal.LinuxAppBundler.LINUX_PACKAGE_DEPENDENCIES; 50 51 public class LinuxDebBundler extends AbstractBundler { 52 53 private static final ResourceBundle I18N = ResourceBundle.getBundle( 54 "jdk.jpackage.internal.resources.LinuxResources"); 55 56 public static final BundlerParamInfo<LinuxAppBundler> APP_BUNDLER = 57 new StandardBundlerParam<>( 58 "linux.app.bundler", 303 } 304 305 // bundle name has some restrictions 306 // the string converter will throw an exception if invalid 307 BUNDLE_NAME.getStringConverter().apply( 308 BUNDLE_NAME.fetchFrom(params), params); 309 310 return true; 311 } catch (RuntimeException re) { 312 if (re.getCause() instanceof ConfigException) { 313 throw (ConfigException) re.getCause(); 314 } else { 315 throw new ConfigException(re); 316 } 317 } 318 } 319 320 private boolean prepareProto(Map<String, ? super Object> params) 321 throws PackagerException, IOException { 322 File appImage = StandardBundlerParam.getPredefinedAppImage(params); 323 324 // we either have an application image or need to build one 325 if (appImage != null) { 326 // copy everything from appImage dir into appDir/name 327 IOUtils.copyRecursive(appImage.toPath(), 328 getConfig_RootDirectory(params).toPath()); 329 } else { 330 File bundleDir = APP_BUNDLER.fetchFrom(params).doBundle(params, 331 APP_IMAGE_ROOT.fetchFrom(params), true); 332 if (bundleDir == null) { 333 return false; 334 } 335 Files.move(bundleDir.toPath(), getConfig_RootDirectory( 336 params).toPath(), StandardCopyOption.REPLACE_EXISTING); 337 } 338 return true; 339 } 340 341 public File bundle(Map<String, ? super Object> params, 342 File outdir) throws PackagerException { 343 344 IOUtils.writableOutputDir(outdir.toPath()); 345 346 // we want to create following structure 347 // <package-name> 348 // DEBIAN 349 // control (file with main package details) 350 // menu (request to create menu) 351 // ... other control files if needed .... 352 // opt (by default) 353 // AppFolder (this is where app image goes) 354 // launcher executable 355 // app 356 // runtime 357 358 File imageDir = DEB_IMAGE_DIR.fetchFrom(params); 359 File configDir = CONFIG_DIR.fetchFrom(params); 360 361 try { 362 363 imageDir.mkdirs(); 364 configDir.mkdirs(); 365 if (prepareProto(params) && prepareProjectConfig(params)) { 366 adjustPermissionsRecursive(imageDir); 367 return buildDeb(params, outdir); 368 } 369 return null; 370 } catch (IOException ex) { 371 Log.verbose(ex); 372 throw new PackagerException(ex); 373 } 374 } 375 376 /* 377 * set permissions with a string like "rwxr-xr-x" 378 * 379 * This cannot be directly backport to 22u which is built with 1.6 380 */ 381 private void setPermissions(File file, String permissions) { 382 Set<PosixFilePermission> filePermissions = 383 PosixFilePermissions.fromString(permissions); 384 try { 385 if (file.exists()) { 386 Files.setPosixFilePermissions(file.toPath(), filePermissions); 404 private long getInstalledSizeKB(Map<String, ? super Object> params) { 405 return getInstalledSizeKB(APP_IMAGE_ROOT.fetchFrom(params)) >> 10; 406 } 407 408 private long getInstalledSizeKB(File dir) { 409 long count = 0; 410 File[] children = dir.listFiles(); 411 if (children != null) { 412 for (File file : children) { 413 if (file.isFile()) { 414 count += file.length(); 415 } 416 else if (file.isDirectory()) { 417 count += getInstalledSizeKB(file); 418 } 419 } 420 } 421 return count; 422 } 423 424 private void adjustPermissionsRecursive(File dir) throws IOException { 425 Files.walkFileTree(dir.toPath(), new SimpleFileVisitor<Path>() { 426 @Override 427 public FileVisitResult visitFile(Path file, 428 BasicFileAttributes attrs) 429 throws IOException { 430 if (file.endsWith(".so") || !Files.isExecutable(file)) { 431 setPermissions(file.toFile(), "rw-r--r--"); 432 } else if (Files.isExecutable(file)) { 433 setPermissions(file.toFile(), "rwxr-xr-x"); 434 } 435 return FileVisitResult.CONTINUE; 436 } 437 438 @Override 439 public FileVisitResult postVisitDirectory(Path dir, IOException e) 440 throws IOException { 441 if (e == null) { 442 setPermissions(dir.toFile(), "rwxr-xr-x"); 443 return FileVisitResult.CONTINUE; 444 } else { 445 // directory iteration failed 446 throw e; 447 } 448 } 449 }); 450 } 451 452 private boolean prepareProjectConfig(Map<String, ? super Object> params) 453 throws IOException { 454 Map<String, String> data = createReplacementData(params); 455 File rootDir = getConfig_RootDirectory(params); 456 File binDir = new File(rootDir, "bin"); 457 458 File iconTarget = getConfig_IconFile(binDir, params); 459 File icon = ICON_PNG.fetchFrom(params); 460 if (!StandardBundlerParam.isRuntimeInstaller(params)) { 461 // prepare installer icon 462 if (icon == null || !icon.exists()) { 463 fetchResource(iconTarget.getName(), 464 I18N.getString("resource.menu-icon"), 465 DEFAULT_ICON, 466 iconTarget, 467 VERBOSE.fetchFrom(params), 468 RESOURCE_DIR.fetchFrom(params)); 469 } else { 470 fetchResource(iconTarget.getName(), 471 I18N.getString("resource.menu-icon"), 472 icon, 473 iconTarget, 474 VERBOSE.fetchFrom(params), 475 RESOURCE_DIR.fetchFrom(params)); 595 if (description != null && !description.isEmpty()) { 596 mimeInfo.append(" <comment>") 597 .append(description) 598 .append("</comment>\n"); 599 } 600 601 if (extensions != null) { 602 for (String ext : extensions) { 603 mimeInfo.append(" <glob pattern='*.") 604 .append(ext) 605 .append("'/>\n"); 606 } 607 } 608 609 mimeInfo.append(" </mime-type>\n"); 610 if (!addedEntry) { 611 registrations.append(" xdg-mime install ") 612 .append(LINUX_INSTALL_DIR.fetchFrom(params)) 613 .append("/") 614 .append(data.get("APPLICATION_FS_NAME")) 615 .append("/bin/") 616 .append(mimeInfoFile) 617 .append("\n"); 618 619 deregistrations.append(" xdg-mime uninstall ") 620 .append(LINUX_INSTALL_DIR.fetchFrom(params)) 621 .append("/") 622 .append(data.get("APPLICATION_FS_NAME")) 623 .append("/bin/") 624 .append(mimeInfoFile) 625 .append("\n"); 626 addedEntry = true; 627 } else { 628 desktopMimes.append(";"); 629 } 630 desktopMimes.append(thisMime); 631 632 if (faIcon != null && faIcon.exists()) { 633 int size = getSquareSizeOfImage(faIcon); 634 635 if (size > 0) { 636 File target = new File(binDir, 637 APP_NAME.fetchFrom(params) 638 + "_fa_" + faIcon.getName()); 639 IOUtils.copyFile(faIcon, target); 640 641 // xdg-icon-resource install --context mimetypes 642 // --size 64 awesomeapp_fa_1.png 643 // application-x.vnd-awesome 778 String content = preprocessTextResource( 779 getConfig_CopyrightFile(params).getName(), 780 I18N.getString("resource.copyright-file"), 781 DEFAULT_COPYRIGHT_TEMPLATE, 782 data, 783 VERBOSE.fetchFrom(params), 784 RESOURCE_DIR.fetchFrom(params)); 785 w.write(content); 786 } 787 } 788 789 return true; 790 } 791 792 private Map<String, String> createReplacementData( 793 Map<String, ? super Object> params) throws IOException { 794 Map<String, String> data = new HashMap<>(); 795 String launcher = LinuxAppImageBuilder.getLauncherRelativePath(params); 796 797 data.put("APPLICATION_NAME", APP_NAME.fetchFrom(params)); 798 data.put("APPLICATION_FS_NAME", 799 getConfig_RootDirectory(params).getName()); 800 data.put("APPLICATION_PACKAGE", BUNDLE_NAME.fetchFrom(params)); 801 data.put("APPLICATION_VENDOR", VENDOR.fetchFrom(params)); 802 data.put("APPLICATION_MAINTAINER", MAINTAINER.fetchFrom(params)); 803 data.put("APPLICATION_VERSION", VERSION.fetchFrom(params)); 804 data.put("APPLICATION_RELEASE", RELEASE.fetchFrom(params)); 805 data.put("APPLICATION_SECTION", SECTION.fetchFrom(params)); 806 data.put("APPLICATION_LAUNCHER_FILENAME", launcher); 807 data.put("INSTALLATION_DIRECTORY", LINUX_INSTALL_DIR.fetchFrom(params)); 808 data.put("XDG_PREFIX", XDG_FILE_PREFIX.fetchFrom(params)); 809 data.put("DEPLOY_BUNDLE_CATEGORY", MENU_GROUP.fetchFrom(params)); 810 data.put("APPLICATION_DESCRIPTION", DESCRIPTION.fetchFrom(params)); 811 data.put("APPLICATION_COPYRIGHT", COPYRIGHT.fetchFrom(params)); 812 data.put("APPLICATION_LICENSE_TEXT", LICENSE_TEXT.fetchFrom(params)); 813 data.put("APPLICATION_ARCH", getDebArch()); 814 data.put("APPLICATION_INSTALLED_SIZE", 815 Long.toString(getInstalledSizeKB(params))); 816 data.put("PACKAGE_DEPENDENCIES", LINUX_PACKAGE_DEPENDENCIES.fetchFrom( 817 params)); 818 data.put("RUNTIME_INSTALLER", "" + 819 StandardBundlerParam.isRuntimeInstaller(params)); 820 821 return data; 822 } 823 824 private File getConfig_DesktopShortcutFile(File rootDir, 825 Map<String, ? super Object> params) { 826 return new File(rootDir, APP_NAME.fetchFrom(params) + ".desktop"); 827 } 828 829 private File getConfig_IconFile(File rootDir, 830 Map<String, ? super Object> params) { 831 return new File(rootDir, APP_NAME.fetchFrom(params) + ".png"); 832 } 833 834 private File getConfig_ControlFile(Map<String, ? super Object> params) { 835 return new File(CONFIG_DIR.fetchFrom(params), "control"); 836 } 837 838 private File getConfig_PreinstallFile(Map<String, ? super Object> params) { 839 return new File(CONFIG_DIR.fetchFrom(params), "preinst"); 840 } 841 842 private File getConfig_PrermFile(Map<String, ? super Object> params) { 843 return new File(CONFIG_DIR.fetchFrom(params), "prerm"); 844 } 845 846 private File getConfig_PostinstallFile(Map<String, ? super Object> params) { 847 return new File(CONFIG_DIR.fetchFrom(params), "postinst"); 848 } 849 850 private File getConfig_PostrmFile(Map<String, ? super Object> params) { 851 return new File(CONFIG_DIR.fetchFrom(params), "postrm"); 852 } 853 854 private File getConfig_CopyrightFile(Map<String, ? super Object> params) { 855 return Path.of(DEB_IMAGE_DIR.fetchFrom(params).getAbsolutePath(), "usr", 856 "share", "doc", BUNDLE_NAME.fetchFrom(params), "copyright").toFile(); 857 } 858 859 private File getConfig_RootDirectory( 860 Map<String, ? super Object> params) { 861 return Path.of(APP_IMAGE_ROOT.fetchFrom(params).getAbsolutePath(), 862 BUNDLE_NAME.fetchFrom(params)).toFile(); 863 } 864 865 private File buildDeb(Map<String, ? super Object> params, 866 File outdir) throws IOException { 867 File outFile = new File(outdir, 868 FULL_PACKAGE_NAME.fetchFrom(params)+".deb"); 869 Log.verbose(MessageFormat.format(I18N.getString( 870 "message.outputting-to-location"), outFile.getAbsolutePath())); 871 872 outFile.getParentFile().mkdirs(); 873 874 // run dpkg 875 ProcessBuilder pb = new ProcessBuilder( 876 "fakeroot", TOOL_DPKG_DEB, "-b", 877 FULL_PACKAGE_NAME.fetchFrom(params), 878 outFile.getAbsolutePath()); 879 pb = pb.directory(DEB_IMAGE_DIR.fetchFrom(params).getParentFile()); 880 IOUtils.exec(pb); 881 882 Log.verbose(MessageFormat.format(I18N.getString( |