Skip to content

Commit a0bad87

Browse files
alai8rjeberhard
andauthoredJun 14, 2022
Backport owls-99679 to release/3.4 (#3168)
* backport owls-99679 to 3.4 branch Co-authored-by: Ryan Eberhard <ryan.eberhard@oracle.com>
1 parent 7495629 commit a0bad87

File tree

10 files changed

+133
-8
lines changed

10 files changed

+133
-8
lines changed
 

‎documentation/domains/Domain.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,7 @@
480480
"type": "string"
481481
},
482482
"introspectVersion": {
483-
"description": "Changes to this field cause the operator to repeat its introspection of the WebLogic domain configuration. Repeating introspection is required for the operator to recognize changes to the domain configuration, such as adding a new WebLogic cluster or Managed Server instance, to regenerate configuration overrides, or to regenerate the WebLogic domain home when the `domainHomeSourceType` is FromModel. Introspection occurs automatically, without requiring change to this field, when servers are first started or restarted after a full domain shut down. For the FromModel `domainHomeSourceType`, introspection also occurs when a running server must be restarted because of changes to any of the fields listed here: https://oracle.github.io/weblogic-kubernetes-operator/userguide/managing-domains/domain-lifecycle/startup/#properties-that-cause-servers-to-be-restarted. See also `domains.spec.configuration.overrideDistributionStrategy`.",
483+
"description": "Changes to this field cause the operator to repeat its introspection of the WebLogic domain configuration. Repeating introspection is required for the operator to recognize changes to the domain configuration, such as adding a new WebLogic cluster or Managed Server instance, to regenerate configuration overrides, or to regenerate the WebLogic domain home when the `domainHomeSourceType` is FromModel. Introspection occurs automatically, without requiring change to this field, when servers are first started or restarted after a full domain shut down. For the FromModel `domainHomeSourceType`, introspection also occurs when a running server must be restarted because of changes to any of the fields listed here: https://oracle.github.io/weblogic-kubernetes-operator/userguide/managing-domains/domain-lifecycle/startup/#properties-that-cause-servers-to-be-restarted. The introspectVersion value must be a valid label value in Kubernetes. See also `domains.spec.configuration.overrideDistributionStrategy`.",
484484
"type": "string"
485485
},
486486
"dataHome": {

‎documentation/domains/Domain.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ The specification of the operation of the WebLogic domain. Required.
3232
| `imagePullPolicy` | string | The image pull policy for the WebLogic Server image. Legal values are Always, Never, and IfNotPresent. Defaults to Always if image ends in :latest; IfNotPresent, otherwise. |
3333
| `imagePullSecrets` | Array of [Local Object Reference](k8s1.13.5.md#local-object-reference) | A list of image pull Secrets for the WebLogic Server image. |
3434
| `includeServerOutInPodLog` | Boolean | Specifies whether the server .out file will be included in the Pod's log. Defaults to true. |
35-
| `introspectVersion` | string | Changes to this field cause the operator to repeat its introspection of the WebLogic domain configuration. Repeating introspection is required for the operator to recognize changes to the domain configuration, such as adding a new WebLogic cluster or Managed Server instance, to regenerate configuration overrides, or to regenerate the WebLogic domain home when the `domainHomeSourceType` is FromModel. Introspection occurs automatically, without requiring change to this field, when servers are first started or restarted after a full domain shut down. For the FromModel `domainHomeSourceType`, introspection also occurs when a running server must be restarted because of changes to any of the fields listed here: https://oracle.github.io/weblogic-kubernetes-operator/userguide/managing-domains/domain-lifecycle/startup/#properties-that-cause-servers-to-be-restarted. See also `domains.spec.configuration.overrideDistributionStrategy`. |
35+
| `introspectVersion` | string | Changes to this field cause the operator to repeat its introspection of the WebLogic domain configuration. Repeating introspection is required for the operator to recognize changes to the domain configuration, such as adding a new WebLogic cluster or Managed Server instance, to regenerate configuration overrides, or to regenerate the WebLogic domain home when the `domainHomeSourceType` is FromModel. Introspection occurs automatically, without requiring change to this field, when servers are first started or restarted after a full domain shut down. For the FromModel `domainHomeSourceType`, introspection also occurs when a running server must be restarted because of changes to any of the fields listed here: https://oracle.github.io/weblogic-kubernetes-operator/userguide/managing-domains/domain-lifecycle/startup/#properties-that-cause-servers-to-be-restarted. The introspectVersion value must be a valid label value in Kubernetes. See also `domains.spec.configuration.overrideDistributionStrategy`. |
3636
| `livenessProbeCustomScript` | string | Full path of an optional liveness probe custom script for WebLogic Server instance pods. The existing liveness probe script `livenessProbe.sh` will invoke this custom script after the existing script performs its own checks. This element is optional and is for advanced usage only. Its value is not set by default. If the custom script fails with non-zero exit status, then pod will fail the liveness probe and Kubernetes will restart the container. If the script specified by this element value is not found, then it is ignored. |
3737
| `logHome` | string | The directory in a server's container in which to store the domain, Node Manager, server logs, server *.out, introspector .out, and optionally HTTP access log files if `httpAccessLogInLogHome` is true. Default is `/shared/logs/DOMAIN-UID`. Ignored if `logHomeEnabled` is false. |
3838
| `logHomeEnabled` | Boolean | Specifies whether the log home folder is enabled. Defaults to true if `domainHomeSourceType` is PersistentVolume; false, otherwise. |

‎documentation/domains/index.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -1401,7 +1401,7 @@
14011401
"type": "string"
14021402
},
14031403
"introspectVersion": {
1404-
"description": "Changes to this field cause the operator to repeat its introspection of the WebLogic domain configuration. Repeating introspection is required for the operator to recognize changes to the domain configuration, such as adding a new WebLogic cluster or Managed Server instance, to regenerate configuration overrides, or to regenerate the WebLogic domain home when the `domainHomeSourceType` is FromModel. Introspection occurs automatically, without requiring change to this field, when servers are first started or restarted after a full domain shut down. For the FromModel `domainHomeSourceType`, introspection also occurs when a running server must be restarted because of changes to any of the fields listed here: https://oracle.github.io/weblogic-kubernetes-operator/userguide/managing-domains/domain-lifecycle/startup/#properties-that-cause-servers-to-be-restarted. See also `domains.spec.configuration.overrideDistributionStrategy`.",
1404+
"description": "Changes to this field cause the operator to repeat its introspection of the WebLogic domain configuration. Repeating introspection is required for the operator to recognize changes to the domain configuration, such as adding a new WebLogic cluster or Managed Server instance, to regenerate configuration overrides, or to regenerate the WebLogic domain home when the `domainHomeSourceType` is FromModel. Introspection occurs automatically, without requiring change to this field, when servers are first started or restarted after a full domain shut down. For the FromModel `domainHomeSourceType`, introspection also occurs when a running server must be restarted because of changes to any of the fields listed here: https://oracle.github.io/weblogic-kubernetes-operator/userguide/managing-domains/domain-lifecycle/startup/#properties-that-cause-servers-to-be-restarted. The introspectVersion value must be a valid label value in Kubernetes. See also `domains.spec.configuration.overrideDistributionStrategy`.",
14051405
"type": "string"
14061406
},
14071407
"dataHome": {

‎integration-tests/src/test/java/oracle/weblogic/kubernetes/ItIntrospectVersion.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -830,7 +830,7 @@ void testDedicatedModeSameNamespaceScale() {
830830
* Update the introspectVersion of the domain resource using lifecycle script.
831831
* Refer to kubernetes/samples/scripts/domain-lifecycle/introspectDomain.sh
832832
* The usecase update the introspectVersion by passing different value to -i
833-
* option (non-numeric, non-numeric with space, no value) and make sure that
833+
* option (non-numeric, non-numeric with underscore and dash, no value) and make sure that
834834
* the introspectVersion is updated accordingly in both domain spec level
835835
* and server pod level.
836836
* It also verifies the introspector job is started/stopped and none of the
@@ -894,8 +894,8 @@ void testIntrospectDomainScript() {
894894
verifyIntrospectVersionLabelInPod();
895895

896896
// use introspectDomain.sh to initiate introspection
897-
logger.info("Initiate introspection with non numeric string with space");
898-
introspectVersion = "My Version";
897+
logger.info("Initiate introspection with non numeric string with underscore and dash");
898+
introspectVersion = "My_Version-1";
899899
String extraParam2 = " -i " + "\"" + introspectVersion + "\"";
900900
assertDoesNotThrow(() -> executeLifecycleScript(INTROSPECT_DOMAIN_SCRIPT, extraParam2),
901901
String.format("Failed to run %s", INTROSPECT_DOMAIN_SCRIPT));

‎kubernetes/crd/domain-crd.yaml

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ apiVersion: apiextensions.k8s.io/v1
55
kind: CustomResourceDefinition
66
metadata:
77
annotations:
8-
weblogic.sha256: bd0abf9c35b0f0fae26a2f0fa1a8e7e4ef15e54858054eece1411ebb8257622c
8+
weblogic.sha256: daef2448066da223ba8cb86e31e2d711d9588eb736cf4558071113c396d95b69
99
name: domains.weblogic.oracle
1010
spec:
1111
group: weblogic.oracle
@@ -6341,6 +6341,7 @@ spec:
63416341
full domain shut down. For the FromModel `domainHomeSourceType`,
63426342
introspection also occurs when a running server must be restarted
63436343
because of changes to any of the fields listed here: https://oracle.github.io/weblogic-kubernetes-operator/userguide/managing-domains/domain-lifecycle/startup/#properties-that-cause-servers-to-be-restarted.
6344+
The introspectVersion value must be a valid label value in Kubernetes.
63446345
See also `domains.spec.configuration.overrideDistributionStrategy`.'
63456346
type: string
63466347
dataHome:

‎operator/src/main/java/oracle/kubernetes/operator/helpers/JobHelper.java

+23-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import java.util.List;
1010
import java.util.Objects;
1111
import java.util.Optional;
12+
import javax.annotation.Nonnull;
1213

1314
import io.kubernetes.client.openapi.models.V1ContainerState;
1415
import io.kubernetes.client.openapi.models.V1ContainerStateWaiting;
@@ -489,7 +490,8 @@ static OffsetDateTime createNextSteps(List<Step> nextSteps, Packet packet, V1Job
489490
.map(V1ObjectMeta::getCreationTimestamp).orElse(OffsetDateTime.now());
490491
String lastIntrospectJobProcessedId = getLastIntrospectJobProcessedId(info);
491492

492-
if (isJobTimedout(info) || (isImagePullError(jobPodContainerWaitingReason)) || jobInitContainerImagePullError) {
493+
if (isJobTimedout(info) || (isImagePullError(jobPodContainerWaitingReason))
494+
|| jobInitContainerImagePullError || isInProgressJobOutdated(job, info)) {
493495
jobStartTime = OffsetDateTime.now();
494496
packet.put(DOMAIN_INTROSPECT_REQUESTED, ReadDomainIntrospectorPodLogResponseStep.INTROSPECTION_FAILED);
495497
nextSteps.add(Step.chain(deleteDomainIntrospectorJobStep(null),
@@ -517,6 +519,26 @@ private static Boolean getjobInitContainerImagePullError(Packet packet) {
517519
return Optional.ofNullable(packet.<Boolean>getValue(ProcessingConstants.JOB_POD_INIT_CONTAINER_WAITING_REASON))
518520
.orElse(Boolean.FALSE);
519521
}
522+
523+
private static boolean isInProgressJobOutdated(V1Job job, DomainPresenceInfo info) {
524+
return Optional.ofNullable(job)
525+
.map(j -> !JobWatcher.isComplete(j) && hasIntrospectVersionChanged(j, info))
526+
.orElse(false);
527+
}
528+
529+
private static boolean hasIntrospectVersionChanged(@Nonnull V1Job job, DomainPresenceInfo info) {
530+
return !Objects.equals(getIntrospectVersionLabelFromJob(job),
531+
getIntrospectVersion(info));
532+
}
533+
534+
private static String getIntrospectVersionLabelFromJob(V1Job job) {
535+
return Optional.ofNullable(job)
536+
.map(V1Job::getMetadata)
537+
.map(V1ObjectMeta::getLabels)
538+
.map(m -> m.get(INTROSPECTION_STATE_LABEL))
539+
.orElse("");
540+
}
541+
520542
}
521543

522544
static ReadDomainIntrospectorPodLogStep readDomainIntrospectorPodLog(Step next) {

‎operator/src/main/java/oracle/kubernetes/operator/helpers/JobStepContext.java

+5
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,10 @@ private String getAsName() {
371371
return domainTopology.getAdminServerName();
372372
}
373373

374+
private String getIntrospectVersionLabel() {
375+
return Optional.ofNullable(getDomain().getIntrospectVersion()).orElse(null);
376+
}
377+
374378
private long getIntrospectorJobActiveDeadlineSeconds(TuningParameters.PodTuning podTuning) {
375379
return Optional.ofNullable(getDomain().getIntrospectorJobActiveDeadlineSeconds())
376380
.orElse(podTuning.introspectorJobActiveDeadlineSeconds);
@@ -397,6 +401,7 @@ private V1ObjectMeta createMetadata() {
397401
new V1ObjectMeta()
398402
.name(getJobName())
399403
.namespace(getNamespace())
404+
.putLabelsItem(LabelConstants.INTROSPECTION_STATE_LABEL, getIntrospectVersionLabel())
400405
.putLabelsItem(LabelConstants.DOMAINUID_LABEL, getDomainUid())
401406
.putLabelsItem(LabelConstants.CREATEDBYOPERATOR_LABEL, "true"));
402407
}

‎operator/src/main/java/oracle/kubernetes/weblogic/domain/model/DomainSpec.java

+1
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ public class DomainSpec extends BaseConfiguration {
274274
+ "server must be restarted because of changes to any of the fields listed here: "
275275
+ "https://oracle.github.io/weblogic-kubernetes-operator/userguide/managing-domains/"
276276
+ "domain-lifecycle/startup/#properties-that-cause-servers-to-be-restarted. "
277+
+ "The introspectVersion value must be a valid label value in Kubernetes. "
277278
+ "See also `domains.spec.configuration.overrideDistributionStrategy`.")
278279
private String introspectVersion;
279280

‎operator/src/test/java/oracle/kubernetes/operator/helpers/DomainIntrospectorJobTest.java

+70
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
import static oracle.kubernetes.operator.DomainProcessorTestSetup.NS;
7373
import static oracle.kubernetes.operator.DomainProcessorTestSetup.UID;
7474
import static oracle.kubernetes.operator.DomainUpPlanTest.StepChainMatcher.hasChainWithStepsInOrder;
75+
import static oracle.kubernetes.operator.LabelConstants.INTROSPECTION_STATE_LABEL;
7576
import static oracle.kubernetes.operator.ProcessingConstants.DOMAIN_INTROSPECTOR_JOB;
7677
import static oracle.kubernetes.operator.ProcessingConstants.DOMAIN_TOPOLOGY;
7778
import static oracle.kubernetes.operator.ProcessingConstants.EXCEEDED_INTROSPECTOR_MAX_RETRY_COUNT_ERROR_MSG;
@@ -780,6 +781,75 @@ void whenJobHasImagePullBackOffError_correctStepsExecuted() {
780781
"DomainIntrospectorJobStep"));
781782
}
782783

784+
@Test
785+
void whenJobInProgressAndIntrospectVersionAdded_correctStepsExecuted() {
786+
List<Step> nextSteps = new ArrayList<>();
787+
V1Job job = new V1Job().metadata(new V1ObjectMeta().name(getJobName()).namespace(NS).uid(JOB_UID))
788+
.status(new V1JobStatus());
789+
testSupport.defineResources(job);
790+
getConfigurator().withIntrospectVersion("v2");
791+
IntrospectionTestUtils.defineResources(testSupport, "passed");
792+
testSupport.addToPacket(DOMAIN_INTROSPECTOR_JOB, testSupport.getResourceWithName(JOB, getJobName()));
793+
794+
JobHelper.ReplaceOrCreateStep.createNextSteps(nextSteps, testSupport.getPacket(), job, terminalStep);
795+
796+
assertThat(nextSteps.get(0), hasChainWithStepsInOrder("DeleteDomainIntrospectorJobStep",
797+
"DomainIntrospectorJobStep"));
798+
}
799+
800+
@Test
801+
void whenJobInProgressAndIntrospectVersionChanged_correctStepsExecuted() {
802+
List<Step> nextSteps = new ArrayList<>();
803+
V1Job job = new V1Job().metadata(new V1ObjectMeta().name(getJobName()).namespace(NS).uid(JOB_UID))
804+
.status(new V1JobStatus());
805+
job.getMetadata().putLabelsItem(INTROSPECTION_STATE_LABEL, "v1");
806+
testSupport.defineResources(job);
807+
getConfigurator().withIntrospectVersion("v2");
808+
IntrospectionTestUtils.defineResources(testSupport, "passed");
809+
testSupport.addToPacket(DOMAIN_INTROSPECTOR_JOB, testSupport.getResourceWithName(JOB, getJobName()));
810+
811+
JobHelper.ReplaceOrCreateStep.createNextSteps(nextSteps, testSupport.getPacket(), job, terminalStep);
812+
813+
assertThat(nextSteps.get(0), hasChainWithStepsInOrder("DeleteDomainIntrospectorJobStep",
814+
"DomainIntrospectorJobStep"));
815+
}
816+
817+
@Test
818+
void whenJobInProgressAndIntrospectVersionUnchanged_correctStepsExecuted() {
819+
List<Step> nextSteps = new ArrayList<>();
820+
V1Job job = new V1Job().metadata(new V1ObjectMeta().name(getJobName()).namespace(NS).uid(JOB_UID))
821+
.status(new V1JobStatus());
822+
job.getMetadata().putLabelsItem(INTROSPECTION_STATE_LABEL, "v2");
823+
testSupport.defineResources(job);
824+
getConfigurator().withIntrospectVersion("v2");
825+
IntrospectionTestUtils.defineResources(testSupport, "passed");
826+
testSupport.addToPacket(DOMAIN_INTROSPECTOR_JOB, testSupport.getResourceWithName(JOB, getJobName()));
827+
828+
JobHelper.ReplaceOrCreateStep.createNextSteps(nextSteps, testSupport.getPacket(), job, terminalStep);
829+
830+
assertThat(nextSteps.get(0), hasChainWithStepsInOrder("WatchDomainIntrospectorJobReadyStep",
831+
"ReadDomainIntrospectorPodStep", "ReadDomainIntrospectorPodLogStep",
832+
"DeleteDomainIntrospectorJobStep", "IntrospectionConfigMapStep", "TerminalStep"));
833+
}
834+
835+
@Test
836+
void whenJobInProgressAndNullIntrospectVersionUnchanged_correctStepsExecuted() {
837+
List<Step> nextSteps = new ArrayList<>();
838+
V1Job job = new V1Job().metadata(new V1ObjectMeta().name(getJobName()).namespace(NS).uid(JOB_UID))
839+
.status(new V1JobStatus());
840+
job.getMetadata().putLabelsItem(INTROSPECTION_STATE_LABEL, null);
841+
testSupport.defineResources(job);
842+
getConfigurator().withIntrospectVersion(null);
843+
IntrospectionTestUtils.defineResources(testSupport, "passed");
844+
testSupport.addToPacket(DOMAIN_INTROSPECTOR_JOB, testSupport.getResourceWithName(JOB, getJobName()));
845+
846+
JobHelper.ReplaceOrCreateStep.createNextSteps(nextSteps, testSupport.getPacket(), job, terminalStep);
847+
848+
assertThat(nextSteps.get(0), hasChainWithStepsInOrder("WatchDomainIntrospectorJobReadyStep",
849+
"ReadDomainIntrospectorPodStep", "ReadDomainIntrospectorPodLogStep",
850+
"DeleteDomainIntrospectorJobStep", "IntrospectionConfigMapStep", "TerminalStep"));
851+
}
852+
783853
@Test
784854
void whenCurrentJobIsNull_correctStepsExecuted() {
785855
List<Step> nextSteps = new ArrayList<>();

‎operator/src/test/java/oracle/kubernetes/operator/helpers/JobHelperTest.java

+26
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,14 @@ private V1JobSpec createJobSpec() {
341341
return domainIntrospectorJobStepContext.createJobSpec(TuningParameters.getInstance());
342342
}
343343

344+
private V1Job createJob() {
345+
Packet packet = new Packet();
346+
packet
347+
.getComponents()
348+
.put(ProcessingConstants.DOMAIN_COMPONENT_NAME, Component.createFor(domainPresenceInfo));
349+
return new DomainIntrospectorJobStepContext(packet).getJobModel();
350+
}
351+
344352
@Test
345353
void introspectorPodStartsWithDefaultUser_Mem_Args_environmentVariable() {
346354
V1JobSpec jobSpec = createJobSpec();
@@ -1237,6 +1245,24 @@ void whenDomainIsIstioEnabled_istioLocalhostBindingsDisabledEnv_hasIstioUseLocal
12371245
);
12381246
}
12391247

1248+
@Test
1249+
void whenDomainHasIntrospectVersion_jobMetatadataCreatedWithLabel() {
1250+
final String INTROSPECT_VERSION = "v123";
1251+
configureDomain().withIntrospectVersion(INTROSPECT_VERSION);
1252+
1253+
V1Job job = createJob();
1254+
assertThat(job.getMetadata().getLabels().get(LabelConstants.INTROSPECTION_STATE_LABEL),
1255+
is(INTROSPECT_VERSION));
1256+
}
1257+
1258+
@Test
1259+
void whenDomainHasNoIntrospectVersion_jobMetatadataCreatedWithoutNoLabel() {
1260+
configureDomain().withIntrospectVersion(null);
1261+
1262+
V1Job job = createJob();
1263+
assertThat(job.getMetadata().getLabels().get(LabelConstants.INTROSPECTION_STATE_LABEL), is(nullValue()));
1264+
}
1265+
12401266
private void markJobCompleted(V1Job job) {
12411267
job.setStatus(new V1JobStatus().addConditionsItem(new V1JobCondition().status("True").type("Complete")));
12421268
}

0 commit comments

Comments
 (0)