Skip to content

Commit cafd8d2

Browse files
authored
Merge branch 'main' into read-failure-store-privilege-role-building
2 parents f6b6cfb + 877963c commit cafd8d2

File tree

35 files changed

+663
-401
lines changed

35 files changed

+663
-401
lines changed
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
package org.elasticsearch.gradle.internal.dependencies.patches.hdfs;
11+
12+
import org.gradle.api.artifacts.transform.CacheableTransform;
13+
import org.gradle.api.artifacts.transform.InputArtifact;
14+
import org.gradle.api.artifacts.transform.TransformAction;
15+
import org.gradle.api.artifacts.transform.TransformOutputs;
16+
import org.gradle.api.artifacts.transform.TransformParameters;
17+
import org.gradle.api.file.FileSystemLocation;
18+
import org.gradle.api.provider.Provider;
19+
import org.gradle.api.tasks.Classpath;
20+
import org.gradle.api.tasks.Input;
21+
import org.gradle.api.tasks.Optional;
22+
import org.jetbrains.annotations.NotNull;
23+
import org.objectweb.asm.ClassReader;
24+
import org.objectweb.asm.ClassVisitor;
25+
import org.objectweb.asm.ClassWriter;
26+
27+
import java.io.File;
28+
import java.io.FileOutputStream;
29+
import java.io.IOException;
30+
import java.io.InputStream;
31+
import java.util.Enumeration;
32+
import java.util.HashMap;
33+
import java.util.List;
34+
import java.util.Locale;
35+
import java.util.Map;
36+
import java.util.function.Function;
37+
import java.util.jar.JarEntry;
38+
import java.util.jar.JarFile;
39+
import java.util.jar.JarOutputStream;
40+
import java.util.regex.Pattern;
41+
42+
import static java.util.Map.entry;
43+
44+
@CacheableTransform
45+
public abstract class HdfsClassPatcher implements TransformAction<HdfsClassPatcher.Parameters> {
46+
47+
record JarPatchers(String artifactTag, Pattern artifactPattern, Map<String, Function<ClassWriter, ClassVisitor>> jarPatchers) {}
48+
49+
static final List<JarPatchers> allPatchers = List.of(
50+
new JarPatchers(
51+
"hadoop-common",
52+
Pattern.compile("hadoop-common-(?!.*tests)"),
53+
Map.ofEntries(
54+
entry("org/apache/hadoop/util/ShutdownHookManager.class", ShutdownHookManagerPatcher::new),
55+
entry("org/apache/hadoop/util/Shell.class", ShellPatcher::new),
56+
entry("org/apache/hadoop/security/UserGroupInformation.class", SubjectGetSubjectPatcher::new)
57+
)
58+
),
59+
new JarPatchers(
60+
"hadoop-client-api",
61+
Pattern.compile("hadoop-client-api.*"),
62+
Map.ofEntries(
63+
entry("org/apache/hadoop/util/ShutdownHookManager.class", ShutdownHookManagerPatcher::new),
64+
entry("org/apache/hadoop/util/Shell.class", ShellPatcher::new),
65+
entry("org/apache/hadoop/security/UserGroupInformation.class", SubjectGetSubjectPatcher::new),
66+
entry("org/apache/hadoop/security/authentication/client/KerberosAuthenticator.class", SubjectGetSubjectPatcher::new)
67+
)
68+
)
69+
);
70+
71+
interface Parameters extends TransformParameters {
72+
@Input
73+
@Optional
74+
List<String> getMatchingArtifacts();
75+
76+
void setMatchingArtifacts(List<String> matchingArtifacts);
77+
}
78+
79+
@Classpath
80+
@InputArtifact
81+
public abstract Provider<FileSystemLocation> getInputArtifact();
82+
83+
@Override
84+
public void transform(@NotNull TransformOutputs outputs) {
85+
File inputFile = getInputArtifact().get().getAsFile();
86+
87+
List<String> matchingArtifacts = getParameters().getMatchingArtifacts();
88+
List<JarPatchers> patchersToApply = allPatchers.stream()
89+
.filter(jp -> matchingArtifacts.contains(jp.artifactTag()) && jp.artifactPattern().matcher(inputFile.getName()).find())
90+
.toList();
91+
if (patchersToApply.isEmpty()) {
92+
outputs.file(getInputArtifact());
93+
} else {
94+
patchersToApply.forEach(patchers -> {
95+
System.out.println("Patching " + inputFile.getName());
96+
97+
Map<String, Function<ClassWriter, ClassVisitor>> jarPatchers = new HashMap<>(patchers.jarPatchers());
98+
File outputFile = outputs.file(inputFile.getName().replace(".jar", "-patched.jar"));
99+
100+
patchJar(inputFile, outputFile, jarPatchers);
101+
102+
if (jarPatchers.isEmpty() == false) {
103+
throw new IllegalArgumentException(
104+
String.format(
105+
Locale.ROOT,
106+
"error patching [%s] with [%s]: the jar does not contain [%s]",
107+
inputFile.getName(),
108+
patchers.artifactPattern().toString(),
109+
String.join(", ", jarPatchers.keySet())
110+
)
111+
);
112+
}
113+
});
114+
}
115+
}
116+
117+
private static void patchJar(File inputFile, File outputFile, Map<String, Function<ClassWriter, ClassVisitor>> jarPatchers) {
118+
try (JarFile jarFile = new JarFile(inputFile); JarOutputStream jos = new JarOutputStream(new FileOutputStream(outputFile))) {
119+
Enumeration<JarEntry> entries = jarFile.entries();
120+
while (entries.hasMoreElements()) {
121+
JarEntry entry = entries.nextElement();
122+
String entryName = entry.getName();
123+
// Add the entry to the new JAR file
124+
jos.putNextEntry(new JarEntry(entryName));
125+
126+
Function<ClassWriter, ClassVisitor> classPatcher = jarPatchers.remove(entryName);
127+
if (classPatcher != null) {
128+
byte[] classToPatch = jarFile.getInputStream(entry).readAllBytes();
129+
130+
ClassReader classReader = new ClassReader(classToPatch);
131+
ClassWriter classWriter = new ClassWriter(classReader, 0);
132+
classReader.accept(classPatcher.apply(classWriter), 0);
133+
134+
jos.write(classWriter.toByteArray());
135+
} else {
136+
// Read the entry's data and write it to the new JAR
137+
try (InputStream is = jarFile.getInputStream(entry)) {
138+
is.transferTo(jos);
139+
}
140+
}
141+
jos.closeEntry();
142+
}
143+
} catch (IOException ex) {
144+
throw new RuntimeException(ex);
145+
}
146+
}
147+
}

