Skip to content

Commit 676d72c

Browse files
committed
Merge pull request #174 from sbt/wip/server-permissions
Wip/server permissions
2 parents cfe8ff8 + fd0e8b2 commit 676d72c

File tree

9 files changed

+102
-106
lines changed

9 files changed

+102
-106
lines changed

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

+66-70
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@ package packager
33

44
import Keys._
55
import sbt._
6-
import sbt.Keys.{name, mappings, sourceDirectory}
6+
import sbt.Keys.{ name, mappings, sourceDirectory }
77
import linux.LinuxSymlink
88
import linux.LinuxPackageMapping
99

10-
trait GenericPackageSettings
11-
extends linux.LinuxPlugin
12-
with debian.DebianPlugin
13-
with rpm.RpmPlugin
14-
with windows.WindowsPlugin
15-
with universal.UniversalPlugin {
10+
trait GenericPackageSettings
11+
extends linux.LinuxPlugin
12+
with debian.DebianPlugin
13+
with rpm.RpmPlugin
14+
with windows.WindowsPlugin
15+
with universal.UniversalPlugin {
1616

1717
import linux.LinuxPlugin.Users
1818

@@ -21,10 +21,10 @@ trait GenericPackageSettings
2121
// It is by no means 100% accurate, but should be ok for the simplest cases.
2222
// For advanced users, use the underlying APIs.
2323
// Right now, it's also pretty focused on command line scripts packages.
24-
24+
2525
/**
2626
* Maps linux file format from the universal from the conventions:
27-
*
27+
*
2828
* `<project>/src/linux` files are mapped directly into linux packages.
2929
* `<universal>` files are placed under `/usr/share/<package-name>`
3030
* `<universal>/bin` files are given symlinks in `/usr/bin`
@@ -40,114 +40,110 @@ trait GenericPackageSettings
4040
case (file, name) => (name contains "man/") && (name endsWith ".1")
4141
}
4242
val compressedManPages =
43-
for((file, name) <- manPages)
44-
yield file -> (name + ".gz")
43+
for ((file, name) <- manPages)
44+
yield file -> (name + ".gz")
4545
val (configFiles, remaining) = nonManPages partition {
4646
case (file, name) => (name contains "etc/") || (name contains "conf/")
4747
}
4848
def packageMappingWithRename(mappings: (File, String)*): LinuxPackageMapping = {
4949
val renamed =
50-
for((file, name) <- mappings)
51-
yield file -> rename(name)
52-
packageMapping(renamed:_*)
50+
for ((file, name) <- mappings)
51+
yield file -> rename(name)
52+
packageMapping(renamed: _*)
5353
}
54-
54+
5555
Seq(
56-
packageMappingWithRename((binaries ++ directories):_*) withUser user withGroup group withPerms "0755",
57-
packageMappingWithRename(compressedManPages:_*).gzipped withUser user withGroup group withPerms "0644",
58-
packageMappingWithRename(configFiles:_*) withConfig() withUser user withGroup group withPerms "0644",
59-
packageMappingWithRename(remaining:_*) withUser user withGroup group withPerms "0644"
60-
)
56+
packageMappingWithRename((binaries ++ directories): _*) withUser user withGroup group withPerms "0755",
57+
packageMappingWithRename(compressedManPages: _*).gzipped withUser user withGroup group withPerms "0644",
58+
packageMappingWithRename(configFiles: _*) withConfig () withUser user withGroup group withPerms "0644",
59+
packageMappingWithRename(remaining: _*) withUser user withGroup group withPerms "0644")
6160
}
6261

6362
def mapGenericFilesToLinux: Seq[Setting[_]] = Seq(
6463

6564
// Default place to install code.
6665
defaultLinuxInstallLocation := "/usr/share",
6766
defaultLinuxLogsLocation := "/var/log",
67+
defaultLinuxConfigLocation := "/etc",
6868

6969
// First we look at the src/linux files
70-
linuxPackageMappings <++= (sourceDirectory in Linux, appUser in Linux, appGroup in Linux) map { (dir, user, group) =>
71-
mapGenericMappingsToLinux((dir.*** --- dir) x relativeTo(dir), user, group)(identity)
70+
linuxPackageMappings <++= (sourceDirectory in Linux, daemonUser in Linux, daemonGroup in Linux) map { (dir, user, group) =>
71+
mapGenericMappingsToLinux(MappingsHelper contentOf dir, user, group)(identity)
7272
},
7373
// Now we look at the src/universal files.
74-
linuxPackageMappings <++= (normalizedName in Universal, mappings in Universal, defaultLinuxInstallLocation, appUser in Linux, appGroup in Linux) map {
74+
linuxPackageMappings <++= (normalizedName in Universal, mappings in Universal, defaultLinuxInstallLocation, daemonUser in Linux, daemonGroup in Linux) map {
7575
(pkg, mappings, installLocation, user, group) =>
76-
// TODO - More windows filters...
77-
def isWindowsFile(f: (File, String)): Boolean =
78-
f._2 endsWith ".bat"
79-
80-
mapGenericMappingsToLinux(mappings filterNot isWindowsFile, user, group) { name =>
81-
installLocation + "/" + pkg + "/" + name
82-
}
76+
// TODO - More windows filters...
77+
def isWindowsFile(f: (File, String)): Boolean =
78+
f._2 endsWith ".bat"
79+
80+
mapGenericMappingsToLinux(mappings filterNot isWindowsFile, user, group) { name =>
81+
installLocation + "/" + pkg + "/" + name
82+
}
8383
},
8484
// Now we generate symlinks.
8585
linuxPackageSymlinks <++= (normalizedName in Universal, mappings in Universal, defaultLinuxInstallLocation) map { (pkg, mappings, installLocation) =>
86-
for {
87-
(file, name) <- mappings
88-
if !file.isDirectory
89-
if name startsWith "bin/"
90-
if !(name endsWith ".bat") // IGNORE windows-y things.
91-
} yield LinuxSymlink("/usr/" + name, installLocation+"/"+pkg+"/"+name)
86+
for {
87+
(file, name) <- mappings
88+
if !file.isDirectory
89+
if name startsWith "bin/"
90+
if !(name endsWith ".bat") // IGNORE windows-y things.
91+
} yield LinuxSymlink("/usr/" + name, installLocation + "/" + pkg + "/" + name)
9292
},
9393
// Map configuration files
94-
linuxPackageSymlinks <++= (normalizedName in Universal, mappings in Universal, defaultLinuxInstallLocation) map { (pkg, mappings, installLocation) =>
94+
linuxPackageSymlinks <++= (normalizedName in Universal, mappings in Universal, defaultLinuxInstallLocation, defaultLinuxConfigLocation)
95+
map { (pkg, mappings, installLocation, configLocation) =>
9596
val needsConfLink =
96-
mappings exists { case (file, name) =>
97-
(name startsWith "conf/") && !file.isDirectory
97+
mappings exists {
98+
case (file, name) =>
99+
(name startsWith "conf/") && !file.isDirectory
98100
}
99-
if(needsConfLink) Seq(LinuxSymlink(
100-
link="/etc/" + pkg,
101-
destination=installLocation+"/"+pkg+"/conf"))
101+
if (needsConfLink) Seq(LinuxSymlink(
102+
link = configLocation + "/" + pkg,
103+
destination = installLocation + "/" + pkg + "/conf"))
102104
else Seq.empty
103-
}
104-
)
105-
105+
})
106+
106107
def mapGenericFilesToWindows: Seq[Setting[_]] = Seq(
107108
mappings in Windows <<= mappings in Universal,
108-
wixFeatures <<= (name in Windows, mappings in Windows) map makeWindowsFeatures
109-
)
109+
wixFeatures <<= (name in Windows, mappings in Windows) map makeWindowsFeatures)
110110
// TODO select main script! Filter Config links!
111111
def makeWindowsFeatures(name: String, mappings: Seq[(File, String)]): Seq[windows.WindowsFeature] = {
112112
import windows._
113-
113+
114114
val files =
115115
for {
116116
(file, name) <- mappings
117117
if !file.isDirectory
118118
} yield ComponentFile(name, editable = (name startsWith "conf"))
119119
val corePackage =
120120
WindowsFeature(
121-
id=WixHelper.cleanStringForId(name + "_core").takeRight(38), // Must be no longer
122-
title=name,
123-
desc="All core files.",
124-
absent="disallow",
125-
components = files
126-
)
121+
id = WixHelper.cleanStringForId(name + "_core").takeRight(38), // Must be no longer
122+
title = name,
123+
desc = "All core files.",
124+
absent = "disallow",
125+
components = files)
127126
// TODO - Detect bat files to add paths...
128127
val addBinToPath =
129128
// TODO - we may have issues here...
130129
WindowsFeature(
131-
id="AddBinToPath",
132-
title="Update Enviornment Variables",
133-
desc="Update PATH environment variables (requires restart).",
134-
components = Seq(AddDirectoryToPath("bin"))
135-
)
130+
id = "AddBinToPath",
131+
title = "Update Enviornment Variables",
132+
desc = "Update PATH environment variables (requires restart).",
133+
components = Seq(AddDirectoryToPath("bin")))
136134
val configLinks = for {
137-
(file, name) <- mappings
138-
if !file.isDirectory
139-
if name startsWith "conf/"
140-
} yield name.replaceAll("//", "/").stripSuffix("/").stripSuffix("/")
135+
(file, name) <- mappings
136+
if !file.isDirectory
137+
if name startsWith "conf/"
138+
} yield name.replaceAll("//", "/").stripSuffix("/").stripSuffix("/")
141139
val menuLinks =
142140
WindowsFeature(
143-
id="AddConfigLinks",
144-
title="Configuration start menu links",
145-
desc="Adds start menu shortcuts to edit configuration files.",
146-
components = Seq(AddShortCuts(configLinks))
147-
)
141+
id = "AddConfigLinks",
142+
title = "Configuration start menu links",
143+
desc = "Adds start menu shortcuts to edit configuration files.",
144+
components = Seq(AddShortCuts(configLinks)))
148145
// TODO - Add feature for shortcuts to binary scripts.
149146
Seq(corePackage, addBinToPath, menuLinks)
150147
}
151-
152-
148+
153149
}

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

+1
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,5 @@ object Keys extends linux.Keys
3131
| """.stripMargin)
3232
val defaultLinuxInstallLocation = SettingKey[String]("defaultLinuxInstallLocation", "The location where we will install generic linux packages.")
3333
val defaultLinuxLogsLocation = SettingKey[String]("defaultLinuxLogsLocation", "The location where application logs will be stored.")
34+
val defaultLinuxConfigLocation = SettingKey[String]("defaultLinuxConfigLocation", "The location where application config files will be stored")
3435
}

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

+7-7
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import Keys._
66
import sbt._
77
import sbt.Project.Initialize
88
import sbt.Keys.{ mappings, target, name, mainClass, normalizedName, sourceDirectory }
9-
import com.typesafe.sbt.packager.linux.{LinuxFileMetaData, LinuxPackageMapping}
9+
import com.typesafe.sbt.packager.linux.{ LinuxFileMetaData, LinuxPackageMapping }
1010
import SbtNativePackager._
1111

1212
/**
@@ -64,9 +64,9 @@ object JavaAppPackaging {
6464
s <- script.toSeq
6565
} yield s -> ("bin/" + name + ".bat")
6666
},
67-
linuxPackageMappings in Debian <+= (normalizedName, defaultLinuxInstallLocation, target in Debian, appUser in Linux, appGroup in Linux) map {
67+
linuxPackageMappings in Debian <+= (normalizedName, defaultLinuxInstallLocation, target in Debian, daemonUser in Linux, daemonGroup in Linux) map {
6868
(name, installLocation, target, user, group) =>
69-
// create empty var/log directory
69+
// create empty var/log directory
7070
val d = target / installLocation
7171
d.mkdirs()
7272
LinuxPackageMapping(Seq(d -> (installLocation + "/" + name)), LinuxFileMetaData(user, group))
@@ -86,8 +86,8 @@ object JavaAppPackaging {
8686
if (defines.isEmpty) None
8787
else {
8888
val defaultTemplateLocation = sourceDir / "templates" / "bash-template"
89-
val scriptBits =
90-
if(defaultTemplateLocation.exists) JavaAppBashScript.generateScript(defines, defaultTemplateLocation.toURI.toURL)
89+
val scriptBits =
90+
if (defaultTemplateLocation.exists) JavaAppBashScript.generateScript(defines, defaultTemplateLocation.toURI.toURL)
9191
else JavaAppBashScript.generateScript(defines)
9292
val script = tmpDir / "tmp" / "bin" / name
9393
IO.write(script, scriptBits)
@@ -100,8 +100,8 @@ object JavaAppPackaging {
100100
if (replacements.isEmpty) None
101101
else {
102102
val defaultTemplateLocation = sourceDir / "templates" / "bat-template"
103-
val scriptBits =
104-
if(defaultTemplateLocation.exists) JavaAppBatScript.generateScript(replacements, defaultTemplateLocation.toURI.toURL)
103+
val scriptBits =
104+
if (defaultTemplateLocation.exists) JavaAppBatScript.generateScript(replacements, defaultTemplateLocation.toURI.toURL)
105105
else JavaAppBatScript.generateScript(replacements)
106106
val script = tmpDir / "tmp" / "bin" / (name + ".bat")
107107
IO.write(script, scriptBits)

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

+3-1
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ object JavaAppStartScript {
8989
chdir: String,
9090
appName: String,
9191
daemonUser: String,
92+
daemonGroup: String,
9293
retries: Int = 0,
9394
retryTimeout: Int = 60): Seq[(String, String)] =
9495
Seq(
@@ -99,7 +100,8 @@ object JavaAppStartScript {
99100
"retries" -> retries.toString,
100101
"retryTimeout" -> retryTimeout.toString,
101102
"app_name" -> appName,
102-
"daemon_user" -> daemonUser)
103+
"daemon_user" -> daemonUser,
104+
"daemon_group" -> daemonGroup)
103105
}
104106

105107
object ServerLoader extends Enumeration {

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

+10-10
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,11 @@ object JavaServerAppPackaging {
2929
def debianSettings: Seq[Setting[_]] =
3030
Seq(
3131
serverLoading := Upstart,
32-
daemonUser <<= appUser in Linux,
3332
// This one is begging for sbt 0.13 syntax...
3433
debianScriptReplacements <<= (
35-
maintainer in Debian, packageSummary in Debian, serverLoading in Debian, daemonUser in Debian, normalizedName,
34+
maintainer in Debian, packageSummary in Debian, serverLoading in Debian, daemonUser in Linux, daemonGroup in Linux, normalizedName,
3635
sbt.Keys.version, defaultLinuxInstallLocation)
37-
map { (author, descr, loader, daemonUser, name, version, installLocation) =>
36+
map { (author, descr, loader, daemonUser, daemonGroup, name, version, installLocation) =>
3837
val appDir = installLocation + "/" + name
3938

4039
JavaAppStartScript.makeReplacements(
@@ -43,7 +42,8 @@ object JavaServerAppPackaging {
4342
execScript = name,
4443
chdir = appDir,
4544
appName = name,
46-
daemonUser = daemonUser)
45+
daemonUser = daemonUser,
46+
daemonGroup = daemonGroup)
4747
},
4848
// TODO - Default locations shouldn't be so hacky.
4949

@@ -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, appUser in Linux, appGroup in Linux)
59-
map { (script, name, loader, owner, ownerGroup) =>
58+
linuxPackageMappings in Debian <++= (debianMakeStartScript, normalizedName, serverLoading in Debian)
59+
map { (script, name, loader) =>
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), LinuxFileMetaData(owner, ownerGroup, permissions, "true"))
66+
} yield LinuxPackageMapping(Seq(s -> path), LinuxFileMetaData(Users.Root, Users.Root, 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, appUser in Linux, appGroup in Linux) map { (conf, name, owner, ownerGroup) =>
79-
conf.map(c => LinuxPackageMapping(Seq(c -> ("/etc/default/" + name)), LinuxFileMetaData(owner, ownerGroup)).withConfig()).toSeq
78+
linuxPackageMappings in Debian <++= (debianMakeEtcDefault, normalizedName) map { (conf, name) =>
79+
conf.map(c => LinuxPackageMapping(Seq(c -> ("/etc/default/" + name)), LinuxFileMetaData(Users.Root, Users.Root)).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, appUser in Linux, appGroup in Linux) map {
84+
linuxPackageMappings in Debian <+= (normalizedName, defaultLinuxLogsLocation, target in Debian, daemonUser in Linux, daemonGroup in Linux) map {
8585
(name, logsDir, target, user, group) =>
8686
// create empty var/log directory
8787
val d = target / logsDir

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

-5
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,7 @@ 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-
def appGroup = linux.Keys.appGroup
89-
9086
//init script parameters
91-
def daemonUser = linux.Keys.daemonUser
9287
def serverLoading = linux.Keys.serverLoading
9388

9489
val debianPackageInstallSize = TaskKey[Long]("debian-installed-size")

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

+3-4
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,13 @@ 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")
15-
val appGroup = SettingKey[String]("app-group", "The group owner of the files in the package")
1614
val daemonUser = SettingKey[String]("daemon-user", "User to start application daemon")
15+
val daemonGroup = SettingKey[String]("daemon-group", "Group to start application daemon")
1716
val serverLoading = SettingKey[ServerLoader]("server-loader", "Loading system to be used for application start script")
1817
val linuxPackageMappings = TaskKey[Seq[LinuxPackageMapping]]("linux-package-mappings", "File to install location mappings including owner and privileges.")
1918
val linuxPackageSymlinks = TaskKey[Seq[LinuxSymlink]]("linux-package-symlinks", "Symlinks we should produce in the underlying package.")
20-
val generateManPages = TaskKey[Unit]("generate-man-pages", "Shows all the man files in the current project")
21-
19+
val generateManPages = TaskKey[Unit]("generate-man-pages", "Shows all the man files in the current project")
20+
2221
val linuxStartScriptTemplate = TaskKey[URL]("linuxStartScriptTemplate", "The location of the template start script file we use for debian (upstart or init.d")
2322
val linuxEtcDefaultTemplate = TaskKey[URL]("linuxEtcDefaultTemplate", "The location of the /etc/default/<pkg> template script.")
2423
}

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ trait LinuxPlugin extends Plugin {
2828
},
2929
packageSummary in Linux <<= packageSummary,
3030
packageDescription in Linux <<= packageDescription,
31-
appUser <<= normalizedName, appGroup <<= appUser in Linux)
31+
daemonUser in Linux <<= normalizedName,
32+
daemonGroup <<= daemonUser in Linux)
3233

3334
/** DSL for packaging files into .deb */
3435
def packageMapping(files: (File, String)*) = LinuxPackageMapping(files)

0 commit comments

Comments
 (0)