Merge changes from topic "fix-apexkeys" into main

* changes:
  Rewrite how to generate apexkeys.txt
  Refactor around apexKeysText singleton
This commit is contained in:
Jooyung Han
2023-11-01 05:13:06 +00:00
committed by Gerrit Code Review
6 changed files with 69 additions and 93 deletions

View File

@@ -260,6 +260,7 @@ func (a *apexBundle) androidMkForType() android.AndroidMkData {
fmt.Fprintln(w, "LOCAL_SOONG_INSTALL_PAIRS :=", a.outputFile.String()+":"+a.installedFile.String()) fmt.Fprintln(w, "LOCAL_SOONG_INSTALL_PAIRS :=", a.outputFile.String()+":"+a.installedFile.String())
fmt.Fprintln(w, "LOCAL_SOONG_INSTALL_SYMLINKS := ", strings.Join(a.compatSymlinks.Strings(), " ")) fmt.Fprintln(w, "LOCAL_SOONG_INSTALL_SYMLINKS := ", strings.Join(a.compatSymlinks.Strings(), " "))
} }
fmt.Fprintln(w, "LOCAL_APEX_KEY_PATH := ", a.apexKeysPath.String())
// Because apex writes .mk with Custom(), we need to write manually some common properties // Because apex writes .mk with Custom(), we need to write manually some common properties
// which are available via data.Entries // which are available via data.Entries

View File

