From 7d88893683c183f0ed8680b1999d1797a16c62b3 Mon Sep 17 00:00:00 2001 From: Shreay Patel Date: Wed, 24 Jan 2024 10:25:16 -0800 Subject: [PATCH] enable lr --- cloud/corfu/.swp | Bin 0 -> 376832 bytes cloud/corfu/cluster_deploy.sh | 143 ++++++++++++++ .../templates/job.yaml | 4 +- .../corfu-client-example-helm/values.yaml | 5 +- .../corfu-client-example/build.gradle.kts | 2 + .../Main.java | 186 +++++++++++++----- .../config/corfu_plugin_config.properties | 22 ++- cloud/corfu/corfu/files/init_layout.py | 3 +- cloud/corfu/corfu/serial_number/serial_number | 1 + cloud/corfu/corfu/templates/Deployment.yaml | 53 +++++ cloud/corfu/corfu/templates/_helpers.tpl | 10 +- cloud/corfu/corfu/templates/certificate.yaml | 3 +- cloud/corfu/corfu/templates/configmap-lr.yaml | 10 + cloud/corfu/corfu/templates/service-lr.yaml | 15 ++ cloud/corfu/corfu/templates/service.yaml | 2 +- .../corfu/corfu/templates/serviceaccount.yaml | 2 +- cloud/corfu/corfu/templates/statefulset.yaml | 30 +-- cloud/corfu/corfu/values.yaml | 13 +- 18 files changed, 431 insertions(+), 73 deletions(-) create mode 100644 cloud/corfu/.swp create mode 100755 cloud/corfu/cluster_deploy.sh create mode 100644 cloud/corfu/corfu/serial_number/serial_number create mode 100644 cloud/corfu/corfu/templates/Deployment.yaml create mode 100644 cloud/corfu/corfu/templates/configmap-lr.yaml create mode 100644 cloud/corfu/corfu/templates/service-lr.yaml diff --git a/cloud/corfu/.swp b/cloud/corfu/.swp new file mode 100644 index 0000000000000000000000000000000000000000..cfd5527897bc609059c13b71a93778aebf00666c GIT binary patch literal 376832 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%0Ah*6B^3y;pkw&dg7Y(IZB?6XN zSqO+(DF7$lguNonR(_<5rM{@Wx|*#8P?lL)K#5tcaJpN+1B8fZTK>s0pS5dBbFTtXHQmU5>qNf|^zVNqWqVEGyg0r52oz}1ODP#C||j-|e+ zy{xD~Vb%gD%d9M*#H?00-L3D3jH-GWmt~1GYJECclxCF(SY~A*AZDci-0kJ*pG{vl zsHw#l2Q7 z$G8WTcZ7ug|4Hcb{|`;*|8JDS`uWiPKLp+Xx6u42(LM;>|KFkcMg9M4p!pwy_5$es zS3viF8Jhp!qP+;Z|2b%X3Edx~{VKHopF{V@X!+;sMf<<}xBp^+MO&aAC=!=F=V6}a zRdd#lu@-EVF^)ItQZ1aX6aT@X;yy{ z9Mqdt?v_~yh*>EBvxU)VRSB}Q35Aotk-gG zvd)UoVeHC@3ZVMYHUUaT+X|=Iq^J{LahdUIWLon1An$>0rs9LsN7o&6A@GcLg z>B0HY!J*j1jSnth1J~Q$>s@!Ff5Y+K_4qg2qpcoZWVC-^cRu~=TEHY=R({fh722RK zNr_FttOWwSuSsTQAt1g+0k}HR02Ibpi6k?y&WccbSy6++tOZcLSxtZvvs&SFx4v(X z^kAu2YJECclxCF(^k$W_m4$$ql>%_Lm#2Row91}5f;~MNZ=Ss-r_d9= 2) { - keyStore = args[1]; + job = Integer.parseInt(args[1]); } if (args.length >= 3) { - keyStorePassword = args[2]; + keyStore = args[2]; } if (args.length >= 4) { - trustStore = args[3]; + keyStorePassword = args[3]; } if (args.length >= 5) { - trustStorePassword = args[4]; + trustStore = args[4]; + } + if (args.length >= 6) { + trustStorePassword = args[5]; } - if (args.length == 5) { + if (args.length == 6) { tlsEnabled = true; } + if (job >= 1) { + if (job != 2) { + test(ip, tlsEnabled, keyStore, keyStorePassword, trustStore, trustStorePassword); + } + validate(ip, tlsEnabled, keyStore, keyStorePassword, trustStore, trustStorePassword); + } + } + public static void test(String ip, boolean tlsEnabled, String keyStore, String keyStorePassword, String trustStore, String trustStorePassword) throws Exception { + CorfuRuntime runtimeSource = getRuntimeAndConnect(ip, tlsEnabled, keyStore, keyStorePassword, trustStore, trustStorePassword); + CorfuRuntime runtimeSink = getRuntimeAndConnect("corfu2-0.corfu2-headless.default.svc.cluster.local", + tlsEnabled, keyStore, keyStorePassword, trustStore, trustStorePassword); - CorfuRuntime runtime = getRuntimeAndConnect(ip, tlsEnabled, keyStore, keyStorePassword, trustStore, trustStorePassword); + CorfuStore corfuStoreSource = new CorfuStore(runtimeSource); + CorfuStore corfuStoreSink = new CorfuStore(runtimeSink); - /** - * Obviously, this application is not doing much yet, - * but you can already invoke getRuntimeAndConnect to test if you can connect to a deployed Corfu service. - * - * Above, you will need to point it to a host and port which is running the service. - * See {@link https://github.com/CorfuDB/CorfuDB} for instructions on how to deploy Corfu. - */ + String NAMESPACE = "LR-Test"; + String streamA = "MyTestTable"; - /** - * Next, we will illustrate how to declare a Java object backed by a Corfu Stream. - * A Corfu Stream is a log dedicated specifically to the history of updates of one object. - * We will instantiate a stream by giving it a name "A", - * and then instantiate an object by specifying its class - */ - Map map = runtime.getObjectsView() - .build() - .setStreamName("A") // stream name - .setTypeToken(new TypeToken>() {}) - .open(); // instantiate the object! + Table mapA = corfuStoreSource.openTable( + NAMESPACE, + streamA, + Sample.StringKey.class, + Sample.IntValue.class, + Sample.Metadata.class, + TableOptions.builder().schemaOptions( + CorfuOptions.SchemaOptions.newBuilder() + .setIsFederated(true) + .build()) + .build() + ); - /** - * The magic has already happened! map is an in-memory view of a shared map, backed by the Corfu log. - * The application can perform put and get on this map from different application instances, - * crash and restart applications, and so on. - * The map will persist and be consistent across all applications. - * - * For example, try the following code repeatedly in a sequence, in between run/exit, - * from multiple instances, and see the different interleaving of values that result. - */ - Integer previous = map.get("a"); - if (previous == null) { - System.out.println("This is the first time we were run!"); - map.put("a", 1); + Table mapASink = corfuStoreSink.openTable( + NAMESPACE, + streamA, + Sample.StringKey.class, + Sample.IntValue.class, + Sample.Metadata.class, + TableOptions.builder().schemaOptions( + CorfuOptions.SchemaOptions.newBuilder() + .setIsFederated(true) + .build()) + .build() + ); + + int totalEntries = 200; + int startIndex = 0; + + int maxIndex = totalEntries + startIndex; + for (int i = startIndex; i < maxIndex; i++) { + try (TxnContext txn = corfuStoreSource.txn(NAMESPACE)) { + txn.putRecord(mapA, Sample.StringKey.newBuilder().setKey(String.valueOf(i)).build(), + Sample.IntValue.newBuilder().setValue(i).build(), null); + txn.commit(); + } + } + + try (TxnContext txn = corfuStoreSource.txn(NAMESPACE)) { + int tableSize = txn.getTable(streamA).count(); + System.out.println("Size of source table after adding entries is: " + tableSize); + txn.commit(); } - else { - map.put("a", ++previous); - System.out.println("This is the " + previous + " time we were run!"); + } + + public static void validate(String ip, boolean tlsEnabled, String keyStore, String keyStorePassword, String trustStore, String trustStorePassword) throws Exception { + CorfuRuntime runtimeSource = getRuntimeAndConnect(ip, tlsEnabled, keyStore, keyStorePassword, trustStore, trustStorePassword); + CorfuRuntime runtimeSink = getRuntimeAndConnect("corfu2-0.corfu2-headless.default.svc.cluster.local", + tlsEnabled, keyStore, keyStorePassword, trustStore, trustStorePassword); + + CorfuStore corfuStoreSource = new CorfuStore(runtimeSource); + CorfuStore corfuStoreSink = new CorfuStore(runtimeSink); + + String NAMESPACE = "LR-Test"; + String streamA = "MyTestTable"; + + Table mapA = corfuStoreSource.openTable( + NAMESPACE, + streamA, + Sample.StringKey.class, + Sample.IntValue.class, + Sample.Metadata.class, + TableOptions.builder().schemaOptions( + CorfuOptions.SchemaOptions.newBuilder() + .setIsFederated(true) + .build()) + .build() + ); + + Table mapASink = corfuStoreSink.openTable( + NAMESPACE, + streamA, + Sample.StringKey.class, + Sample.IntValue.class, + Sample.Metadata.class, + TableOptions.builder().schemaOptions( + CorfuOptions.SchemaOptions.newBuilder() + .setIsFederated(true) + .build()) + .build() + ); + + while (true) { + try (TxnContext txn = corfuStoreSource.txn(NAMESPACE)) { + int tableSize = txn.getTable(streamA).count(); + System.out.println("Size of source table is: " + tableSize); + txn.commit(); + } + + try (TxnContext txn = corfuStoreSink.txn(NAMESPACE)) { + int tableSize = txn.getTable(streamA).count(); + + System.out.println("Size of sink table is: " + tableSize); + txn.commit(); + + if (tableSize == 200) { + break; + } + } + TimeUnit.SECONDS.sleep(5); } } } \ No newline at end of file diff --git a/cloud/corfu/corfu/config/corfu_plugin_config.properties b/cloud/corfu/corfu/config/corfu_plugin_config.properties index 81e90c01..9065d87f 100644 --- a/cloud/corfu/corfu/config/corfu_plugin_config.properties +++ b/cloud/corfu/corfu/config/corfu_plugin_config.properties @@ -1,15 +1,27 @@ -# Transport Plugin Configuration transport_adapter_JAR_path=/app/corfu.jar +GRPC_transport_adapter_server_class_name=org.corfudb.infrastructure.logreplication.transport.sample.GRPCLogReplicationServerChannelAdapter +GRPC_transport_adapter_client_class_name=org.corfudb.infrastructure.logreplication.transport.sample.GRPCLogReplicationClientChannelAdapter +NETTY_transport_adapter_server_class_name=org.corfudb.infrastructure.logreplication.transport.sample.NettyLogReplicationServerChannelAdapter +NETTY_transport_adapter_client_class_name=org.corfudb.infrastructure.logreplication.transport.sample.NettyLogReplicationClientChannelAdapter + +# Transport plugin selector +transport_plugin_selector_JAR_path=/app/corfu.jar +transport_plugin_selector_class_name=org.corfudb.infrastructure.logreplication.infrastructure.plugins.DefaultTransportPluginSelector + +# Transport Plugin Configuration transport_adapter_server_class_name=org.corfudb.infrastructure.logreplication.transport.sample.GRPCLogReplicationServerChannelAdapter transport_adapter_client_class_name=org.corfudb.infrastructure.logreplication.transport.sample.GRPCLogReplicationClientChannelAdapter + # Stream Fetcher Plugin Configuration stream_fetcher_plugin_JAR_path=/app/corfu.jar -stream_fetcher_plugin_class_name=org.corfudb.infrastructure.logreplication.infrastructure.plugins.DefaultLogReplicationConfigAdapter +stream_fetcher_plugin_class_name=org.corfudb.infrastructure.logreplication.infrastructure.plugins.DefaultLogReplicationCloudConfigAdapter + # Topology Manager Plugin Configuration topology_manager_adapter_JAR_path=/app/corfu.jar -topology_manager_adapter_class_name=org.corfudb.infrastructure.logreplication.infrastructure.plugins.DefaultClusterManager +topology_manager_adapter_class_name=org.corfudb.infrastructure.logreplication.infrastructure.plugins.DefaultCloudClusterManager + # Snapshot Sync Configuration (Plugin) snapshot_sync_plugin_JAR_path=/app/corfu.jar snapshot_sync_plugin_class_name=org.corfudb.infrastructure.logreplication.infrastructure.plugins.DefaultSnapshotSyncPlugin -saas_endpoint=corfu:9000 -local_node_id_path=/usr/share/corfu/conf/serial_number \ No newline at end of file + +saas_endpoint=corfu-0.corfu-headless.default.svc.cluster.local:9000 \ No newline at end of file diff --git a/cloud/corfu/corfu/files/init_layout.py b/cloud/corfu/corfu/files/init_layout.py index 27c703bd..b8a99e51 100644 --- a/cloud/corfu/corfu/files/init_layout.py +++ b/cloud/corfu/corfu/files/init_layout.py @@ -20,7 +20,7 @@ def generate_layout(args): layout_template["layoutServers"] = fqdn_list layout_template["sequencers"] = fqdn_list layout_template["segments"][0]["stripes"][0]["logServers"] = fqdn_list - layout_template["clusterId"] = "123e4567-e89b-12d3-a456-556642440000" + layout_template["clusterId"] = "456e4567-e89b-12d3-a456-556642440001" if args.type == "source" else "456e4567-e89b-12d3-a456-556642440002" # print layout print("Generated layout:") @@ -39,6 +39,7 @@ def main(): parser.add_argument('--replica', '-r', type=int, required=True, help='The replica of Corfu cluster.') parser.add_argument('--statefulset', type=str, default='corfu', help='Corfu statefulset name.') parser.add_argument('--headless', type=str, default='corfu-headless', required=True, help='Corfu headless service name.') + parser.add_argument('--type', type=str, default='source', required=True, help='Source or sink.') args = parser.parse_args() generate_layout(args) diff --git a/cloud/corfu/corfu/serial_number/serial_number b/cloud/corfu/corfu/serial_number/serial_number new file mode 100644 index 00000000..1c02b1a7 --- /dev/null +++ b/cloud/corfu/corfu/serial_number/serial_number @@ -0,0 +1 @@ +serial=B1310142-311D-B7AE-D6A7-F66DEE607871 \ No newline at end of file diff --git a/cloud/corfu/corfu/templates/Deployment.yaml b/cloud/corfu/corfu/templates/Deployment.yaml new file mode 100644 index 00000000..650f0702 --- /dev/null +++ b/cloud/corfu/corfu/templates/Deployment.yaml @@ -0,0 +1,53 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "corfu.service.lr" . }} + labels: + {{- include "corfu.labels" . | indent 4 }} +spec: + replicas: {{ include "corfu.replicas" . }} + updateStrategy: + type: RollingUpdate + serviceName: {{ include "corfu.service.lr" . }} + selector: + matchLabels: + {{- include "corfu.selectors.lr" . | nindent 6 }} + template: + metadata: + labels: + {{- include "corfu.selectors.lr" . | nindent 8 }} + spec: + containers: + - name: {{ include "corfu.service.lr" . }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - name: http + containerPort: {{ .Values.lr.port }} + protocol: TCP + env: + - name: CONFIG_FILE_PATH + value: "/usr/share/corfu/conf/corfu_replication_config.properties" + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_UID + valueFrom: + fieldRef: + fieldPath: metadata.uid + VolumeMounts: + - name: log-dir + mountPath: /var/log/corfu-log-replication + - name: config-dir + mountPath: /config/corfu-log-replication + - name: lr + mountPath: /common/configs/ + command: + - "sh" + - "-c" + - "java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/log/corfu/corfu_oom.hprof -XX:+HeapDumpOnOutOfMemoryError -Djdk.nio.maxCachedBufferSize=1048576 -Dio.netty.recycler.maxCapacityPerThread=0 -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime -Djava.io.tmpdir=/image/corfu-server/temp -cp /app/corfu.jar:/opt/vmware/log-replication/log-replication_deploy.jar -Djava.io.tmpdir=/tmp org.corfudb.infrastructure.CorfuServer --plugin=/usr/share/corfu/conf/corfu_plugin_config.properties -d DEBUG 9010 -m" \ No newline at end of file diff --git a/cloud/corfu/corfu/templates/_helpers.tpl b/cloud/corfu/corfu/templates/_helpers.tpl index ef4f144d..999b445d 100644 --- a/cloud/corfu/corfu/templates/_helpers.tpl +++ b/cloud/corfu/corfu/templates/_helpers.tpl @@ -1,5 +1,5 @@ {{- define "corfu.name" -}} -corfu +{{ .Values.nameOverride }} {{- end }} {{- define "corfu.fullname" -}} @@ -30,6 +30,14 @@ type: {{ .Values.type | default "config" | quote }} app.kubernetes.io/name: {{ include "corfu.fullname" . }} {{- end }} +{{- define "corfu.service.lr" -}} +{{- .Values.lr.name }} +{{- end }} + +{{- define "corfu.selectors.lr" -}} +app.kubernetes.io/name: {{ include "corfu.service.lr" . }} +{{- end }} + {{/* If replicas tag is defined in its own helm chart values.yaml it will always override the global value. If not, we will use the global value. diff --git a/cloud/corfu/corfu/templates/certificate.yaml b/cloud/corfu/corfu/templates/certificate.yaml index 1ecb8133..20ff3337 100644 --- a/cloud/corfu/corfu/templates/certificate.yaml +++ b/cloud/corfu/corfu/templates/certificate.yaml @@ -1,5 +1,5 @@ {{- if .Values.tls.certificate.enabled }} -{{- $dns := printf "*.corfu-headless.%s.svc.cluster.local" .Release.Namespace }} +{{- $dns := printf "*.%s-headless.%s.svc.cluster.local" .Values.nameOverride .Release.Namespace }} apiVersion: cert-manager.io/v1 kind: Certificate metadata: @@ -25,6 +25,7 @@ spec: - client auth dnsNames: - corfu + - corfu2 - "{{ $dns }}" issuerRef: name: {{ .Values.tls.certificate.issuer.name }} diff --git a/cloud/corfu/corfu/templates/configmap-lr.yaml b/cloud/corfu/corfu/templates/configmap-lr.yaml new file mode 100644 index 00000000..a6254cd1 --- /dev/null +++ b/cloud/corfu/corfu/templates/configmap-lr.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "corfu.fullname" . }}-corfu-configs-lr + labels: + {{- include "corfu.labels" . | indent 4 }} +data: + {{- with .Files.Glob "serial_number/*" }} + {{- .AsConfig | nindent 2 }} + {{- end }} \ No newline at end of file diff --git a/cloud/corfu/corfu/templates/service-lr.yaml b/cloud/corfu/corfu/templates/service-lr.yaml new file mode 100644 index 00000000..e292939b --- /dev/null +++ b/cloud/corfu/corfu/templates/service-lr.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "corfu.service.lr" . }} + labels: + {{- include "corfu.labels" . | indent 4 }} +spec: + type: ClusterIP + ports: + - port: {{ .Values.lr.port }} + targetPort: http + protocol: TCP + name: http + selector: + {{- include "corfu.selectors.lr" . | nindent 4 }} \ No newline at end of file diff --git a/cloud/corfu/corfu/templates/service.yaml b/cloud/corfu/corfu/templates/service.yaml index e542a21a..e51036ec 100644 --- a/cloud/corfu/corfu/templates/service.yaml +++ b/cloud/corfu/corfu/templates/service.yaml @@ -33,7 +33,7 @@ spec: apiVersion: v1 kind: Service metadata: - name: {{ include "corfu.fullname" . }}-headless + name: {{ include "corfu.name" . }}-headless labels: {{- include "corfu.labels" . | indent 4 }} spec: diff --git a/cloud/corfu/corfu/templates/serviceaccount.yaml b/cloud/corfu/corfu/templates/serviceaccount.yaml index bc0d7b6b..5fa800f3 100644 --- a/cloud/corfu/corfu/templates/serviceaccount.yaml +++ b/cloud/corfu/corfu/templates/serviceaccount.yaml @@ -26,7 +26,7 @@ rules: apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: - name: {{ include "corfu.name" . }}-role-binding + name: {{ include "corfu.serviceAccountName" . }}-role-binding labels: {{- include "corfu.labels" . | indent 4 }} subjects: diff --git a/cloud/corfu/corfu/templates/statefulset.yaml b/cloud/corfu/corfu/templates/statefulset.yaml index 7c2296eb..1dde49b2 100644 --- a/cloud/corfu/corfu/templates/statefulset.yaml +++ b/cloud/corfu/corfu/templates/statefulset.yaml @@ -5,8 +5,10 @@ metadata: labels: {{- include "corfu.labels" . | indent 4 }} spec: - serviceName: {{ include "corfu.fullname" . }}-headless + serviceName: {{ include "corfu.name" . }}-headless replicas: {{ include "corfu.replicas" . }} + updateStrategy: + type: RollingUpdate podManagementPolicy: Parallel selector: matchLabels: @@ -29,7 +31,7 @@ spec: {{- toYaml .Values.podSecurityContext | nindent 8 }} initContainers: - name: create-layout - image: "{{ .Values.image.registry }}/{{ .Values.image.repository }}:{{ .Values.image.tag }}" + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" imagePullPolicy: {{ .Values.image.pullPolicy }} command: - "/bin/bash" @@ -37,7 +39,7 @@ spec: - | set -e python3 /etc/corfu/configs/init_layout.py --template /etc/corfu/configs/layout_template.json --layout /usr/share/configs/layout.json \ - --replica {{ include "corfu.replicas" . }} --statefulset {{ include "corfu.name" . }} --headless {{ include "corfu.name" . }}-headless --port {{ .Values.service.port }} + --replica {{ include "corfu.replicas" . }} --statefulset {{ include "corfu.fullname" . }} --headless {{ include "corfu.name" . }}-headless --port {{ .Values.service.port }} --type {{ .Values.cluster.type }} env: - name: POD_NAMESPACE valueFrom: @@ -46,11 +48,11 @@ spec: volumeMounts: - name: workdir mountPath: /usr/share/configs - - name: corfu-layout-configs + - name: {{ include "corfu.fullname" . }}-layout-configs mountPath: /etc/corfu/configs containers: - name: bootstrap-corfu - image: "{{ .Values.image.registry }}/{{ .Values.image.repository }}:{{ .Values.image.tag }}" + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" imagePullPolicy: {{ .Values.image.pullPolicy }} volumeMounts: - name: workdir @@ -74,7 +76,8 @@ spec: echo "Current node is bootstrapped. Nothing to do." sleep inf fi - + + {{- if .Values.version.new }} {{- if .Values.tls.enabled }} certs_truststore_file=/certs/truststore.jks if test -f "$certs_truststore_file"; @@ -90,7 +93,7 @@ spec: --enable-tls --keystore=/certs/keystore.jks --truststore=/certs/truststore.jks \ --keystore-password-file=/password/password --truststore-password-file=/password/password \ {{- end }} - --retries 10 --timeout 5000 $POD_NAME.corfu-headless.$POD_NAMESPACE.svc.cluster.local:9000 \ + --retries 10 --timeout 5000 $POD_NAME.{{ include "corfu.name" . }}-headless.$POD_NAMESPACE.svc.cluster.local:9000 \ &> /tmp/ping.log if grep -q "All nodes are reachable!" "/tmp/ping.log"; then @@ -99,13 +102,14 @@ spec: cat /tmp/ping.log exit 1 fi + {{- end }} echo "bootstrap local node with layout:" cat /configs/layout.json echo /usr/share/corfu/bin/corfu_bootstrap_cluster --layout=/configs/layout.json \ - -n "$POD_NAME.corfu-headless.$POD_NAMESPACE.svc.cluster.local:9000" \ + -n "$POD_NAME.{{ include "corfu.name" . }}-headless.$POD_NAMESPACE.svc.cluster.local:9000" \ --connection-timeout 2000 \ {{- if .Values.tls.enabled }} --enable-tls --keystore=/certs/keystore.jks --truststore=/certs/truststore.jks \ @@ -130,8 +134,8 @@ spec: valueFrom: fieldRef: fieldPath: metadata.namespace - - name: {{ include "corfu.fullname" . }} - image: "{{ .Values.image.registry }}/{{ .Values.image.repository }}:{{ .Values.image.tag }}" + - name: corfu + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" imagePullPolicy: {{ .Values.image.pullPolicy }} readinessProbe: exec: @@ -156,7 +160,7 @@ spec: - "sh" - "-c" - | - output=$(curl $POD_NAME.corfu-headless.$POD_NAMESPACE.svc.cluster.local:8080/health | jq -r .liveness.status) + output=$(curl $POD_NAME.{{ include "corfu.name" . }}-headless.$POD_NAMESPACE.svc.cluster.local:8080/health | jq -r .liveness.status) if [ "$output" == "DOWN"]; then exit 1 fi @@ -174,7 +178,7 @@ spec: -Dlogback.configurationFile=/usr/share/corfu/conf/logback.prod.xml \ -Djava.io.tmpdir=/tmp \ org.corfudb.infrastructure.CorfuServer \ - -a $POD_NAME.corfu-headless.$POD_NAMESPACE.svc.cluster.local \ + -a $POD_NAME.{{ include "corfu.name" . }}-headless.$POD_NAMESPACE.svc.cluster.local \ {{- if .Values.persistence.enabled }} -l /config \ {{- else }} @@ -188,10 +192,12 @@ spec: -k {{ .Values.extraServerArgs.sequencerCacheSize }} \ -d {{ .Values.extraServerArgs.logLevel }} \ --log-size-quota-percentage {{ .Values.extraServerArgs.logSizeQuotaPercentage }} \ + {{- if .Values.version.new }} --compactor-script {{ .Values.extraServerArgs.compactorScript }} \ --compactor-config {{ .Values.extraServerArgs.compactorConfig }} \ --compaction-trigger-freq-ms {{ .Values.extraServerArgs.compactorTriggerFreqMs }} \ --health-port={{ .Values.service.healthPort }} \ + {{- end }} {{- if .Values.extraServerArgs.metricsEnabled }} --metrics \ {{- end }} diff --git a/cloud/corfu/corfu/values.yaml b/cloud/corfu/corfu/values.yaml index 402ca348..10ff6db3 100644 --- a/cloud/corfu/corfu/values.yaml +++ b/cloud/corfu/corfu/values.yaml @@ -1,4 +1,4 @@ -nameOverride: "" +nameOverride: "corfu" fullnameOverride: "corfu" branch: master commitSha: "" @@ -7,7 +7,7 @@ image: registry: "docker.io" repository: "corfudb/corfu-server" tag: "cloud" - pullPolicy: Always + pullPolicy: IfNotPresent imagePullSecretsEnabled: false imagePullSecrets: - name: "secret" @@ -15,6 +15,11 @@ persistence: enabled: true storageSize: 2Gi storageClass: "local-path" +cluster: + type: "source" +lr: + port: 9010 + name: "log-replication" resources: {} resourcesLR: {} service: @@ -42,6 +47,7 @@ tls: passwordName: corfu-password password: "MTIzNDU2" jvmArgsFilePath: "java_opts/default" +jvmArgsFilePathLR: "java_opts/lr" extraServerArgs: cacheHeapRatio: 0.2 sequencerCacheSize: "5000000" @@ -51,4 +57,5 @@ extraServerArgs: compactorConfig: "/usr/share/corfu/conf/corfu-compactor-config.yml" compactorTriggerFreqMs: 900000 metricsEnabled: true - +version: + new: false \ No newline at end of file