184 lines
No EOL
6.8 KiB
Markdown
184 lines
No EOL
6.8 KiB
Markdown
# apt-layer C Refactor Plan
|
|
|
|
If you want to turn `apt-layer.sh` into a C binary, here's a practical, staged approach:
|
|
|
|
---
|
|
|
|
## 1. **Clarify the Scope**
|
|
- **Current:** Build-time tool for adding packages during image creation (not live/transactional)
|
|
- **Future:** End-user transactional package layering (like `rpm-ostree install`)
|
|
- **Platforms:** Linux only initially, Debian/Ubuntu-specific due to apt integration
|
|
- **Note:** Deep apt integration makes portability to other package managers a major rewrite
|
|
|
|
---
|
|
|
|
## 2. **Current Shell Script Analysis**
|
|
- **OSTree repo management:** Creating commits, managing branches
|
|
- **Package installation:** Using apt/apt-get in chroot/container
|
|
- **Container integration:** Podman/Docker for isolated builds
|
|
- **Recipe parsing:** YAML/JSON layer definitions
|
|
- **Logging and error handling:** Progress reporting and failure recovery
|
|
|
|
**Break down into:**
|
|
- **Shell glue** (calling external tools)
|
|
- **Logic** (parsing, validation, error handling)
|
|
- **User interaction** (progress reporting, prompts)
|
|
|
|
---
|
|
|
|
## 3. **Design the C Program**
|
|
|
|
### Phase 1: Build-Time Tool (MVP)
|
|
- **CLI interface:** `getopt` or `argp` for argument parsing
|
|
- **Subcommands:** `create`, `list`, `info`, `export`
|
|
- **System calls:** Use `fork`/`exec` (not `system()`) for better control and security
|
|
- **Logging:** Simple file logging or syslog
|
|
- **Config/Recipes:** YAML/JSON parser library
|
|
|
|
### Phase 2: End-User Layering (Future)
|
|
- **Transactional commands:** `install`, `remove`, `rollback`, `status`
|
|
- **Live system integration:** OSTree admin/deploy operations with atomic commits
|
|
- **User session handling:** Prompts, reboots, error recovery
|
|
- **History management:** Layer tracking and rollback support
|
|
- **Critical:** Deep `libapt-pkg` integration for reliable package management
|
|
|
|
---
|
|
|
|
## 4. **Incremental Porting Strategy**
|
|
- **MVP:** C program that wraps shell logic (calls `ostree`, `apt`, etc.)
|
|
- **Refactor:** Gradually replace shell-outs with native C code
|
|
- **Testing:** Ensure C binary produces same results as shell script
|
|
- **Transition:** Keep shell script as fallback during development
|
|
- **Phase 2 Prerequisite:** `libapt-pkg` integration before attempting live layering
|
|
|
|
---
|
|
|
|
## 5. **Libraries to Consider**
|
|
|
|
### Essential Libraries
|
|
- **Argument parsing:** `argp`, `getopt_long`
|
|
- **YAML/JSON parsing:** `libyaml`, `jansson`
|
|
- **Process management:** `fork`, `execvp`, `popen`
|
|
- **Logging:** `syslog` or custom implementation
|
|
- **OSTree integration:** `libostree` (avoid shelling out)
|
|
|
|
### Critical for Phase 2
|
|
- **`libapt-pkg`:** **ESSENTIAL** for client-side layering - not just an enhancement
|
|
- **`libdpkg`:** Alternative package management interface
|
|
- **Container integration:** Shell out to `podman`/`docker` initially
|
|
|
|
---
|
|
|
|
## 6. **Project Structure**
|
|
```
|
|
apt-layer/
|
|
├── src/
|
|
│ ├── main.c # Entry point, CLI parsing
|
|
│ ├── cli.c / cli.h # Command line interface
|
|
│ ├── layer.c / layer.h # Layer creation logic
|
|
│ ├── ostree.c / ostree.h # OSTree operations
|
|
│ ├── apt.c / apt.h # Package management (shell-out initially)
|
|
│ ├── apt_pkg.c / apt_pkg.h # libapt-pkg integration (Phase 2)
|
|
│ ├── config.c / config.h # Configuration/recipe parsing
|
|
│ ├── log.c / log.h # Logging system
|
|
│ ├── container.c / container.h # Container integration
|
|
│ └── transaction.c / transaction.h # Transactional operations (Phase 2)
|
|
├── include/
|
|
├── tests/
|
|
├── Makefile
|
|
├── README.md
|
|
└── LICENSE
|
|
```
|
|
|
|
---
|
|
|
|
## 7. **Development Steps**
|
|
|
|
### Phase 1: Build-Time Tool
|
|
1. **Scaffold CLI:** Parse arguments, print help/version
|
|
2. **Implement shell-out logic:** Use `fork`/`exec` for external tool calls
|
|
3. **Add config/recipe parsing:** Use library for YAML/JSON
|
|
4. **Implement core logic:** Layer creation, listing, info
|
|
5. **Replace shell-outs with native code:** Use libraries where possible
|
|
6. **Testing:** Write tests for each feature
|
|
|
|
### Phase 2: End-User Layering (Future)
|
|
1. **Integrate `libapt-pkg`:** **CRITICAL** - implement dependency resolution and package operations
|
|
2. **Design transactional data structures:** Layer history, rollback info
|
|
3. **Implement live system integration:** OSTree admin operations with atomic commits
|
|
4. **Add user interaction:** Prompts, confirmations, progress
|
|
5. **Implement rollback system:** History tracking and recovery
|
|
6. **Add TUI (optional):** Curses-based interface
|
|
|
|
---
|
|
|
|
## 8. **Command Structure**
|
|
|
|
### Build-Time Commands (Phase 1)
|
|
```bash
|
|
apt-layer create <base-branch> <new-branch> [packages...]
|
|
apt-layer list [branch-pattern]
|
|
apt-layer info <branch>
|
|
apt-layer export <branch> <image-name>
|
|
apt-layer --recipe <file>
|
|
```
|
|
|
|
### End-User Commands (Phase 2)
|
|
```bash
|
|
apt-layer install <packages...>
|
|
apt-layer remove <packages...>
|
|
apt-layer rollback [commit]
|
|
apt-layer status
|
|
apt-layer history
|
|
```
|
|
|
|
---
|
|
|
|
## 9. **Critical Technical Challenges**
|
|
|
|
### Phase 2 Complexity
|
|
- **Atomic Operations:** Ensuring package installation and OSTree commit happen atomically
|
|
- **Dependency Resolution:** Using `libapt-pkg` for reliable dependency handling
|
|
- **State Management:** Tracking package state across OSTree commits
|
|
- **Failure Recovery:** Handling failed installations without breaking the system
|
|
- **Performance:** Making client-side operations fast enough for interactive use
|
|
|
|
### libapt-pkg Integration
|
|
- **Not Optional:** Shelling out to `apt-get` for client-side layering will be brittle and slow
|
|
- **Complexity:** Direct integration with apt's internals is challenging but necessary
|
|
- **Benefits:** Reliable dependency resolution, state management, and immutability guarantees
|
|
|
|
---
|
|
|
|
## 10. **Long-Term Enhancements**
|
|
- Use `libostree` for direct repo manipulation
|
|
- **Use `libapt-pkg` for package management** (Phase 2 requirement)
|
|
- Add TUI with `ncurses`
|
|
- Add parallelism and better error handling
|
|
- Support for remote repositories
|
|
- Layer signing and verification
|
|
|
|
---
|
|
|
|
## 11. **Transitional Strategy**
|
|
- Keep shell script as fallback for unimplemented features
|
|
- Gradually phase out shell script as C code matures
|
|
- Maintain compatibility with existing build systems
|
|
- Test both build-time and user-time scenarios
|
|
- **Phase 2 milestone:** Must have `libapt-pkg` integration before attempting live layering
|
|
|
|
---
|
|
|
|
**Summary:**
|
|
Start with build-time tool in C, then incrementally add end-user layering features. The integration with `libapt-pkg` is **critical** for Phase 2 success - it's not just an enhancement but a fundamental requirement for achieving true `rpm-ostree`-like behavior.
|
|
|
|
**Next Steps:**
|
|
1. Create basic CLI skeleton
|
|
2. Implement build-time layer creation
|
|
3. Add recipe support
|
|
4. **Research and prototype `libapt-pkg` integration**
|
|
5. Prepare for transactional layering
|
|
|
|
**Success Criteria:**
|
|
- Phase 1: C binary that replicates current shell script functionality
|
|
- Phase 2: Reliable client-side package layering with atomic operations and rollback support |