@@ -454,6 +454,9 @@ type apexBundle struct {
// Path where this APEX was installed. // Path where this APEX was installed.
installedFile android.InstallPath installedFile android.InstallPath
// fragment for this apex for apexkeys.txt
apexKeysPath android.WritablePath
// Installed locations of symlinks for backward compatibility. // Installed locations of symlinks for backward compatibility.
compatSymlinks android.InstallPaths compatSymlinks android.InstallPaths
@@ -1923,6 +1926,7 @@ func (a *apexBundle) ProcessBazelQueryResponse(ctx android.ModuleContext) {
a.filesInfo = append(a.filesInfo, fileInfo) a.filesInfo = append(a.filesInfo, fileInfo)
} }
a.apexKeysPath = writeApexKeys(ctx, a)
} }
func (a *apexBundle) setCompression(ctx android.ModuleContext) { func (a *apexBundle) setCompression(ctx android.ModuleContext) {

View File

@@ -9089,8 +9089,8 @@ func TestApexKeysTxt(t *testing.T) {
} }
`) `)
apexKeysText := ctx.SingletonForTests("apex_keys_text") myapex := ctx.ModuleForTests("myapex", "android_common_myapex")
content := apexKeysText.MaybeDescription("apexkeys.txt").BuildParams.Args["content"] content := myapex.Output("apexkeys.txt").BuildParams.Args["content"]
ensureContains(t, content, `name="myapex.apex" public_key="vendor/foo/devkeys/testkey.avbpubkey" private_key="vendor/foo/devkeys/testkey.pem" container_certificate="vendor/foo/devkeys/test.x509.pem" container_private_key="vendor/foo/devkeys/test.pk8" partition="system" sign_tool="sign_myapex"`) ensureContains(t, content, `name="myapex.apex" public_key="vendor/foo/devkeys/testkey.avbpubkey" private_key="vendor/foo/devkeys/testkey.pem" container_certificate="vendor/foo/devkeys/test.x509.pem" container_private_key="vendor/foo/devkeys/test.pk8" partition="system" sign_tool="sign_myapex"`)
} }
@@ -9130,10 +9130,10 @@ func TestApexKeysTxtOverrides(t *testing.T) {
} }
`) `)
apexKeysText := ctx.SingletonForTests("apex_keys_text") content := ctx.ModuleForTests("myapex", "android_common_myapex").Output("apexkeys.txt").BuildParams.Args["content"]
content := apexKeysText.MaybeDescription("apexkeys.txt").BuildParams.Args["content"] ensureContains(t, content, `name="myapex.apex" public_key="vendor/foo/devkeys/testkey.avbpubkey" private_key="vendor/foo/devkeys/testkey.pem" container_certificate="vendor/foo/devkeys/test.x509.pem" container_private_key="vendor/foo/devkeys/test.pk8" partition="system" sign_tool="sign_myapex"`)
content = ctx.ModuleForTests("myapex_set", "android_common_myapex_set").Output("apexkeys.txt").BuildParams.Args["content"]
ensureContains(t, content, `name="myapex_set.apex" public_key="PRESIGNED" private_key="PRESIGNED" container_certificate="PRESIGNED" container_private_key="PRESIGNED" partition="system"`) ensureContains(t, content, `name="myapex_set.apex" public_key="PRESIGNED" private_key="PRESIGNED" container_certificate="PRESIGNED" container_private_key="PRESIGNED" partition="system"`)
ensureContains(t, content, `name="myapex.apex" public_key="PRESIGNED" private_key="PRESIGNED" container_certificate="PRESIGNED" container_private_key="PRESIGNED" partition="system"`)
} }
func TestAllowedFiles(t *testing.T) { func TestAllowedFiles(t *testing.T) {

View File

@@ -948,6 +948,8 @@ func (a *apexBundle) buildApex(ctx android.ModuleContext) {
// installed-files.txt is dist'ed // installed-files.txt is dist'ed
a.installedFilesFile = a.buildInstalledFilesFile(ctx, a.outputFile, imageDir) a.installedFilesFile = a.buildInstalledFilesFile(ctx, a.outputFile, imageDir)
a.apexKeysPath = writeApexKeys(ctx, a)
} }
// getCertificateAndPrivateKey retrieves the cert and the private key that will be used to sign // getCertificateAndPrivateKey retrieves the cert and the private key that will be used to sign

View File

@@ -16,8 +16,6 @@ package apex
import ( import (
"fmt" "fmt"
"sort"
"strings"
"android/soong/android" "android/soong/android"
"android/soong/bazel" "android/soong/bazel"
@@ -33,7 +31,6 @@ func init() {
func registerApexKeyBuildComponents(ctx android.RegistrationContext) { func registerApexKeyBuildComponents(ctx android.RegistrationContext) {
ctx.RegisterModuleType("apex_key", ApexKeyFactory) ctx.RegisterModuleType("apex_key", ApexKeyFactory)
ctx.RegisterParallelSingletonType("apex_keys_text", apexKeysTextFactory)
} }
type apexKey struct { type apexKey struct {
@@ -102,14 +99,6 @@ func (m *apexKey) GenerateAndroidBuildActions(ctx android.ModuleContext) {
} }
} }
// //////////////////////////////////////////////////////////////////////
// apex_keys_text
type apexKeysText struct {
output android.OutputPath
}
func (s *apexKeysText) GenerateBuildActions(ctx android.SingletonContext) {
s.output = android.PathForOutput(ctx, "apexkeys.txt")
type apexKeyEntry struct { type apexKeyEntry struct {
name string name string
presigned bool presigned bool
@@ -120,7 +109,8 @@ func (s *apexKeysText) GenerateBuildActions(ctx android.SingletonContext) {
partition string partition string
signTool string signTool string
} }
toString := func(e apexKeyEntry) string {
func (e apexKeyEntry) String() string {
signTool := "" signTool := ""
if e.signTool != "" { if e.signTool != "" {
signTool = fmt.Sprintf(" sign_tool=%q", e.signTool) signTool = fmt.Sprintf(" sign_tool=%q", e.signTool)
@@ -133,11 +123,11 @@ func (s *apexKeysText) GenerateBuildActions(ctx android.SingletonContext) {
} }
} }
apexKeyMap := make(map[string]apexKeyEntry) func apexKeyEntryFor(ctx android.ModuleContext, module android.Module) apexKeyEntry {
ctx.VisitAllModules(func(module android.Module) { switch m := module.(type) {
if m, ok := module.(*apexBundle); ok && m.Enabled() && m.installable() { case *apexBundle:
pem, key := m.getCertificateAndPrivateKey(ctx) pem, key := m.getCertificateAndPrivateKey(ctx)
apexKeyMap[m.Name()] = apexKeyEntry{ return apexKeyEntry{
name: m.Name() + ".apex", name: m.Name() + ".apex",
presigned: false, presigned: false,
publicKey: m.publicKeyFile.String(), publicKey: m.publicKeyFile.String(),
@@ -147,54 +137,27 @@ func (s *apexKeysText) GenerateBuildActions(ctx android.SingletonContext) {
partition: m.PartitionTag(ctx.DeviceConfig()), partition: m.PartitionTag(ctx.DeviceConfig()),
signTool: proptools.String(m.properties.Custom_sign_tool), signTool: proptools.String(m.properties.Custom_sign_tool),
} }
case *Prebuilt:
return apexKeyEntry{
name: m.InstallFilename(),
presigned: true,
partition: m.PartitionTag(ctx.DeviceConfig()),
} }
}) case *ApexSet:
return apexKeyEntry{
// Find prebuilts and let them override apexBundle if they are preferred
ctx.VisitAllModules(func(module android.Module) {
if m, ok := module.(*Prebuilt); ok && m.Enabled() && m.installable() &&
m.Prebuilt().UsePrebuilt() {
apexKeyMap[m.BaseModuleName()] = apexKeyEntry{
name: m.InstallFilename(), name: m.InstallFilename(),
presigned: true, presigned: true,
partition: m.PartitionTag(ctx.DeviceConfig()), partition: m.PartitionTag(ctx.DeviceConfig()),
} }
} }
}) panic(fmt.Errorf("unknown type(%t) for apexKeyEntry", module))
// Find apex_set and let them override apexBundle or prebuilts. This is done in a separate pass
// so that apex_set are not overridden by prebuilts.
ctx.VisitAllModules(func(module android.Module) {
if m, ok := module.(*ApexSet); ok && m.Enabled() {
entry := apexKeyEntry{
name: m.InstallFilename(),
presigned: true,
partition: m.PartitionTag(ctx.DeviceConfig()),
}
apexKeyMap[m.BaseModuleName()] = entry
}
})
// iterating over map does not give consistent ordering in golang
var moduleNames []string
for key, _ := range apexKeyMap {
moduleNames = append(moduleNames, key)
}
sort.Strings(moduleNames)
var filecontent strings.Builder
for _, name := range moduleNames {
filecontent.WriteString(toString(apexKeyMap[name]))
}
android.WriteFileRule(ctx, s.output, filecontent.String())
} }
func apexKeysTextFactory() android.Singleton { func writeApexKeys(ctx android.ModuleContext, module android.Module) android.WritablePath {
return &apexKeysText{} path := android.PathForModuleOut(ctx, "apexkeys.txt")
} entry := apexKeyEntryFor(ctx, module)
android.WriteFileRuleVerbatim(ctx, path, entry.String())
func (s *apexKeysText) MakeVars(ctx android.MakeVarsContext) { return path
ctx.Strict("SOONG_APEX_KEYS_FILE", s.output.String())
} }
// For Bazel / bp2build // For Bazel / bp2build

View File

@@ -60,6 +60,9 @@ type prebuiltCommon struct {
installedFile android.InstallPath installedFile android.InstallPath
outputApex android.WritablePath outputApex android.WritablePath
// fragment for this apex for apexkeys.txt
apexKeysPath android.WritablePath
// A list of apexFile objects created in prebuiltCommon.initApexFilesForAndroidMk which are used // A list of apexFile objects created in prebuiltCommon.initApexFilesForAndroidMk which are used
// to create make modules in prebuiltCommon.AndroidMkEntries. // to create make modules in prebuiltCommon.AndroidMkEntries.
apexFilesForAndroidMk []apexFile apexFilesForAndroidMk []apexFile
@@ -238,6 +241,7 @@ func (p *prebuiltCommon) AndroidMkEntries() []android.AndroidMkEntries {
entries.AddStrings("LOCAL_SOONG_INSTALL_SYMLINKS", p.compatSymlinks.Strings()...) entries.AddStrings("LOCAL_SOONG_INSTALL_SYMLINKS", p.compatSymlinks.Strings()...)
entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", !p.installable()) entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", !p.installable())
entries.AddStrings("LOCAL_OVERRIDES_MODULES", p.prebuiltCommonProperties.Overrides...) entries.AddStrings("LOCAL_OVERRIDES_MODULES", p.prebuiltCommonProperties.Overrides...)
entries.SetString("LOCAL_APEX_KEY_PATH", p.apexKeysPath.String())
p.addRequiredModules(entries) p.addRequiredModules(entries)
}, },
}, },
@@ -759,6 +763,7 @@ func (p *Prebuilt) ApexInfoMutator(mctx android.TopDownMutatorContext) {
} }
func (p *Prebuilt) GenerateAndroidBuildActions(ctx android.ModuleContext) { func (p *Prebuilt) GenerateAndroidBuildActions(ctx android.ModuleContext) {
p.apexKeysPath = writeApexKeys(ctx, p)
// TODO(jungjw): Check the key validity. // TODO(jungjw): Check the key validity.
p.inputApex = android.OptionalPathForModuleSrc(ctx, p.prebuiltCommonProperties.Selected_apex).Path() p.inputApex = android.OptionalPathForModuleSrc(ctx, p.prebuiltCommonProperties.Selected_apex).Path()
p.installDir = android.PathForModuleInstall(ctx, "apex") p.installDir = android.PathForModuleInstall(ctx, "apex")
@@ -975,6 +980,7 @@ func (a *ApexSet) ApexInfoMutator(mctx android.TopDownMutatorContext) {
} }
func (a *ApexSet) GenerateAndroidBuildActions(ctx android.ModuleContext) { func (a *ApexSet) GenerateAndroidBuildActions(ctx android.ModuleContext) {
a.apexKeysPath = writeApexKeys(ctx, a)
a.installFilename = a.InstallFilename() a.installFilename = a.InstallFilename()
if !strings.HasSuffix(a.installFilename, imageApexSuffix) && !strings.HasSuffix(a.installFilename, imageCapexSuffix) { if !strings.HasSuffix(a.installFilename, imageApexSuffix) && !strings.HasSuffix(a.installFilename, imageCapexSuffix) {
ctx.ModuleErrorf("filename should end in %s or %s for apex_set", imageApexSuffix, imageCapexSuffix) ctx.ModuleErrorf("filename should end in %s or %s for apex_set", imageApexSuffix, imageCapexSuffix)