plugins/repository-hdfs/hadoop-client-api/src/patcher/java/org/elasticsearch/hdfs/patch/MethodReplacement.java renamed to build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/dependencies/patches/hdfs/MethodReplacement.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* License v3.0 only", or the "Server Side Public License, v 1".
88
*/
99

10-
package org.elasticsearch.hdfs.patch;
10+
package org.elasticsearch.gradle.internal.dependencies.patches.hdfs;
1111

1212
import org.objectweb.asm.MethodVisitor;
1313
import org.objectweb.asm.Opcodes;

plugins/repository-hdfs/hadoop-client-api/src/patcher/java/org/elasticsearch/hdfs/patch/ShellPatcher.java renamed to build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/dependencies/patches/hdfs/ShellPatcher.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* License v3.0 only", or the "Server Side Public License, v 1".
88
*/
99

10-
package org.elasticsearch.hdfs.patch;
10+
package org.elasticsearch.gradle.internal.dependencies.patches.hdfs;
1111

1212
import org.objectweb.asm.ClassVisitor;
1313
import org.objectweb.asm.ClassWriter;

plugins/repository-hdfs/hadoop-client-api/src/patcher/java/org/elasticsearch/hdfs/patch/ShutdownHookManagerPatcher.java renamed to build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/dependencies/patches/hdfs/ShutdownHookManagerPatcher.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* License v3.0 only", or the "Server Side Public License, v 1".
88
*/
99

