mirror of
https://github.com/eunomia-bpf/bpf-developer-tutorial.git
synced 2026-02-03 10:14:44 +08:00
fix website path
This commit is contained in:
219
scripts/generate_toc.py
Normal file
219
scripts/generate_toc.py
Normal file
@@ -0,0 +1,219 @@
|
||||
import os
|
||||
import re
|
||||
|
||||
# Define a function to walk through the directory and generate the TOC structure
|
||||
def generate_toc(base_dir, project_root):
|
||||
toc = "## Table of Contents\n\n"
|
||||
section_headers = {
|
||||
"Basic": "### Getting Started Examples\n\nThis section contains simple eBPF program examples and introductions. It primarily utilizes the `eunomia-bpf` framework to simplify development and introduces the basic usage and development process of eBPF.\n\n",
|
||||
"Advance": "### Advanced Documents and Examples\n\nWe start to build complete eBPF projects mainly based on `libbpf` and combine them with various application scenarios for practical use.\n\n",
|
||||
"Depth": "### In-Depth Topics\n\nThis section covers advanced topics related to eBPF, including using eBPF programs on Android, possible attacks and defenses using eBPF programs, and complex tracing. Combining the user-mode and kernel-mode aspects of eBPF can bring great power (as well as security risks).\n\n"
|
||||
}
|
||||
|
||||
subsection_titles = {
|
||||
"Android": "\n\nAndroid:\n\n",
|
||||
"Networking": "\n\nNetworking:\n\n",
|
||||
"tracing": "\n\ntracing:\n\n",
|
||||
"Security": "\n\nSecurity:\n\n",
|
||||
"Scheduler": "\n\nScheduler:\n\n",
|
||||
"Other": "\n\nOther:\n\n"
|
||||
}
|
||||
|
||||
subsection_order = ['Android', 'Networking', 'tracing', 'Security', 'Scheduler', 'Other']
|
||||
|
||||
# To ensure numeric sorting of directories
|
||||
def sort_key(directory_name):
|
||||
return list(map(int, re.findall(r'\d+', directory_name)))
|
||||
|
||||
sections = {} # {section_level: {subsection_type: [lessons]}}
|
||||
|
||||
# Sort directories properly by numeric order
|
||||
all_dirs = sorted([d for d in os.listdir(base_dir) if os.path.isdir(os.path.join(base_dir, d))], key=sort_key)
|
||||
|
||||
# Loop over the sorted directories
|
||||
for directory in all_dirs:
|
||||
lesson_path = os.path.join(base_dir, directory)
|
||||
config_path = os.path.join(lesson_path, ".config")
|
||||
readme_path = os.path.join(lesson_path, "README.md")
|
||||
|
||||
if os.path.exists(config_path) and os.path.exists(readme_path):
|
||||
# Read the .config file for 'level', 'type', and 'desc'
|
||||
with open(config_path, 'r') as config_file:
|
||||
config_lines = config_file.readlines()
|
||||
level = None
|
||||
lesson_type = None
|
||||
desc = None
|
||||
for line in config_lines:
|
||||
if line.startswith("level="):
|
||||
level = line.split("=",1)[1].strip()
|
||||
elif line.startswith("type="):
|
||||
lesson_type = line.split("=",1)[1].strip()
|
||||
elif line.startswith("desc="):
|
||||
desc = line.split("=",1)[1].strip()
|
||||
|
||||
# Extract the first markdown title in README_en.md
|
||||
with open(readme_path, 'r') as readme_file:
|
||||
first_title = None
|
||||
for line in readme_file:
|
||||
if line.startswith("#"):
|
||||
first_title = line.strip().lstrip("#").strip()
|
||||
break
|
||||
|
||||
# If title starts with "eBPF", remove the part before the colon
|
||||
if first_title and first_title.startswith("eBPF"):
|
||||
if ":" in first_title:
|
||||
first_title = first_title.split(":", 1)[1].strip()
|
||||
|
||||
# Get the relative path for the lesson
|
||||
lesson_rel_path = os.path.relpath(readme_path, project_root)
|
||||
|
||||
# Prepare lesson data
|
||||
lesson_number = directory.split('-')[0]
|
||||
lesson_name = directory.split('-', 1)[1]
|
||||
link_text = f"lesson {lesson_number}-{lesson_name}"
|
||||
link = f"{lesson_rel_path}"
|
||||
# Use description if available, else use first title
|
||||
lesson_desc = desc if desc else first_title
|
||||
|
||||
lesson_entry = {
|
||||
'link_text': link_text,
|
||||
'link': link,
|
||||
'desc': lesson_desc
|
||||
}
|
||||
|
||||
# Organize lessons into sections and subsections
|
||||
sections.setdefault(level, {}).setdefault(lesson_type, []).append(lesson_entry)
|
||||
|
||||
# Now, output the TOC in the desired order
|
||||
section_order = ['Basic', 'Advance', 'Depth']
|
||||
|
||||
for level in section_order:
|
||||
if level in sections:
|
||||
toc += section_headers.get(level, "")
|
||||
# For Basic and Advance sections, no subsections
|
||||
if level != 'Depth':
|
||||
for lesson in sum(sections[level].values(), []): # Flatten the list
|
||||
toc += f"- [{lesson['link_text']}]({lesson['link']}) {lesson['desc']}\n"
|
||||
else:
|
||||
# For Depth section, output subsections in the desired order
|
||||
for subsection in subsection_order:
|
||||
if subsection in sections[level]:
|
||||
toc += subsection_titles.get(subsection, "")
|
||||
for lesson in sections[level][subsection]:
|
||||
toc += f"- [{lesson['link_text']}]({lesson['link']}) {lesson['desc']}\n"
|
||||
|
||||
toc += "\nContinuously updating..."
|
||||
return toc
|
||||
|
||||
|
||||
# Define a function to walk through the directory and generate the TOC structure in Chinese
|
||||
def generate_toc_cn(base_dir, project_root):
|
||||
toc = "## 目录\n\n"
|
||||
section_headers = {
|
||||
"Basic": "### 入门示例\n\n这一部分包含简单的 eBPF 程序示例和介绍。主要利用 `eunomia-bpf` 框架简化开发,介绍 eBPF 的基本用法和开发流程。\n\n",
|
||||
"Advance": "### 高级文档和示例\n\n我们开始构建完整的 eBPF 项目,主要基于 `libbpf`,并将其与各种应用场景结合起来,以便实际使用。\n\n",
|
||||
"Depth": "### 深入主题\n\n这一部分涵盖了与 eBPF 相关的高级主题,包括在 Android 上使用 eBPF 程序、利用 eBPF 程序进行的潜在攻击和防御以及复杂的追踪。结合用户模式和内核模式的 eBPF 可以带来强大的能力(也可能带来安全风险)。\n\n"
|
||||
}
|
||||
|
||||
subsection_titles = {
|
||||
"Android": "Android:\n\n",
|
||||
"Networking": "网络:\n\n",
|
||||
"tracing": "追踪:\n\n",
|
||||
"Security": "安全:\n\n",
|
||||
"Scheduler": "调度器:\n\n",
|
||||
"Other": "其他:\n\n"
|
||||
}
|
||||
|
||||
subsection_order = ['Android', 'Networking', 'tracing', 'Security', 'Scheduler', 'Other']
|
||||
|
||||
# To ensure numeric sorting of directories
|
||||
def sort_key(directory_name):
|
||||
return list(map(int, re.findall(r'\d+', directory_name)))
|
||||
|
||||
sections = {} # {section_level: {subsection_type: [lessons]}}
|
||||
|
||||
# Sort directories properly by numeric order
|
||||
all_dirs = sorted([d for d in os.listdir(base_dir) if os.path.isdir(os.path.join(base_dir, d))], key=sort_key)
|
||||
|
||||
# Loop over the sorted directories
|
||||
for directory in all_dirs:
|
||||
lesson_path = os.path.join(base_dir, directory)
|
||||
config_path = os.path.join(lesson_path, ".config")
|
||||
readme_path = os.path.join(lesson_path, "README.zh.md")
|
||||
|
||||
if os.path.exists(config_path) and os.path.exists(readme_path):
|
||||
# Read the .config file for 'level', 'type', and 'desc'
|
||||
with open(config_path, 'r') as config_file:
|
||||
config_lines = config_file.readlines()
|
||||
level = None
|
||||
lesson_type = None
|
||||
desc = None
|
||||
for line in config_lines:
|
||||
if line.startswith("level="):
|
||||
level = line.split("=",1)[1].strip()
|
||||
elif line.startswith("type="):
|
||||
lesson_type = line.split("=",1)[1].strip()
|
||||
elif line.startswith("desc="):
|
||||
desc = line.split("=",1)[1].strip()
|
||||
|
||||
# Extract the first markdown title in README.md
|
||||
with open(readme_path, 'r') as readme_file:
|
||||
first_title = None
|
||||
for line in readme_file:
|
||||
if line.startswith("#"):
|
||||
first_title = line.strip().lstrip("#").strip()
|
||||
break
|
||||
|
||||
# If title starts with "eBPF", remove the part before the colon
|
||||
if first_title and first_title.startswith("eBPF"):
|
||||
if ":" in first_title:
|
||||
first_title = first_title.split(":", 1)[1].strip()
|
||||
|
||||
# Get the relative path for the lesson
|
||||
lesson_rel_path = os.path.relpath(readme_path, project_root)
|
||||
|
||||
# Prepare lesson data
|
||||
lesson_number = directory.split('-')[0]
|
||||
lesson_name = directory.split('-', 1)[1]
|
||||
link_text = f"lesson {lesson_number}-{lesson_name}"
|
||||
link = f"{lesson_rel_path}"
|
||||
# Use description if available, else use first title
|
||||
lesson_desc = desc if desc else first_title
|
||||
|
||||
lesson_entry = {
|
||||
'link_text': link_text,
|
||||
'link': link,
|
||||
'desc': lesson_desc
|
||||
}
|
||||
|
||||
# Organize lessons into sections and subsections
|
||||
sections.setdefault(level, {}).setdefault(lesson_type, []).append(lesson_entry)
|
||||
|
||||
# Now, output the TOC in the desired order
|
||||
section_order = ['Basic', 'Advance', 'Depth']
|
||||
|
||||
for level in section_order:
|
||||
if level in sections:
|
||||
toc += section_headers.get(level, "")
|
||||
# For Basic and Advance sections, no subsections
|
||||
if level != 'Depth':
|
||||
for lesson in sum(sections[level].values(), []): # Flatten the list
|
||||
toc += f"- [{lesson['link_text']}]({lesson['link']}) {lesson['desc']}\n"
|
||||
else:
|
||||
# For Depth section, output subsections in the desired order
|
||||
for subsection in subsection_order:
|
||||
if subsection in sections[level]:
|
||||
toc += subsection_titles.get(subsection, "")
|
||||
for lesson in sections[level][subsection]:
|
||||
toc += f"- [{lesson['link_text']}]({lesson['link']}) {lesson['desc']}\n"
|
||||
|
||||
toc += "\n持续更新中..."
|
||||
return toc
|
||||
|
||||
# Example usage
|
||||
base_directory = "src/" # Replace with the actual base directory
|
||||
project_root = "./" # The root of the project
|
||||
toc_output = generate_toc(base_directory, project_root)
|
||||
# toc_output = generate_toc_cn(base_directory, project_root)
|
||||
# Output the TOC
|
||||
print(toc_output)
|
||||
81
scripts/guideline_advance.md
Normal file
81
scripts/guideline_advance.md
Normal file
@@ -0,0 +1,81 @@
|
||||
# Blog Guidelines for Advanced eBPF Tutorials
|
||||
|
||||
This document outlines the key patterns and requirements for writing advanced eBPF tutorials. Advanced tutorials focus on complex eBPF programs, tools, or features that extend beyond basic concepts. They require a deeper understanding of eBPF and kernel interactions.
|
||||
|
||||
The audience for advanced tutorials includes developers, system administrators, and security professionals with intermediate to advanced eBPF knowledge. The goal is to provide in-depth explanations of advanced eBPF topics and practical examples that readers can apply in real-world scenarios.
|
||||
|
||||
The key point in tone: Using oral English, clear and simple words and short sentence, make it attractive and easy to read, do not make it like a paper. Not too much fancy words, try to be attracive.
|
||||
|
||||
You should also include all the details and information I provide to you. do not simplify or change any of them, you just need to regorganize them in a more attractive way as a tutorial blog.
|
||||
|
||||
## starting with a clear and descriptive title
|
||||
|
||||
Begin with a clear and descriptive title:
|
||||
|
||||
```
|
||||
# eBPF Tutorial by Example: [Advanced Topic]
|
||||
```
|
||||
|
||||
Kick off with a brief intro to the advanced eBPF topic you're covering, and the example or tool you'll discuss. Highlight its significance and how it extends beyond basic concepts. Let readers know what they'll learn and why it's important.
|
||||
|
||||
## Incroduction to the concept, tool and Background
|
||||
|
||||
(Come up with a better session title)
|
||||
|
||||
Provide an overview of the specific eBPF programs, tools, or features you'll discuss. Explain their purpose, use cases, and the key eBPF features or kernel events involved. Focus on aspects that are crucial for advanced understanding.
|
||||
|
||||
## High-Level Code Analysis
|
||||
|
||||
Dive into the kernel-mode eBPF code and user-space code, focusing on high-level concepts rather than basic syntax.
|
||||
|
||||
Always include the full code as it is first. then break down the key parts.
|
||||
|
||||
Try to avoid using too much list, make it more like a story.
|
||||
|
||||
Follow the steps:
|
||||
|
||||
1. First, introduce The overall processing logic in both kernel and user space.
|
||||
2. Then break down the kernel-mode eBPF code, include
|
||||
|
||||
- How the eBPF program is structured.
|
||||
- Key eBPF functionalities utilized.
|
||||
- How the code interacts with kernel events.
|
||||
|
||||
Do not make them a list, make them some paragraphs, you can also quote some code snippets to explain the key parts of the code if needed, focus on the logic and features used in advanced eBPF development. Don't make it too long, but make sure it is informative enough and you explain everything a advanced eBPF developer wants to know.
|
||||
|
||||
3. Then briefly explain the user-space code
|
||||
|
||||
Aim to help readers grasp how the code works without getting bogged down in basic details.
|
||||
|
||||
## Any more detailed concepts or features explanation
|
||||
|
||||
If there are other information or features that are important to understand the code, you can add them here.
|
||||
|
||||
## 5. Compilation and Execution
|
||||
|
||||
Provide instructions on compiling and running the eBPF programs, noting any advanced configurations or dependencies. Include commands and what readers should expect as output. Typically, you can run `make` in the relevant directory in the tutorial repository to build the code.
|
||||
|
||||
Include links to complete source code and resources:
|
||||
|
||||
- **Repository:** <https://github.com/eunomia-bpf/bpf-developer-tutorial>
|
||||
- **Website:** <https://eunomia.dev/tutorials/>
|
||||
|
||||
## 6. Summary and Call to Action
|
||||
|
||||
Wrap up by summarizing the key points. Emphasize the advanced concepts covered and encourage readers to apply this knowledge. Invite them to explore more examples and tutorials, as one paragraph:
|
||||
|
||||
> If you'd like to dive deeper into eBPF, check out our tutorial repository at <https://github.com/eunomia-bpf/bpf-developer-tutorial> or visit our website at <https://eunomia.dev/tutorials/>.
|
||||
|
||||
## reference
|
||||
|
||||
You should include the important references and resources that used in the tutorial. If this is from other sources like kernel sample or tools, make sure to include them here and clearly mention them in the tutorial.
|
||||
|
||||
## Additional Guidelines
|
||||
|
||||
- **Clarity:** Use simple language and short sentences to explain complex ideas. But the information should be complete and detailed.
|
||||
- **Focus on Advanced Concepts:** Assume readers have basic eBPF knowledge; skip elementary explanations.
|
||||
- **Engagement:** Encourage readers to think critically and engage with the material.
|
||||
- **Consistency:** Keep a consistent style and formatting throughout.
|
||||
- **Code Formatting:** Ensure code snippets are well-formatted and highlight key parts. Do not change or simplify any of the code and commands, keep them as they are.
|
||||
- **Proofreading:** Double-check for errors and ensure technical accuracy.
|
||||
- **Accessibility:** Make the content valuable for readers with advanced expertise, avoiding unnecessary simplifications.
|
||||
114
scripts/guideline_basic.md
Normal file
114
scripts/guideline_basic.md
Normal file
@@ -0,0 +1,114 @@
|
||||
# blog guideline or pattern
|
||||
|
||||
## Key Pattern and Requirements for eBPF Tutorial Blog Posts
|
||||
|
||||
### 1. **Title**
|
||||
|
||||
- Begin with a clear and descriptive title, following the format:
|
||||
|
||||
```
|
||||
# eBPF Tutorial by Example: [Topic Description]
|
||||
```
|
||||
|
||||
*Example:*
|
||||
|
||||
```
|
||||
# eBPF Tutorial by Example: Recording TCP Connection Status and TCP RTT
|
||||
```
|
||||
|
||||
- Or slightly different
|
||||
|
||||
```
|
||||
# eBPF Developer Tutorial: [Topic Description]
|
||||
```
|
||||
|
||||
### 2. **Introduction** and background
|
||||
|
||||
- Start with a brief introduction to eBPF, explaining its significance and capabilities.
|
||||
- Provide context for the tutorial's focus, mentioning the specific tools, example or use cases that will be covered.
|
||||
- **Goal:** Help readers understand what they will learn and why it's important.
|
||||
|
||||
### 3. **Overview of the Tools, Examples or features or what we are describing in this tutorial**
|
||||
|
||||
Think of a better subtitle related to this part.
|
||||
|
||||
- Introduce the specific eBPF programs or tools that will be discussed.
|
||||
- Explain their purpose and how they can help you, their usecase or why you need them.
|
||||
- What key eBPF feature or kernel events is used or related? Only discuss important ones, but should be detailed
|
||||
- **Goal:** Give readers a clear understanding of what each tool does.
|
||||
|
||||
Note that it might not always be a tool. Might be examples or others.
|
||||
|
||||
### 4. **Kernel eBPF Code Analysis**
|
||||
|
||||
- Present the kernel-mode eBPF code related to the tools.
|
||||
- Include code snippets with proper formatting for readability.
|
||||
- if not too long, include the full code first.
|
||||
- Provide detailed explanations of key sections in the code.
|
||||
- for example:
|
||||
- *Define BPF Maps:* Explain the maps used and their purposes.
|
||||
- *Events:* Describe how the code attaches to kernel events.
|
||||
- *Logic:* Explain how the processing in kernel happens
|
||||
- *Features*: introduce used features in eBPF
|
||||
- **Goal:** Help readers understand how the eBPF code works internally.
|
||||
|
||||
### 5. **User-Space Code Analysis**
|
||||
|
||||
- Present the user-space code that interacts with the eBPF program.
|
||||
- if not too long, include the full code first.
|
||||
- Include code snippets and explain how the user-space application processes data from the eBPF program.
|
||||
- for example:
|
||||
- *Event Handling:* Describe how events are received and processed.
|
||||
- *Data Presentation:* Explain how data is formatted and displayed to the user.
|
||||
- **Goal:** Show how the eBPF program communicates with user-space and how to interpret the results.
|
||||
|
||||
### 6. **Compilation and Execution Instructions**
|
||||
|
||||
- Provide step-by-step instructions on how to compile and run the eBPF programs.
|
||||
- Include commands and expected outputs.
|
||||
- Mention any prerequisites or dependencies required.
|
||||
- *Compiling the eBPF Program:* Commands and explanations.
|
||||
- *Running the User-Space Application:* How to execute and interpret outputs.
|
||||
- **Goal:** Enable readers to replicate the examples on their own systems.
|
||||
|
||||
You need to provide **Complete Source Code and Resources** link in ompilation and Execution Instructions.
|
||||
|
||||
- Provide links to the complete source code repositories.
|
||||
- Include references to related tools, documentation, or tutorials.
|
||||
- *Source Code:* Direct links to GitHub or relevant repositories.
|
||||
- *References:* List of resources for further reading.
|
||||
- **Goal:** Offer additional resources for readers to explore more deeply.
|
||||
|
||||
The repo is in <https://github.com/eunomia-bpf/bpf-developer-tutorial>, website at <https://eunomia.dev/tutorials/>. Typically you can run `make` in the related fir, such as `bpf-developer-tutorial/src/41-xdp-tcpdump` to build it.
|
||||
|
||||
### 7. **Summary and Conclusion**
|
||||
|
||||
- Summarize the key points covered in the tutorial.
|
||||
- Emphasize the importance of the tools and concepts learned.
|
||||
- Encourage readers to apply this knowledge and explore further.
|
||||
- **Goal:** Reinforce learning outcomes and inspire continued learning.
|
||||
|
||||
You need to have **Call to Action** in Summary and Conclusion
|
||||
|
||||
- Invite readers to visit your tutorial repository and website for more examples and complete tutorials.
|
||||
- Provide links to the main tutorial site and any relevant sections. The link should be show directly.
|
||||
|
||||
- **Example:**
|
||||
|
||||
```md
|
||||
If you would like to learn more about eBPF, visit our tutorial code repository at <https://github.com/eunomia-bpf/bpf-developer-tutorial> or our website at <https://eunomia.dev/tutorials/>.
|
||||
```
|
||||
|
||||
## Additional Guidelines
|
||||
|
||||
- **Consistency:** Maintain a consistent writing style and formatting across all blog posts.
|
||||
- **Clarity:** Use clear and concise language to explain complex concepts.
|
||||
- **Code Formatting:** Ensure all code snippets are properly formatted and syntax-highlighted for readability.
|
||||
- **Visual Aids:** Include diagrams or charts if they help in explaining concepts better.
|
||||
- **Audience Engagement:** Pose questions or scenarios that encourage readers to think and engage with the material.
|
||||
- **Proofreading:** Check for grammatical errors and ensure technical accuracy.
|
||||
- **Accessibility:** Make sure that the tutorials are accessible to readers with varying levels of expertise in eBPF.
|
||||
|
||||
Also, do not just list points, try to make it using paragraph unless points list is clear.
|
||||
|
||||
The key point in tone: Using oral English, clear and simple words and short sentence, make it attractive and easy to read, do not make it like a paper. Not too much fancy words, try to be attracive.
|
||||
34
scripts/rename.py
Normal file
34
scripts/rename.py
Normal file
@@ -0,0 +1,34 @@
|
||||
import os
|
||||
|
||||
def rename_readme_en_to_readme(base_dir):
|
||||
# First pass: Rename README_en.md to README.md
|
||||
for root, dirs, files in os.walk(base_dir):
|
||||
for file in files:
|
||||
file_path = os.path.join(root, file)
|
||||
|
||||
# Rename README_en.md to README.md
|
||||
if file == "README_en.md":
|
||||
new_file_path = os.path.join(root, "README.md")
|
||||
os.rename(file_path, new_file_path)
|
||||
print(f"Renamed {file_path} to {new_file_path}")
|
||||
|
||||
def rename_readme_to_readme_zh(base_dir):
|
||||
# Second pass: Rename README.md to README.zh.md
|
||||
for root, dirs, files in os.walk(base_dir):
|
||||
for file in files:
|
||||
file_path = os.path.join(root, file)
|
||||
|
||||
# Rename README.md to README.zh.md if it exists
|
||||
if file == "README.md":
|
||||
zh_file_path = os.path.join(root, "README.zh.md")
|
||||
os.rename(file_path, zh_file_path)
|
||||
print(f"Renamed {file_path} to {zh_file_path}")
|
||||
|
||||
# Example usage
|
||||
base_directory = "/root/bpf-developer-tutorial/src" # Replace with the actual base directory
|
||||
|
||||
# Second pass: Rename README.md to README.zh.md
|
||||
rename_readme_to_readme_zh(base_directory)
|
||||
|
||||
# First pass: Rename README_en.md to README.md
|
||||
rename_readme_en_to_readme(base_directory)
|
||||
Reference in New Issue
Block a user