fix: use RWO for single-replica Longhorn volumes
This commit is contained in:
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
# 2.5.2-rc.1
|
# 2.5.2
|
||||||
|
|
||||||
## Fixed
|
## Fixed
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -37,7 +37,7 @@ function cloneCommand<T extends object>(command: T): T {
|
|||||||
export const main = defineCommand({
|
export const main = defineCommand({
|
||||||
meta: {
|
meta: {
|
||||||
name: "kuber",
|
name: "kuber",
|
||||||
version: "2.5.2-rc.1",
|
version: "2.5.2",
|
||||||
description: "Docker Compose -> K8s translation layer",
|
description: "Docker Compose -> K8s translation layer",
|
||||||
},
|
},
|
||||||
args: {
|
args: {
|
||||||
|
|||||||
+3
-1
@@ -1286,7 +1286,9 @@ export function volumesToPvc(
|
|||||||
labels: LABELS,
|
labels: LABELS,
|
||||||
},
|
},
|
||||||
spec: {
|
spec: {
|
||||||
accessModes: ["ReadWriteMany"],
|
accessModes: [
|
||||||
|
policy?.replicaCount === 1 ? "ReadWriteOnce" : "ReadWriteMany",
|
||||||
|
],
|
||||||
storageClassName: policy
|
storageClassName: policy
|
||||||
? toLonghornStorageClassName(policy)
|
? toLonghornStorageClassName(policy)
|
||||||
: undefined,
|
: undefined,
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@dmgnr/kuber",
|
"name": "@dmgnr/kuber",
|
||||||
"version": "2.5.2-rc.1",
|
"version": "2.5.2",
|
||||||
"description": "Docker Compose to Kubernetes translation layer",
|
"description": "Docker Compose to Kubernetes translation layer",
|
||||||
"bin": {
|
"bin": {
|
||||||
"kuber": "dist/index.js"
|
"kuber": "dist/index.js"
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ describe("volume conversion", () => {
|
|||||||
expect(claims[0]).toMatchObject({
|
expect(claims[0]).toMatchObject({
|
||||||
metadata: { name: "project-data", namespace: "project" },
|
metadata: { name: "project-data", namespace: "project" },
|
||||||
spec: {
|
spec: {
|
||||||
|
accessModes: ["ReadWriteMany"],
|
||||||
resources: { requests: { storage: "1Gi" } },
|
resources: { requests: { storage: "1Gi" } },
|
||||||
storageClassName: expect.stringMatching(
|
storageClassName: expect.stringMatching(
|
||||||
/^kuber-longhorn-[a-f0-9]{12}$/,
|
/^kuber-longhorn-[a-f0-9]{12}$/,
|
||||||
@@ -64,6 +65,16 @@ describe("volume conversion", () => {
|
|||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("renders single-replica Longhorn volumes as ReadWriteOnce", () => {
|
||||||
|
const service = { volumes: ["data(20Gi on 1 fast):/data"] } as Service;
|
||||||
|
const [claim] = volumesToPvc("project", service);
|
||||||
|
const [storageClass] = volumesToStorageClasses(service);
|
||||||
|
|
||||||
|
expect(claim?.spec?.accessModes).toEqual(["ReadWriteOnce"]);
|
||||||
|
expect(claim?.spec?.storageClassName).toBe(storageClass?.metadata?.name);
|
||||||
|
expect(storageClass?.parameters?.numberOfReplicas).toBe("1");
|
||||||
|
});
|
||||||
|
|
||||||
test("parses inline storage sizing and placement", () => {
|
test("parses inline storage sizing and placement", () => {
|
||||||
const [claim] = volumesToPvc("project", {
|
const [claim] = volumesToPvc("project", {
|
||||||
volumes: ["data(20Gi on 3 fast,archive):/data"],
|
volumes: ["data(20Gi on 3 fast,archive):/data"],
|
||||||
@@ -71,6 +82,7 @@ describe("volume conversion", () => {
|
|||||||
expect(claim).toMatchObject({
|
expect(claim).toMatchObject({
|
||||||
metadata: { name: "project-data" },
|
metadata: { name: "project-data" },
|
||||||
spec: {
|
spec: {
|
||||||
|
accessModes: ["ReadWriteMany"],
|
||||||
resources: { requests: { storage: "20Gi" } },
|
resources: { requests: { storage: "20Gi" } },
|
||||||
storageClassName: expect.stringMatching(/^kuber-longhorn-/),
|
storageClassName: expect.stringMatching(/^kuber-longhorn-/),
|
||||||
},
|
},
|
||||||
@@ -103,11 +115,29 @@ describe("volume conversion", () => {
|
|||||||
} as ComposeSpecification["volumes"],
|
} as ComposeSpecification["volumes"],
|
||||||
);
|
);
|
||||||
expect(claim?.spec).toMatchObject({
|
expect(claim?.spec).toMatchObject({
|
||||||
|
accessModes: ["ReadWriteMany"],
|
||||||
resources: { requests: { storage: "50Gi" } },
|
resources: { requests: { storage: "50Gi" } },
|
||||||
storageClassName: expect.stringMatching(/^kuber-longhorn-/),
|
storageClassName: expect.stringMatching(/^kuber-longhorn-/),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("uses top-level single-replica policy for the PVC and StorageClass", () => {
|
||||||
|
const service = { volumes: ["data:/data"] } as Service;
|
||||||
|
const volumes = {
|
||||||
|
data: { "x-replicaCount": 1 },
|
||||||
|
} as ComposeSpecification["volumes"];
|
||||||
|
const [claim] = volumesToPvc("project", service, process.cwd(), volumes);
|
||||||
|
const [storageClass] = volumesToStorageClasses(
|
||||||
|
service,
|
||||||
|
process.cwd(),
|
||||||
|
volumes,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(claim?.spec?.accessModes).toEqual(["ReadWriteOnce"]);
|
||||||
|
expect(claim?.spec?.storageClassName).toBe(storageClass?.metadata?.name);
|
||||||
|
expect(storageClass?.parameters?.numberOfReplicas).toBe("1");
|
||||||
|
});
|
||||||
|
|
||||||
test("does not create PVCs for anonymous, tmpfs, or managed claims", () => {
|
test("does not create PVCs for anonymous, tmpfs, or managed claims", () => {
|
||||||
expect(
|
expect(
|
||||||
volumesToPvc("project", {
|
volumesToPvc("project", {
|
||||||
|
|||||||
Reference in New Issue
Block a user