From 1fc9862706d7bef65ca5f021e163497e4097221d Mon Sep 17 00:00:00 2001
From: William Warriner <6930772+wwarriner@users.noreply.github.com>
Date: Tue, 23 Sep 2025 12:36:28 -0500
Subject: [PATCH 01/32] enable emoji
---
.vscode/settings.json | 6 +++++-
mkdocs.yml | 3 +++
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 5f040d0db..f62eeed4e 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -81,5 +81,9 @@
"markdown.extension.tableFormatter.enabled": false,
"markdown.extension.toc.updateOnSave": false,
"markdown.validate.unusedLinkDefinitions.enabled": "warning",
- "redhat.telemetry.enabled": false
+ "redhat.telemetry.enabled": false,
+ "yaml.customTags": [
+ "tag:yaml.org,2002:python/name:material.extensions.emoji.to_svg",
+ "tag:yaml.org,2002:python/name:material.extensions.emoji.twemoji"
+ ],
}
diff --git a/mkdocs.yml b/mkdocs.yml
index 2ffa3a84c..e83053541 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -32,6 +32,9 @@ markdown_extensions:
- pymdownx.arithmatex:
generic: true
- pymdownx.details
+ - pymdownx.emoji:
+ emoji_index: !!python/name:material.extensions.emoji.twemoji
+ emoji_generator: !!python/name:material.extensions.emoji.to_svg
- pymdownx.highlight:
anchor_linenums: true
- pymdownx.keys
From c0f90a6e1659553df82fd34292c806ad40d60fd4 Mon Sep 17 00:00:00 2001
From: William Warriner <6930772+wwarriner@users.noreply.github.com>
Date: Thu, 9 Oct 2025 15:29:58 -0500
Subject: [PATCH 02/32] add grid cards framework
---
macros/__init__.py | 52 +++++++++++
macros/base.py | 40 ++++++++
macros/card.py | 169 ++++++++++++++++++++++++++++++++++
macros/render.py | 183 +++++++++++++++++++++++++++++++++++++
res/.grid_cards_schema.yml | 154 +++++++++++++++++++++++++++++++
5 files changed, 598 insertions(+)
create mode 100644 macros/__init__.py
create mode 100644 macros/base.py
create mode 100644 macros/card.py
create mode 100644 macros/render.py
create mode 100644 res/.grid_cards_schema.yml
diff --git a/macros/__init__.py b/macros/__init__.py
new file mode 100644
index 000000000..065e974c4
--- /dev/null
+++ b/macros/__init__.py
@@ -0,0 +1,52 @@
+"""Grid Card macro definitions."""
+
+import os
+from pathlib import Path, PurePath
+from typing import Callable
+
+import yaml
+from mkdocs_macros.plugin import MacrosPlugin
+
+from .card import CardNamespace
+from .render import CardRenderer
+
+
+def define_env(env: MacrosPlugin) -> None:
+ """Define grid card macros for use in docs."""
+
+ def page_url_getter(env: MacrosPlugin) -> Callable[[], str]:
+ def fn() -> str:
+ return env.page.url
+
+ return fn
+
+ renderer = CardRenderer(page_url_getter(env)) # replace with macros fix_url()
+
+ cards_path = PurePath("res/grid_cards.yml")
+ with Path(cards_path).open("r") as f:
+ content = yaml.safe_load(f)
+ cards = CardNamespace.from_yaml("cards", content)
+
+ env.variables["cards"] = cards
+ env.variables["renderer"] = renderer
+ env.macro(list, "__dummy")
+
+ @env.macro
+ def include(rel_url: str, *, indent: int = 0) -> str:
+ mkdocs_url = to_docs_abs_url(rel_url)
+ with Path(mkdocs_url).open("r") as f:
+ lines = f.readlines()
+
+ if not lines:
+ return ""
+
+ first = lines[0]
+ lines = [" " * indent + line for line in lines[1:]]
+ lines.insert(0, first)
+ return "".join(lines)
+
+ def to_docs_abs_url(rel_url: str) -> PurePath:
+ link_url = PurePath(rel_url)
+ page_url = PurePath(env.page.url).parent
+ docs_dir = PurePath(env.conf["docs_dir"])
+ return docs_dir / os.path.normpath(page_url / link_url)
diff --git a/macros/base.py b/macros/base.py
new file mode 100644
index 000000000..a06007705
--- /dev/null
+++ b/macros/base.py
@@ -0,0 +1,40 @@
+"""Base definitions for Grid Card objects."""
+
+from __future__ import annotations
+
+import abc
+from dataclasses import dataclass, field
+from typing import TYPE_CHECKING, Self
+
+if TYPE_CHECKING:
+ from macros.card import CardNamespace
+
+
+@dataclass
+class CardElement:
+ """Base CardElement."""
+
+ name: str
+ parent: CardNamespace | None = field(default=None, init=False)
+
+ def __post_init__(self) -> None:
+ """Validate card element name."""
+ if not self.name.isidentifier():
+ msg = "CardElement name must be a valid identifier."
+ raise ValueError(msg)
+
+ def get_path(self) -> str:
+ """Get path of this namespace down to root."""
+ parts: list[str] = []
+ element = self
+
+ while element.parent:
+ parts.append(element.name)
+ element = element.parent
+
+ return ".".join(reversed(parts))
+
+ @classmethod
+ @abc.abstractmethod
+ def from_yaml(cls, name: str, content: dict) -> Self:
+ """Build from YAML."""
diff --git a/macros/card.py b/macros/card.py
new file mode 100644
index 000000000..2e1345450
--- /dev/null
+++ b/macros/card.py
@@ -0,0 +1,169 @@
+"""Grid Card definitions.
+
+Derives from CardElement for shared elements.
+
+Leaves of a tree structure.
+"""
+
+from __future__ import annotations
+
+import enum
+from dataclasses import dataclass, field
+from types import SimpleNamespace
+from typing import Literal, Self, overload
+
+from macros.base import CardElement
+
+
+class EmojiSizesCss(enum.Enum):
+ """CSS Emoji Sizes."""
+
+ standard = ""
+ large = ".lg"
+ xlarge = ".xlg"
+ xxlarge = ".xxlg"
+ xxxlarge = ".xxxlg"
+
+ @classmethod
+ def default(cls) -> EmojiSizesCss:
+ """Return default."""
+ return cls.large
+
+
+class EmojiVerticalAlignmentCss(enum.Enum):
+ """CSS Emoji Vertical Alignments."""
+
+ standard = ""
+ middle = ".middle"
+
+ @classmethod
+ def default(cls) -> EmojiVerticalAlignmentCss:
+ """Return default."""
+ return cls.middle
+
+
+@dataclass
+class Card(CardElement):
+ """Representation of a grid card."""
+
+ title_text: str
+ title_url: str | None = None
+
+ icon_name: str | None = None
+ icon_color: str | None = None
+ icon_size: EmojiSizesCss | None = None
+ icon_vertical_alignment: EmojiVerticalAlignmentCss | None = None
+ content: str | None = None
+
+ link_url: str | None = None
+ link_text: str | None = None
+ link_icon_name: str | None = None
+
+ def __post_init__(self) -> None:
+ """Validate title text."""
+ super().__post_init__()
+ if not self.title_text:
+ msg = "Card must have non-empty title."
+ raise ValueError(msg)
+
+ @classmethod
+ def from_yaml(cls, name: str, content: dict) -> Self:
+ """Build card from YAML representation."""
+ return cls(
+ name=name,
+ title_text=content["title_text"],
+ title_url=content.get("title_url"),
+ icon_name=content.get("icon_name"),
+ icon_color=content.get("icon_color"),
+ icon_size=content.get("icon_size"),
+ icon_vertical_alignment=content.get("icon_vertical_alignment"),
+ content=content.get("content"),
+ link_text=content.get("link_text"),
+ link_url=content.get("link_url"),
+ )
+
+
+@dataclass
+class CardNamespace(CardElement, SimpleNamespace):
+ """Namespace of grid card collection."""
+
+ def __setattr__(self, name: str, value: CardNamespace | Card) -> None:
+ """Override setattr() and dot operator."""
+ if name.startswith("_") or name in ("name", "parent"):
+ object.__setattr__(self, name, value)
+ return
+ if isinstance(value, (Card, CardNamespace)):
+ if hasattr(self, name):
+ path = self.get_path()
+ path = f"{path}.{name}" if path else name
+ msg = f"duplicate namespace or card found: {path}"
+ raise KeyError(msg)
+ value.parent = self
+ self._children.append(value)
+ object.__setattr__(self, name, value)
+ return
+ msg = "CardNamespace may only hold CardNamespace or Card."
+ raise TypeError(msg)
+
+ @overload
+ def get_children(
+ self,
+ *,
+ recursive: bool = ...,
+ cards_only: Literal[False],
+ ) -> list[Card | CardNamespace]: ...
+
+ @overload
+ def get_children(
+ self,
+ *,
+ recursive: bool = ...,
+ cards_only: Literal[True] = True,
+ ) -> list[Card]: ...
+
+ def get_children(
+ self,
+ *,
+ recursive: bool = False,
+ cards_only: bool = True,
+ ) -> list[Card | CardNamespace] | list[Card]:
+ """Get all cards that are children of this card.
+
+ If recursive is True, children of children, etc., are also returned,
+ depth first.
+ """
+ children: list[Card | CardNamespace] = []
+ for child in self._children:
+ if not cards_only or isinstance(child, Card):
+ children.append(child)
+ if isinstance(child, CardNamespace) and recursive:
+ children.extend(
+ child.get_children(recursive=recursive, cards_only=cards_only),
+ )
+ return children
+
+ def to_dict(
+ self,
+ *,
+ cards_only: bool = True,
+ ) -> dict[str, Card | CardNamespace] | dict[str, Card]:
+ """Children as dict of (path, Card).
+
+ If cards_only is False, also returns CardNamespaces.
+ """
+ return {
+ c.get_path(): c
+ for c in self.get_children(recursive=True, cards_only=cards_only)
+ }
+
+ @classmethod
+ def from_yaml(cls, name: str, content: dict) -> Self:
+ """Build from YAML."""
+ namespace = cls(name)
+ for child_name, child_content in content.items():
+ child_type = Card if "title_text" in child_content else cls
+ child = child_type.from_yaml(child_name, child_content)
+ setattr(namespace, child_name, child)
+ return namespace
+
+ _children: list[CardNamespace | Card] = field(default_factory=list)
diff --git a/macros/render.py b/macros/render.py
new file mode 100644
index 000000000..c8a1b7703
--- /dev/null
+++ b/macros/render.py
@@ -0,0 +1,183 @@
+"""Model rendering."""
+
+from __future__ import annotations
+
+import os
+import textwrap
+from pathlib import PurePath
+from typing import Callable
+
+from macros.card import Card, CardNamespace, EmojiSizesCss, EmojiVerticalAlignmentCss
+
+
+class CardRenderer:
+ """Handles rendering of cards."""
+
+ def __init__(
+ self,
+ get_page_url_fn: Callable[[], str],
+ *,
+ indent: int = 4,
+ ) -> None:
+ """Initialize new object."""
+ self._get_page_url: Callable[[], str] = get_page_url_fn
+ self._indent: int = indent
+
+ def render_cards(self, *cards: Card) -> str:
+ """Render input to markdown string.
+
+ Intended for use with mkdocs-material grid cards.
+ """
+ parts = [self._div_open]
+ extractors = [
+ _CardExtractor(self._get_page_url(), card, self._indent) for card in cards
+ ]
+ card_parts = [ex.extract() for ex in extractors]
+ card_parts = [part for cards in card_parts for part in cards]
+ parts.extend(card_parts)
+ parts.append(self._div_close)
+ return "\n\n" + "\n\n".join(parts) + "\n\n"
+
+ def render_namespace(
+ self,
+ namespace: CardNamespace,
+ *,
+ recursive: bool = False,
+ ) -> str:
+ """Render input namespaceto markdown string.
+
+ Intended for use with mkdocs-material grid cards.
+ """
+ cards = namespace.get_children(recursive=recursive, cards_only=True)
+ return self.render_cards(*cards)
+
+ _div_open = r'
'
+ _div_close = r"
"
+
+
+class _CardExtractor:
+ def __init__(self, page_url: str, card: Card, indent: int) -> None:
+ self._page_url: str = page_url
+ self._card: Card = card
+ self._indent: int = indent
+
+ def extract(self) -> list[str]:
+ indented_block = []
+ content = self._content_part()
+ if content:
+ indented_block.append(content)
+ link = self._link_part()
+ if link:
+ indented_block.append(link)
+ if indented_block:
+ indented_block.insert(0, self._hr)
+
+ parts = [self._title_part()]
+ parts.extend([self._clean_and_indent(part) for part in indented_block])
+ return parts
+
+ #### DEFAULTS
+ _DEFAULT_ICON_COLOR = ".icon-color-uab-green"
+ _DEFAULT_ICON_SIZE = EmojiSizesCss.large
+ _DEFAULT_ICON_VERTICAL_ALIGNMENT = EmojiVerticalAlignmentCss.middle
+ _DEFAULT_LINK_TEXT = "Read more"
+ _DEFAULT_LINK_ICON_NAME = ":octicons-arrow-right-24:"
+
+ #### DEFINITIONS
+ _ul = "-"
+ _hr = "---"
+
+ #### TITLE PART
+ def _title_part(self) -> str:
+ parts = [self._ul]
+ icon = self._icon()
+ if icon:
+ parts.append(icon)
+ parts.append(self._title())
+ return " ".join(parts)
+
+ ## TITLE
+ def _title(self) -> str:
+ text = self._title_text()
+ url = self._title_url()
+ return self._to_md_internal_link(text, url) if url else text
+
+ def _title_text(self) -> str:
+ return f"**{self._card.title_text}**"
+
+ def _title_url(self) -> str | None:
+ url = self._card.title_url
+ return self._to_url_relative_to_page(url) if url else None
+
+ ## ICON
+ def _icon(self) -> str | None:
+ name = self._icon_name()
+ css = self._icon_css()
+ if name and css:
+ return name + css
+ if name:
+ return name
+ return None
+
+ def _icon_name(self) -> str | None:
+ return self._card.icon_name
+
+ def _icon_css(self) -> str | None:
+ css_classes = [
+ self._icon_size(),
+ self._icon_vertical_alignment(),
+ self._icon_color(),
+ ]
+ return "{ " + " ".join(css_classes) + " }" if css_classes else None
+
+ def _icon_size(self) -> str:
+ size = self._card.icon_size
+ return size.value if size else EmojiSizesCss.default().value
+
+ def _icon_vertical_alignment(self) -> str:
+ va = self._card.icon_vertical_alignment
+ return va.value if va else EmojiVerticalAlignmentCss.default().value
+
+ def _icon_color(self) -> str:
+ color = self._card.icon_color
+ return color if color else self._DEFAULT_ICON_COLOR
+
+ #### CONTENT PART
+ def _content_part(self) -> str | None:
+ return self._card.content
+
+ #### LINK PART
+ def _link_part(self) -> str | None:
+ text = f"{self._link_text()} {self._link_icon()}"
+ url = self._link_url()
+ return self._to_md_internal_link(text, url) if url else None
+
+ def _link_text(self) -> str:
+ text = self._card.link_text
+ return text if text else self._DEFAULT_LINK_TEXT
+
+ def _link_icon(self) -> str:
+ name = self._card.link_icon_name
+ return name if name else self._DEFAULT_LINK_ICON_NAME
+
+ def _link_url(self) -> str | None:
+ url = self._card.link_url
+ return self._to_url_relative_to_page(url) if url else None
+
+ #### HELPERS
+ def _clean_and_indent(self, s: str) -> str:
+ out = s
+ out = textwrap.dedent(out)
+ out = out.strip()
+ return textwrap.indent(out, " " * self._indent)
+
+ def _to_url_relative_to_page(self, start_url: str) -> str:
+ root = PurePath("/root/")
+
+ link = root / start_url
+ page = root / self._page_url
+
+ return PurePath(os.path.relpath(link, page)).as_posix()
+
+ def _to_md_internal_link(self, text: str, url: str) -> str:
+ return f"[{text}]({url})"
diff --git a/res/.grid_cards_schema.yml b/res/.grid_cards_schema.yml
new file mode 100644
index 000000000..186d18449
--- /dev/null
+++ b/res/.grid_cards_schema.yml
@@ -0,0 +1,154 @@
+$ref: "#/definitions/namespace"
+
+definitions:
+ namespace:
+ type: object
+ title: Namespace
+ description: |
+ A namespace for organizing grid cards.
+ minProperties: 1
+ propertyNames:
+ pattern: "^(?!^title_text|name|parent|_children$).*$"
+ patternProperties:
+ "^(?!^title_text|name|parent|_children$).*$":
+ oneOf:
+ - $ref: "#/definitions/namespace"
+ - $ref: "#/definitions/content_card"
+ - $ref: "#/definitions/title_card"
+
+ content_card:
+ type: object
+ title: Content Card
+ description: |
+ The definition for a card with descriptive content.
+ Content and a link url are both required.
+ All fields are allowed except the title URL.
+ required:
+ - title_text
+ - content
+ - link_url
+ additionalProperties: false
+ properties:
+ title_text:
+ ref: "#/definitions/title_text"
+ icon_name:
+ ref: "#/definitions/icon_name"
+ icon_color:
+ ref: "#/definitions/icon_color"
+ icon_size:
+ ref: "#/definitions/icon_size"
+ icon_vertical_alignment:
+ ref: "#/definitions/icon_vertical_alignment"
+ content:
+ ref: "#/definitions/content"
+ link_text:
+ ref: "#/definitions/link_text"
+ link_url:
+ ref: "#/definitions/link_url"
+ link_icon_name:
+ ref: "#/definitions/icon_name"
+
+ title_card:
+ type: object
+ title: Title-only Card
+ description: |
+ The definition for a card with only a title line.
+ A URL must be supplied so the title links to a page or section.
+ Icon information may be supplied.
+ No other information is allowed.
+ required:
+ - title_text
+ - title_url
+ additionalProperties: false
+ properties:
+ title_text:
+ ref: "#/definitions/title_text"
+ title_url:
+ ref: "#/definitions/link_url"
+ icon_name:
+ ref: "#/definitions/icon_name"
+ icon_color:
+ ref: "#/definitions/icon_color"
+ icon_size:
+ ref: "#/definitions/icon_size"
+ icon_vertical_alignment:
+ ref: "#/definitions/icon_vertical_alignment"
+
+ title_text:
+ type: string
+ title: Card Title Text
+ description: |
+ A brief, descriptive, single-line title for the card.
+ Inline Markdown formatting may be used, such as links.
+ minLength: 1
+
+ content:
+ type: string
+ title: Card Markdown Content
+ description: |
+ Markdown content to describe the card.
+ Inline and block Markdown formatting may be used.
+ Links to other pages are encouraged.
+ Please keep it relatively brief.
+ Nested blocks are not recommended.
+ minLength: 1
+
+ link_text:
+ type: string
+ title: Absolute Internal Link Text
+ description: |
+ Optional text to use as link text for "link_url".
+ Defaults to "Read more".
+ minLength: 1
+
+ link_url:
+ type: string
+ title: Absolute Internal Link URL
+ description: |
+ Absolute url from within "docs_dir" to referenced page or section.
+ minLength: 1
+
+ icon_name:
+ type: string
+ title: Mkdocs Material Theme Icon Name
+ description: |
+ Icon name, formatted like ":icon-name:".
+ Icons come from https://squidfunk.github.io/mkdocs-material/reference/icons-emojis/?h=emoji.
+ An eye-catching, relevant icon is recommended.
+ minLength: 1
+ pattern: "^:([a-z0-9]+)(-[a-z0-9]+)*:$"
+
+ icon_color:
+ type: string
+ title: Icon Color CSS Class
+ description: |
+ Icon color.
+ The icon color must be formatted like ".icon-name-...".
+ Colors must be defined as CSS classes in "docs/stylesheets/extra.css"
+ minLength: 13
+ pattern: "^\\.icon-color-[a-z0-9]+[a-z0-9-]*$"
+
+ icon_size:
+ type: string
+ title: Icon Size
+ description: |
+ Icon size.
+ A CSS class indicating desired icon size.
+ These come from the Mkdocs Material theme.
+ enum:
+ - ""
+ - ".lg"
+ - ".xlg"
+ - ".xxlg"
+ - ".xxxlg"
+
+ icon_vertical_alignment:
+ type: string
+ title: Icon Vertical Alignment
+ description: |
+ Icon vertical alignment.
+ A CSS class indicating desired icon vertical alignment.
+ These come from the Mkdocs Material theme.
+ enum:
+ - ""
+ - ".middle"
From f7ee1d4c644cf636526299cf8880a9d724fc6b3f Mon Sep 17 00:00:00 2001
From: William Warriner <6930772+wwarriner@users.noreply.github.com>
Date: Thu, 9 Oct 2025 15:31:41 -0500
Subject: [PATCH 03/32] add yaml schemas for vscode
---
.vscode/settings.json | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 9be1023b0..d283e5298 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -109,7 +109,16 @@
"markdown.validate.unusedLinkDefinitions.enabled": "warning",
"redhat.telemetry.enabled": false,
"yaml.customTags": [
+ "!ENV scalar",
+ "!ENV sequence",
+ "!relative scalar",
"tag:yaml.org,2002:python/name:material.extensions.emoji.to_svg",
- "tag:yaml.org,2002:python/name:material.extensions.emoji.twemoji"
+ "tag:yaml.org,2002:python/name:material.extensions.emoji.twemoji",
+ "tag:yaml.org,2002:python/name:pymdownx.superfences.fence_code_format",
+ "tag:yaml.org,2002:python/object/apply:pymdownx.slugs.slugify mapping"
],
+ "yaml.schemas": {
+ "./res/.grid_cards_schema.yml": "/res/grid_cards.yml",
+ // "https://squidfunk.github.io/mkdocs-material/schema.json": "mkdocs.yml"
+ }
}
From 2e77f12f00fe5bdd6da8a12a03fad38f26fa3b59 Mon Sep 17 00:00:00 2001
From: William Warriner <6930772+wwarriner@users.noreply.github.com>
Date: Wed, 15 Oct 2025 14:10:33 -0500
Subject: [PATCH 04/32] pre-migrate faq-style content out of account-mgmt
---
docs/cheaha/getting_started.md | 17 +++++++++++++++++
docs/uab_cloud/index.md | 10 ++++++++++
2 files changed, 27 insertions(+)
diff --git a/docs/cheaha/getting_started.md b/docs/cheaha/getting_started.md
index 0bc588b6d..f31b1d36d 100644
--- a/docs/cheaha/getting_started.md
+++ b/docs/cheaha/getting_started.md
@@ -175,3 +175,20 @@ If the software installation instructions tell you to use either `conda install`
## How to Get Help
For questions, you can reach out via our various [channels](../help/support.md).
+
+## Frequently Asked Questions
+
+- **What should I do to access shared storages and recognize my group membership after being added to a group on Cheaha?**
+
+ - **Do you have any processes/connections on `cheaha.rc.uab.edu`**?
+
+ - Please exit and log back in.
+ - If you have active Tmux/Screen sessions, you will need to terminate those as well, log out, log back in and start Tmux.
+
+ - **Do you have an active Open OnDemand session?**
+
+ - In Open OnDemand (), navigate to the green navigation bar in the top right corner. Look for the `Help` or `Developer` dropdown menu and click on it. Then, click `Restart Web Server`. Once the restart is complete, please try again.
+
+ - **Do you have one or more OOD HPC Desktops running?**
+
+ - Terminate the desktops and start new ones.
diff --git a/docs/uab_cloud/index.md b/docs/uab_cloud/index.md
index 0d4923150..d8969f395 100644
--- a/docs/uab_cloud/index.md
+++ b/docs/uab_cloud/index.md
@@ -49,3 +49,13 @@ Please use the following rules when naming entities:
- Must: use only letters, numbers, dash `-` and underscore `_`.
- Must: have the first character in the name be a letter.
- Should: use short, descriptive, memorable names.
+
+## Frequently Asked Questions
+
+- **How Do I Access Cloud.rc?**
+
+ - To access the Cloud.rc, you must be on the campus network.
+ - For off-campus access, use the [UAB Campus VPN](https://www.uab.edu/it/home/tech-solutions/network/vpn), which requires [Duo 2FA](https://www.uab.edu/it/home/security/2-factor).
+ - UAB employees and students can log in using their BlazerID
+ - External Collaborators can use their XIAS email.
+ - For login details, visit our [Cloud.rc](#first-steps) section.
From a1c4e4ed1660498c67a65712e484cf534138fa6b Mon Sep 17 00:00:00 2001
From: William Warriner <6930772+wwarriner@users.noreply.github.com>
Date: Wed, 15 Oct 2025 14:13:41 -0500
Subject: [PATCH 05/32] content cleanup
---
docs/cheaha/getting_started.md | 32 ++++++++++++++++++++++++--------
1 file changed, 24 insertions(+), 8 deletions(-)
diff --git a/docs/cheaha/getting_started.md b/docs/cheaha/getting_started.md
index f31b1d36d..80fb656e3 100644
--- a/docs/cheaha/getting_started.md
+++ b/docs/cheaha/getting_started.md
@@ -4,7 +4,23 @@ toc_depth: 3
# Getting Started
-Cheaha is a High Performance Computing (HPC) resource intended primarily for batch processing of research computing software. We offer a user-friendly portal website Open OnDemand with graphical interfaces to the most common features, all in one place. Read on to learn more about our resources and how to access them.
+Cheaha is the batch compute cluster platform of the Research Computing System (RCS). Cheaha is intended primarily for batch processing of research computing software. We offer a user-friendly portal website Open OnDemand with graphical interfaces to the most common features, all in one place. Read on to learn more about our resources and how to access them.
+
+Cheaha is appropriate for the following types of workflows:
+
+- High Performance Computing (HPC)
+- High Throughput Computing (HTC)
+- Batch Computing
+- Graphical User Interface (GUI) and other interactive software
+
+Please bear in mind the following expectations when using Cheaha.
+
+- Resources are shared by many researchers.
+- Jobs may take time to start.
+- Jobs, partitions, and researchers all have caps on total resources in use at any one time.
+- All jobs have a maximum time limit.
+
+If your needs go beyond these expectations, please [Contact Support](../help/support.md).
## Getting Help
@@ -50,13 +66,13 @@ Please visit our [Storage page](../data_management/index.md) for detailed inform
Compute nodes are divided into groups called partitions each with specific qualities suitable for different kinds of workflows or software. In order to submit a compute job, a partition must be chosen in the Slurm options. The partitions can be roughly grouped as such:
-| Use | Partition Names | Notes |
-|---|---|---|
-| GPU Processing | pascalnodes, pascalnodes-medium, amperenodes, amperenodes-medium | These are the only partitions with GPUs |
-| All Purpose | amd-hdr100 | Runs AMD CPUs compared to all other CPU partitions running Intel. [Contact us](../index.md#how-to-contact-us) with issues running on this partition |
-| Shorter time | express, short, intel-dcb | |
-| Medium-long time | medium, long | |
-| Very large memory | largemem, largemem-long | |
+| Use | Partition Names | Notes |
+|-------------------|------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------|
+| GPU Processing | pascalnodes, pascalnodes-medium, amperenodes, amperenodes-medium | These are the only partitions with GPUs |
+| All Purpose | amd-hdr100 | Runs AMD CPUs compared to all other CPU partitions running Intel. [Contact us](../index.md#how-to-contact-us) with issues running on this partition |
+| Shorter time | express, short, intel-dcb | |
+| Medium-long time | medium, long | |
+| Very large memory | largemem, largemem-long | |
Please visit our [hardware](hardware.md#cheaha-hpc-cluster) for more details about the partitions.
From 0b2d4e56fee5a74e89fc7e793a25b0eb4d3d3532 Mon Sep 17 00:00:00 2001
From: William Warriner <6930772+wwarriner@users.noreply.github.com>
Date: Wed, 15 Oct 2025 14:14:56 -0500
Subject: [PATCH 06/32] resolve tab anchor bug
---
build_env.yml | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/build_env.yml b/build_env.yml
index 8cc451ceb..dbb2ac832 100644
--- a/build_env.yml
+++ b/build_env.yml
@@ -3,18 +3,13 @@ dependencies:
- conda-forge::click=8.2.1
- conda-forge::jinja2=3.1.6
- conda-forge::libffi=3.4.6
- - conda-forge::markdown=3.8.0
- conda-forge::markupsafe=3.0.2 # Not semver, be cautious
- conda-forge::mergedeep=1.3.4
- - conda-forge::mkdocs=1.6.1
- - conda-forge::mkdocs-material=9.6.14
- - conda-forge::mkdocs-material-extensions=1.3.1
- conda-forge::numpy=2.2.6
- conda-forge::pandas=2.3.0
- conda-forge::pandoc=3.7.0.2
- conda-forge::pip=25.1.1
- conda-forge::pygments=2.19.1
- - conda-forge::pymdown-extensions=10.15 # Not semver, be cautious
- conda-forge::pypandoc=1.15
- conda-forge::pyparsing=3.0.9
- conda-forge::python=3.13.3
@@ -31,11 +26,16 @@ dependencies:
- conda-forge::yaml=0.2.5
- conda-forge::yamllint=1.37.1
- pip:
+ - markdown==3.8.0
- mkdocs-gen-files==0.5.0
- mkdocs-glightbox==0.3.7
- mkdocs-git-revision-date-localized-plugin==1.2.6
+ - mkdocs-macros-plugin==1.3.9 # new
+ - mkdocs-material==9.6.14
- mkdocs-redirects==1.2.1
- - mkdocs-table-reader-plugin==2.0.3
+ - mkdocs-table-reader-plugin==3.1.0
- linkchecker==10.4.0
- pre-commit==3.7.1
+ - pymdown-extensions==10.8.1 # Not semver, be cautious
+ - git+https://github.com/uabrc/mkdocs@888fd28f92a320352f63600c24635231a42e5fac # new
- git+https://github.com/uabrc/mkdocs-title-casing-plugin.git@stable
From 851ab9024354f0f5cecf893ba1b60f039f4484a5 Mon Sep 17 00:00:00 2001
From: William Warriner <6930772+wwarriner@users.noreply.github.com>
Date: Wed, 15 Oct 2025 14:18:09 -0500
Subject: [PATCH 07/32] add some j2 templates
---
docs/_template/base_help_section.md.j2 | 4 ++++
docs/_template/help_macros.md.j2 | 13 +++++++++++++
docs/_template/link.md.j2 | 3 +++
docs/_template/uab_employee_use_only.md.j2 | 3 +++
4 files changed, 23 insertions(+)
create mode 100644 docs/_template/base_help_section.md.j2
create mode 100644 docs/_template/help_macros.md.j2
create mode 100644 docs/_template/link.md.j2
create mode 100644 docs/_template/uab_employee_use_only.md.j2
diff --git a/docs/_template/base_help_section.md.j2 b/docs/_template/base_help_section.md.j2
new file mode 100644
index 000000000..2324afb52
--- /dev/null
+++ b/docs/_template/base_help_section.md.j2
@@ -0,0 +1,4 @@
+{% import "_template/help_macros.md.j2" as help %}
+{{ help.help_header(2) }}
+
+For help, please {{ help.contact_support_link() }}.
diff --git a/docs/_template/help_macros.md.j2 b/docs/_template/help_macros.md.j2
new file mode 100644
index 000000000..847b05980
--- /dev/null
+++ b/docs/_template/help_macros.md.j2
@@ -0,0 +1,13 @@
+{% from "_template/link.md.j2" import link %}
+
+{% macro contact_support_link() -%}
+{{ link("Contact Support", "help/support.md") }}
+{%- endmacro %}
+
+{% macro _header(title, level) -%}
+{% for i in range(level) -%}{{- "#" -}}{%- endfor %} {{ title }}
+{%- endmacro %}
+
+{% macro help_header(level) -%}
+{{ _header("Help", level) }}
+{%- endmacro %}
diff --git a/docs/_template/link.md.j2 b/docs/_template/link.md.j2
new file mode 100644
index 000000000..d68f9177d
--- /dev/null
+++ b/docs/_template/link.md.j2
@@ -0,0 +1,3 @@
+{% macro link(text, path) -%}
+[{{ text }}]({{ path | to_page_rel_url }})
+{%- endmacro %}
diff --git a/docs/_template/uab_employee_use_only.md.j2 b/docs/_template/uab_employee_use_only.md.j2
new file mode 100644
index 000000000..aadf0b757
--- /dev/null
+++ b/docs/_template/uab_employee_use_only.md.j2
@@ -0,0 +1,3 @@
+!!! note
+
+ These instructions are intended for use by UAB employees.
From 2eb08004e093bf48e3da1b7f81e87af586770dda Mon Sep 17 00:00:00 2001
From: William Warriner <6930772+wwarriner@users.noreply.github.com>
Date: Wed, 15 Oct 2025 14:32:10 -0500
Subject: [PATCH 08/32] prepare machinery for cards
---
.vscode/extensions.json | 1 +
.vscode/settings.json | 17 +++--
macros/__init__.py | 19 ++++-
mkdocs.yml | 9 +++
res/grid_cards.yml | 152 ++++++++++++++++++++++++++++++++++++++++
5 files changed, 192 insertions(+), 6 deletions(-)
create mode 100644 res/grid_cards.yml
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
index faa2964bf..e4a2a577d 100644
--- a/.vscode/extensions.json
+++ b/.vscode/extensions.json
@@ -4,6 +4,7 @@
"DavidAnson.vscode-markdownlint",
"ms-python.python",
"redhat.vscode-yaml",
+ "samuelcolvin.jinjahtml",
"tamasfe.even-better-toml",
"yzhang.markdown-all-in-one",
]
diff --git a/.vscode/settings.json b/.vscode/settings.json
index d283e5298..ae3f6b816 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -16,6 +16,15 @@
"editor.wordWrap": "on",
"files.eol": "\n"
},
+ "[jinja-md]": {
+ "editor.defaultFormatter": "samuelcolvin.jinjahtml",
+ "editor.formatOnSave": true,
+ "editor.indentSize": 4,
+ "editor.insertSpaces": true,
+ "editor.tabSize": 4,
+ "editor.wordWrap": "on",
+ "files.eol": "\n"
+ },
"[json]": {
"editor.defaultFormatter": "vscode.json-language-features",
"editor.formatOnSave": true,
@@ -90,12 +99,12 @@
"editor.tabSize": 2,
"files.eol": "\n"
},
- "files.insertFinalNewline": true,
- "files.trimFinalNewlines": true,
- "files.trimTrailingWhitespace": true,
"files.exclude": {
"**/node_modules/*": true
},
+ "files.insertFinalNewline": true,
+ "files.trimFinalNewlines": true,
+ "files.trimTrailingWhitespace": true,
"files.watcherExclude": {
"**/node_modules/*": true
},
@@ -118,7 +127,7 @@
"tag:yaml.org,2002:python/object/apply:pymdownx.slugs.slugify mapping"
],
"yaml.schemas": {
- "./res/.grid_cards_schema.yml": "/res/grid_cards.yml",
+ "./res/.grid_cards_schema.yml": "/res/grid_cards.yml"
// "https://squidfunk.github.io/mkdocs-material/schema.json": "mkdocs.yml"
}
}
diff --git a/macros/__init__.py b/macros/__init__.py
index 065e974c4..6a07b3380 100644
--- a/macros/__init__.py
+++ b/macros/__init__.py
@@ -23,7 +23,7 @@ def fn() -> str:
renderer = CardRenderer(page_url_getter(env)) # replace with macros fix_url()
cards_path = PurePath("res/grid_cards.yml")
- with Path(cards_path).open("r") as f:
+ with Path(cards_path).open("r", encoding="utf-8") as f:
content = yaml.safe_load(f)
cards = CardNamespace.from_yaml("cards", content)
@@ -46,7 +46,22 @@ def include(rel_url: str, *, indent: int = 0) -> str:
return "".join(lines)
def to_docs_abs_url(rel_url: str) -> PurePath:
+ page = env.page
+
link_url = PurePath(rel_url)
- page_url = PurePath(env.page.url).parent
+ page_url = PurePath(page.url)
+ if not page.is_index:
+ page_url = page_url.parent
docs_dir = PurePath(env.conf["docs_dir"])
return docs_dir / os.path.normpath(page_url / link_url)
+
+ @env.filter
+ def to_page_rel_url(docs_dir_url: str) -> str:
+ page = env.page
+ docs_dir = PurePath(env.conf["docs_dir"])
+ target_url = docs_dir / docs_dir_url
+ page_url = docs_dir / page.url
+ if not page.is_index:
+ page_url = page_url.parent
+ out = PurePath(os.path.relpath(target_url, page_url))
+ return out.as_posix()
diff --git a/mkdocs.yml b/mkdocs.yml
index 7c7f9d7c0..e5a112a80 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -66,6 +66,11 @@ plugins: # order matters!
type: date
strict: false
- glightbox
+ - macros:
+ module_name: macros
+ on_undefined: strict
+ render_by_default: false
+ verbose: true
- table-reader:
data_path: docs
- title-casing
@@ -107,9 +112,11 @@ plugins: # order matters!
exclude_docs: |
/**/res/*.md
+ /**/_template/
not_in_nav: |
/**/res/*.md
+ /**/_template/
nav:
- Home: index.md
@@ -246,5 +253,7 @@ validation:
unrecognized_links: warn
watch:
+ - macros
+ - res
- scripts
- theme
diff --git a/res/grid_cards.yml b/res/grid_cards.yml
new file mode 100644
index 000000000..c61245eb7
--- /dev/null
+++ b/res/grid_cards.yml
@@ -0,0 +1,152 @@
+account:
+ xias_create:
+ title_text: Create Account (External)
+ icon_name: ":material-account-network:"
+ content: |
+ Are you an external collaborator?
+ Do you need to sponsor an external collaborator?
+ Create an external collaborator (XIAS) account today!
+ link_url: "account/xias/index.md"
+ leaving:
+ title_text: Leaving UAB?
+ icon_name: ":material-account-off:"
+ content: |
+ Planning to leave UAB?
+ Want to learn happens to your data and system access?
+ link_url: "account/leaving.md"
+ responsibilities:
+ title_text: Responsibilities and Policies
+ icon_name: ":material-clipboard-check-multiple:"
+ content: |
+ Want to learn who is responsible for what?
+ Learn more about what to expect on our systems.
+ Become familiar with RCS responsibilities and policies.
+ link_url: "account/responsibilities.md"
+
+ code_rc_create:
+ title_text: Create Code.rc (GitLab) Account
+ icon_name: ":simple-gitlab:"
+ icon_color: .icon-color-gitlab-orange
+ content: |
+ Need a place to securely store code?
+ Store git repositories in our on-premises GitLab server.
+ Create a Code.rc account today!
+ link_url: "account/code.rc/create.md"
+ rcs:
+ create:
+ title_text: Create Account (RCS / Cheaha)
+ icon_name: ":material-account-plus:"
+ content: |
+ Affiliated with UAB?
+ Need access to Cheaha, Cloud.rc, Code.rc, or other RCS services?
+ Create an RCS account today in minutes!
+ link_url: "account/rcs/create.md"
+ status:
+ title_text: Check Account Status
+ icon_name: ":material-account-cog:"
+ content: |
+ Want to check your RCS account status?
+ Learn about account statuses and what they mean.
+ link_url: "account/rcs/status.md"
+ xias:
+ sponsor_site:
+ title_text: 1. Sponsor — Create Site
+ icon_name: ":material-sitemap:"
+ content: |
+ First, the Sponsor will need to configure a Site.
+ The Site allows configuring Guests.
+ link_url: "account/xias/1_sponsor_manage_sites.md"
+ sponsor_user:
+ title_text: 2. Sponsor — Create User
+ icon_name: ":material-account-multiple-plus:"
+ content: |
+ Second, the Sponsor will need to configure a User for the Guest.
+ User configuration allows Guest account creation.
+ link_url: "account/xias/2_sponsor_manage_users.md"
+ guest_instructions:
+ title_text: 3. Guest — Create XIAS Account
+ icon_name: ":material-clipboard-account:"
+ content: |
+ Third, the Guest should follow these instructions to create their XIAS account.
+ link_url: "account/xias/3_guest_create_xias_account.md"
+ guest_create_rcs:
+ title_text: 4. Guest — Create RCS Account
+ icon_name: ":material-account-plus:"
+ content: |
+ Lastly, the Guest may now create an RCS account.
+ link_url: "account/rcs/create.md"
+ manage_site:
+ title_text: Sponsor — Manage Site
+ icon_name: ":material-cog-sync:"
+ content: |
+ Need to update Site URIs or end date, or add new Users?
+ link_url: "account/xias/1_sponsor_manage_sites.md#how-do-i-manage-a-xias-site"
+ manage_user:
+ title_text: Sponsor — Manage User
+ icon_name: ":material-account-cog:"
+ content: |
+ Need to update User end dates, or add to a new Site?
+ link_url: "account/xias/2_sponsor_manage_users.md#how-do-i-manage-a-xias-user"
+
+news:
+ title_text: UAB RCS News
+ icon_name: ":fontawesome-solid-newspaper:"
+ content: |
+ See what's new with Research Computing System services!
+ link_url: "news/index.md"
+
+platforms:
+ cheaha:
+ ood:
+ overview:
+ title_text: Open OnDemand Web App
+ icon_name: ":octicons-browser-24:"
+ content: |
+ Check out our interactive science apps, right in your browser!
+ Jupyter, RStudio, MATLAB, a virtual desktop, and more!
+ link_url: "cheaha/open_ondemand/index.md"
+ slurm:
+ overview:
+ title_text: Slurm Batch Job Scheduler
+ icon_name: ":material-script-text-play:"
+ content: |
+ Scale up your work!
+ Learn how to schedule batch jobs with Slurm.
+ link_url: "cheaha/slurm/introduction.md"
+
+data:
+ storage_options:
+ title_text: Storage Options
+ icon_name: ":material-server-network:"
+ content: |
+ Did you know researchers can get RCS storage at no charge?
+ Check out our platforms and offerings.
+ link_url: "data_management/index.md"
+ transfer_options:
+ title_text: Transfer Options
+ icon_name: ":material-transfer:"
+ content: |
+ RCS has multiple options for data transfers, within UAB and with other institutions.
+ Globus, rclone, and more!
+ link_url: "data_management/transfer/index.md"
+# personas:
+# administrative_staff:
+# title_text: Administrative Staff
+# icon_name: ":material-office-building:"
+# content: |
+# link_url:
+# core_director:
+# title_text: Core Director
+# icon_name: ":material-desk:"
+# external_collaborator:
+# title_text: External Collaborator
+# icon_name: ":material-clipboard-account:"
+# research_faculty_lab_pi:
+# title_text: Research Faculty Lab PI
+# icon_name: ":material-account-group:"
+# research_staff:
+# title_text: Research Staff
+# icon_name: ":material-test-tube:"
+# student:
+# title_text: Student
+# icon_name: ":material-book-education:"
From 6038215a0f3cd9b48712c53386aa88bfe26f6d7f Mon Sep 17 00:00:00 2001
From: William Warriner <6930772+wwarriner@users.noreply.github.com>
Date: Wed, 15 Oct 2025 14:39:09 -0500
Subject: [PATCH 09/32] update account page to use cards and tabs
---
.../_res}/user_responsibilities.csv | 10 +-
docs/account/_template/authorization.md.j2 | 20 ++
docs/account/_template/first_time_2fa.md.j2 | 4 +
docs/account/_template/first_time_vpn.md.j2 | 4 +
.../_template/not_affiliated_with_uab.md.j2 | 6 +
.../_template/uab_medicine_credentials.md.j2 | 3 +
.../code.rc/_img/gitlab_researcher_ldap.png | Bin 0 -> 5151 bytes
.../_img/gitlab_researcher_standard.png | Bin 0 -> 6358 bytes
docs/account/code.rc/create.md | 101 +++++++
docs/account/code.rc/index.md | 21 ++
docs/account/code.rc/manage.md | 40 +++
docs/account/index.md | 20 ++
.../leaving_uab.md => account/leaving.md} | 2 +-
.../rcs/_img/rcs-create-account-form.png | Bin 0 -> 37870 bytes
.../rcs/_img/rcs-create-account-wait.png | Bin 0 -> 4318 bytes
.../rcs/_img/rcs-status-page-certify-form.png | Bin 0 -> 40781 bytes
.../_img/rcs-status-page-good-standing-ok.png | Bin 0 -> 19498 bytes
.../account/rcs/_img/rcs-status-page-hold.png | Bin 0 -> 20993 bytes
.../rcs-status-page-pre-and-certification.png | Bin 0 -> 24108 bytes
docs/account/rcs/_res/status_summary.csv | 5 +
docs/account/rcs/create.md | 116 ++++++++
docs/account/rcs/index.md | 15 +
docs/account/rcs/status.md | 130 +++++++++
docs/account/responsibilities.md | 15 +
docs/account/xias/1_sponsor_manage_sites.md | 85 ++++++
docs/account/xias/2_sponsor_manage_users.md | 102 +++++++
.../xias/3_guest_create_xias_account.md | 118 ++++++++
.../xias/_img}/xias_guest_001.png | Bin
.../xias/_img}/xias_guest_002.png | Bin
docs/account/xias/_img/xias_guest_003.png | Bin 0 -> 102211 bytes
docs/account/xias/_img/xias_guest_004.png | Bin 0 -> 23955 bytes
.../xias/_img}/xias_guest_006.png | Bin
docs/account/xias/_img/xias_guest_007.png | Bin 0 -> 28619 bytes
docs/account/xias/_img/xias_guest_008.png | Bin 0 -> 14645 bytes
.../xias/_img}/xias_guest_009.png | Bin
.../_img}/xias_guest_activate_accounts.png | Bin
.../xias/_img}/xias_guest_change_password.png | Bin
.../xias/_img}/xias_guest_it_info.png | Bin
.../xias/_img}/xias_guest_resend.png | Bin
.../xias/_img}/xias_sites_add_000.png | Bin
.../xias/_img}/xias_sites_add_001.png | Bin
.../xias/_img}/xias_sites_add_002.png | Bin
.../xias/_img}/xias_sites_add_003.png | Bin
.../xias/_img}/xias_sites_add_004.png | Bin
docs/account/xias/_img/xias_users_add_000.png | Bin 0 -> 12064 bytes
.../xias/_img}/xias_users_add_001.png | Bin
.../xias/_img}/xias_users_add_002.png | Bin
.../xias/_img}/xias_users_add_003.png | Bin
.../xias/_img}/xias_users_add_004.png | Bin
.../xias/_img}/xias_users_add_005.png | Bin
.../xias/_img}/xias_users_add_006.png | Bin
.../xias/_img}/xias_users_list_000.png | Bin
.../xias/_img}/xias_users_list_001.png | Bin
.../xias/_img/xias_users_manage_001.png | Bin 0 -> 31683 bytes
docs/account/xias/_res/rcs_uri.csv | 5 +
.../xias/_template/revoke_access.md.j2 | 4 +
.../_template/sponsor_responsibility.md.j2 | 6 +
.../xias/_template/xias_help_section.md.j2 | 9 +
docs/account/xias/index.md | 57 ++++
docs/account_management/cheaha_account.md | 145 ----------
docs/account_management/gitlab_account.md | 198 -------------
.../images/gitlab_researcher_ldap.png | Bin 4190 -> 0 bytes
.../images/gitlab_researcher_standard.png | Bin 5146 -> 0 bytes
.../images/uab_auth_error.png | Bin 28168 -> 0 bytes
.../images/uab_certify_001.png | Bin 29783 -> 0 bytes
.../images/uab_certify_002.png | Bin 43040 -> 0 bytes
.../images/uab_good_standing.png | Bin 23288 -> 0 bytes
.../account_management/images/uab_on_hold.png | Bin 23792 -> 0 bytes
.../images/uab_on_hold_ssh.png | Bin 18054 -> 0 bytes
.../images/uab_self_register_001.png | Bin 42096 -> 0 bytes
.../images/uab_self_register_002.png | Bin 9248 -> 0 bytes
docs/account_management/index.md | 37 ---
.../xias/guest_instructions.md | 70 -----
.../xias/images/xias_guest_003.png | Bin 3989 -> 0 bytes
.../xias/images/xias_guest_004.png | Bin 20081 -> 0 bytes
.../xias/images/xias_guest_007.png | Bin 30136 -> 0 bytes
.../xias/images/xias_guest_008.png | Bin 18025 -> 0 bytes
.../xias/images/xias_users_add_000.png | Bin 5057 -> 0 bytes
docs/account_management/xias/index.md | 30 --
.../xias/pi_guest_management.md | 83 ------
.../xias/pi_site_management.md | 40 ---
docs/cheaha/getting_started.md | 6 +-
.../_img}/uab-gitlab-creategrp.png | Bin
.../_img}/uab-gitlab-creategrp2.png | Bin
.../_img}/uab-gitlab-createproject.png | Bin
.../_img}/uab-gitlab-createproject2.png | Bin
.../_img}/uab-gitlab-domaindiff.png | Bin
.../_img}/uab-gitlab-group1.png | Bin
.../_img}/uab-gitlab-group2.png | Bin
.../_img}/uab-gitlab-grouptest.png | Bin
.../_img}/uab-gitlab-grplist.png | Bin
.../_img}/uab-gitlab-grpmembers.png | Bin
.../_img}/uab-gitlab-invitemembers.png | Bin
.../_img}/uab-gitlab-invitemembers2.png | Bin
.../_img}/uab-gitlab-invitemembers3.png | Bin
.../_img}/uab-gitlab-landingpage.png | Bin
.../_img}/uab-gitlab-projectgroup.png | Bin
.../_img}/uab-gitlab-projectlist.png | Bin
.../_img}/uab-gitlab-updaterole.png | Bin
.../res => code.rc/_res}/gitlab_roles.csv | 0
docs/code.rc/index.md | 160 +++++++++++
docs/data_management/code_storage.md | 4 +-
docs/data_management/index.md | 2 +-
docs/data_management/lts/iam_and_policies.md | 2 +-
docs/data_management/lts/index.md | 2 +-
.../tutorial/globus_individual_tutorial.md | 4 +-
.../tutorial/globus_organization_tutorial.md | 2 +-
docs/index.md | 2 +-
docs/stylesheets/extra.css | 260 ++++++++++++++----
docs/workflow_solutions/getting_containers.md | 6 +-
docs/workflow_solutions/git_collaboration.md | 4 +-
mkdocs.yml | 55 +++-
112 files changed, 1312 insertions(+), 698 deletions(-)
rename docs/{account_management/res => account/_res}/user_responsibilities.csv (99%)
create mode 100644 docs/account/_template/authorization.md.j2
create mode 100644 docs/account/_template/first_time_2fa.md.j2
create mode 100644 docs/account/_template/first_time_vpn.md.j2
create mode 100644 docs/account/_template/not_affiliated_with_uab.md.j2
create mode 100644 docs/account/_template/uab_medicine_credentials.md.j2
create mode 100644 docs/account/code.rc/_img/gitlab_researcher_ldap.png
create mode 100644 docs/account/code.rc/_img/gitlab_researcher_standard.png
create mode 100644 docs/account/code.rc/create.md
create mode 100644 docs/account/code.rc/index.md
create mode 100644 docs/account/code.rc/manage.md
create mode 100644 docs/account/index.md
rename docs/{account_management/leaving_uab.md => account/leaving.md} (98%)
create mode 100644 docs/account/rcs/_img/rcs-create-account-form.png
create mode 100644 docs/account/rcs/_img/rcs-create-account-wait.png
create mode 100644 docs/account/rcs/_img/rcs-status-page-certify-form.png
create mode 100644 docs/account/rcs/_img/rcs-status-page-good-standing-ok.png
create mode 100644 docs/account/rcs/_img/rcs-status-page-hold.png
create mode 100644 docs/account/rcs/_img/rcs-status-page-pre-and-certification.png
create mode 100644 docs/account/rcs/_res/status_summary.csv
create mode 100644 docs/account/rcs/create.md
create mode 100644 docs/account/rcs/index.md
create mode 100644 docs/account/rcs/status.md
create mode 100644 docs/account/responsibilities.md
create mode 100644 docs/account/xias/1_sponsor_manage_sites.md
create mode 100644 docs/account/xias/2_sponsor_manage_users.md
create mode 100644 docs/account/xias/3_guest_create_xias_account.md
rename docs/{account_management/xias/images => account/xias/_img}/xias_guest_001.png (100%)
rename docs/{account_management/xias/images => account/xias/_img}/xias_guest_002.png (100%)
create mode 100644 docs/account/xias/_img/xias_guest_003.png
create mode 100644 docs/account/xias/_img/xias_guest_004.png
rename docs/{account_management/xias/images => account/xias/_img}/xias_guest_006.png (100%)
create mode 100644 docs/account/xias/_img/xias_guest_007.png
create mode 100644 docs/account/xias/_img/xias_guest_008.png
rename docs/{account_management/xias/images => account/xias/_img}/xias_guest_009.png (100%)
rename docs/{account_management/xias/images => account/xias/_img}/xias_guest_activate_accounts.png (100%)
rename docs/{account_management/xias/images => account/xias/_img}/xias_guest_change_password.png (100%)
rename docs/{account_management/xias/images => account/xias/_img}/xias_guest_it_info.png (100%)
rename docs/{account_management/xias/images => account/xias/_img}/xias_guest_resend.png (100%)
rename docs/{account_management/xias/images => account/xias/_img}/xias_sites_add_000.png (100%)
rename docs/{account_management/xias/images => account/xias/_img}/xias_sites_add_001.png (100%)
rename docs/{account_management/xias/images => account/xias/_img}/xias_sites_add_002.png (100%)
rename docs/{account_management/xias/images => account/xias/_img}/xias_sites_add_003.png (100%)
rename docs/{account_management/xias/images => account/xias/_img}/xias_sites_add_004.png (100%)
create mode 100644 docs/account/xias/_img/xias_users_add_000.png
rename docs/{account_management/xias/images => account/xias/_img}/xias_users_add_001.png (100%)
rename docs/{account_management/xias/images => account/xias/_img}/xias_users_add_002.png (100%)
rename docs/{account_management/xias/images => account/xias/_img}/xias_users_add_003.png (100%)
rename docs/{account_management/xias/images => account/xias/_img}/xias_users_add_004.png (100%)
rename docs/{account_management/xias/images => account/xias/_img}/xias_users_add_005.png (100%)
rename docs/{account_management/xias/images => account/xias/_img}/xias_users_add_006.png (100%)
rename docs/{account_management/xias/images => account/xias/_img}/xias_users_list_000.png (100%)
rename docs/{account_management/xias/images => account/xias/_img}/xias_users_list_001.png (100%)
create mode 100644 docs/account/xias/_img/xias_users_manage_001.png
create mode 100644 docs/account/xias/_res/rcs_uri.csv
create mode 100644 docs/account/xias/_template/revoke_access.md.j2
create mode 100644 docs/account/xias/_template/sponsor_responsibility.md.j2
create mode 100644 docs/account/xias/_template/xias_help_section.md.j2
create mode 100644 docs/account/xias/index.md
delete mode 100644 docs/account_management/cheaha_account.md
delete mode 100644 docs/account_management/gitlab_account.md
delete mode 100644 docs/account_management/images/gitlab_researcher_ldap.png
delete mode 100644 docs/account_management/images/gitlab_researcher_standard.png
delete mode 100644 docs/account_management/images/uab_auth_error.png
delete mode 100644 docs/account_management/images/uab_certify_001.png
delete mode 100644 docs/account_management/images/uab_certify_002.png
delete mode 100644 docs/account_management/images/uab_good_standing.png
delete mode 100644 docs/account_management/images/uab_on_hold.png
delete mode 100644 docs/account_management/images/uab_on_hold_ssh.png
delete mode 100644 docs/account_management/images/uab_self_register_001.png
delete mode 100644 docs/account_management/images/uab_self_register_002.png
delete mode 100644 docs/account_management/index.md
delete mode 100644 docs/account_management/xias/guest_instructions.md
delete mode 100644 docs/account_management/xias/images/xias_guest_003.png
delete mode 100644 docs/account_management/xias/images/xias_guest_004.png
delete mode 100644 docs/account_management/xias/images/xias_guest_007.png
delete mode 100644 docs/account_management/xias/images/xias_guest_008.png
delete mode 100644 docs/account_management/xias/images/xias_users_add_000.png
delete mode 100644 docs/account_management/xias/index.md
delete mode 100644 docs/account_management/xias/pi_guest_management.md
delete mode 100644 docs/account_management/xias/pi_site_management.md
rename docs/{account_management/images => code.rc/_img}/uab-gitlab-creategrp.png (100%)
rename docs/{account_management/images => code.rc/_img}/uab-gitlab-creategrp2.png (100%)
rename docs/{account_management/images => code.rc/_img}/uab-gitlab-createproject.png (100%)
rename docs/{account_management/images => code.rc/_img}/uab-gitlab-createproject2.png (100%)
rename docs/{account_management/images => code.rc/_img}/uab-gitlab-domaindiff.png (100%)
rename docs/{account_management/images => code.rc/_img}/uab-gitlab-group1.png (100%)
rename docs/{account_management/images => code.rc/_img}/uab-gitlab-group2.png (100%)
rename docs/{account_management/images => code.rc/_img}/uab-gitlab-grouptest.png (100%)
rename docs/{account_management/images => code.rc/_img}/uab-gitlab-grplist.png (100%)
rename docs/{account_management/images => code.rc/_img}/uab-gitlab-grpmembers.png (100%)
rename docs/{account_management/images => code.rc/_img}/uab-gitlab-invitemembers.png (100%)
rename docs/{account_management/images => code.rc/_img}/uab-gitlab-invitemembers2.png (100%)
rename docs/{account_management/images => code.rc/_img}/uab-gitlab-invitemembers3.png (100%)
rename docs/{account_management/images => code.rc/_img}/uab-gitlab-landingpage.png (100%)
rename docs/{account_management/images => code.rc/_img}/uab-gitlab-projectgroup.png (100%)
rename docs/{account_management/images => code.rc/_img}/uab-gitlab-projectlist.png (100%)
rename docs/{account_management/images => code.rc/_img}/uab-gitlab-updaterole.png (100%)
rename docs/{account_management/res => code.rc/_res}/gitlab_roles.csv (100%)
create mode 100644 docs/code.rc/index.md
diff --git a/docs/account_management/res/user_responsibilities.csv b/docs/account/_res/user_responsibilities.csv
similarity index 99%
rename from docs/account_management/res/user_responsibilities.csv
rename to docs/account/_res/user_responsibilities.csv
index 977ecf746..274d84e22 100644
--- a/docs/account_management/res/user_responsibilities.csv
+++ b/docs/account/_res/user_responsibilities.csv
@@ -1,5 +1,5 @@
-Category,User Group,Requirements,Responsibilities
-UAB Employees,UAB Campus and UAB Medicine Faculty/Staff and Postdocs,Must have an active BlazerID,[Refer to All User Responsibilities](../account_management/index.md#all-users-responsibilities).
For Lab PIs and Core Directors please refer [Lab PIs responsibilities](#lab-pis).
-UAB Students,All UAB Campus and UAB Medicine Students,Must have an active BlazerID,[Refer to All User Responsibilities](../account_management/index.md#all-users-responsibilities).
-External Collaborators,All sponsored by UAB Employee,Must be sponsored by UAB employee
Must have XIAS email address,Collaborators' Responsibility:
- [Refer to All User Responsibilities](../account_management/index.md#all-users-responsibilities).
- [Create a XIAS Guest Account](../account_management/xias/guest_instructions.md#create-account).
Sponsor's Responsibility:
- Sponsor is accountable for collaborators actions on UAB systems.
- Please refer to [external collaborators](./xias/index.md#external-collaborator-xias-accounts) page.
-Lab PIs,All Lab PIs and Core Directors,Must have an active BlazerID,Data Management and Storage:
- Periodically check group membership is correct.
- Periodically check access controls to directories/buckets are correct.
- Moving unused data to LTS or external archival solutions.
- Managing backup plans.
OpenStack Projects:
- Periodically check group membership is correct.
- Periodically check unused resources are released.
PIs are also responsible to:
- Regularly reviewing membership permissions and access control.
- Ensure students are aware about [FERPA-protected project metadata](https://www.uab.edu/registrar/ferpa/faculty-staff).
- [Refer to All User Responsibilities](../account_management/index.md#all-users-responsibilities).
+Category,User Group,Requirements,Responsibilities
+UAB Employees,UAB Campus and UAB Medicine Faculty/Staff and Postdocs,Must have an active BlazerID,[Refer to All User Responsibilities](../account_management/index.md#all-users-responsibilities).
For Lab PIs and Core Directors please refer [Lab PIs responsibilities](#lab-pis).
+UAB Students,All UAB Campus and UAB Medicine Students,Must have an active BlazerID,[Refer to All User Responsibilities](../account_management/index.md#all-users-responsibilities).
+External Collaborators,All sponsored by UAB Employee,Must be sponsored by UAB employee
Must have XIAS email address,Collaborators' Responsibility:
- [Refer to All User Responsibilities](../account_management/index.md#all-users-responsibilities).
- [Create a XIAS Guest Account](../account_management/xias/guest_instructions.md#create-account).
Sponsor's Responsibility:
- Sponsor is accountable for collaborators actions on UAB systems.
- Please refer to [external collaborators](./xias/index.md#external-collaborator-xias-accounts) page.
+Lab PIs,All Lab PIs and Core Directors,Must have an active BlazerID,Data Management and Storage:
- Periodically check group membership is correct.
- Periodically check access controls to directories/buckets are correct.
- Moving unused data to LTS or external archival solutions.
- Managing backup plans.
OpenStack Projects:
- Periodically check group membership is correct.
- Periodically check unused resources are released.
PIs are also responsible to:
- Regularly reviewing membership permissions and access control.
- Ensure students are aware about [FERPA-protected project metadata](https://www.uab.edu/registrar/ferpa/faculty-staff).
- [Refer to All User Responsibilities](../account_management/index.md#all-users-responsibilities).
diff --git a/docs/account/_template/authorization.md.j2 b/docs/account/_template/authorization.md.j2
new file mode 100644
index 000000000..ed1b126f5
--- /dev/null
+++ b/docs/account/_template/authorization.md.j2
@@ -0,0 +1,20 @@
+# Research Computing System (RCS) Authorization
+
+## Who Is Eligible For RCS Authorization?
+
+Due to security requirements imposed by US federal funding agencies, RCS authorization is limited to specific UAB affiliations. If you are in one of the following categories, you are eligible to access RCS.
+
+- UAB Campus Employee
+- UAB Campus Student
+- UAB Medicine Employee
+- XIAS Guest with UAB Campus Employee Sponsor
+
+Other affiliations, including alumni and volunteer, are not authorized to access RCS.
+
+## What Else Is Required for RCS Authorization?
+
+Being in one of the categories above is necessary for RCS authorization, but not sufficient. Researchers are also expected to adhere to all relevant and prevailing policies, regulations, and laws, at all times.
+
+## Where Can I Read More About Policies?
+
+LINK GOES HERE
diff --git a/docs/account/_template/first_time_2fa.md.j2 b/docs/account/_template/first_time_2fa.md.j2
new file mode 100644
index 000000000..16e9be645
--- /dev/null
+++ b/docs/account/_template/first_time_2fa.md.j2
@@ -0,0 +1,4 @@
+
+!!! security
+
+ If this is your first time logging in, you will first need to setup [Two-Factor Authentication](https://www.uab.edu/it/home/security/2-factor).
diff --git a/docs/account/_template/first_time_vpn.md.j2 b/docs/account/_template/first_time_vpn.md.j2
new file mode 100644
index 000000000..d4d4cbafa
--- /dev/null
+++ b/docs/account/_template/first_time_vpn.md.j2
@@ -0,0 +1,4 @@
+
+!!! security
+
+ If this is your first time logging in, you will first need to setup [UAB Campus Network VPN Access](https://www.uab.edu/it/home/tech-solutions/network/vpn). VPN access requires [Two-Factor Authentication](https://www.uab.edu/it/home/security/2-factor).
diff --git a/docs/account/_template/not_affiliated_with_uab.md.j2 b/docs/account/_template/not_affiliated_with_uab.md.j2
new file mode 100644
index 000000000..4cd2fb623
--- /dev/null
+++ b/docs/account/_template/not_affiliated_with_uab.md.j2
@@ -0,0 +1,6 @@
+{% from "_template/link.md.j2" import link %}
+Not affiliated with UAB? To access RCS, you must first {{ link("Create an External Collaborator (XIAS) Account", "account/xias/index.md") }}.
+
+!!! important
+
+ All researchers creating and using XIAS accounts must have a UAB employed sponsor.
diff --git a/docs/account/_template/uab_medicine_credentials.md.j2 b/docs/account/_template/uab_medicine_credentials.md.j2
new file mode 100644
index 000000000..8374130e4
--- /dev/null
+++ b/docs/account/_template/uab_medicine_credentials.md.j2
@@ -0,0 +1,3 @@
+!!! important
+
+ UAB Medicine employees must authenticate with their BlazerID credentials. These are different from your UAB Medicine credentials.
diff --git a/docs/account/code.rc/_img/gitlab_researcher_ldap.png b/docs/account/code.rc/_img/gitlab_researcher_ldap.png
new file mode 100644
index 0000000000000000000000000000000000000000..d9b276e98cabc357b0c130ad4109830fa0864da7
GIT binary patch
literal 5151
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
FzW}YSA!h&p
literal 0
HcmV?d00001
diff --git a/docs/account/code.rc/create.md b/docs/account/code.rc/create.md
new file mode 100644
index 000000000..92aff01fe
--- /dev/null
+++ b/docs/account/code.rc/create.md
@@ -0,0 +1,101 @@
+---
+render_macros: true
+toc_depth: 2
+---
+
+# Create Your Code.rc (GitLab) Account
+
+**Code.rc** is an on-premises GitLab server running on UAB IT infrastructure, administered by Research Computing, and part of the Research Computing System (RCS).
+
+Creating a Code.rc account is an automated, self-service process for researchers affiliated with UAB. External collaborators follow a different process.
+
+## What Do I Need Before Starting?
+
+Before starting, you'll need the following prerequisites.
+
+- An [RCS Account](../rcs/index.md) in [Good Standing](../rcs/status.md#what-are-the-possible-statuses-good-standing-ok).
+
+## How Do I Create a Code.rc Account?
+
+Please select the tab that best described your affiliation to UAB to see instructions for creating a Code.rc account.
+
+
+=== "UAB Campus & UAB Medicine"
+
+ Please select the LDAP tab and authenticate with your BlazerID credentials.
+
+ {% filter indent(4) %}
+ {% include "account/_template/uab_medicine_credentials.md.j2" %}
+ {% endfilter %}
+
+ 
+
+=== "External Collaborator (XIAS)"
+
+ 1. Ensure that your sponsor has included `https://code.rc.uab.edu` in the list of [approved URIs](../xias/1_sponsor_manage_sites.md) on the XIAS Site configuration page.
+
+ !!! important
+
+ XIAS account researchers will only be granted access if their sponsor adds the Code.rc URI to the list of approved URIs.
+
+ 1. Have your sponsor send a request to for a Code.rc account for their XIAS Guest. Please have the sponsor use the following template.
+
+ ```text
+ I hereby request a Code.rc account created for a XIAS account, and affirm that the external collaborator has an RCS account in good standing.
+
+ XIAS full name: _____
+ XIAS email address: _____
+ ```
+
+ 1. UAB Research Computing will create an account.
+ 1. You will receive an automated email from `donotreply.rc.code@uab.edu` with a link to create a password.
+ 1. Follow the link to create a password for your account.
+ 1. Navigate to to authenticate.
+ 1. Select the Standard tab and authenticate with your XIAS credentials. Only use the `name` portion of your XIAS email address `name@domain.tld`. Do not include the `@` symbol or anything after. Use the password you created in the previous steps.
+
+ > Username or primary email: `name`
+ >
+ > Password: `********`
+
+ 
+
+ 1. Click `Sign in` to authenticate.
+
+=== "Unaffiliated"
+
+ {% filter indent(width=4) %}
+ {% include "account/_template/not_affiliated_with_uab.md.j2" %}
+ {% endfilter %}
+
+
+## Next Steps
+
+CARD GRID GOES HERE
+
+- Manage Account
+- Git
+- Cheaha
+- Data Management
+- Cloud.rc
+- Support
+
+### For Students, Staff, and Faculty
+
+- [Get Started with Open OnDemand](../../cheaha/open_ondemand/index.md)
+- [Additional Learning Resources](../../education/training_resources.md)
+- [Data Science Journal Club Course](../../education/courses.md#data-science-journal-club-course)
+
+### For Lab PIs and Core Directors
+
+- [No-cost storage offerings](../../data_management/index.md#what-type-of-storage-do-i-need)
+ - [GPFS](../../data_management/index.md#what-shared-storage-solutions-are-available): Hot storage, compute adjacent, directly accessible from Cheaha
+ - [LTS](../../data_management/lts/index.md): Cool storage, large capacity
+ - [Transfer data with Globus](../../data_management/transfer/globus.md)
+- [Batch computing](../../cheaha/slurm/introduction.md)
+ - [Desktop](../../cheaha/open_ondemand/hpc_desktop.md), [Jupyter](../../cheaha/open_ondemand/ood_jupyter.md), [RStudio](../../cheaha/open_ondemand/ood_rstudio.md), [Matlab](../../cheaha/open_ondemand/ood_matlab.md), and more
+ - [GPUs](../../cheaha/slurm/gpu.md)
+- [On-prem cloud computing](../../uab_cloud/index.md)
+ - [Tutorial](../../uab_cloud/tutorial/index.md)
+ - [Web servers](../../uab_cloud/remote_access.md#make-instances-publically-accessible-from-the-internet)
+
+{% include "_template/base_help_section.md.j2" %}
diff --git a/docs/account/code.rc/index.md b/docs/account/code.rc/index.md
new file mode 100644
index 000000000..bccd2e999
--- /dev/null
+++ b/docs/account/code.rc/index.md
@@ -0,0 +1,21 @@
+# Create and Manage Code.rc (GitLab) Accounts
+
+UAB Research Computing maintains an on-premises GitLab server, part of the Research Computing System (RCS), called **Code.rc**. Generally speaking, [GitLab](https://about.gitlab.com/) is a service designed for collaborating on software development projects and is similar in structure and purpose to [GitHub](https://github.com/). In contrast to the Git hosting services [GitLab.com](https://gitlab.com) and [GitHub.com](https://github.com), Code.rc is hosted on-premises and stored in a secure physical environment on UAB Campus.
+
+
+!!! important
+
+ Code.rc accounts are managed separately from [Research Computing System (RCS) accounts](../rcs/index.md). Before creating a Code.rc account, you must create an RCS account.
+
+
+{{
+ renderer.render_cards(
+ cards.account.code_rc
+ )
+}}
+
+## Where Can I Find Code.rc?
+
+Code.rc may be found at .
+
+{% include "_template/base_help_section.md.j2" %}
diff --git a/docs/account/code.rc/manage.md b/docs/account/code.rc/manage.md
new file mode 100644
index 000000000..cf0dc9a7e
--- /dev/null
+++ b/docs/account/code.rc/manage.md
@@ -0,0 +1,40 @@
+---
+hide:
+ toc: true
+---
+
+# Managing Code.rc (GitLab) Accounts
+
+You can manage your Code.rc (GitLab) account by navigating to the web interface at and checking your User Profile. Within Code.rc, you can create and manage Groups and Projects, including which other Users and Groups have access, and what level of access, by assigning Roles.
+
+## What Do I Need to Get Started?
+
+Before starting, you'll need the following prerequisites.
+
+- A [Code.rc Account](./index.md).
+
+## How Do I View User Profiles?
+
+To view a profile, including your own:
+
+- Visit `https://code.rc.uab.edu/your-username`.
+- _or_
+ 1. Login to .
+ 1. Click your profile picture at the top of the left-hand sidebar. On narrow displays, the sidebar may be hidden. If so, click the "Show Sidebar" icon at the top-left of any page.
+ 1. A pop-up menu will appear.
+ 1. Click your name at the top of the pop-up menu.
+
+## How Do I Edit My User Profile?
+
+To edit your profile:
+
+- Visit .
+- _or_ [View Your Profile](#how-do-i-view-user-profiles), except instead of clicking your name at the last step, click "Edit Profile".
+
+## What Can Be Edited on My User Profile?
+
+You can change your profile picture, name, social media links, and bio in your user profile page.
+
+Please see the [Official GitLab Documentation](https://docs.gitlab.com/user/profile/) for more details.
+
+{% include "_template/base_help_section.md.j2" %}
diff --git a/docs/account/index.md b/docs/account/index.md
new file mode 100644
index 000000000..c644eca43
--- /dev/null
+++ b/docs/account/index.md
@@ -0,0 +1,20 @@
+---
+render_macros: true
+hide:
+ toc: true
+---
+
+# Account Creation and Management
+
+{{
+ renderer.render_cards(
+ cards.account.rcs.create,
+ cards.account.rcs.status,
+ cards.account.responsibilities,
+ cards.account.leaving,
+ cards.account.xias_create,
+ cards.account.code_rc_create,
+ )
+}}
+
+{% include "_template/base_help_section.md.j2" %}
diff --git a/docs/account_management/leaving_uab.md b/docs/account/leaving.md
similarity index 98%
rename from docs/account_management/leaving_uab.md
rename to docs/account/leaving.md
index 020f7f4e3..24d094522 100644
--- a/docs/account_management/leaving_uab.md
+++ b/docs/account/leaving.md
@@ -22,7 +22,7 @@ If you anticipate needing more than 30 days to finalize transfers, [contact us](
## What Happens to Data in My Individual Storage Allocations?
-Data in your individual storage allocations, on all storage platforms, will be retained for the full grace period. We recommend making a plan for your data. Download any personal, non-UAB-owned data you wish to keep. [Transfer any UAB-owned data to an appropriate location.](#what-should-i-do-with-uab-owned-data)
+Data in your individual storage allocations, on all storage platforms, will be retained for the full grace period. We recommend making a plan for your data. Download any personal, non-UAB-owned data you want to keep. [Transfer any UAB-owned data to an appropriate location.](#what-should-i-do-with-uab-owned-data)
## What Should I Do With UAB-Owned Data?
diff --git a/docs/account/rcs/_img/rcs-create-account-form.png b/docs/account/rcs/_img/rcs-create-account-form.png
new file mode 100644
index 0000000000000000000000000000000000000000..cf8882f756f1533258b263ff369736c24cdfc721
GIT binary patch
literal 37870
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%0An7mInbOtGoVk%B%#@Z~at>q0g#w1yNpn0s
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