Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
140 changes: 78 additions & 62 deletions docs/.vitepress/sidebar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,82 +20,98 @@ export function generateDocumentationSidebar(): any {
}]);

// Post-process sidebar to fix folder titles and extract descriptions from frontmatter
const fixFolderTitles = (items: any[]): any[] => {
return items.map(item => {
let frontmatter: Record<string, any> | undefined;
const fixFolderTitles = (items: any[], depth = 0): any[] => {
return items.map((item, index) => {
try {
let frontmatter: Record<string, any> | undefined;

// Fix folder links for proper active state detection
// VitePress normalizes "/tutorials/index.md" to "/tutorials/" (WITH trailing slash)
// The regex /(?:(^|\/)index)?\.(?:md|html)$/ captures the "/" before "index"
// So we must ensure sidebar links for index pages also have trailing slashes

// IMPORTANT: Don't add leading slash - VitePress adds base path
// If we have "/tutorials/", VitePress makes it "//tutorials/" (external link!)

if (item.link && item.link.endsWith('/index.md')) {
// Convert "tutorials/index.md" to "tutorials/"
item.link = item.link.replace(/\/index\.md$/, '/');
} else if (item.link && item.link.startsWith('/')) {
// Remove leading slash that vitepress-sidebar added
item.link = item.link.substring(1);
}

// Now check if link needs trailing slash
if (item.link && !item.link.endsWith('/')) {
const possibleIndexPath = path.join('docs', item.link, 'index.md');
if (fs.existsSync(possibleIndexPath)) {
// Add trailing slash: "tutorials" to "tutorials/"
item.link = item.link + '/';
// Recursively fix nested items first (works regardless of whether this item has a link)
if (item.items && Array.isArray(item.items)) {
item.items = fixFolderTitles(item.items, depth + 1);
}
}

// Check if this is a folder with index.md to read its frontmatter
const possibleIndexPath = path.join('docs', item.link, 'index.md');
if (item.link && fs.existsSync(possibleIndexPath)) {
try {
const content = fs.readFileSync(possibleIndexPath, 'utf-8');
frontmatter = matter(content).data;
if (frontmatter?.title) {
item.text = frontmatter.title;
}
} catch (err) {
// Ignore errors, keep the original text
// Skip processing if no link (section headers, collapsed groups, etc.)
if (!item.link || typeof item.link !== 'string') {
console.log(`[sidebar] Skipping item without link: text="${item.text}", hasItems=${!!item.items}`);
return item;
}
} else if (item.link && item.link.endsWith('.md')) {
// This is a file link - read frontmatter from the page
const pagePath = path.join('docs', item.link);
if (fs.existsSync(pagePath)) {
try {
const content = fs.readFileSync(pagePath, 'utf-8');
frontmatter = matter(content).data;
} catch (err) {
// Ignore errors

// Fix folder links for proper active state detection
// VitePress normalizes "/tutorials/index.md" to "/tutorials/" (WITH trailing slash)
// The regex /(?:(^|\/)index)?\.(?:md|html)$/ captures the "/" before "index"
// So we must ensure sidebar links for index pages also have trailing slashes

// IMPORTANT: Don't add leading slash - VitePress adds base path
// If we have "/tutorials/", VitePress makes it "//tutorials/" (external link!)

if (item.link.endsWith('/index.md')) {
// Convert "tutorials/index.md" to "tutorials/"
item.link = item.link.replace(/\/index\.md$/, '/');
} else if (item.link.startsWith('/')) {
// Remove leading slash that vitepress-sidebar added
item.link = item.link.substring(1);
}

// Now check if link needs trailing slash
if (!item.link.endsWith('/')) {
const possibleIndexPath = path.join('docs', item.link, 'index.md');
if (fs.existsSync(possibleIndexPath)) {
// Add trailing slash: "tutorials" to "tutorials/"
item.link = item.link + '/';
}
}
} else if (item.link && !item.link.includes('.')) {
// Link has no extension (vitepress-sidebar strips .md for leaf pages)
// Try appending .md to find the source file
const pagePath = path.join('docs', item.link + '.md');
if (fs.existsSync(pagePath)) {

// Check if this is a folder with index.md to read its frontmatter
const possibleIndexPath = path.join('docs', item.link, 'index.md');
if (fs.existsSync(possibleIndexPath)) {
try {
const content = fs.readFileSync(pagePath, 'utf-8');
const content = fs.readFileSync(possibleIndexPath, 'utf-8');
frontmatter = matter(content).data;
if (frontmatter?.title) {
item.text = frontmatter.title;
}
} catch (err) {
// Ignore errors
// Ignore errors, keep the original text
}
} else if (item.link.endsWith('.md')) {
// This is a file link - read frontmatter from the page
const pagePath = path.join('docs', item.link);
if (fs.existsSync(pagePath)) {
try {
const content = fs.readFileSync(pagePath, 'utf-8');
frontmatter = matter(content).data;
} catch (err) {
// Ignore errors
}
}
} else if (!item.link.includes('.')) {
// Link has no extension (vitepress-sidebar strips .md for leaf pages)
// Try appending .md to find the source file
const pagePath = path.join('docs', item.link + '.md');
if (fs.existsSync(pagePath)) {
try {
const content = fs.readFileSync(pagePath, 'utf-8');
frontmatter = matter(content).data;
} catch (err) {
// Ignore errors
}
}
}
}

if (frontmatter?.description) {
item.description = frontmatter.description;
}
if (frontmatter?.description) {
item.description = frontmatter.description;
}

// Recursively fix nested items
if (item.items && Array.isArray(item.items)) {
item.items = fixFolderTitles(item.items);
return item;
} catch (error) {
console.error(`Error processing sidebar item at index ${index}:`, {
text: item.text,
link: item.link,
hasItems: !!item.items,
error: error instanceof Error ? error.message : String(error)
});
throw error; // Re-throw after logging
}

return item;
});
};

Expand Down
4 changes: 2 additions & 2 deletions docs/introduction/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,10 @@ explain how Garden Linux works.
**Start here**: [Explanation](/explanation/)

Topics include [use cases](/explanation/use-cases),
[flavors and features](/explanation/flavors-and-features),
[Flavors](/explanation/flavors),
[architecture](/explanation/architecture),
[security posture](/explanation/security-posture), and
[design decisions](/explanation/design-decisions).
[design decisions](/explanation/architectural-decisions).

## Reference

Expand Down
8 changes: 4 additions & 4 deletions docs/reference/glossary.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ A platform target for Garden Linux images designed to run directly on physical h

### Builder

The [gardenlinux/builder](https://github.com/gardenlinux/builder) component that creates customized Linux distributions. The builder is a separate project maintained by the Garden Linux team and is used to build Garden Linux images with specific flavors and features. See [Building Images documentation](../how-to/building-images.md) for practical guidance, [ADR-0020](./adr/0020-enforce-single-platform-by-default-in-builder.md) for details on platform enforcement in the builder, and [ADR-0031](./adr/0031-builder-glci-interface.md) for the builder-GLCI interface design.
The [gardenlinux/builder](https://github.com/gardenlinux/builder) component that creates customized Linux distributions. The builder is a separate project maintained by the Garden Linux team and is used to build Garden Linux images with specific Flavors. See [Building Images documentation](../how-to/building-images.md) for practical guidance, [ADR-0020](./adr/0020-enforce-single-platform-by-default-in-builder.md) for details on platform enforcement in the builder, and [ADR-0031](./adr/0031-builder-glci-interface.md) for the builder-GLCI interface design.

### Build Flavor String

Expand Down Expand Up @@ -95,7 +95,7 @@ Refers to the [`_ephemeral`](https://github.com/gardenlinux/gardenlinux/blob/mai

### Feature

A modular component that adds specific functionality to a Garden Linux image. Features are defined in the `features/` directory. Features prefixed with an underscore (`_`) are internal/private (e.g., [`_secureboot`](https://github.com/gardenlinux/gardenlinux/blob/main/features/_secureboot/README.md), [`_dev`](https://github.com/gardenlinux/gardenlinux/blob/main/features/_dev/README.md)), while features without a prefix are public (e.g., [`cis`](https://github.com/gardenlinux/gardenlinux/blob/main/features/cis/README.md), [`gardener`](https://github.com/gardenlinux/gardenlinux/blob/main/features/gardener/README.md), [`python`](https://github.com/gardenlinux/gardenlinux/blob/main/features/python/README.md)). See [Flavors and Features documentation](../explanation/flavors-and-features.md) for an overview, and [ADR-0032](./adr/0032-static-feature-test-coverage-analysis.md) for details on feature test coverage analysis.
A modular component that adds specific functionality to a Garden Linux image. Features are defined in the `features/` directory. Features prefixed with an underscore (`_`) are internal/private (e.g., [`_secureboot`](https://github.com/gardenlinux/gardenlinux/blob/main/features/_secureboot/README.md), [`_dev`](https://github.com/gardenlinux/gardenlinux/blob/main/features/_dev/README.md)), while features without a prefix are public (e.g., [`cis`](https://github.com/gardenlinux/gardenlinux/blob/main/features/cis/README.md), [`gardener`](https://github.com/gardenlinux/gardenlinux/blob/main/features/gardener/README.md), [`python`](https://github.com/gardenlinux/gardenlinux/blob/main/features/python/README.md)). See [Flavors documentation](../explanation/flavors.md) for an overview, and [ADR-0032](./adr/0032-static-feature-test-coverage-analysis.md) for details on feature test coverage analysis.

### FedRAMP

Expand All @@ -111,15 +111,15 @@ A lightweight virtual machine monitor (VMM) for running microVMs. Garden Linux h

### Flavor

A specific combination of a platform and one or more features that defines a complete Garden Linux image configuration. Flavors are expressed as hyphen-separated strings, e.g., `kvm-python_dev` or `aws-gardener_prod-amd64`. The platform must come first, and the architecture (if specified) must come last. See [Flavors and Features documentation](../explanation/flavors-and-features.md), [Choosing Flavors guide](../how-to/choosing-flavors.md), and [Flavor Matrix reference](./flavor-matrix.md) for more details.
A specific combination of a platform and one or more features that defines a complete Garden Linux image configuration. Flavors are expressed as hyphen-separated strings, e.g., `kvm-python_dev` or `aws-gardener_prod-amd64`. The platform must come first, and the architecture (if specified) must come last. See [Flavors documentation](../explanation/flavors.md), [Choosing Flavors guide](../how-to/choosing-flavors.md), and [Flavor Matrix reference](./flavor-matrix.md) for more details.

---

## G

### Garden Linux

A Debian GNU/Linux derivative designed to provide small, auditable Linux images for cloud providers and bare-metal machines. Garden Linux is optimized for Gardener nodes and provides extensive customization through features. See [Design Decisions](../explanation/design-decisions.md), [Use Cases](../explanation/use-cases.md), and [Security Posture](../explanation/security-posture.md) for more information.
A Debian GNU/Linux derivative designed to provide small, auditable Linux images for cloud providers and bare-metal machines. Garden Linux is optimized for Gardener nodes and provides extensive customization through features. See [Architectural Decisions](../explanation/architectural-decisions.md), [Use Cases](../explanation/use-cases.md), and [Security Posture](../explanation/security-posture.md) for more information.

### Gardener

Expand Down
30 changes: 28 additions & 2 deletions repos-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"docs_path": "docs",
"target_path": "projects/gardenlinux",
"ref": "docs-ng",
"commit": "a6251a94a3e75d13f3a22ce826a2760b69165b94",
"commit": "7544e2f732ccd8fd5aa66a202925df575eca6247",
"root_files": [
"CONTRIBUTING.md",
"SECURITY.md",
Expand Down Expand Up @@ -60,7 +60,33 @@
"docs_path": "docs",
"target_path": "projects/package-linux",
"ref": "docs-ng",
"commit": "057e2cef82be30255ed68281ffd0452cfc1cb76c",
"commit": "9570d0f81eae4e1e500dd3f36ea845a2dce14357",
"media_directories": [
".media",
"assets",
"_static"
]
},
{
"name": "package-build",
"url": "https://github.com/gardenlinux/package-build",
"docs_path": "docs",
"target_path": "projects/package-build",
"ref": "docs-ng",
"commit": "b4bce8b1dbb48cfedefdd866f3bc28d1c395c060",
"media_directories": [
".media",
"assets",
"_static"
]
},
{
"name": "repo",
"url": "https://github.com/gardenlinux/repo",
"docs_path": "docs",
"target_path": "projects/repo",
"ref": "docs-ng",
"commit": "4953feba27c5efd31421a883dec7c5bd61ac40f5",
"media_directories": [
".media",
"assets",
Expand Down
16 changes: 16 additions & 0 deletions repos-config.local.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,22 @@
"structure": "flat",
"media_directories": [".media", "assets", "_static"]
},
{
"name": "package-build",
"url": "file://../package-build",
"docs_path": "docs",
"target_path": "projects/package-build",
"structure": "flat",
"media_directories": [".media", "assets", "_static"]
},
{
"name": "repo",
"url": "file://../repo",
"docs_path": "docs",
"target_path": "projects/repo",
"structure": "flat",
"media_directories": [".media", "assets", "_static"]
},
{
"name": "glrd",
"url": "file://../glrd",
Expand Down
Loading