如何在sbt-native-packager构建RPM时过滤/etc/default和/var/run目录
我懂你碰到的这个问题——用sbt-native-packager结合JavaServerAppPackaging构建RPM时,/etc/default和/var/run这俩目录是插件通过内置的系统服务模板自动生成的,所以你查看linuxPackageMappings根本找不到它们的身影。下面给你几个可行的解决办法:
方法一:自定义服务模板,移除目录创建逻辑
JavaServerAppPackaging会默认使用systemd或sysvinit的模板来生成服务配置,这些模板里包含了创建/etc/default(存放环境变量)和/var/run(运行时目录)的指令。你可以通过自定义模板来精准移除这些部分:
在项目根目录下创建模板目录:
- 如果用systemd服务:新建
src/templates/systemd文件夹 - 如果用sysvinit服务:新建
src/templates/sysvinit文件夹
- 如果用systemd服务:新建
复制sbt-native-packager原生模板的内容到对应目录的模板文件中(比如systemd对应
script.service.template,sysvinit对应script.template),然后删除其中涉及目标目录的配置:- 对于systemd模板:删掉
EnvironmentFile=-/etc/default/<你的应用名>和RuntimeDirectory=<你的应用名>这类行 - 对于sysvinit模板:删掉脚本中创建
/var/run目录的代码段,以及读取/etc/default配置的逻辑
- 对于systemd模板:删掉
方法二:直接修改RPM Spec文件排除目录
sbt-native-packager允许你直接修改生成的RPM Spec内容,添加排除规则。在build.sbt中加入以下配置:
// 过滤掉RPM映射中的目标目录 rpmPackageMappings := rpmPackageMappings.value.map { mapping => mapping.copy( fileFilter = mapping.fileFilter -- new File("/etc/default") -- new File("/var/run") ) } // 或者直接修改生成的Spec文本,移除目录声明 rpmSpecTemplate := rpmSpecTemplate.value .replaceAll("%dir /etc/default", "") .replaceAll("%dir /var/run", "")
注意:不同版本的sbt-native-packager生成的Spec结构可能略有差异,你可能需要根据实际生成的Spec内容调整替换规则。
方法三:禁用默认服务生成逻辑(彻底自定义)
如果不需要插件自动生成任何服务相关配置,可以直接禁用JavaServerAppPackaging的默认服务逻辑,完全自己控制打包内容:
// 只启用基础Java打包和RPM插件,不启用JavaServerAppPackaging enablePlugins(JavaAppPackaging, RpmPlugin) // 禁用默认的守护用户和服务配置 linuxMakeDaemonUser := false daemonUser := "" daemonGroup := ""
这种方式会完全取消插件自动创建/etc/default和/var/run的行为,但你需要自行处理服务启动脚本、用户权限等配置。
最推荐的是方法一,因为它能精准控制服务配置的细节,不会破坏其他打包逻辑,也符合sbt-native-packager的设计思路。
内容的提问来源于stack exchange,提问作者Alex L.

