diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 00000000..b484939c --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,10 @@ +## Goal + + +## Changes + + +## Testing +- [ ] Code compiles/runs without errors +- [ ] Signed commits verified +- [ ] Documentation updated \ No newline at end of file diff --git a/.github/workflows/lab3.yml b/.github/workflows/lab3.yml new file mode 100644 index 00000000..1befd647 --- /dev/null +++ b/.github/workflows/lab3.yml @@ -0,0 +1,58 @@ +name: Lab3 CI + +on: + push: + workflow_dispatch: + +jobs: + info: + name: Basic info + runs-on: ubuntu-latest + steps: + - name: Checkout repo + uses: actions/checkout@v4 + + - name: Print workflow context + run: | + echo "Event: ${{ github.event_name }}" + echo "Branch ref: ${{ github.ref }}" + echo "Commit SHA: ${{ github.sha }}" + echo "Repository: ${{ github.repository }}" + echo "Actor: ${{ github.actor }}" + + - name: Print OS basics + run: | + uname -a + git --version + + - name: Gather system information + run: | + echo "===== OS / Kernel =====" + uname -a + cat /etc/os-release || true + + echo "===== CPU =====" + nproc + lscpu || true + + echo "===== Memory =====" + free -h || true + + echo "===== Disk =====" + df -h || true + + echo "===== Network =====" + ip -br a || true + + echo "===== Tooling =====" + git --version + python --version || true + + second-job: + name: Dependent job + runs-on: ubuntu-latest + needs: info + steps: + - name: Confirm dependency + run: | + echo "Second job after first (needs: info)" diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..a38dbc03 --- /dev/null +++ b/.gitignore @@ -0,0 +1,164 @@ +### Python template +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/latest/usage/project/#working-with-version-control +.pdm.toml +.pdm-python +.pdm-build/ + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +.idea/ + diff --git a/demo.txt b/demo.txt new file mode 100644 index 00000000..bf80a2ac Binary files /dev/null and b/demo.txt differ diff --git a/labs/screenshots/lab_1/lab_1_1.png b/labs/screenshots/lab_1/lab_1_1.png new file mode 100644 index 00000000..10f8534a Binary files /dev/null and b/labs/screenshots/lab_1/lab_1_1.png differ diff --git a/labs/screenshots/lab_1/lab_1_2.png b/labs/screenshots/lab_1/lab_1_2.png new file mode 100644 index 00000000..5c63cac2 Binary files /dev/null and b/labs/screenshots/lab_1/lab_1_2.png differ diff --git a/labs/screenshots/lab_1/lab_1_3.png b/labs/screenshots/lab_1/lab_1_3.png new file mode 100644 index 00000000..08a3a4f1 Binary files /dev/null and b/labs/screenshots/lab_1/lab_1_3.png differ diff --git a/labs/screenshots/lab_1/lab_1_4.png b/labs/screenshots/lab_1/lab_1_4.png new file mode 100644 index 00000000..80872a22 Binary files /dev/null and b/labs/screenshots/lab_1/lab_1_4.png differ diff --git a/labs/screenshots/lab_1/lab_1_5.png b/labs/screenshots/lab_1/lab_1_5.png new file mode 100644 index 00000000..e9fee709 Binary files /dev/null and b/labs/screenshots/lab_1/lab_1_5.png differ diff --git a/labs/screenshots/lab_2/lab_2_1.png b/labs/screenshots/lab_2/lab_2_1.png new file mode 100644 index 00000000..b592e779 Binary files /dev/null and b/labs/screenshots/lab_2/lab_2_1.png differ diff --git a/labs/screenshots/lab_2/lab_2_10.png b/labs/screenshots/lab_2/lab_2_10.png new file mode 100644 index 00000000..5cff1289 Binary files /dev/null and b/labs/screenshots/lab_2/lab_2_10.png differ diff --git a/labs/screenshots/lab_2/lab_2_11.png b/labs/screenshots/lab_2/lab_2_11.png new file mode 100644 index 00000000..578ddd1d Binary files /dev/null and b/labs/screenshots/lab_2/lab_2_11.png differ diff --git a/labs/screenshots/lab_2/lab_2_12.png b/labs/screenshots/lab_2/lab_2_12.png new file mode 100644 index 00000000..96854959 Binary files /dev/null and b/labs/screenshots/lab_2/lab_2_12.png differ diff --git a/labs/screenshots/lab_2/lab_2_13.png b/labs/screenshots/lab_2/lab_2_13.png new file mode 100644 index 00000000..b6122754 Binary files /dev/null and b/labs/screenshots/lab_2/lab_2_13.png differ diff --git a/labs/screenshots/lab_2/lab_2_14.png b/labs/screenshots/lab_2/lab_2_14.png new file mode 100644 index 00000000..217f968e Binary files /dev/null and b/labs/screenshots/lab_2/lab_2_14.png differ diff --git a/labs/screenshots/lab_2/lab_2_15.png b/labs/screenshots/lab_2/lab_2_15.png new file mode 100644 index 00000000..c7b89bbe Binary files /dev/null and b/labs/screenshots/lab_2/lab_2_15.png differ diff --git a/labs/screenshots/lab_2/lab_2_16.png b/labs/screenshots/lab_2/lab_2_16.png new file mode 100644 index 00000000..9851216d Binary files /dev/null and b/labs/screenshots/lab_2/lab_2_16.png differ diff --git a/labs/screenshots/lab_2/lab_2_2.png b/labs/screenshots/lab_2/lab_2_2.png new file mode 100644 index 00000000..5028476c Binary files /dev/null and b/labs/screenshots/lab_2/lab_2_2.png differ diff --git a/labs/screenshots/lab_2/lab_2_3.png b/labs/screenshots/lab_2/lab_2_3.png new file mode 100644 index 00000000..007f8e65 Binary files /dev/null and b/labs/screenshots/lab_2/lab_2_3.png differ diff --git a/labs/screenshots/lab_2/lab_2_4.png b/labs/screenshots/lab_2/lab_2_4.png new file mode 100644 index 00000000..8c42f527 Binary files /dev/null and b/labs/screenshots/lab_2/lab_2_4.png differ diff --git a/labs/screenshots/lab_2/lab_2_5.png b/labs/screenshots/lab_2/lab_2_5.png new file mode 100644 index 00000000..b0b4332f Binary files /dev/null and b/labs/screenshots/lab_2/lab_2_5.png differ diff --git a/labs/screenshots/lab_2/lab_2_6.png b/labs/screenshots/lab_2/lab_2_6.png new file mode 100644 index 00000000..ad7e391d Binary files /dev/null and b/labs/screenshots/lab_2/lab_2_6.png differ diff --git a/labs/screenshots/lab_2/lab_2_7.png b/labs/screenshots/lab_2/lab_2_7.png new file mode 100644 index 00000000..201d64ca Binary files /dev/null and b/labs/screenshots/lab_2/lab_2_7.png differ diff --git a/labs/screenshots/lab_2/lab_2_8.png b/labs/screenshots/lab_2/lab_2_8.png new file mode 100644 index 00000000..9372e8d4 Binary files /dev/null and b/labs/screenshots/lab_2/lab_2_8.png differ diff --git a/labs/screenshots/lab_2/lab_2_9.png b/labs/screenshots/lab_2/lab_2_9.png new file mode 100644 index 00000000..c5c4b574 Binary files /dev/null and b/labs/screenshots/lab_2/lab_2_9.png differ diff --git a/labs/screenshots/lab_3/lab_3_0.png b/labs/screenshots/lab_3/lab_3_0.png new file mode 100644 index 00000000..d3c7a769 Binary files /dev/null and b/labs/screenshots/lab_3/lab_3_0.png differ diff --git a/labs/screenshots/lab_3/lab_3_1.png b/labs/screenshots/lab_3/lab_3_1.png new file mode 100644 index 00000000..adaecf03 Binary files /dev/null and b/labs/screenshots/lab_3/lab_3_1.png differ diff --git a/labs/screenshots/lab_3/lab_3_10.png b/labs/screenshots/lab_3/lab_3_10.png new file mode 100644 index 00000000..1f8cd0a3 Binary files /dev/null and b/labs/screenshots/lab_3/lab_3_10.png differ diff --git a/labs/screenshots/lab_3/lab_3_2.png b/labs/screenshots/lab_3/lab_3_2.png new file mode 100644 index 00000000..a5775044 Binary files /dev/null and b/labs/screenshots/lab_3/lab_3_2.png differ diff --git a/labs/screenshots/lab_3/lab_3_3.png b/labs/screenshots/lab_3/lab_3_3.png new file mode 100644 index 00000000..4c673887 Binary files /dev/null and b/labs/screenshots/lab_3/lab_3_3.png differ diff --git a/labs/screenshots/lab_3/lab_3_4.png b/labs/screenshots/lab_3/lab_3_4.png new file mode 100644 index 00000000..172447e7 Binary files /dev/null and b/labs/screenshots/lab_3/lab_3_4.png differ diff --git a/labs/screenshots/lab_3/lab_3_5.png b/labs/screenshots/lab_3/lab_3_5.png new file mode 100644 index 00000000..0c18e71f Binary files /dev/null and b/labs/screenshots/lab_3/lab_3_5.png differ diff --git a/labs/screenshots/lab_3/lab_3_6.png b/labs/screenshots/lab_3/lab_3_6.png new file mode 100644 index 00000000..44c56a5b Binary files /dev/null and b/labs/screenshots/lab_3/lab_3_6.png differ diff --git a/labs/screenshots/lab_3/lab_3_7.png b/labs/screenshots/lab_3/lab_3_7.png new file mode 100644 index 00000000..9c28c767 Binary files /dev/null and b/labs/screenshots/lab_3/lab_3_7.png differ diff --git a/labs/screenshots/lab_3/lab_3_8.png b/labs/screenshots/lab_3/lab_3_8.png new file mode 100644 index 00000000..b9a8c5d0 Binary files /dev/null and b/labs/screenshots/lab_3/lab_3_8.png differ diff --git a/labs/screenshots/lab_3/lab_3_9.png b/labs/screenshots/lab_3/lab_3_9.png new file mode 100644 index 00000000..c8e63cb1 Binary files /dev/null and b/labs/screenshots/lab_3/lab_3_9.png differ diff --git a/labs/screenshots/lab_4/lab_4_1.png b/labs/screenshots/lab_4/lab_4_1.png new file mode 100644 index 00000000..2223a5f1 Binary files /dev/null and b/labs/screenshots/lab_4/lab_4_1.png differ diff --git a/labs/submission1.md b/labs/submission1.md new file mode 100644 index 00000000..f44a5ed5 --- /dev/null +++ b/labs/submission1.md @@ -0,0 +1,62 @@ +# Lab 1 + +## Task 1: SSH Commit Signature Verification + +* A short summary explaining the benefits of signing commits. + +Signing your Git commits proves you are the actual author. It attaches a digital signature, generated by your private +key, to the commit itself. This serves several important purposes. + +First, it provides verification. It confirms that the commit truly came from you and not someone else using your name +and email address. On platforms like GitHub or GitLab, this is shown with a "Verified" badge next to the commit, making +trusted contributions easy to spot. + +Second, it ensures integrity. The signature also confirms that the commit—its code, message, author, and date—has not +been tampered with after you created it. If any part is altered, the verification will fail. + +This practice is a cornerstone of software supply chain security, particularly for open-source projects and teams. It +prevents malicious actors from injecting code while pretending to be a trusted contributor. For organizations, it can be +a requirement for security compliance and audit trails, as it creates a non-repudiable record of who changed what and +when. + +In short, signing commits is a straightforward technical step that establishes a chain of trust for your code's history. +It moves the project from "this commit claims to be from person X" to "this commit is verified to be from person X." + +* Evidence of successful SSH key setup and signed commit. + + ![SSH Key Setup](screenshots/lab_1/lab_1_2.png) + ![Signed Commit](screenshots/lab_1/lab_1_3.png) +* +* Answer: "Why is commit signing important in DevOps workflows?" + + In DevOps workflows, automation plays a huge role. CI/CD pipelines automatically build and deploy code. + If a hacker impersonates a developer and pushes malicious code, the pipeline might deploy it to production. + Commit signing prevents this: pipelines can be configured to reject any commits that are not signed by a trusted key. + This protects the software supply chain. + +* Screenshots or verification of the "Verified" badge on GitHub. + + ![Verified Badge](screenshots/lab_1/lab_1_1.png) + + +## Task 2: PR Template & Checklist + +* Screenshot of PR template auto-filling the description. + + ![PR Template Logic](screenshots/lab_1/lab_1_5.png) + +* Evidence that .github/pull_request_template.md exists on main branch. + + The file exists at `.github/pull_request_template.md` in the repository root. + ![File in .github folder](screenshots/lab_1/lab_1_4.png) + +* Analysis of how PR templates improve collaboration. + + PR templates standardize the code review process. + 1. **Clarity:** They ensure every PR has a clear goal and description of changes, so reviewers don't have to guess. + 2. **Consistency:** All developers follow the same format. + 3. **Quality Assurance:** The checklist reminds the author to perform essential checks (like testing or documentation) before requesting a review, reducing back-and-forth communication. + +* Note any challenges encountered during setup. + + The main challenge was the order of operations: the template file must be pushed to the `main` branch *before* creating the Pull Request, otherwise GitHub does not load it automatically. \ No newline at end of file diff --git a/labs/submission2.md b/labs/submission2.md new file mode 100644 index 00000000..6d93f059 --- /dev/null +++ b/labs/submission2.md @@ -0,0 +1,439 @@ +# Lab 2 — Version Control & Advanced Git + +## Task 1 — Git Object Model Exploration + +### What each object represents + +* Blob: stores the content of a file (bytes). It does not store filename or path. +* Tree: stores a directory snapshot: filenames + file modes + pointers to blobs (files) and other trees (subdirectories). +* Commit: stores metadata (author, message, timestamp) and points to a single root tree (snapshot) plus parent commit(s). + +### Analysis: how Git stores repository data + +Git is a content-addressable object store: each object (blob/tree/commit) is identified by its hash. +A commit represents a full snapshot via a root tree; trees reference blobs/trees, so the repository history is a chain of snapshots linked by parent pointers. + +### Commands and outputs + +**Create a sample commit** +```bash +echo "Test content" > test.txt +git add test.txt +git commit -m "Add test file" +git log --oneline -1 +``` + +```text +31c58a9 (HEAD -> feature/lab2) Add test file +``` + +**Inspect tree entries referenced by HEAD** + +```bash +git ls-tree HEAD +``` + +```text +100644 blob a38dbc03f5f790c14c955f7cc235f89bef651095 .gitignore +100644 blob 6e60bebec0724892a7c82c52183d0a7b467cb6bb README.md +040000 tree a1061247fd38ef2a568735939f86af7b1000f83c app +040000 tree 47f8b14e105dc6c7b484342b01f7d9e03c452bb4 labs +040000 tree d3fb3722b7a867a83efde73c57c49b5ab3e62c63 lectures +100644 blob 418a98ced2ac70b5bdee0be9732ecdaae7264515 test.txt +``` + +**Inspect blob content (test.txt)** + +```bash +git cat-file -p 418a98ced2ac70b5bdee0be9732ecdaae7264515 +``` + +```text +Test content +``` + +**Inspect commit object (HEAD)** + +```bash +git cat-file -p HEAD +``` + +```text +tree bc3fdac9ed1c923ddb4d97cc1cbc9eb2f76da041 +parent 31c58a917df7998afb6953b5a13b4e7705612974 +author Batsiev Oleg <122930346+zv3zdochka@users.noreply.github.com> 1770464616 +0300 +committer Batsiev Oleg <122930346+zv3zdochka@users.noreply.github.com> 1770464616 +0300 +(gpgsig omitted) +rename 1 lab screenshots +``` + +**Inspect tree object content** + +```bash +git cat-file -p bc3fdac9ed1c923ddb4d97cc1cbc9eb2f76da041 +``` + +```text +100644 blob a38dbc03f5f790c14c955f7cc235f89bef651095 .gitignore +100644 blob 6e60bebec0724892a7c82c52183d0a7b467cb6bb README.md +040000 tree a1061247fd38ef2a568735939f86af7b1000f83c app +040000 tree 31b249783e5b1d21eb16fea27bbb1c4a975dea70 labs +040000 tree d3fb3722b7a867a83efde73c57c49b5ab3e62c63 lectures +100644 blob 418a98ced2ac70b5bdee0be9732ecdaae7264515 test.txt +``` + +### Screenshots +![Task 1 — cat-file](screenshots/lab_2/lab_2_1.png) +![Task 1 — ls-tree ](screenshots/lab_2/lab_2_2.png) +![Task 1 — (cat-file -p HEAD)](screenshots/lab_2/lab_2_3.png) + +## Task 2 — Reset and Reflog Recovery + +### 2.1 Practice branch and commits + +```bash +git switch -c git-reset-practice +echo "First commit" > file.txt +git add file.txt +git commit -m "First commit" +echo "Second commit" >> file.txt +git add file.txt +git commit -m "Second commit" +echo "Third commit" >> file.txt +git add file.txt +git commit -m "Third commit" +``` + +**State after creating commits** + +```bash +git log --oneline -3 +``` + +```text +4930492 (HEAD -> git-reset-practice) Third commit +18c9b06 Second commit +7cb6166 First commit +``` + +--- + +### 2.2 Reset modes + +#### A) `git reset --soft HEAD~1` + +**Commands** + +```bash +git reset --soft HEAD~1 +git log --oneline -3 +git status +git diff --cached +``` + +**Outputs** + +```text +18c9b06 (HEAD -> git-reset-practice) Second commit +7cb6166 First commit +``` + +```text +Changes to be committed: + modified: file.txt +``` + +**Explanation** + +* **History:** HEAD moved back by one commit. +* **Index:** changes from the removed commit remained staged. +* **Working tree:** unchanged. + +--- + +#### B) `git reset --hard HEAD~1` + +Before applying hard reset, the removed commit was recreated: + +```bash +git commit -m "Recommit third (after soft reset)" +``` + +Then: + +```bash +git reset --hard HEAD~1 +git log --oneline -3 +git status +``` + +```text +18c9b06 (HEAD -> git-reset-practice) Second commit +7cb6166 First commit +``` + +**Explanation** + +* **History:** last commit was removed. +* **Index:** cleared. +* **Working tree:** reset to match HEAD. + +--- + +#### C) Recovery using `git reflog` + +```bash +git reflog -10 +``` + +```text +4930492 HEAD@{3}: commit: Third commit +1988c9c HEAD@{1}: commit: Recommit third (after soft reset) +18c9b06 HEAD@{0}: reset: moving to HEAD~1 +``` + +**Recovery** + +```bash +git reset --hard 4930492 +``` + +**Analysis** +Reflog stores previous positions of HEAD even after destructive operations like `reset --hard`. +By selecting the appropriate reflog entry, the lost commit history can be fully restored. + + + +### Screenshots +![Task 2 — commits](screenshots/lab_2/lab_2_4.png) +![Task 1 — git reflog](screenshots/lab_2/lab_2_5.png) + + +## Task 3 — Visualize Commit History + + +### Commands + +```bash +git switch feature/lab2 +git switch -c side-branch +echo "Branch commit" >> history.txt +git add history.txt +git commit -m "Side branch commit" +git switch - +git log --oneline --graph --all --decorate +``` + +### Graph snippet + +```text +(.venv) PS D:\PyCharmProjects\DevOps_Inno> git log --oneline --graph --all --decorate +* 3d98f3e (side-branch) Side branch commit +* 5f97d04 (HEAD -> feature/lab2, origin/feature/lab2) finish 2 task +| * 4930492 (git-reset-practice) Third commit +| * 18c9b06 Second commit +| * 7cb6166 First commit +|/ +* 5c85ae7 finish 1 task +* a0a4e17 finish 1 task +* fff44e8 rename 1 lab screenshots +* 31c58a9 Add test file +* 95510e1 prepare lab 2 +* 657b71a (origin/feature/lab1, feature/lab1) finish 2 task with screenshot +* a08b92f docs: add task 2 report +* 10e8ae5 complete task 1 +* d9ea462 docs: add commit signing summary +| * 49c941b (origin/main, main) chore: add PR template +|/ +* d6b6a03 Update lab2 +* 87810a0 feat: remove old Exam Exemption Policy +* 1e1c32b feat: update structure +* 6c27ee7 feat: publish lecs 9 & 10 +* 1826c36 feat: update lab7 +* 3049f08 feat: publish lec8 +* da8f635 feat: introduce all labs and revised structure +* 04b174e feat: publish lab and lec #5 +* 67f12f1 feat: publish labs 4&5, revise others +* 82d1989 feat: publish lab3 and lec3 +* 3f80c83 feat: publish lec2 +* 499f2ba feat: publish lab2 +* af0da89 feat: update lab1 +* 74a8c27 Publish lab1 +* f0485c0 Publish lec1 +* 31dd11b Publish README.md +``` + +### Reflection + +The `--graph --all` view makes branch divergence and branch pointers visible at a glance, so it’s easier to understand which commits belong to which branch and how HEAD moved during branching/merging. + +### Screenshot + +![Task 3 — git log graph](screenshots/lab_2/lab_2_6.png) + + +## Task 4 — Tagging Commits + +### Commands + +```bash +git switch feature/lab2 +git log --oneline -1 +git tag v1.0.0 +git show v1.0.0 --oneline --no-patch +git push origin v1.0.0 +``` + +```bash +echo "Release note for v1.1.0" >> release.txt +git add release.txt +git commit -m "chore: prepare v1.1.0" +git tag v1.1.0 +git show v1.1.0 --oneline --no-patch +git push origin v1.1.0 +``` + +### Tags and associated commits + +* **v1.0.0** → commit `54c12fc` (`finish task 3`) +* **v1.1.0** → commit `de664a0` (`chore: prepare v1.1.0`) + +### Why tags matter + +Tags mark specific commits as release points. They are used for semantic versioning, generating release notes, and often serve as triggers for CI/CD pipelines to build and deploy a specific version of the project. + + +### Screenshot +![Task 4 — tags](screenshots/lab_2/lab_2_7.png) + +## Task 5 — git switch vs git checkout vs git restore + +### git switch (modern, branch switching) + +```bash +git switch -c cmd-compare +git branch --show-current +git switch - +git branch --show-current +``` + +```text +Switched to a new branch 'cmd-compare' +cmd-compare +Switched to branch 'feature/lab2' +feature/lab2 +``` + +### git checkout (legacy, overloaded) + +```bash +git checkout -b cmd-compare-2 +git branch --show-current +git switch feature/lab2 +``` + +```text +Switched to a new branch 'cmd-compare-2' +cmd-compare-2 +Switched to branch 'feature/lab2' +``` + +### git restore (modern, file operations) + +#### Discard working tree changes + +```bash +echo "original" > demo.txt +git add demo.txt +git commit -m "chore: add demo file for restore" + +echo "scratch" >> demo.txt +git status +git restore demo.txt +git status +type demo.txt +``` + +```text +Changes not staged for commit: + modified: demo.txt +``` + +```text +original +``` + +#### Unstage changes (keep working tree) + +```bash +echo "staged change" >> demo.txt +git add demo.txt +git status +git restore --staged demo.txt +git status +``` + +```text +Changes to be committed: + modified: demo.txt +``` + +```text +Changes not staged for commit: + modified: demo.txt +``` + +#### Restore from another commit + +```bash +git add demo.txt +git commit -m "chore: update demo file" + +echo "junk" >> demo.txt +git restore --source=HEAD~1 demo.txt +type demo.txt +``` + +```text +original +``` + +### When to use each + +Use `git switch` for creating and switching branches because it is focused only on branch operations and reduces ambiguity. +Use `git restore` for undoing file changes (discard working tree edits, unstage, restore from a commit) because it cleanly separates file operations from branch switching. +`git checkout` is legacy and overloaded (branches + files), so it is easier to misuse; prefer `switch/restore` in modern workflows. + + +### Screenshot +![Task 5 — restore status changes](screenshots/lab_2/lab_2_8.png) + +## Task 6 — GitHub Community Engagement + +### Actions completed + +- Starred the course repository. +- Starred `simple-container-com/api`. +- Followed: + - Professor: `@Cre-eD` + - TAs: `@marat-biriushev`, `@pierrepicaud` +- Followed at least 3 classmates from the course. + +![Task 6 — GitHub community](screenshots/lab_2/lab_2_9.png) +![Task 6 — GitHub community](screenshots/lab_2/lab_2_10.png) +![Task 6 — GitHub community](screenshots/lab_2/lab_2_11.png) +![Task 6 — GitHub community](screenshots/lab_2/lab_2_12.png) +![Task 6 — GitHub community](screenshots/lab_2/lab_2_13.png) +![Task 6 — GitHub community](screenshots/lab_2/lab_2_14.png) +![Task 6 — GitHub community](screenshots/lab_2/lab_2_15.png) +![Task 6 — GitHub community](screenshots/lab_2/lab_2_16.png) + + +## Challenges & Solutions + +The main difficulty was understanding how Git actually works with commits, branches, and resets. By running the commands step by step and checking `git status`, `git log`, and `git reflog`, it became much clearer how changes affect the working directory, staging area, and commit history. + + +## GitHub Community + +Starring repositories matters in open source because it helps with discovery, signals community interest and appreciation to maintainers, and increases a project’s visibility in GitHub search and recommendations. Following developers helps in team projects and professional growth by keeping you aware of others’ work, enabling collaboration, learning from experienced contributors, and building a professional network. diff --git a/labs/submission3.md b/labs/submission3.md new file mode 100644 index 00000000..79838eec --- /dev/null +++ b/labs/submission3.md @@ -0,0 +1,77 @@ +# Lab 3 — CI/CD with GitHub Actions + +## Task 1 — First GitHub Actions Workflow + +**Successful run:** https://github.com/zv3zdochka/DevOps-Intro/actions/runs/22070050625 + +### Evidence (screenshots) + +![Actions runs list](screenshots/lab_3/lab_3_0.png) +![Run summary / jobs](screenshots/lab_3/lab_3_1.png) +![Job logs: Basic info](screenshots/lab_3/lab_3_2.png) +![Job logs: Dependent job](screenshots/lab_3/lab_3_3.png) + +### What I did (Quickstart implementation) + +- Created a workflow YAML file in `.github/workflows/` (`lab3.yml`). +- Configured the workflow to run on the `push` event. +- Defined two jobs: + - `info` — prints workflow context and basic OS/tooling information. + - `second-job` — runs only after `info` completes successfully (job dependency). + +### Key concepts + +- **Workflow**: an automation described in a YAML file stored under `.github/workflows/`. +- **Trigger / Event**: the condition that starts a workflow run (here: `on: push`). +- **Runner**: the execution environment (a GitHub-hosted VM) where jobs run (`ubuntu-latest`). +- **Job**: a set of steps executed on the same runner (here: `info`, `second-job`). +- **Step**: an individual action (`uses`) or shell command (`run`) executed inside a job. +- **Job dependency**: `needs: info` ensures `second-job` starts only after `info` succeeds. + +### What triggered the run + +The workflow run started automatically because I pushed a commit to branch `feature/lab3`, and the workflow is configured with the `push` trigger. + +### Execution analysis + +After the `push` event, GitHub Actions matched the workflow by `on: push`, provisioned a GitHub-hosted runner (`ubuntu-latest`) for the `info` job, and executed its steps sequentially (checkout → printing context → OS basics). +Once `info` finished successfully, the dependency condition `needs: info` was satisfied, so `second-job` started and executed its step, confirming the job order via logs. + + +## Task 2 — Manual Trigger + System Information + +### Changes made to the workflow +Workflow file: `.github/workflows/lab3.yml` + +- Added a manual trigger via `workflow_dispatch`, so the workflow can be started from the GitHub UI (Actions → Lab3 CI → Run workflow). +- Added an additional step `Gather system information` inside the `info` job to collect detailed runner environment information (OS, CPU, memory, disk, network, tooling). + +### Evidence (screenshots) + +![Workflow manual run UI / runs list](screenshots/lab_3/lab_3_4.png) +![Manual dispatch form (branch selection)](screenshots/lab_3/lab_3_5.png) +![Run details: workflow_dispatch event](screenshots/lab_3/lab_3_6.png) +![Job Basic info: step list](screenshots/lab_3/lab_3_7.png) +![Logs: Gather system information (part 1)](screenshots/lab_3/lab_3_8.png) +![Logs: Gather system information (part 2)](screenshots/lab_3/lab_3_9.png) +![Logs: Gather system information (part 3)](screenshots/lab_3/lab_3_10.png) + +### Manual run link +https://github.com/zv3zdochka/DevOps-Intro/actions/runs/22074184273 + +### Gathered system information (runner) +The `Gather system information` step prints: +- **OS / Kernel**: `uname -a`, `/etc/os-release` +- **CPU**: `nproc`, `lscpu` +- **Memory**: `free -h` +- **Disk**: `df -h` +- **Network**: `ip -br a` +- **Tooling**: `git --version`, `python --version` + + +### Manual vs automatic triggers (comparison) +- **Automatic trigger (`push`)**: the workflow starts automatically on every push event that matches the workflow rules. It is useful for continuous integration: every change is verified immediately after being pushed. +- **Manual trigger (`workflow_dispatch`)**: the workflow starts only when the user explicitly launches it from the GitHub Actions UI. This is useful for ad-hoc runs: debugging, checking runner environment, re-running without new commits, and collecting diagnostics. + +### Runner environment analysis +The workflow runs on a GitHub-hosted runner (`ubuntu-latest`). The runner environment is ephemeral: each run starts from a clean VM-like environment that already contains common Linux utilities and developer tooling. The collected system information confirms the available CPU cores, memory, disk space, and baseline OS/tooling versions, which is sufficient for typical CI tasks (build/test/lint). If the workflow needs additional dependencies, they must be installed explicitly within the job steps. diff --git a/labs/submission4.md b/labs/submission4.md new file mode 100644 index 00000000..da348083 --- /dev/null +++ b/labs/submission4.md @@ -0,0 +1,401 @@ +# Lab 4 — Operating System & Networking + + +During this lab, I've been using my own VPS server provided by HOSTVDS. +![VPS](screenshots/lab_4/lab_4_1.png) +## Task 1 — Operating System Analysis + + +```bash +systemd-analyze +``` + +``` +Startup finished in 3.072s (kernel) + 11.640s (userspace) = 14.713s +graphical.target reached after 9.486s in userspace. +``` + +```bash +systemd-analyze blame | head -n 25 +``` + +``` +35.313s apt-daily.service +31.193s apt-daily-upgrade.service +2.733s docker.service +2.128s systemd-journal-flush.service +2.123s cloud-init-local.service +2.029s logrotate.service +1.929s cloud-final.service +1.751s cloud-config.service +1.420s dev-vda1.device +1.247s systemd-networkd-wait-online.service +997ms certbot.service +996ms tuned.service +985ms cloud-init.service +921ms containerd.service +838ms gpu-manager.service +751ms accounts-daemon.service +635ms rsyslog.service +563ms ufw.service +405ms user@104.service +396ms man-db.service +396ms user@0.service +392ms systemd-udev-trigger.service +345ms mysql.service +344ms polkit.service +334ms fstrim.service +``` + +```bash +uptime +``` + +``` +14:25:31 up 86 days, 8:06, 3 users, load average: 0.18, 0.11, 0.06 +``` + +```bash +w +``` + +``` +USER TTY FROM LOGIN@ IDLE WHAT +root 172.17.0.XXX 14:24 86days sshd: root@pts/0 +lightdm - 28Nov25 86days lightdm --session-child +``` + +* Total boot time is **14.7 seconds**, indicating fast system initialization. +* The largest boot delays are caused by automatic package update services (`apt-daily`, `apt-daily-upgrade`). +* System load averages are very low (<0.2), showing minimal CPU utilization. +* The system has been running continuously for **86 days**, indicating stable uptime. + + +```bash +ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%mem | head -n 6 +``` + +``` +PID PPID CMD %MEM %CPU +2771591 ... python3.12 4.7 0.0 +2771590 ... python3.12 4.7 0.0 +2771588 ... python3.12 4.6 0.0 +3605418 ... python3.12 4.5 0.0 +241 1 systemd-journald 3.6 0.0 +``` + +**Top memory-consuming process:** `python3.12` (highest `%MEM` in the snapshot, ~4.7%). + +```bash +ps -eo pid,ppid,cmd,%mem,%cpu --sort=-%cpu | head -n 6 +``` + +``` +PID PPID CMD %MEM %CPU +3655872 547 sshd: root [priv] 0.2 10.1 +3655873 ... sshd: root [net] 0.1 0.9 +``` + +### Observations + +* Multiple Python processes consume the largest portion of memory. +* SSH daemon temporarily shows the highest CPU usage due to active remote session handling. +* Background system processes maintain low CPU utilization. + +--- + +```bash +systemctl list-dependencies | head -n 80 +``` + +output truncated + +``` +default.target +├─accounts-daemon.service +├─lightdm.service +└─multi-user.target + ├─docker.service + ├─nginx.service + ├─openvpn.service + ├─ssh.service + ├─systemd-networkd.service + └─ufw.service +``` + +```bash +systemctl list-dependencies multi-user.target | head -n 120 +``` + +output truncated + +``` +multi-user.target +├─docker.service +├─nginx.service +├─openvpn.service +├─ssh.service +├─rsyslog.service +├─systemd-networkd.service +└─timers.target +``` + +### Observations + +* The system follows a standard Linux service hierarchy managed by `systemd`. +* Core infrastructure services include Docker, SSH, networking, logging, and firewall services. +* One dependency (`mysql.service`) appears inactive or failed, which may indicate unused or misconfigured service. + +--- + +```bash +who -a +``` + +``` +system boot 2025-11-28 +run-level 5 2025-11-28 +root pts/0 172.17.0.XXX still logged in +``` + +```bash +last -n 5 +``` + +``` +root pts/0 172.17.0.XXX still logged in +root pts/0 188.130.155.XXX Mon Feb 16 +root pts/0 172.17.0.XXX Mon Feb 9 +root pts/0 188.130.155.XXX Fri Feb 6 +root pts/1 172.17.0.XXX Sun Feb 1 +``` + +### Observations + +* Remote access is performed via SSH sessions. +* Login history confirms repeated administrative access. +* No abnormal login patterns were observed. + +--- + +```bash +free -h +``` + +``` +Mem: 3.8Gi total, 1.3Gi used, 199Mi free, 2.6Gi buff/cache +Swap: 4.0Gi total, 194Mi used +``` + +```bash +cat /proc/meminfo | grep -e MemTotal -e SwapTotal -e MemAvailable +``` + +``` +MemTotal: 4009884 kB +MemAvailable: 2608444 kB +SwapTotal: 4194300 kB +``` + +### Observations + +* Significant portion of RAM is used as filesystem cache. +* Available memory (~2.5 GB) indicates no memory pressure. +* Swap usage is minimal, confirming efficient memory management. + +--- + +## Resource Utilization Patterns + +* CPU usage remains consistently low. +* Memory consumption is dominated by application-level Python processes. +* System services operate efficiently with stable long-term uptime. +* Cached memory usage improves disk I/O performance. + +--- + +## Task 2 — Networking Analysis + +--- + +```bash +traceroute github.com +``` + +``` +traceroute to github.com (4.225.11.194), 30 hops max, 60 byte packets + 1 _gateway (95.182.115.XXX) 3.918 ms 3.817 ms 3.763 ms + 2 ae14-218.rt.rad.hki.fi.retn.net (87.245.244.XXX) 3.728 ms 3.683 ms 3.589 ms + 3 ae6-6.rt.tc1.sto.se.retn.net (87.245.233.XXX) 6.682 ms 6.608 ms * + 4 ae62-0.ier01.sto.ntwk.msn.net (104.44.47.XXX) 6.777 ms 7.990 ms ae60-0.ier02.sto.ntwk.msn.net (104.44.47.XXX) 6.683 ms + 5 ae21-0.ear02.sto31.ntwk.msn.net (104.44.239.XXX) 7.934 ms ae20-0.ear02.sto30.ntwk.msn.net (104.44.239.XXX) 7.848 ms 7.812 ms + 6 be-22-0.ibr02.sto31.ntwk.msn.net (104.44.22.XXX) 10.370 ms be-24-0.ibr01.sto30.ntwk.msn.net (104.44.22.XXX) 10.306 ms be-22-0.ibr02.sto31.ntwk.msn.net (104.44.22.XXX) 10.103 ms + 7 51.10.15.XXX (51.10.15.XXX) 10.054 ms 10.377 ms be-5-0.ibr01.gvx01.ntwk.msn.net (104.44.17.XXX) 9.681 ms + 8 51.10.45.XXX (51.10.45.XXX) 10.147 ms 51.10.15.XXX (51.10.15.XXX) 11.103 ms 51.10.36.XXX (51.10.36.XXX) 10.661 ms + 9 * 51.10.12.XXX (51.10.12.XXX) 11.711 ms 51.10.27.XXX (51.10.27.XXX) 10.961 ms +10 * * * +11 * * * +12 * * * +13 * * * +14 * * * +15 * * * +16 * * * +17 * * * +18 * * * +19 * * * +20 * * * +21 * * * +22 * * * +23 * * * +24 * * * +25 * * * +26 * * * +27 * * * +28 * * * +29 * * * +30 * * * +``` + +### Insights + +* The path reaches several upstream providers quickly (low latency ~4–12 ms for first ~9 hops). +* Many later hops return `* * *`, which typically indicates ICMP/UDP traceroute responses are filtered or rate-limited beyond a certain point (common in provider networks and cloud edges). +* Despite incomplete hop visibility, DNS resolution confirms GitHub is reachable and provides an IP (next section). + + +```bash +dig github.com +``` + +``` +; <<>> DiG 9.18.39-0ubuntu0.24.04.2-Ubuntu <<>> github.com +;; global options: +cmd +;; Got answer: +;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 16093 +;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 + +;; OPT PSEUDOSECTION: +; EDNS: version: 0, flags:; udp: 65494 +;; QUESTION SECTION: +;github.com. IN A + +;; ANSWER SECTION: +github.com. 5 IN A 4.225.11.194 + +;; Query time: 0 msec +;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP) +;; WHEN: Sun Feb 22 14:35:18 UTC 2026 +;; MSG SIZE rcvd: 55 +``` + +### Insights (DNS) + +* DNS resolution succeeded with status `NOERROR` and returned an A record: `4.225.11.194`. +* The resolver used is `127.0.0.53` (systemd-resolved local stub), meaning queries are served via the local caching resolver. +* Query time is `0 ms`, consistent with cached responses or a fast local resolver path. + + +```bash +sudo timeout 10 tcpdump -c 5 -i any 'port 53' -nn +``` + +**Capture #1 (external DNS traffic to Cloudflare 1.1.1.1):** + +``` +tcpdump: data link type LINUX_SLL2 +tcpdump: verbose output suppressed, use -v[v]... for full protocol decode +listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes +14:35:25.520289 vethf7595f4 P IP 172.17.0.XXX.59787 > 1.1.1.XXX.53: 6997+ A? download.jetbrains.com. (40) +14:35:25.520289 docker0 In IP 172.17.0.XXX.59787 > 1.1.1.XXX.53: 6997+ A? download.jetbrains.com. (40) +14:35:25.520306 eth0 Out IP 95.182.115.XXX.59787 > 1.1.1.XXX.53: 6997+ A? download.jetbrains.com. (40) +14:35:25.528167 eth0 In IP 1.1.1.XXX.53 > 95.182.115.XXX.59787: 6997 5/0/0 CNAME d1do0znm134sif.cloudfront.net., A 18.239.18.XXX, A 18.239.18.XXX, A 18.239.18.XXX, A 18.239.18.XXX (147) +14:35:25.528211 docker0 Out IP 1.1.1.XXX.53 > 172.17.0.XXX.59787: 6997 5/0/0 CNAME d1do0znm134sif.cloudfront.net., A 18.239.18.XXX, A 18.239.18.XXX, A 18.239.18.XXX, A 18.239.18.XXX (147) +5 packets captured +16 packets received by filter +0 packets dropped by kernel +``` + +**Capture #2 (local stub resolver traffic via 127.0.0.53):** + +``` +tcpdump: data link type LINUX_SLL2 +tcpdump: verbose output suppressed, use -v[v]... for full protocol decode +listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes +14:35:47.888747 lo In IP 127.0.0.XXX.57271 > 127.0.0.XXX.53: 65129+ [1au] A? google.com. (51) +14:35:47.889204 lo In IP 127.0.0.XXX.53 > 127.0.0.XXX.57271: 65129 1/0/1 A 172.217.21.XXX (55) +14:35:51.021425 lo In IP 127.0.0.XXX.49499 > 127.0.0.XXX.53: 25918+ [1au] A? google.com. (51) +14:35:51.021911 lo In IP 127.0.0.XXX.53 > 127.0.0.XXX.49499: 25918 1/0/1 A 172.217.21.XXX (55) +14:35:51.585157 lo In IP 127.0.0.XXX.44772 > 127.0.0.XXX.53: 43941+ [1au] A? google.com. (51) +5 packets captured +17 packets received by filter +0 packets dropped by kernel +``` + +### One example DNS query + +Example query: + +``` +IP 95.182.115.XXX.59787 > 1.1.1.XXX.53: A? download.jetbrains.com. +``` + +### Analysis + +* The tcpdump output shows a standard DNS exchange over UDP/53: an A-record query followed by a response containing records. +* Capture #1 demonstrates DNS from a container/bridge context (`veth*`, `docker0`) going out through the host interface (`eth0`) to a public resolver (1.1.1.1), and returning multiple A records + a CNAME (CDN-backed resolution via CloudFront). +* Capture #2 demonstrates the local systemd-resolved stub behavior: the client queries `127.0.0.53:53` on loopback, receives replies locally (often cached), hence very low response times. + + +```bash +dig -x 8.8.4.4 +``` + +``` +; <<>> DiG 9.18.39-0ubuntu0.24.04.2-Ubuntu <<>> -x 8.8.4.4 +;; global options: +cmd +;; Got answer: +;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 3567 +;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 + +;; QUESTION SECTION: +;4.4.8.8.in-addr.arpa. IN PTR + +;; ANSWER SECTION: +4.4.8.8.in-addr.arpa. 71574 IN PTR dns.google. + +;; Query time: 10 msec +;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP) +;; WHEN: Sun Feb 22 14:36:03 UTC 2026 +;; MSG SIZE rcvd: 73 +``` + +```bash +dig -x 1.1.2.2 +``` + +``` +; <<>> DiG 9.18.39-0ubuntu0.24.04.2-Ubuntu <<>> -x 1.1.2.2 +;; global options: +cmd +;; Got answer: +;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 57000 +;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1 + +;; QUESTION SECTION: +;2.2.1.1.in-addr.arpa. IN PTR + +;; AUTHORITY SECTION: +1.in-addr.arpa. 2735 IN SOA ns.apnic.net. read-txt-record-of-zone-first-dns-admin.apnic.net. 23597 7200 1800 604800 3600 + +;; Query time: 10 msec +;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP) +;; WHEN: Sun Feb 22 14:36:03 UTC 2026 +;; MSG SIZE rcvd: 137 +``` + +### Comparison (Reverse lookup results) + +* `8.8.4.4` returns a valid PTR record: `dns.google.` (Google public DNS reverse mapping exists). +* `1.1.2.2` returns `NXDOMAIN`, meaning no PTR record is defined for that address (not all IPs in a public range have reverse DNS configured). +* Both lookups were performed via the local stub resolver `127.0.0.53`. + +--- diff --git a/release.txt b/release.txt new file mode 100644 index 00000000..bb1917bb Binary files /dev/null and b/release.txt differ diff --git a/test.txt b/test.txt new file mode 100644 index 00000000..418a98ce Binary files /dev/null and b/test.txt differ