gccが入ってないとエラーになるので注意が必要。
$ python3 -m venv venv
$ source venv/bin/activate
$ python3 -V
$ sudo yum install postgresql-devel python3-devel
$ sudo yum -y install gcc
$ pip3 install wheel
$ pip3 install psycopg2
随机应变 ABCD: Always Be Coding and … : хороший
gccが入ってないとエラーになるので注意が必要。
$ python3 -m venv venv
$ source venv/bin/activate
$ python3 -V
$ sudo yum install postgresql-devel python3-devel
$ sudo yum -y install gcc
$ pip3 install wheel
$ pip3 install psycopg2
conohaコンソール側のセキュリティグループで指定したポートを開放してもアクセスできない時。
Ubuntu側の設定を確認する。
# sudo ufw status
Status: active
To Action From
— —— —-
OpenSSH ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
OpenSSHしか許可されていないので、開放したいportを追加する。
# sudo ufw allow 3000/tcp
Rule added
Rule added (v6)
# sudo ufw status
Status: active
To Action From
— —— —-
OpenSSH ALLOW Anywhere
3000/tcp ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
3000/tcp (v6) ALLOW Anywhere (v6)
焦った……
let s = "sato".to_string().into_bytes();
println!("{:?}", s);
let l = LittleEndian::read_u32(&s);
println!("{}", l);
let b = BigEndian::read_u32(&s);
println!("{}", b);
let mut wtr = vec![];
wtr.write_u32::<LittleEndian>(l).unwrap();
println!("{:?}", wtr);
[115, 97, 116, 111]
1869898099
1935766639
[115, 97, 116, 111]
構造体をバイト列にする
#[derive(Serialize, Deserialize, Debug)]
struct Name {
family: Vec<u8>,
first: Vec<u8>,
}
let name1 = Name {family: "sato".to_string().into_bytes(), first: "taro".to_string().into_bytes()};
println!("{:?}", name1);
let family = String::from_utf8(name1.family).unwrap();
println!("{}", family);
Name { family: [115, 97, 116, 111], first: [116, 97, 114, 111] }
sato
なるほどー 前処理、後処理が多くなるが、安全性は高まりそう。
.github/workflows内にymlファイルを設置し、Workflowを書く
push, pull_request, deployment, release, issues, scheduleなどのイベントがよく使われる
チュートリアルのコード
name: GitHub Actions Demo
run-name: ${{ github.actor }} is testing out GitHub Actions 🚀
on: [push]
jobs:
Explore-GitHub-Actions:
runs-on: ubuntu-latest
steps:
- run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event."
- run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!"
- run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}."
- name: Check out repository code
uses: actions/checkout@v4
- run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner."
- run: echo "🖥️ The workflow is now ready to test your code on the runner."
- name: List files in the repository
run: |
ls ${{ github.workspace }}
- run: echo "🍏 This job's status is ${{ job.status }}."
### 実際に何を書くか
build
test
lint
Type
Unit Testを実行して、Clippyを確認する
name: GitHub Actions CI
run-name: Testing out 🚀
on: [push]
jobs:
GitHub-Actions-Check:
runs-on: ubuntu-latest
steps:
- name: Check out repository code
uses: actions/checkout@v4
- name: List files in the repository
run: |
ls
- name: Build
run: |
cargo build
- name: Test
run: |
cargo test
- name: Clippy
run: |
rustup component add clippy
cargo clippy
“{:?}”, resp だとstatusだが、resp.text().await.unwrap()とすると、bodyを表示できる。
let mut post_url = format!("http://192.168.33.10:3000/health");
let client = reqwest::Client::new();
let resp = client.post(post_url)
.header(reqwest::header::CONTENT_TYPE, "application/json")
.json(&str)
.send()
.await
.unwrap();
println!("{:?}", resp);
println!("{}", resp.text().await.unwrap());
Finished `dev` profile [unoptimized + debuginfo] target(s) in 7.43s
Running `target/debug/axum`
Response { url: Url { scheme: “http”, cannot_be_a_base: false, username: “”, password: None, host: Some(Ipv4(192.168.33.10)), port: Some(3000), path: “/health”, query: None, fragment: None }, status: 200, headers: {“content-type”: “text/plain; charset=utf-8”, “content-length”: “8”, “date”: “Thu, 13 Mar 2025 13:44:24 GMT”} }
All good
下のように書くと、DNSエラーとなる。
#[tokio::main]
async fn main() {
let res = tokio::spawn(async move {
let v = get_myip().await.unwrap();
println!("{}", v);
});
}
pub async fn get_myip() -> Result<String, Box<dyn std::error::Error>> {
let ip: Ip = serde_json::from_str(&reqwest::get("https://httpbin.org/ip")
.await?
.text()
.await?)?;
Ok(ip.origin)
}
しかし、実行されるまで待って、res.await.unwrap();とすれば、エラーは解消される。
let res = tokio::spawn(async move {
let v = get_myip().await.unwrap();
println!("{}", v);
});
res.await.unwrap();
レスポンスがないままtokio::spawnが終了してしまうからっぽい。
うーん、奥が深い… httpbin.org に問題があるかと思ったけど、全然違った…
echoサーバにリクエストを送り、このレスポンスが、”foo”なので、received_msgがfooだと思っていたが、
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut ws = WebSocket::connect("wss://echo.websocket.org/").await?;
ws.send_text("foo".to_string()).await?;
ws.receive().await?;
if let Frame::Text { payload: received_msg, .. } = ws.receive().await? {
println!("{}", received_msg);
}
ws.close(None).await?;
Ok(())
}
Finished `dev` profile [unoptimized + debuginfo] target(s) in 1.60s
Running `target/debug/app`
foo
以下のように書くと、”Request served by *****”がレスポンスで帰ってくる。websocketのreceiveは以下のように書くのが正解
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut ws = WebSocket::connect("wss://echo.websocket.org/").await?;
ws.send_text("foo".to_string()).await?;
if let Frame::Text { payload: received_msg, .. } = ws.receive().await? {
println!("{}", received_msg);
}
ws.close(None).await?;
Ok(())
}
Finished `dev` profile [unoptimized + debuginfo] target(s) in 2.07s
Running `target/debug/app`
Request served by 7811941c69e658
File::createとwrite_allで元のデータは上書かれる。
例えば、元データが4行で、上書きデータが2行だった場合でも、上書き後は2行になる。
{"family":"john","first":"fox"}
{"family":"adam","first":"can"}
{"family":"john","first":"fox"}
{"family":"adam","first":"can"}
use serde::{Serialize, Deserialize};
use std::path::Path;
use std::fs::{File};
use std::io::{Write};
#[derive(Serialize, Deserialize, Clone, Debug)]
struct Name {
family: String,
first: String,
}
#[tokio::main]
async fn main() {
let name1 = Name {family:"yamada".to_string(), first: "taro".to_string()};
let name2 = Name {family:"sato".to_string(), first: "kazuki".to_string()};
let mut vect: Vec<Name> = Vec::new();
vect.push(name1);
vect.push(name2);
let file_path = format!("./data/names.txt");
let mut file = File::create(file_path.clone()).unwrap();
for name in vect {
let serialized: Vec<u8> = serde_json::to_vec(&name).unwrap();
file.write_all(&serialized).expect("write failed");
file.write_all(b"\n").expect("write failed");
}
println!("done");
}
{"family":"yamada","first":"taro"}
{"family":"sato","first":"kazuki"}
なるほどね!
$ df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/root 7034376 7015828 2164 100% /
tmpfs 232532 1052 231480 1% /dev/shm
tmpfs 93016 3224 89792 4% /run
tmpfs 5120 0 5120 0% /run/lock
/dev/xvda16 901520 80068 758324 10% /boot
/dev/xvda15 106832 6246 100586 6% /boot/efi
tmpfs 46504 12 46492 1% /run/user/1000
↓
EBSの設定で20GBに拡張します。
$ sudo growpart /dev/xvda 1
$ sudo resize2fs /dev/root
$ df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/root 19221248 7032216 12172648 37% /
tmpfs 232532 1052 231480 1% /dev/shm
tmpfs 93016 896 92120 1% /run
tmpfs 5120 0 5120 0% /run/lock
/dev/xvda16 901520 80068 758324 10% /boot
/dev/xvda15 106832 6246 100586 6% /boot/efi
tmpfs 46504 12 46492 1% /run/user/1000
ほう…
$ sudo vi /etc/ssh/sshd_config
ClientAliveInterval 120
$ sudo service ssh restart
参考サイト: https://onoredekaiketsu.com/prevent-ssh-connection-timeout/
細かいことだが、これで作業効率が随分変わるような気がする