1
0
Fork 0
mirror of https://codeberg.org/Mo8it/How_To_Linux.git synced 2024-12-05 01:40:32 +00:00

Compare commits

...

3 commits

Author SHA1 Message Date
0e94ff32c1 Add nginx config 2023-08-14 04:43:07 +02:00
3d399b5417 Add Containerfile 2023-08-14 04:43:02 +02:00
dd7f1941fc Done first day tasks 2023-08-14 04:32:47 +02:00
15 changed files with 439 additions and 23 deletions

2
.containerignore Normal file
View file

@ -0,0 +1,2 @@
Containerfile
.containerignore

4
Containerfile Normal file
View file

@ -0,0 +1,4 @@
FROM docker.io/library/nginx:alpine
EXPOSE 80
COPY ./nginx.conf /etc/nginx/nginx.conf
COPY ./book/ /usr/share/nginx/html/

15
cs/Cargo.lock generated
View file

@ -190,9 +190,9 @@ checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b"
[[package]]
name = "collective-score-client"
version = "0.0.2"
version = "0.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18bad7c08c5e9754d1b3a09aab531b2a5112ecb241c8bbf7d52c164db5cfab37"
checksum = "d7bf3513f18ebf36b12e0bf91049c2091d5d014a585c65bf54648d19223abe19"
dependencies = [
"anyhow",
"clap",
@ -218,6 +218,8 @@ name = "cs"
version = "0.1.0"
dependencies = [
"collective-score-client",
"dirs",
"regex",
]
[[package]]
@ -229,6 +231,15 @@ dependencies = [
"dirs-sys",
]
[[package]]
name = "dirs"
version = "5.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225"
dependencies = [
"dirs-sys",
]
[[package]]
name = "dirs-sys"
version = "0.4.1"

View file

@ -8,4 +8,6 @@ license = "AGPL-3.0"
repository = "https://codeberg.org/mo8it/dev-tools"
[dependencies]
collective-score-client = "0.0.2"
collective-score-client = "0.0.5"
dirs = "5.0.1"
regex = "1.9.3"

View file

@ -1,9 +1,9 @@
use collective_score_client::{
check::{Check, IntoTask, RunnableCheck},
check::{Check, IntoTask, Task},
validator::{stdin::Stdin, string_content::StringContent},
};
pub fn task() -> (&'static str, Box<dyn RunnableCheck>) {
pub fn task() -> Task {
Check::builder()
.description("Checking stdin")
.validator(Stdin {

60
cs/src/day1/cowsay.rs Normal file
View file

@ -0,0 +1,60 @@
use collective_score_client::{
check::{Check, IntoTask, Task},
validator::{
command::{Command, CommandStatus, StdioVariant},
file::FileContent,
string_content::StringContent,
},
};
use regex::Regex;
pub fn task() -> Task {
let fish_history = dirs::home_dir()
.expect("Failed to get the home directory!")
.join(".local/share/fish/fish_history");
[
Check::builder()
.description("Checking that `cowsay` is installed")
.validator(
CommandStatus::builder()
.command(
Command::builder()
.program("which")
.args(vec!["cowsay".into()])
.stdout(StdioVariant::Null)
.stderr(StdioVariant::Null)
.stdin(StdioVariant::Null)
.build(),
)
.status_code(0)
.build(),
)
.hint("Did you install `cowsay` using the `dnf` package manager?")
.build()
.into_box(),
Check::builder()
.description("Checking that you tried to change the eyes")
.validator(FileContent {
file: fish_history.clone(),
expected: StringContent::Regex(
Regex::new(r"\n- cmd: cowsay.* -e .+\n").expect("Failed to build a regex"),
),
})
.hint("Did you read the help message of `cowsay` to find out how to change the eyes?")
.build()
.into_box(),
Check::builder()
.description("Checking that you tried to change the tongue")
.validator(FileContent {
file: fish_history.clone(),
expected: StringContent::Regex(
Regex::new(r"\n- cmd: cowsay.* -T .+\n").expect("Failed to build a regex"),
),
})
.hint("Did you read the help message of `cowsay` to find out how to change the tongue?")
.build()
.into_box(),
]
.into_task("cowsay")
}

View file

@ -0,0 +1,61 @@
use collective_score_client::{
check::{Check, IntoTask, Task},
validator::{file::FileContent, string_content::StringContent},
};
use std::path::PathBuf;
pub fn task() -> Task {
[
Check::builder()
.description("Checking the bedroom")
.validator(FileContent {
file: PathBuf::from("bedroom/bed.txt"),
expected: StringContent::Full(""),
})
.hint("Did you create the directory `bedroom` containing the empty file `bed.txt`?")
.build()
.into_box(),
Check::builder()
.description("Checking the bathroom")
.validator(FileContent {
file: PathBuf::from("bathroom/toilet.txt"),
expected: StringContent::Full(""),
})
.build()
.into_box(),
Check::builder()
.description("Checking the living room")
.validator(FileContent {
file: PathBuf::from("living_room/couch.txt"),
expected: StringContent::Full(""),
})
.build()
.into_box(),
Check::builder()
.description("Checking the kitchen")
.validator(FileContent {
file: PathBuf::from("kitchen/fridge.txt"),
expected: StringContent::Full(""),
})
.build()
.into_box(),
Check::builder()
.description("Checking the dining room")
.validator(FileContent {
file: PathBuf::from("dining_room/chair.txt"),
expected: StringContent::Full(""),
})
.build()
.into_box(),
Check::builder()
.description("Looking for Max in the living room")
.validator(FileContent {
file: PathBuf::from("living_room/max.txt"),
expected: StringContent::Part("beatboxing"),
})
.hint("Did you add his hobby `beatboxing` to his file?")
.build()
.into_box(),
]
.into_task("initial-house")
}

60
cs/src/day1/lolcat.rs Normal file
View file

@ -0,0 +1,60 @@
use collective_score_client::{
check::{Check, IntoTask, Task},
validator::{
command::{Command, CommandStatus, StdioVariant},
file::FileContent,
string_content::StringContent,
},
};
use regex::Regex;
pub fn task() -> Task {
let fish_history = dirs::home_dir()
.expect("Failed to get the home directory!")
.join(".local/share/fish/fish_history");
[
Check::builder()
.description("Checking that `lolcat` is installed")
.validator(
CommandStatus::builder()
.command(
Command::builder()
.program("which")
.args(vec!["lolcat".into()])
.stdout(StdioVariant::Null)
.stderr(StdioVariant::Null)
.stdin(StdioVariant::Null)
.build(),
)
.status_code(0)
.build(),
)
.hint("Did you install `lolcat` using the `dnf` package manager?")
.build()
.into_box(),
Check::builder()
.description("Checking that you piped `cowsay` into `lolcat`")
.validator(FileContent {
file: fish_history.clone(),
expected: StringContent::Regex(
Regex::new(r"\n- cmd: cowsay .+ \| lolcat").expect("Failed to build a regex"),
),
})
.hint("Did you try the syntax with `|`?")
.build()
.into_box(),
Check::builder()
.description("Checking that you tried adding randomness to `lolcat`")
.validator(FileContent {
file: fish_history.clone(),
expected: StringContent::Regex(
Regex::new(r"lolcat.* (-r |--random)").expect("Failed to build a regex"),
),
})
.hint("Did you read the help message of `lolcat` to find out how to add randomness to the output colors?")
.build()
.into_box(),
]
.into_task("lolcat")
}

View file

@ -1,7 +1,23 @@
mod collective_score_intro;
mod cowsay;
mod initial_house;
mod lolcat;
mod passwd;
mod system_update;
mod zombie;
mod zombie_nuked;
use collective_score_client::check::RunnableCheck;
pub fn tasks() -> [(&'static str, Box<dyn RunnableCheck>); 1] {
[collective_score_intro::task()]
pub fn tasks() -> [(&'static str, Box<dyn RunnableCheck>); 8] {
[
collective_score_intro::task(),
initial_house::task(),
zombie::task(),
zombie_nuked::task(),
passwd::task(),
system_update::task(),
cowsay::task(),
lolcat::task(),
]
}

18
cs/src/day1/passwd.rs Normal file
View file

@ -0,0 +1,18 @@
use collective_score_client::{
check::{Check, IntoTask, Task},
validator::{file::FileContent, string_content::StringContent},
};
pub fn task() -> Task {
Check::builder()
.description("Checking that you changed your password")
.validator(FileContent {
file: dirs::home_dir()
.expect("Failed to get the home directory!")
.join(".local/share/fish/fish_history"),
expected: StringContent::Part("- cmd: passwd\n"),
})
.hint("Did you change your password by running the command `passwd`? Are you in the fish shell?")
.build()
.into_task("passwd")
}

View file

@ -0,0 +1,18 @@
use collective_score_client::{
check::{Check, IntoTask, Task},
validator::{file::FileContent, string_content::StringContent},
};
pub fn task() -> Task {
Check::builder()
.description("Checking that you tried to update the system")
.validator(FileContent {
file: dirs::home_dir()
.expect("Failed to get the home directory!")
.join(".local/share/fish/fish_history"),
expected: StringContent::Part("\n- cmd: dnf upgrade"),
})
.hint("Did you try to update the system? Are you in the fish shell?")
.build()
.into_task("system-update")
}

52
cs/src/day1/zombie.rs Normal file
View file

@ -0,0 +1,52 @@
use collective_score_client::{
check::{Check, IntoTask, Task},
validator::{
command::{Command, CommandStatus, StdioVariant},
file::FileContent,
string_content::StringContent,
},
};
use std::path::PathBuf;
pub fn task() -> Task {
[
Check::builder()
.description("Looking for the zombie")
.validator(FileContent {
file: PathBuf::from("living_room/zombie.txt"),
expected: StringContent::Part("Brainzzz"),
})
.hint("Did you put a zombie in the living room having `Brainzzz` in his head?")
.build()
.into_box(),
Check::builder()
.description("Checking that Max ran away")
.validator(
CommandStatus::builder()
.command(
Command::builder()
.program("ls")
.args(vec!["living_room/max.txt".into()])
.stdout(StdioVariant::Null)
.stderr(StdioVariant::Null)
.stdin(StdioVariant::Null)
.build(),
)
.status_code(2)
.build(),
)
.hint("Did you move Max away from the living room? Maybe you cloned Max and left one of his copies in the living room 😯")
.build()
.into_box(),
Check::builder()
.description("Looking for Max")
.validator(FileContent {
file: PathBuf::from("bedroom/max.txt"),
expected: StringContent::Part("beatboxing"),
})
.hint("Did you move Max into the bedroom? Does he still have his hobby?")
.build()
.into_box(),
]
.into_task("zombie")
}

View file

@ -0,0 +1,43 @@
use collective_score_client::{
check::{Check, IntoTask, Task},
validator::{
command::{Command, CommandStatus, StdioVariant},
file::FileContent,
string_content::StringContent,
},
};
use std::path::PathBuf;
pub fn task() -> Task {
[
Check::builder()
.description("Checking that the zombie was nuked")
.validator(
CommandStatus::builder()
.command(
Command::builder()
.program("ls")
.args(vec!["living_room".into()])
.stdout(StdioVariant::Null)
.stderr(StdioVariant::Null)
.stdin(StdioVariant::Null)
.build(),
)
.status_code(2)
.build(),
)
.hint("Did you destroy the living room with the Zombie in it?")
.build()
.into_box(),
Check::builder()
.description("Looking for Max")
.validator(FileContent {
file: PathBuf::from("bedroom/max.txt"),
expected: StringContent::Part("beatboxing"),
})
.hint("Is Max in the bedroom? Does he still have his hobby?")
.build()
.into_box(),
]
.into_task("zombie-nuked")
}

36
nginx.conf Normal file
View file

@ -0,0 +1,36 @@
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log error;
events {
worker_connections 1024;
}
http {
charset utf-8;
access_log off;
log_not_found off;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
gzip on;
server_tokens off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
server {
root /usr/share/nginx/html;
index index.html;
location / {
}
error_page 404 /404.html;
}
}

View file

@ -32,7 +32,7 @@ In general, you will do a task and then run `cs task TASKCODE` to validate your
`TASKCODE` is a code unique to every task/subtask.
For this demo task, the task code is `collective-score-intro`.
Now, for this demo task to pass the check, run the following command:
🟢 Now, for this demo task to pass the check, run the following command:
```bash
echo "OK" | cs task collective-score-intro
@ -42,39 +42,66 @@ Congratulations, you have done your first task 🎉
To see your progress at any time, run the command **`cs progress show`**.
## Task 1: Building houses
## Task 1: Building houses 🏠️
In this task, you will build a house with different rooms using (nested) directories.
Start with an empty directory as the house and add directories to it as rooms.
The house should have at least 5 rooms. Give the rooms meaningful names.
Rooms (represented by directories) contain objects as text files (ending with `.txt`).
The text files for the objects should be empty for now.
Place a box as a text file in one of the rooms. Put some content in the box as text lines.
The house should have the following 5 rooms:
Place some persons as text files in different rooms. You can add some information about the persons like hobbies in their files.
- `bedroom` containing `bed.txt`
- `bathroom` containing `toilet.txt`
- `living_room` containing `couch.txt`
- `kitchen` containing `fridge.txt`
- `dining_room` containing `chair.txt`
Visualise your house structure and content using `tree` and make a screenshot.
Place Max in the living room by creating a file `Max.txt` in the living room containing his hobby `beatboxing` as text in his file.
Now, clone your whole house and then rename the persons in the new house. Make another screenshot of `tree` afterwards.
Example:
In the new house, choose a non empty room and move everything within this room into another room. Why? Because zombies are back! They did get in through _windows_...
```console
$ cat living_room/max.txt
He is watching TV.
His hobby is beatboxing.
```
Make a screenshot of `tree`.
Run the command `tree` to see the structure of the house.
Put some zombies in this room after it is empty, make a screenshot of `tree` and then delete the room with the zombies in it. Make sure to not destroy the whole house!
🟢 Run `cs task initial-house` in the house directory.
Make a final `tree` screenshot of the rest of the house.
Zombies are back!
They did get in through _windows_… (You got it?)
Take a screenshot of the content of some files. Tipp: 😺
Place a zombie in the living room having `Brainzzz` in his file `zombie.txt`.
Max runs out of the living room!
Move him to the bedroom.
🟢 Run `cs task zombie` in the house directory.
Now, destroy the whole living room with the zombie in it.
🟢 Run `cs task zombie-nuked` in the house directory.
Tipps:
- If you get lost, use `pwd`.
- If you are looking for an option but you can not remember it, use `--help`.
## Task 2: Reset your password
⚠️ Launch the [fish shell](https://fishshell.com/) by running the command `fish` and stay in it for all following tasks.
If you close the terminal and lauch it later again, you have to run `fish` again.
We will learn more about the fish shell later.
Use the command `passwd` to reset the password of your user. It is important to have a secure password!
🟢 Run `cs task passwd`.
## Task 3: Update your system
Find out how to update your system with `dnf` and run the updates.
@ -83,6 +110,8 @@ Before you confirm, make sure that you read what packages are updated. Make a sc
It is possible that you don't find any updates. In this case, you can try it again on another day!
🟢 Run `cs task system-update`.
## Task 4: Package installation and usage
Install the package `cowsay` and find out how to use it!
@ -91,10 +120,14 @@ Spoiler: You will have to deal with some cows 🐄
Find out how to give a fancy tongue and shinny eyes.
Make a screenshot of some cow wisdom 🐮
🟢 Run `cs task cowsay`.
Now install the package `lolcat`.
Now, install the package `lolcat`.
Let's say the wisdom command you did take the last screenshot of is `cowsay (...)`. Now run `cowsay (...) | lolcat`. Describe what changed. Can you guess how this internally works?
Generate some wisdom with `cowsay (…)`. Now, run `cowsay (…) | lolcat`.
What did change?
Can you guess how this internally works?
Now read the help of `lolcat` and find out how to add some randomness. Run the command above again with the option you found and take a screenshot after you are satisfied with the randomness you get.
Now, read the help of `lolcat` and find out how to add some randomness.
🟢 Run `cs task lolcat`.