@@ -1555,6 +1555,222 @@ var _ = Describe("DevWorkspace Controller", func() {
15551555
15561556 })
15571557
1558+ Context ("Init container imagePullPolicy" , func () {
1559+ const testURL = "test-url"
1560+
1561+ BeforeEach (func () {
1562+ httpfactory .SetupHttpClientsForTesting (& http.Client {
1563+ Transport : & testutil.TestRoundTripper {
1564+ Data : map [string ]testutil.TestResponse {
1565+ fmt .Sprintf ("%s/healthz" , testURL ): {
1566+ StatusCode : http .StatusOK ,
1567+ },
1568+ },
1569+ },
1570+ })
1571+ })
1572+
1573+ AfterEach (func () {
1574+ deleteDevWorkspace (devWorkspaceName )
1575+ httpfactory .SetupHttpClientsForTesting (getBasicTestHttpClient ())
1576+ })
1577+
1578+ It ("Defaults project-clone imagePullPolicy to IfNotPresent" , func () {
1579+ createDevWorkspace (devWorkspaceName , "test-devworkspace.yaml" )
1580+ devworkspace := getExistingDevWorkspace (devWorkspaceName )
1581+ workspaceID := devworkspace .Status .DevWorkspaceId
1582+
1583+ By ("Manually making Routing ready to continue" )
1584+ markRoutingReady (testURL , common .DevWorkspaceRoutingName (workspaceID ))
1585+
1586+ deploy := & appsv1.Deployment {}
1587+ deployNN := namespacedName (common .DeploymentName (workspaceID ), testNamespace )
1588+ Eventually (func () error {
1589+ return k8sClient .Get (ctx , deployNN , deploy )
1590+ }, timeout , interval ).Should (Succeed (), "Getting workspace deployment from cluster" )
1591+
1592+ var projectClone * corev1.Container
1593+ for i := range deploy .Spec .Template .Spec .InitContainers {
1594+ if deploy .Spec .Template .Spec .InitContainers [i ].Name == projects .ProjectClonerContainerName {
1595+ projectClone = & deploy .Spec .Template .Spec .InitContainers [i ]
1596+ }
1597+ }
1598+ Expect (projectClone ).NotTo (BeNil (), "project-clone init container should be present" )
1599+ Expect (projectClone .ImagePullPolicy ).To (Equal (corev1 .PullIfNotPresent ), "project-clone should default to IfNotPresent" )
1600+ })
1601+
1602+ It ("Uses DWOC override for project-clone imagePullPolicy" , func () {
1603+ config .SetGlobalConfigForTesting (& controllerv1alpha1.OperatorConfiguration {
1604+ Workspace : & controllerv1alpha1.WorkspaceConfig {
1605+ ProjectCloneConfig : & controllerv1alpha1.ProjectCloneConfig {
1606+ ImagePullPolicy : corev1 .PullAlways ,
1607+ },
1608+ },
1609+ })
1610+ defer config .SetGlobalConfigForTesting (nil )
1611+
1612+ createDevWorkspace (devWorkspaceName , "test-devworkspace.yaml" )
1613+ devworkspace := getExistingDevWorkspace (devWorkspaceName )
1614+ workspaceID := devworkspace .Status .DevWorkspaceId
1615+
1616+ By ("Manually making Routing ready to continue" )
1617+ markRoutingReady (testURL , common .DevWorkspaceRoutingName (workspaceID ))
1618+
1619+ deploy := & appsv1.Deployment {}
1620+ deployNN := namespacedName (common .DeploymentName (workspaceID ), testNamespace )
1621+ Eventually (func () error {
1622+ return k8sClient .Get (ctx , deployNN , deploy )
1623+ }, timeout , interval ).Should (Succeed (), "Getting workspace deployment from cluster" )
1624+
1625+ var projectClone * corev1.Container
1626+ for i := range deploy .Spec .Template .Spec .InitContainers {
1627+ if deploy .Spec .Template .Spec .InitContainers [i ].Name == projects .ProjectClonerContainerName {
1628+ projectClone = & deploy .Spec .Template .Spec .InitContainers [i ]
1629+ }
1630+ }
1631+ Expect (projectClone ).NotTo (BeNil (), "project-clone init container should be present" )
1632+ Expect (projectClone .ImagePullPolicy ).To (Equal (corev1 .PullAlways ), "project-clone should use DWOC override" )
1633+ })
1634+
1635+ It ("Defaults DWOC init container imagePullPolicy to IfNotPresent" , func () {
1636+ config .SetGlobalConfigForTesting (& controllerv1alpha1.OperatorConfiguration {
1637+ Workspace : & controllerv1alpha1.WorkspaceConfig {
1638+ InitContainers : []corev1.Container {
1639+ {
1640+ Name : "test-init" ,
1641+ Image : "busybox:latest" ,
1642+ Command : []string {"sh" , "-c" , "echo hello" },
1643+ },
1644+ },
1645+ },
1646+ })
1647+ defer config .SetGlobalConfigForTesting (nil )
1648+
1649+ createDevWorkspace (devWorkspaceName , "test-devworkspace.yaml" )
1650+ devworkspace := getExistingDevWorkspace (devWorkspaceName )
1651+ workspaceID := devworkspace .Status .DevWorkspaceId
1652+
1653+ By ("Manually making Routing ready to continue" )
1654+ markRoutingReady (testURL , common .DevWorkspaceRoutingName (workspaceID ))
1655+
1656+ deploy := & appsv1.Deployment {}
1657+ deployNN := namespacedName (common .DeploymentName (workspaceID ), testNamespace )
1658+ Eventually (func () error {
1659+ return k8sClient .Get (ctx , deployNN , deploy )
1660+ }, timeout , interval ).Should (Succeed (), "Getting workspace deployment from cluster" )
1661+
1662+ var testInit * corev1.Container
1663+ for i := range deploy .Spec .Template .Spec .InitContainers {
1664+ if deploy .Spec .Template .Spec .InitContainers [i ].Name == "test-init" {
1665+ testInit = & deploy .Spec .Template .Spec .InitContainers [i ]
1666+ }
1667+ }
1668+ Expect (testInit ).NotTo (BeNil (), "test-init container should be present" )
1669+ Expect (testInit .ImagePullPolicy ).To (Equal (corev1 .PullIfNotPresent ), "DWOC init container should default to IfNotPresent" )
1670+ })
1671+
1672+ It ("Preserves explicit imagePullPolicy on DWOC init containers" , func () {
1673+ config .SetGlobalConfigForTesting (& controllerv1alpha1.OperatorConfiguration {
1674+ Workspace : & controllerv1alpha1.WorkspaceConfig {
1675+ InitContainers : []corev1.Container {
1676+ {
1677+ Name : "test-init" ,
1678+ Image : "busybox:latest" ,
1679+ Command : []string {"sh" , "-c" , "echo hello" },
1680+ ImagePullPolicy : corev1 .PullAlways ,
1681+ },
1682+ },
1683+ },
1684+ })
1685+ defer config .SetGlobalConfigForTesting (nil )
1686+
1687+ createDevWorkspace (devWorkspaceName , "test-devworkspace.yaml" )
1688+ devworkspace := getExistingDevWorkspace (devWorkspaceName )
1689+ workspaceID := devworkspace .Status .DevWorkspaceId
1690+
1691+ By ("Manually making Routing ready to continue" )
1692+ markRoutingReady (testURL , common .DevWorkspaceRoutingName (workspaceID ))
1693+
1694+ deploy := & appsv1.Deployment {}
1695+ deployNN := namespacedName (common .DeploymentName (workspaceID ), testNamespace )
1696+ Eventually (func () error {
1697+ return k8sClient .Get (ctx , deployNN , deploy )
1698+ }, timeout , interval ).Should (Succeed (), "Getting workspace deployment from cluster" )
1699+
1700+ var testInit * corev1.Container
1701+ for i := range deploy .Spec .Template .Spec .InitContainers {
1702+ if deploy .Spec .Template .Spec .InitContainers [i ].Name == "test-init" {
1703+ testInit = & deploy .Spec .Template .Spec .InitContainers [i ]
1704+ }
1705+ }
1706+ Expect (testInit ).NotTo (BeNil (), "test-init container should be present" )
1707+ Expect (testInit .ImagePullPolicy ).To (Equal (corev1 .PullAlways ), "Explicit imagePullPolicy should be preserved" )
1708+ })
1709+
1710+ It ("Does not override base imagePullPolicy when DWOC init container has no explicit policy" , func () {
1711+ config .SetGlobalConfigForTesting (& controllerv1alpha1.OperatorConfiguration {
1712+ Workspace : & controllerv1alpha1.WorkspaceConfig {
1713+ ProjectCloneConfig : & controllerv1alpha1.ProjectCloneConfig {
1714+ ImagePullPolicy : corev1 .PullAlways ,
1715+ },
1716+ InitContainers : []corev1.Container {
1717+ {
1718+ Name : projects .ProjectClonerContainerName ,
1719+ Env : []corev1.EnvVar {{Name : "EXTRA_VAR" , Value : "injected" }},
1720+ },
1721+ },
1722+ },
1723+ })
1724+ defer config .SetGlobalConfigForTesting (nil )
1725+
1726+ createDevWorkspace (devWorkspaceName , "test-devworkspace.yaml" )
1727+ devworkspace := getExistingDevWorkspace (devWorkspaceName )
1728+ workspaceID := devworkspace .Status .DevWorkspaceId
1729+
1730+ By ("Manually making Routing ready to continue" )
1731+ markRoutingReady (testURL , common .DevWorkspaceRoutingName (workspaceID ))
1732+
1733+ deploy := & appsv1.Deployment {}
1734+ deployNN := namespacedName (common .DeploymentName (workspaceID ), testNamespace )
1735+ Eventually (func () error {
1736+ return k8sClient .Get (ctx , deployNN , deploy )
1737+ }, timeout , interval ).Should (Succeed (), "Getting workspace deployment from cluster" )
1738+
1739+ var projectClone * corev1.Container
1740+ for i := range deploy .Spec .Template .Spec .InitContainers {
1741+ if deploy .Spec .Template .Spec .InitContainers [i ].Name == projects .ProjectClonerContainerName {
1742+ projectClone = & deploy .Spec .Template .Spec .InitContainers [i ]
1743+ }
1744+ }
1745+ Expect (projectClone ).NotTo (BeNil (), "project-clone init container should be present" )
1746+ Expect (projectClone .ImagePullPolicy ).To (Equal (corev1 .PullAlways ), "DWOC patch should not override base imagePullPolicy" )
1747+ })
1748+
1749+ It ("Keeps workspace container imagePullPolicy as Always" , func () {
1750+ createDevWorkspace (devWorkspaceName , "test-devworkspace.yaml" )
1751+ devworkspace := getExistingDevWorkspace (devWorkspaceName )
1752+ workspaceID := devworkspace .Status .DevWorkspaceId
1753+
1754+ By ("Manually making Routing ready to continue" )
1755+ markRoutingReady (testURL , common .DevWorkspaceRoutingName (workspaceID ))
1756+
1757+ deploy := & appsv1.Deployment {}
1758+ deployNN := namespacedName (common .DeploymentName (workspaceID ), testNamespace )
1759+ Eventually (func () error {
1760+ return k8sClient .Get (ctx , deployNN , deploy )
1761+ }, timeout , interval ).Should (Succeed (), "Getting workspace deployment from cluster" )
1762+
1763+ var devContainer * corev1.Container
1764+ for i := range deploy .Spec .Template .Spec .Containers {
1765+ if deploy .Spec .Template .Spec .Containers [i ].Name == "web-terminal" {
1766+ devContainer = & deploy .Spec .Template .Spec .Containers [i ]
1767+ }
1768+ }
1769+ Expect (devContainer ).NotTo (BeNil (), "web-terminal container should be present" )
1770+ Expect (devContainer .ImagePullPolicy ).To (Equal (corev1 .PullAlways ), "Workspace containers should still default to Always" )
1771+ })
1772+ })
1773+
15581774 Context ("Edge cases" , func () {
15591775
15601776 It ("Allows Kubernetes and Container components to share same target port on endpoint" , func () {
0 commit comments