- The container image reference is invalid or points to an
- unsupported registry. Please verify the image and check if the
- registry is in the currently supported{" "}
-
-
- integrations
-
- . If you're certain the image is correct and points to a
- registry we don't currently support,{" "}
-
-
- contact us
- {" "}
- about adding an integration.
-
+ The container image reference is invalid or points to an
+ unsupported registry. Please verify the image and check if
+ the registry is in the currently supported{" "}
- View integration
+ integrations
- >
- )}
-
- ) : (
-
-
- This container image reference is from a supported registry,
- but you haven't activated the integration yet. Activate
- the integration to check if you have access to this image.
-
-
-
- Go to Integration
-
-
- )}
-
- )}
+ . If you're certain the image is correct and points to
+ a registry we don't currently support,{" "}
+
+
+ contact us
+ {" "}
+ about adding an integration.
+
+
+ ) : data.connection?.status === "connected" ? (
+
+
+ Either the container image reference does not exist, or you
+ do not have access to it.
+
+ {data?.provider?.id && (
+ <>
+
+ If you think you should have access, check your
+ integration configuration.
+
+
+
+ View integration
+
+ >
+ )}
+
+ ) : (
+
+
+ This container image reference is from a supported registry,
+ but you haven't activated the integration yet. Activate
+ the integration to check if you have access to this image.
+
+
+
+ Go to Integration
+
+
+ )}
+
+ )}
{
@@ -80,6 +83,11 @@ export function BuildStatusBadge({
return isImageCompatibleWith(imageCheck, resourcePool.platform);
}, [imageCheck, resourcePool]);
+ const privateImageNotFound = useMemo(
+ () => imageSourceCheck?.status === "invalid",
+ [imageSourceCheck?.status]
+ );
+
const badgeIcon =
buildStatus === "in_progress" ? (
@@ -90,6 +98,8 @@ export function BuildStatusBadge({
const badgeText =
isCompatible === false
? "Image incompatible"
+ : privateImageNotFound
+ ? "Image not accessible"
: buildStatus === "in_progress"
? "Build in progress"
: buildStatus === "cancelled"
@@ -99,7 +109,7 @@ export function BuildStatusBadge({
: "Build failed";
const badgeColorClasses =
- isCompatible === false
+ isCompatible === false || privateImageNotFound
? ["border-danger", "bg-danger-subtle", "text-danger-emphasis"]
: buildStatus === "in_progress"
? ["border-warning", "bg-warning-subtle", "text-warning-emphasis"]
diff --git a/client/src/features/sessionsV2/components/SessionForm/BuilderEnvironmentFields.tsx b/client/src/features/sessionsV2/components/SessionForm/BuilderEnvironmentFields.tsx
index 1fff1297a5..99817f3cf7 100644
--- a/client/src/features/sessionsV2/components/SessionForm/BuilderEnvironmentFields.tsx
+++ b/client/src/features/sessionsV2/components/SessionForm/BuilderEnvironmentFields.tsx
@@ -19,10 +19,10 @@
import { skipToken } from "@reduxjs/toolkit/query";
import cx from "classnames";
import { useContext, useMemo } from "react";
-import { type Control } from "react-hook-form";
+import { useWatch, type Control, type Path } from "react-hook-form";
import { useProject } from "~/routes/projects/root";
-import { ErrorAlert, WarnAlert } from "../../../../components/Alert";
+import { ErrorAlert, InfoAlert, WarnAlert } from "../../../../components/Alert";
import RtkOrDataServicesError from "../../../../components/errors/RtkOrDataServicesError";
import { Loader } from "../../../../components/Loader";
import AppContext from "../../../../utils/context/appContext";
@@ -55,12 +55,26 @@ export default function BuilderEnvironmentFields({
repositories.length > 0 ? repositories : skipToken
);
+ const selectedRepositoryUrl = useWatch({
+ control,
+ name: "repository" as Path,
+ }) as string;
+
+ const selectedRepositoryIsPrivate = useMemo(
+ () =>
+ data?.find(
+ (repo) =>
+ repo.url === selectedRepositoryUrl &&
+ repo.data?.metadata?.visibility === "private"
+ ),
+ [data, selectedRepositoryUrl]
+ );
+
const firstEligibleRepository = useMemo(
() =>
data?.findIndex(
(repo) =>
- repo.data?.status === "valid" &&
- repo.data.metadata?.visibility === "public"
+ repo.data?.status === "valid" && repo.data.metadata?.pull_permission
),
[data]
);
@@ -91,8 +105,8 @@ export default function BuilderEnvironmentFields({
>
) : firstEligibleRepository == null || firstEligibleRepository < 0 ? (
- No publicly accessible code repositories found in this project. RenkuLab
- can only build session environments from public code repositories.
+ No accessible code repositories found in this project. Please ensure that
+ you have proper access to them.
) : (
@@ -102,6 +116,12 @@ export default function BuilderEnvironmentFields({
control={control}
repositoriesDetails={data}
/>
+ {selectedRepositoryIsPrivate && (
+
+ This is a private repository, launching the session will only be
+ available to users who have pull access to the repository.
+
+ )}
@@ -114,9 +134,7 @@ export default function BuilderEnvironmentFields({
{!isEdit && (
- Let RenkuLab create a customized environment from a code repository. A
- container image will be created based on the requirements found in the
- code repository.
+ Let RenkuLab create a customized environment from a code repository.