Merge changes from topic "canned_fs_config" am: ae9cf26353
Original change: https://android-review.googlesource.com/c/platform/build/soong/+/1918606 Change-Id: I410b8879fe424c4ad5a70b8b5ef94166f241b83b
This commit is contained in:
@@ -96,6 +96,14 @@ type apexBundleProperties struct {
|
||||
// /system/sepolicy/apex/<module_name>_file_contexts.
|
||||
File_contexts *string `android:"path"`
|
||||
|
||||
// Path to the canned fs config file for customizing file's uid/gid/mod/capabilities. The
|
||||
// format is /<path_or_glob> <uid> <gid> <mode> [capabilities=0x<cap>], where path_or_glob is a
|
||||
// path or glob pattern for a file or set of files, uid/gid are numerial values of user ID
|
||||
// and group ID, mode is octal value for the file mode, and cap is hexadecimal value for the
|
||||
// capability. If this property is not set, or a file is missing in the file, default config
|
||||
// is used.
|
||||
Canned_fs_config *string `android:"path"`
|
||||
|
||||
ApexNativeDependencies
|
||||
|
||||
Multilib apexMultilibProperties
|
||||
|
@@ -2581,22 +2581,21 @@ func TestFilesInSubDir(t *testing.T) {
|
||||
`)
|
||||
|
||||
generateFsRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("generateFsConfig")
|
||||
dirs := strings.Split(generateFsRule.Args["exec_paths"], " ")
|
||||
cmd := generateFsRule.RuleParams.Command
|
||||
|
||||
// Ensure that the subdirectories are all listed
|
||||
ensureListContains(t, dirs, "etc")
|
||||
ensureListContains(t, dirs, "etc/foo")
|
||||
ensureListContains(t, dirs, "etc/foo/bar")
|
||||
ensureListContains(t, dirs, "lib64")
|
||||
ensureListContains(t, dirs, "lib64/foo")
|
||||
ensureListContains(t, dirs, "lib64/foo/bar")
|
||||
ensureListContains(t, dirs, "lib")
|
||||
ensureListContains(t, dirs, "lib/foo")
|
||||
ensureListContains(t, dirs, "lib/foo/bar")
|
||||
|
||||
ensureListContains(t, dirs, "bin")
|
||||
ensureListContains(t, dirs, "bin/foo")
|
||||
ensureListContains(t, dirs, "bin/foo/bar")
|
||||
ensureContains(t, cmd, "/etc ")
|
||||
ensureContains(t, cmd, "/etc/foo ")
|
||||
ensureContains(t, cmd, "/etc/foo/bar ")
|
||||
ensureContains(t, cmd, "/lib64 ")
|
||||
ensureContains(t, cmd, "/lib64/foo ")
|
||||
ensureContains(t, cmd, "/lib64/foo/bar ")
|
||||
ensureContains(t, cmd, "/lib ")
|
||||
ensureContains(t, cmd, "/lib/foo ")
|
||||
ensureContains(t, cmd, "/lib/foo/bar ")
|
||||
ensureContains(t, cmd, "/bin ")
|
||||
ensureContains(t, cmd, "/bin/foo ")
|
||||
ensureContains(t, cmd, "/bin/foo/bar ")
|
||||
}
|
||||
|
||||
func TestFilesInSubDirWhenNativeBridgeEnabled(t *testing.T) {
|
||||
|
123
apex/builder.go
123
apex/builder.go
@@ -72,19 +72,6 @@ func init() {
|
||||
}
|
||||
|
||||
var (
|
||||
// Create a canned fs config file where all files and directories are
|
||||
// by default set to (uid/gid/mode) = (1000/1000/0644)
|
||||
// TODO(b/113082813) make this configurable using config.fs syntax
|
||||
generateFsConfig = pctx.StaticRule("generateFsConfig", blueprint.RuleParams{
|
||||
Command: `( set -e; echo '/ 1000 1000 0755' ` +
|
||||
`&& for i in ${ro_paths}; do echo "/$$i 1000 1000 0644"; done ` +
|
||||
`&& for i in ${exec_paths}; do echo "/$$i 0 2000 0755"; done ` +
|
||||
`&& ( tr ' ' '\n' <${out}.apklist | for i in ${apk_paths}; do read apk; echo "/$$i 0 2000 0755"; zipinfo -1 $$apk | sed "s:\(.*\):/$$i/\1 1000 1000 0644:"; done ) ) > ${out}`,
|
||||
Description: "fs_config ${out}",
|
||||
Rspfile: "$out.apklist",
|
||||
RspfileContent: "$in",
|
||||
}, "ro_paths", "exec_paths", "apk_paths")
|
||||
|
||||
apexManifestRule = pctx.StaticRule("apexManifestRule", blueprint.RuleParams{
|
||||
Command: `rm -f $out && ${jsonmodify} $in ` +
|
||||
`-a provideNativeLibs ${provideNativeLibs} ` +
|
||||
@@ -583,55 +570,11 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) {
|
||||
// Figure out if need to compress apex.
|
||||
compressionEnabled := ctx.Config().CompressedApex() && proptools.BoolDefault(a.properties.Compressible, false) && !a.testApex && !ctx.Config().UnbundledBuildApps()
|
||||
if apexType == imageApex {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Step 2: create canned_fs_config which encodes filemode,uid,gid of each files
|
||||
// in this APEX. The file will be used by apexer in later steps.
|
||||
// TODO(jiyong): make this as a function
|
||||
// TODO(jiyong): use the RuleBuilder
|
||||
var readOnlyPaths = []string{"apex_manifest.json", "apex_manifest.pb"}
|
||||
var executablePaths []string // this also includes dirs
|
||||
var extractedAppSetPaths android.Paths
|
||||
var extractedAppSetDirs []string
|
||||
for _, f := range a.filesInfo {
|
||||
pathInApex := f.path()
|
||||
if f.installDir == "bin" || strings.HasPrefix(f.installDir, "bin/") {
|
||||
executablePaths = append(executablePaths, pathInApex)
|
||||
for _, d := range f.dataPaths {
|
||||
readOnlyPaths = append(readOnlyPaths, filepath.Join(f.installDir, d.RelativeInstallPath, d.SrcPath.Rel()))
|
||||
}
|
||||
for _, s := range f.symlinks {
|
||||
executablePaths = append(executablePaths, filepath.Join(f.installDir, s))
|
||||
}
|
||||
} else if f.class == appSet {
|
||||
extractedAppSetPaths = append(extractedAppSetPaths, f.builtFile)
|
||||
extractedAppSetDirs = append(extractedAppSetDirs, f.installDir)
|
||||
} else {
|
||||
readOnlyPaths = append(readOnlyPaths, pathInApex)
|
||||
}
|
||||
dir := f.installDir
|
||||
for !android.InList(dir, executablePaths) && dir != "" {
|
||||
executablePaths = append(executablePaths, dir)
|
||||
dir, _ = filepath.Split(dir) // move up to the parent
|
||||
if len(dir) > 0 {
|
||||
// remove trailing slash
|
||||
dir = dir[:len(dir)-1]
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Strings(readOnlyPaths)
|
||||
sort.Strings(executablePaths)
|
||||
cannedFsConfig := android.PathForModuleOut(ctx, "canned_fs_config")
|
||||
ctx.Build(pctx, android.BuildParams{
|
||||
Rule: generateFsConfig,
|
||||
Output: cannedFsConfig,
|
||||
Description: "generate fs config",
|
||||
Inputs: extractedAppSetPaths,
|
||||
Args: map[string]string{
|
||||
"ro_paths": strings.Join(readOnlyPaths, " "),
|
||||
"exec_paths": strings.Join(executablePaths, " "),
|
||||
"apk_paths": strings.Join(extractedAppSetDirs, " "),
|
||||
},
|
||||
})
|
||||
cannedFsConfig := a.buildCannedFsConfig(ctx)
|
||||
implicitInputs = append(implicitInputs, cannedFsConfig)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -1072,3 +1015,65 @@ func (a *apexBundle) buildLintReports(ctx android.ModuleContext) {
|
||||
|
||||
a.lintReports = java.BuildModuleLintReportZips(ctx, depSetsBuilder.Build())
|
||||
}
|
||||
|
||||
func (a *apexBundle) buildCannedFsConfig(ctx android.ModuleContext) android.OutputPath {
|
||||
var readOnlyPaths = []string{"apex_manifest.json", "apex_manifest.pb"}
|
||||
var executablePaths []string // this also includes dirs
|
||||
var appSetDirs []string
|
||||
appSetFiles := make(map[string]android.Path)
|
||||
for _, f := range a.filesInfo {
|
||||
pathInApex := f.path()
|
||||
if f.installDir == "bin" || strings.HasPrefix(f.installDir, "bin/") {
|
||||
executablePaths = append(executablePaths, pathInApex)
|
||||
for _, d := range f.dataPaths {
|
||||
readOnlyPaths = append(readOnlyPaths, filepath.Join(f.installDir, d.RelativeInstallPath, d.SrcPath.Rel()))
|
||||
}
|
||||
for _, s := range f.symlinks {
|
||||
executablePaths = append(executablePaths, filepath.Join(f.installDir, s))
|
||||
}
|
||||
} else if f.class == appSet {
|
||||
appSetDirs = append(appSetDirs, f.installDir)
|
||||
appSetFiles[f.installDir] = f.builtFile
|
||||
} else {
|
||||
readOnlyPaths = append(readOnlyPaths, pathInApex)
|
||||
}
|
||||
dir := f.installDir
|
||||
for !android.InList(dir, executablePaths) && dir != "" {
|
||||
executablePaths = append(executablePaths, dir)
|
||||
dir, _ = filepath.Split(dir) // move up to the parent
|
||||
if len(dir) > 0 {
|
||||
// remove trailing slash
|
||||
dir = dir[:len(dir)-1]
|
||||
}
|
||||
}
|
||||
}
|
||||
sort.Strings(readOnlyPaths)
|
||||
sort.Strings(executablePaths)
|
||||
sort.Strings(appSetDirs)
|
||||
|
||||
cannedFsConfig := android.PathForModuleOut(ctx, "canned_fs_config")
|
||||
builder := android.NewRuleBuilder(pctx, ctx)
|
||||
cmd := builder.Command()
|
||||
cmd.Text("(")
|
||||
cmd.Text("echo '/ 1000 1000 0755';")
|
||||
for _, p := range readOnlyPaths {
|
||||
cmd.Textf("echo '/%s 1000 1000 0644';", p)
|
||||
}
|
||||
for _, p := range executablePaths {
|
||||
cmd.Textf("echo '/%s 0 2000 0755';", p)
|
||||
}
|
||||
for _, dir := range appSetDirs {
|
||||
cmd.Textf("echo '/%s 0 2000 0755';", dir)
|
||||
file := appSetFiles[dir]
|
||||
cmd.Text("zipinfo -1").Input(file).Textf(`| sed "s:\(.*\):/%s/\1 1000 1000 0644:";`, dir)
|
||||
}
|
||||
// Custom fs_config is "appended" to the last so that entries from the file are preferred
|
||||
// over default ones set above.
|
||||
if a.properties.Canned_fs_config != nil {
|
||||
cmd.Text("cat").Input(android.PathForModuleSrc(ctx, *a.properties.Canned_fs_config))
|
||||
}
|
||||
cmd.Text(")").FlagWithOutput("> ", cannedFsConfig)
|
||||
builder.Build("generateFsConfig", fmt.Sprintf("Generating canned fs config for %s", a.BaseModuleName()))
|
||||
|
||||
return cannedFsConfig.OutputPath
|
||||
}
|
||||
|
Reference in New Issue
Block a user