10-
package org.elasticsearch.hdfs.patch;
10+
package org.elasticsearch.gradle.internal.dependencies.patches.hdfs;
1111

1212
import org.objectweb.asm.ClassVisitor;
1313
import org.objectweb.asm.ClassWriter;

plugins/repository-hdfs/hadoop-client-api/src/patcher/java/org/elasticsearch/hdfs/patch/SubjectGetSubjectPatcher.java renamed to build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/dependencies/patches/hdfs/SubjectGetSubjectPatcher.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* License v3.0 only", or the "Server Side Public License, v 1".
88
*/
99

10-
package org.elasticsearch.hdfs.patch;
10+
package org.elasticsearch.gradle.internal.dependencies.patches.hdfs;
1111

1212
import org.objectweb.asm.ClassVisitor;
1313
import org.objectweb.asm.ClassWriter;

docs/changelog/117642.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 117642
2+
summary: Adding endpoint creation validation to `ElasticInferenceService`
3+
area: Machine Learning
4+
type: enhancement
5+
issues: []

docs/changelog/122458.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 122458
2+
summary: '`DesiredBalanceReconciler` always returns `AllocationStats`'
3+
area: Allocation
4+
type: bug
5+
issues: []

libs/entitlement/asm-provider/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ apply plugin: 'elasticsearch.build'
1212
dependencies {
1313
compileOnly project(':libs:entitlement')
1414
compileOnly project(':libs:core')
15+
compileOnly project(':libs:logging')
1516
implementation 'org.ow2.asm:asm:9.7.1'
1617
testImplementation project(":test:framework")
1718
testImplementation project(":libs:entitlement:bridge")

libs/entitlement/asm-provider/src/main/java/module-info.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
requires org.elasticsearch.entitlement;
1616

1717
requires static org.elasticsearch.base; // for SuppressForbidden
18+
requires org.elasticsearch.logging;
1819

1920
provides InstrumentationService with InstrumentationServiceImpl;
2021
}

libs/entitlement/asm-provider/src/main/java/org/elasticsearch/entitlement/instrumentation/impl/InstrumenterImpl.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
import org.elasticsearch.entitlement.instrumentation.CheckMethod;
1313
import org.elasticsearch.entitlement.instrumentation.Instrumenter;
1414
import org.elasticsearch.entitlement.instrumentation.MethodKey;
15+
import org.elasticsearch.logging.LogManager;
16+
import org.elasticsearch.logging.Logger;
1517
import org.objectweb.asm.AnnotationVisitor;
1618
import org.objectweb.asm.ClassReader;
1719
import org.objectweb.asm.ClassVisitor;
@@ -36,6 +38,7 @@
3638
import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL;
3739

3840
public class InstrumenterImpl implements Instrumenter {
41+
private static final Logger logger = LogManager.getLogger(InstrumenterImpl.class);
3942

4043
private final String getCheckerClassMethodDescriptor;
4144
private final String handleClass;
@@ -155,10 +158,10 @@ public MethodVisitor visitMethod(int access, String name, String descriptor, Str
155158
var key = new MethodKey(className, name, Stream.of(Type.getArgumentTypes(descriptor)).map(Type::getInternalName).toList());
156159
var instrumentationMethod = checkMethods.get(key);
157160
if (instrumentationMethod != null) {
158-
// System.out.println("Will instrument method " + key);
161+
logger.debug("Will instrument {}", key);
159162
return new EntitlementMethodVisitor(Opcodes.ASM9, mv, isStatic, isCtor, descriptor, instrumentationMethod);
160163
} else {
161-
// System.out.println("Will not instrument method " + key);
164+
logger.trace("Will not instrument {}", key);
162165
}
163166
}
164167
return mv;

0 commit comments

Comments
 (0)