diff --git a/code/workspaces/infrastructure-api/resources/jupyter.deployment.template.yml b/code/workspaces/infrastructure-api/resources/jupyter.deployment.template.yml index 9c0b2b687..4ce273f7f 100644 --- a/code/workspaces/infrastructure-api/resources/jupyter.deployment.template.yml +++ b/code/workspaces/infrastructure-api/resources/jupyter.deployment.template.yml @@ -67,7 +67,7 @@ spec: - name: R_LIBS_USER value: "/data/packages/R/%p/%v" - name: JUPYTER_DATA_DIR - value: "/data/notebooks/{{ name }}/.jupyter" + value: "/data/.jupyter" - name: CONDA_ENV_DIR value: "/data/conda/" - name: JUPYTER_ALLOW_INSECURE_WRITES diff --git a/code/workspaces/infrastructure-api/src/kubernetes/__snapshots__/deploymentGenerator.spec.js.snap b/code/workspaces/infrastructure-api/src/kubernetes/__snapshots__/deploymentGenerator.spec.js.snap index d522e8d46..6899edb9c 100644 --- a/code/workspaces/infrastructure-api/src/kubernetes/__snapshots__/deploymentGenerator.spec.js.snap +++ b/code/workspaces/infrastructure-api/src/kubernetes/__snapshots__/deploymentGenerator.spec.js.snap @@ -300,7 +300,7 @@ spec: - name: R_LIBS_USER value: \\"/data/packages/R/%p/%v\\" - name: JUPYTER_DATA_DIR - value: \\"/data/notebooks/deployment-name/.jupyter\\" + value: \\"/data/.jupyter\\" - name: CONDA_ENV_DIR value: \\"/data/conda/\\" - name: JUPYTER_ALLOW_INSECURE_WRITES @@ -426,7 +426,7 @@ spec: - name: R_LIBS_USER value: \\"/data/packages/R/%p/%v\\" - name: JUPYTER_DATA_DIR - value: \\"/data/notebooks/deployment-name/.jupyter\\" + value: \\"/data/.jupyter\\" - name: CONDA_ENV_DIR value: \\"/data/conda/\\" - name: JUPYTER_ALLOW_INSECURE_WRITES diff --git a/code/workspaces/infrastructure-api/src/stacks/__snapshots__/shareStackManager.spec.js.snap b/code/workspaces/infrastructure-api/src/stacks/__snapshots__/shareStackManager.spec.js.snap deleted file mode 100644 index ca186ec66..000000000 --- a/code/workspaces/infrastructure-api/src/stacks/__snapshots__/shareStackManager.spec.js.snap +++ /dev/null @@ -1,39 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`handleSharedChange handles Jupyter notebooks changing to private 1`] = ` -"--- -apiVersion: batch/v1 -kind: Job -metadata: - name: job-stackname-1609459200 -spec: - ttlSecondsAfterFinished: 0 - template: - spec: - securityContext: - runAsUser: 1000 - containers: - - name: job-stackname-1609459200 - image: busybox - imagePullPolicy: IfNotPresent - command: [\\"sh\\"] - args: [\\"-c\\", \\"rm -f /mnt/persistentfs/notebooks/jupyterlab-stackname/.jupyter/runtime/jupyter_cookie_secret\\"] - volumeMounts: - - mountPath: /mnt/persistentfs - name: persistentfsvol - - name: curl-job - image: curlimages/curl - imagePullPolicy: IfNotPresent - command: [\\"sh\\"] - # Command in single quotes as there are double quotes in the command itself - args: [\\"-c\\", 'curl -X PUT host.docker.internal:undefined/stack/project/restart -H \\"Authorization: $TOKEN\\" -H \\"Content-Type: application/json\\" -d ''{\\"projectKey\\":\\"project\\",\\"name\\":\\"stackname\\",\\"type\\":\\"jupyterlab\\"}'''] - env: - - name: TOKEN - value: \\"Bearer token\\" - volumes: - - name: persistentfsvol - persistentVolumeClaim: - claimName: volume-claim - restartPolicy: Never -" -`; diff --git a/code/workspaces/infrastructure-api/src/stacks/shareStackManager.js b/code/workspaces/infrastructure-api/src/stacks/shareStackManager.js index 6c8758e98..f14c16347 100644 --- a/code/workspaces/infrastructure-api/src/stacks/shareStackManager.js +++ b/code/workspaces/infrastructure-api/src/stacks/shareStackManager.js @@ -11,7 +11,7 @@ import { visibility } from '../models/stackEnums'; import zeppelin from './zeppelinStack'; const { deploymentName } = nameGenerators; -const { JUPYTER, JUPYTERLAB, ZEPPELIN } = stackTypes; +const { ZEPPELIN } = stackTypes; const mountPath = '/mnt/persistentfs'; @@ -100,8 +100,8 @@ export const makeZeppelinPrivate = async (name, type, projectKey) => { await deploymentApi.restartDeployment(deployment, projectKey); }; -export const handleSharedChange = async (params, existing, newSharedStatus, userToken) => { - const { category, shared, type, volumeMount, visible } = existing; +export const handleSharedChange = async (params, existing, newSharedStatus) => { + const { category, shared, type, visible } = existing; const oldSharedStatus = shared || visible; @@ -126,13 +126,13 @@ export const handleSharedChange = async (params, existing, newSharedStatus, user } // No backend changes needed for other status changes - return; } if (category === NOTEBOOK_CATEGORY && newSharedStatus === visibility.PRIVATE) { - if (type === JUPYTER || type === JUPYTERLAB) { - await makeJupyterPrivate(name, type, projectKey, volumeMount, userToken); - } + // Temporarily disable Jupyter private option due to Conda issue (NERCDL-1188) + // if (type === JUPYTER || type === JUPYTERLAB) { + // await makeJupyterPrivate(name, type, projectKey, volumeMount, userToken); + // } if (type === ZEPPELIN) { await makeZeppelinPrivate(name, type, projectKey); diff --git a/code/workspaces/infrastructure-api/src/stacks/shareStackManager.spec.js b/code/workspaces/infrastructure-api/src/stacks/shareStackManager.spec.js index 1e1590268..4544179a3 100644 --- a/code/workspaces/infrastructure-api/src/stacks/shareStackManager.spec.js +++ b/code/workspaces/infrastructure-api/src/stacks/shareStackManager.spec.js @@ -19,7 +19,7 @@ const name = 'stackname'; const volumeMount = 'volume'; -const { JUPYTERLAB, ZEPPELIN, RSTUDIO, RSHINY } = stackTypes; +const { ZEPPELIN, RSTUDIO, RSHINY } = stackTypes; const getParams = () => ({ projectKey, @@ -146,43 +146,44 @@ describe('handleSharedChange', () => { expect(ingressApi.patchIngress).toHaveBeenCalledWith('rshiny-stackname', projectKey, expectedPatch); }); - it('handles Jupyter notebooks changing to private', async () => { - const existing = { - ...getExisting(), - category: NOTEBOOK_CATEGORY, - type: JUPYTERLAB, - }; - jest.spyOn(Date, 'now').mockReturnValue(1609459200); - - secretManager.createNewJupyterCredentials = jest.fn(() => ({ token: 'token' })); - deploymentApi.getDeployment.mockResolvedValueOnce({ - spec: { - template: { - spec: { - containers: [ - { - name: 'jupyterlab-stackname', - env: [ - { - name: 'JUPYTER_DATA_DIR', - value: '/data/notebooks/jupyterlab-stackname/.jupyter', - }, - ], - }, - ], - }, - }, - }, - }); - - await handleSharedChange(getParams(), existing, 'private', userToken); - - expectCalls({ createJob: 1, createStackCredentialSecret: 1, getDeployment: 1 }); - expect(secretManager.createStackCredentialSecret).toHaveBeenCalledWith(name, JUPYTERLAB, projectKey, { token: 'token' }); - expect(deploymentApi.getDeployment).toHaveBeenCalledWith('jupyterlab-stackname', projectKey); - expect(jobApi.createJob).toHaveBeenCalledWith(name, projectKey, expect.any(String)); - expect(jobApi.createJob.mock.calls[0][2]).toMatchSnapshot(); - }); + // Disable tests for making Jupyter/Zepplin private for the moment + // it('handles Jupyter notebooks changing to private', async () => { + // const existing = { + // ...getExisting(), + // category: NOTEBOOK_CATEGORY, + // type: JUPYTERLAB, + // }; + // jest.spyOn(Date, 'now').mockReturnValue(1609459200); + + // secretManager.createNewJupyterCredentials = jest.fn(() => ({ token: 'token' })); + // deploymentApi.getDeployment.mockResolvedValueOnce({ + // spec: { + // template: { + // spec: { + // containers: [ + // { + // name: 'jupyterlab-stackname', + // env: [ + // { + // name: 'JUPYTER_DATA_DIR', + // value: '/data/notebooks/jupyterlab-stackname/.jupyter', + // }, + // ], + // }, + // ], + // }, + // }, + // }, + // }); + + // await handleSharedChange(getParams(), existing, 'private', userToken); + + // expectCalls({ createJob: 1, createStackCredentialSecret: 1, getDeployment: 1 }); + // expect(secretManager.createStackCredentialSecret).toHaveBeenCalledWith(name, JUPYTERLAB, projectKey, { token: 'token' }); + // expect(deploymentApi.getDeployment).toHaveBeenCalledWith('jupyterlab-stackname', projectKey); + // expect(jobApi.createJob).toHaveBeenCalledWith(name, projectKey, expect.any(String)); + // expect(jobApi.createJob.mock.calls[0][2]).toMatchSnapshot(); + // }); it('handles Zeppelin notebooks changing to private', async () => { const existing = { diff --git a/code/workspaces/web-app/src/components/stacks/StackCardActions/StackCardActions.js b/code/workspaces/web-app/src/components/stacks/StackCardActions/StackCardActions.js index 91bdb1104..b6d6e7b59 100644 --- a/code/workspaces/web-app/src/components/stacks/StackCardActions/StackCardActions.js +++ b/code/workspaces/web-app/src/components/stacks/StackCardActions/StackCardActions.js @@ -60,7 +60,7 @@ export const getSharedButtons = (stack, shareStack, permission) => { const shared = stack.shared || stack.visible; return [ - shareButton(PRIVATE, 'Set Access: Private', shared === PRIVATE), + isSite ? shareButton(PRIVATE, 'Set Access: Private', shared === PRIVATE) : undefined, shareButton(PROJECT, 'Set Access: Project', shared === PROJECT), isSite ? shareButton(PUBLIC, 'Set Access: Public', shared === PUBLIC) : undefined, ]; diff --git a/code/workspaces/web-app/src/components/stacks/StackCardActions/StackCardActions.spec.js b/code/workspaces/web-app/src/components/stacks/StackCardActions/StackCardActions.spec.js index 2eb72fab2..cd5602eda 100644 --- a/code/workspaces/web-app/src/components/stacks/StackCardActions/StackCardActions.spec.js +++ b/code/workspaces/web-app/src/components/stacks/StackCardActions/StackCardActions.spec.js @@ -1,6 +1,6 @@ import React from 'react'; import { render, fireEvent, screen, within } from '@testing-library/react'; -import { SITE_CATEGORY } from 'common/src/config/images'; +import { NOTEBOOK_CATEGORY, SITE_CATEGORY } from 'common/src/config/images'; import { useCurrentUserId } from '../../../hooks/authHooks'; import StackCardActions, { getSharedButtons } from './StackCardActions'; import { getUserActionsForType } from '../../../config/images'; @@ -285,20 +285,24 @@ describe('getSharedButtons', () => { }); it('creates the correct buttons for a private stack', () => { - const stack = getStack(); + const stack = { + ...getStack(), + category: NOTEBOOK_CATEGORY, + }; const buttons = getSharedButtons(stack, jest.fn(), permission); - expect(buttons).toEqual([privateButton(true), projectButton(false), undefined]); + expect(buttons).toEqual([undefined, projectButton(false), undefined]); }); it('creates the correct buttons for a project stack', () => { const stack = { ...getStack(), shared: 'project', + category: NOTEBOOK_CATEGORY, }; const buttons = getSharedButtons(stack, jest.fn(), permission); - expect(buttons).toEqual([privateButton(false), projectButton(true), undefined]); + expect(buttons).toEqual([undefined, projectButton(true), undefined]); }); it('creates the correct buttons for a public stack', () => { diff --git a/code/workspaces/web-app/src/components/stacks/StackCardActions/__snapshots__/StackCardActions.spec.js.snap b/code/workspaces/web-app/src/components/stacks/StackCardActions/__snapshots__/StackCardActions.spec.js.snap index 24509296a..537f4efee 100644 --- a/code/workspaces/web-app/src/components/stacks/StackCardActions/__snapshots__/StackCardActions.spec.js.snap +++ b/code/workspaces/web-app/src/components/stacks/StackCardActions/__snapshots__/StackCardActions.spec.js.snap @@ -102,13 +102,6 @@ exports[`StackCardActions creates correct snapshot 2`] = ` Edit disabled: undefined -
- Set Access: Private - disabled: true -
-
- Set Access: Private - disabled: true -