diff options
author | 2024-08-30 20:18:53 +0000 | |
---|---|---|
committer | 2024-08-30 20:18:53 +0000 | |
commit | 7344482ff3e38659519ca63ebc9b3f78ce6d4d8e (patch) | |
tree | b78ed3eef62c71b43172a5f58307e4f32fc449eb /android/container.go | |
parent | c540beef74e30cf30a4a1cc3f250b2ddbe45ad42 (diff) | |
parent | 85bc19380567dfee327f04162587633673e3dcf7 (diff) |
Merge "Revert^4 "Implement detecting container violations."" into main
Diffstat (limited to 'android/container.go')
-rw-r--r-- | android/container.go | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/android/container.go b/android/container.go index 722b241c1..c048d6c73 100644 --- a/android/container.go +++ b/android/container.go @@ -15,8 +15,10 @@ package android import ( + "fmt" "reflect" "slices" + "strings" "github.com/google/blueprint" ) @@ -398,6 +400,40 @@ func (c *ContainersInfo) UpdatableApex() bool { var ContainersInfoProvider = blueprint.NewProvider[ContainersInfo]() +func satisfyAllowedExceptions(ctx ModuleContext, allowedExceptionLabels []exceptionHandleFuncLabel, m, dep Module) bool { + for _, label := range allowedExceptionLabels { + if exceptionHandleFunctionsTable[label](ctx, m, dep) { + return true + } + } + return false +} + +func (c *ContainersInfo) GetViolations(mctx ModuleContext, m, dep Module, depInfo ContainersInfo) []string { + var violations []string + + // Any containers that the module belongs to but the dependency does not belong to must be examined. + _, containersUniqueToModule, _ := ListSetDifference(c.belongingContainers, depInfo.belongingContainers) + + // Apex container should be examined even if both the module and the dependency belong to + // the apex container to check that the two modules belong to the same apex. + if InList(ApexContainer, c.belongingContainers) && !InList(ApexContainer, containersUniqueToModule) { + containersUniqueToModule = append(containersUniqueToModule, ApexContainer) + } + + for _, containerUniqueToModule := range containersUniqueToModule { + for _, restriction := range containerUniqueToModule.restricted { + if InList(restriction.dependency, depInfo.belongingContainers) { + if !satisfyAllowedExceptions(mctx, restriction.allowedExceptions, m, dep) { + violations = append(violations, restriction.errorMessage) + } + } + } + } + + return violations +} + func generateContainerInfo(ctx ModuleContext) ContainersInfo { var containers []*container @@ -439,3 +475,32 @@ func setContainerInfo(ctx ModuleContext) { SetProvider(ctx, ContainersInfoProvider, containersInfo) } } + +func checkContainerViolations(ctx ModuleContext) { + if _, ok := ctx.Module().(InstallableModule); ok { + containersInfo, _ := getContainerModuleInfo(ctx, ctx.Module()) + ctx.VisitDirectDepsIgnoreBlueprint(func(dep Module) { + if !dep.Enabled(ctx) { + return + } + + // Pre-existing violating dependencies are tracked in containerDependencyViolationAllowlist. + // If this dependency is allowlisted, do not check for violation. + // If not, check if this dependency matches any restricted dependency and + // satisfies any exception functions, which allows bypassing the + // restriction. If all of the exceptions are not satisfied, throw an error. + if depContainersInfo, ok := getContainerModuleInfo(ctx, dep); ok { + if allowedViolations, ok := ContainerDependencyViolationAllowlist[ctx.ModuleName()]; ok && InList(dep.Name(), allowedViolations) { + return + } else { + violations := containersInfo.GetViolations(ctx, ctx.Module(), dep, depContainersInfo) + if len(violations) > 0 { + errorMessage := fmt.Sprintf("%s cannot depend on %s. ", ctx.ModuleName(), dep.Name()) + errorMessage += strings.Join(violations, " ") + ctx.ModuleErrorf(errorMessage) + } + } + } + }) + } +} |