Skip to content

Commit 17db3ca

Browse files
committed
Merge pull request #139 from hindsightsoftware/daemon-user-should-own-files
Change the default owner of packaged files. See #129
2 parents 832aed6 + 90a23cb commit 17db3ca

File tree

8 files changed

+73
-18
lines changed

8 files changed

+73
-18
lines changed

src/main/scala/com/typesafe/sbt/packager/GenericPackageSettings.scala

+10-10
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,8 @@ trait GenericPackageSettings
3232
* Files in `conf/` or `etc/` directories are automatically marked as configuration.
3333
* `../man/...1` files are automatically compressed into .gz files.
3434
*
35-
* TODO - We need to figure out how to handle ownership here.
3635
*/
37-
def mapGenericMappingsToLinux(mappings: Seq[(File, String)])(rename: String => String): Seq[LinuxPackageMapping] = {
36+
def mapGenericMappingsToLinux(mappings: Seq[(File, String)], user: String)(rename: String => String): Seq[LinuxPackageMapping] = {
3837
val (directories, nondirectories) = mappings.partition(_._1.isDirectory)
3938
val (binaries, nonbinaries) = nondirectories.partition(_._1.canExecute)
4039
val (manPages, nonManPages) = nonbinaries partition {
@@ -54,10 +53,10 @@ trait GenericPackageSettings
5453
}
5554

5655
Seq(
57-
packageMappingWithRename((binaries ++ directories):_*) withUser Users.Root withGroup Users.Root withPerms "0755",
58-
packageMappingWithRename(compressedManPages:_*).gzipped withUser Users.Root withGroup Users.Root withPerms "0644",
59-
packageMappingWithRename(configFiles:_*) withConfig() withUser Users.Root withGroup Users.Root withPerms "0644",
60-
packageMappingWithRename(remaining:_*) withUser Users.Root withGroup Users.Root withPerms "0644"
56+
packageMappingWithRename((binaries ++ directories):_*) withUser user withGroup user withPerms "0755",
57+
packageMappingWithRename(compressedManPages:_*).gzipped withUser user withGroup user withPerms "0644",
58+
packageMappingWithRename(configFiles:_*) withConfig() withUser user withGroup user withPerms "0644",
59+
packageMappingWithRename(remaining:_*) withUser user withGroup user withPerms "0644"
6160
)
6261
}
6362

@@ -68,16 +67,17 @@ trait GenericPackageSettings
6867
defaultLinuxLogsLocation := "/var/log",
6968

7069
// First we look at the src/linux files
71-
linuxPackageMappings <++= (sourceDirectory in Linux) map { dir =>
72-
mapGenericMappingsToLinux((dir.*** --- dir) x relativeTo(dir))(identity)
70+
linuxPackageMappings <++= (sourceDirectory in Linux, appUser in Linux) map { (dir, user) =>
71+
mapGenericMappingsToLinux((dir.*** --- dir) x relativeTo(dir), user)(identity)
7372
},
7473
// Now we look at the src/universal files.
75-
linuxPackageMappings <++= (normalizedName in Universal, mappings in Universal, defaultLinuxInstallLocation) map { (pkg, mappings, installLocation) =>
74+
linuxPackageMappings <++= (normalizedName in Universal, mappings in Universal, defaultLinuxInstallLocation, appUser in Linux) map {
75+
(pkg, mappings, installLocation, user) =>
7676
// TODO - More windows filters...
7777
def isWindowsFile(f: (File, String)): Boolean =
7878
f._2 endsWith ".bat"
7979

80-
mapGenericMappingsToLinux(mappings filterNot isWindowsFile) { name =>
80+
mapGenericMappingsToLinux(mappings filterNot isWindowsFile, user) { name =>
8181
installLocation + "/" + pkg + "/" + name
8282
}
8383
},

src/main/scala/com/typesafe/sbt/packager/archetypes/JavaServerApplication.scala

+7-7
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ object JavaServerAppPackaging {
2929
def debianSettings: Seq[Setting[_]] =
3030
Seq(
3131
serverLoading := Upstart,
32-
daemonUser := Users.Root,
32+
daemonUser <<= appUser in Linux,
3333
// This one is begging for sbt 0.13 syntax...
3434
debianScriptReplacements <<= (
3535
maintainer in Debian, packageSummary in Debian, serverLoading in Debian, daemonUser in Debian, normalizedName,
@@ -55,15 +55,15 @@ object JavaServerAppPackaging {
5555
map { (tmpDir, loader, replacements, template) =>
5656
makeDebianMaintainerScript(JavaAppStartScript.startScript, Some(template))(tmpDir, loader, replacements)
5757
},
58-
linuxPackageMappings in Debian <++= (debianMakeStartScript, normalizedName, serverLoading in Debian)
59-
map { (script, name, loader) =>
58+
linuxPackageMappings in Debian <++= (debianMakeStartScript, normalizedName, serverLoading in Debian, appUser in Linux)
59+
map { (script, name, loader, owner) =>
6060
val (path, permissions) = loader match {
6161
case Upstart => ("/etc/init/" + name + ".conf", "0644")
6262
case SystemV => ("/etc/init.d/" + name, "0755")
6363
}
6464
for {
6565
s <- script.toSeq
66-
} yield LinuxPackageMapping(Seq(s -> path)).withPerms(permissions).withConfig()
66+
} yield LinuxPackageMapping(Seq(s -> path), LinuxFileMetaData(owner, owner, permissions, "true"))
6767
},
6868

6969
// === etc config mapping ===
@@ -75,13 +75,13 @@ object JavaServerAppPackaging {
7575
},
7676
debianMakeEtcDefault <<= (normalizedName, target in Universal, linuxEtcDefaultTemplate in Debian, debianScriptReplacements)
7777
map makeEtcDefaultScript,
78-
linuxPackageMappings in Debian <++= (debianMakeEtcDefault, normalizedName) map { (conf, name) =>
79-
conf.map(c => LinuxPackageMapping(Seq(c -> ("/etc/default/" + name))).withConfig()).toSeq
78+
linuxPackageMappings in Debian <++= (debianMakeEtcDefault, normalizedName, appUser in Linux) map { (conf, name, owner) =>
79+
conf.map(c => LinuxPackageMapping(Seq(c -> ("/etc/default/" + name)), LinuxFileMetaData(owner, owner)).withConfig()).toSeq
8080
},
8181
// TODO should we specify daemonGroup in configs?
8282

8383
// === logging directory mapping ===
84-
linuxPackageMappings in Debian <+= (normalizedName, defaultLinuxLogsLocation, target in Debian, daemonUser in Debian) map {
84+
linuxPackageMappings in Debian <+= (normalizedName, defaultLinuxLogsLocation, target in Debian, appUser in Linux) map {
8585
(name, logsDir, target, user) =>
8686
// create empty var/log directory
8787
val d = target / logsDir

src/main/scala/com/typesafe/sbt/packager/debian/Keys.scala

+3
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ object Keys extends DebianKeys {
8383
def target = sbt.Keys.target
8484
def streams = sbt.Keys.streams
8585

86+
// file ownership
87+
def appUser = linux.Keys.appUser
88+
8689
//init script parameters
8790
def daemonUser = linux.Keys.daemonUser
8891
def serverLoading = linux.Keys.serverLoading

src/main/scala/com/typesafe/sbt/packager/linux/Keys.scala

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ trait Keys {
1111
val packageSummary = SettingKey[String]("package-summary", "Summary of the contents of a linux package.")
1212
val packageDescription = SettingKey[String]("package-description", "The description of the package. Used when searching.")
1313
val maintainer = SettingKey[String]("maintainer", "The name/email address of a maintainer for the native package.")
14+
val appUser = SettingKey[String]("app-user", "The owner of the files in the package")
1415
val daemonUser = SettingKey[String]("daemon-user", "User to start application daemon")
1516
val serverLoading = SettingKey[ServerLoader]("server-loader", "Loading system to be used for application start script")
1617
val linuxPackageMappings = TaskKey[Seq[LinuxPackageMapping]]("linux-package-mappings", "File to install location mappings including owner and privileges.")

src/main/scala/com/typesafe/sbt/packager/linux/LinuxPlugin.scala

+3-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package linux
44

55
import Keys._
66
import sbt._
7+
import com.typesafe.sbt.packager.linux.LinuxPlugin.Users
78

89
/**
910
* Plugin trait containing all the generic values used for
@@ -25,7 +26,8 @@ trait LinuxPlugin extends Plugin {
2526
}
2627
},
2728
packageSummary in Linux <<= packageSummary,
28-
packageDescription in Linux <<= packageDescription)
29+
packageDescription in Linux <<= packageDescription,
30+
appUser := Users.Root)
2931

3032
/** DSL for packaging files into .deb */
3133
def packageMapping(files: (File, String)*) = LinuxPackageMapping(files)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import NativePackagerKeys._
2+
import com.typesafe.sbt.packager.archetypes.ServerLoader
3+
4+
packageArchetype.java_server
5+
6+
serverLoading in Debian := ServerLoader.Upstart
7+
8+
appUser in Linux := "daemonUser"
9+
10+
mainClass in Compile := Some("empty")
11+
12+
name := "debian-test"
13+
14+
version := "0.1.0"
15+
16+
maintainer := "Josh Suereth <[email protected]>"
17+
18+
packageSummary := "Test debian package"
19+
20+
packageDescription := """A fun package description of our software,
21+
with multiple lines."""
22+
23+
TaskKey[Unit]("check-control-files") <<= (target, streams) map { (target, out) =>
24+
val debian = target / "debian-test-0.1.0" / "DEBIAN"
25+
val postinst = IO.read(debian / "postinst")
26+
val postrm = IO.read(debian / "postrm")
27+
assert(postinst contains "addgroup --system daemonUser", "postinst misses addgroup for daemonUser: " + postinst)
28+
assert(postinst contains "useradd --system --no-create-home --gid daemonUser --shell /bin/false daemonUser", "postinst misses useradd for daemonUser: " + postinst)
29+
assert(postinst contains "chown daemonUser:daemonUser /var/log/debian-test", "postinst misses chown daemonUser /var/log/debian-test: " + postinst)
30+
assert(postinst contains "chown daemonUser:daemonUser /usr/share/debian-test/bin/debian-test", "postinst misses chown daemonUser /usr/share/debian-test/bin/debian-test: " + postinst)
31+
assert(postrm contains "deluser --quiet --system daemonUser > /dev/null || true", "postrm misses purging daemonUser user: " + postrm)
32+
assert(postrm contains "delgroup --quiet --system daemonUser > /dev/null || true", "postrm misses purging daemonUser group: " + postrm)
33+
out.log.success("Successfully tested upstart control files")
34+
()
35+
}
36+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % sys.props("project.version"))
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Run the debian packaging.
2+
> debian:package-bin
3+
$ exists target/debian-test-0.1.0.deb
4+
5+
$ exists target/debian-test-0.1.0/etc
6+
$ exists target/debian-test-0.1.0/etc/init/debian-test.conf
7+
# Check defaults
8+
$ exists target/debian-test-0.1.0/DEBIAN/prerm
9+
$ exists target/debian-test-0.1.0/DEBIAN/postinst
10+
11+
# Check files for defaults
12+
> check-control-files

0 commit comments

Comments
 (0)