AWS SDK for Rust(Developer Preview)를 터치했습니다.

28389 단어 AWSRusttech

개시하다


이 글은 Rust Advent Calendar 2021의 다섯째 날의 글이다.
AWS re: Invent 2021 Werner Vogeles Keynote는 AWS SDK for Rust의 Developer Preview를 발표했다.what's new의 링크는 여기.,GiitHub의 창고는 여기.입니다.금방 해볼게요.
※ Developer Preview이므로 정식으로 도입하지 않는 것이 좋습니다.

실제로 해봤어요.


할 일


지금 컨테이너를 공부하고 있어서 컨테이너와 관련된 것을 시험해 보고 싶어요.구체적으로 Rust에서 ECR 컨테이너 이미지에 대한 자세한 정보batch-get-image를 얻습니다.왜 이 옵션을 선택했을까요? CLI가 실행되는 경우 Output의 예에서 보듯이 이미지 매니페스트가 문자열로 표시되므로 행을 변경하고 싶습니다.또 저는 Rust에 대해 잘 몰라서 갑작스러운 처리가 어렵다는 의견도 있습니다.

환경 구조


README에도 Rust의 버전은 1.54 이상이 필요하다고 적혀 있다.어제기타 기사에 소개한 바와 같이 저는 개발할 때 VScode Remote Contaainess를 사용했기 때문에 여기서도 Rust의 컨테이너 이미지를 사용해야 합니다.Docker file은 이런 느낌입니다.
FROM rust:1.55.0
RUN rustup component add rust-src rls rust-analysis rustfmt
컨테이너에서 VScodecargo new를 엽니다.Getting Started ECR과 Tokio가 필요할 것 같아서 편집Cargo.toml.
[package]
name = "my-first-rust-sdk"
version = "0.1.0"
authors = []
edition = "2018"

[dependencies]
aws-config = "0.2.0"
aws-sdk-ecr = "0.2.0"
tokio = { version = "1", features = ["full"] }

엿보다


examples에는 각 AWS 서비스를 부르는 API의 예가 기재돼 있다.ECR의 예 이런 느낌이에요.
use aws_config::meta::region::RegionProviderChain;
use aws_sdk_ecr::Region;
use structopt::StructOpt;

#[derive(Debug, StructOpt)]
struct Opt {
    /// The region
    #[structopt(short, long)]
    region: Option<String>,

    #[structopt(long)]
    repository: String,

    #[structopt(short, long)]
    verbose: bool,
}
#[tokio::main]
async fn main() -> Result<(), aws_sdk_ecr::Error> {
    let Opt {
        region,
        repository,
        verbose,
    } = Opt::from_args();
    if verbose {
        tracing_subscriber::fmt::init();
    }
    let region_provider = RegionProviderChain::first_try(region.map(Region::new))
        .or_default_provider()
        .or_else(Region::new("us-west-2"));
    let shared_config = aws_config::from_env().region(region_provider).load().await;
    let client = aws_sdk_ecr::Client::new(&shared_config);
    let rsp = client
        .list_images()
        .repository_name(&repository)
        .send()
        .await?;
    let images = rsp.image_ids.unwrap_or_default();
    println!("found {} images", images.len());
    for image in images {
        println!(
            "image: {}:{}",
            image.image_tag.unwrap(),
            image.image_digest.unwrap()
        );
    }
    Ok(())
}
이 예는list-images를 실행하고 있습니다.strucctopt에서 조사해 봤는데 Rust의 지령선인 것 같아요.기본 공급자 체인에서 영역을 가져오지 않으면 us-west-2가 됩니다.이번에는 us-east-1리hello에 테스트용 ECR 창고를 준비해서 그걸로 할게요.

클라이언트 만들기


먼저 만져야 하기 때문에 고객은 이렇게 할 것이다.
let shared_config = aws_config::load_from_env().await;
let client = aws_sdk_ecr::Client::new(&shared_config);

매개 변수의 전달 방법


batch-get-image의 매개 변수가 무엇을 필요로 하는지 봅시다.필요repository-nameimage-ids.
다음은 Rust SDK의 BatchGetImage 문서를 살펴보겠습니다.아까 봤던 엑시플 느낌으로 fn repository_name(self, inp: impl Into<String>)하고 fn image_ids(self, inp: impl Into<ImageIdentifier>)하면 돼요.그런데 여기impl Into<ImageIdentifier>에서 도대체 어떻게 된 일인지 막혔어요.
보아하니ImageIdentifier 페이지 이 구조체에non_exhaustive attribute가 있기 때문에 struct를 일반적으로 선포할 수 없다.
// こんな感じで宣言できない
let image-identifier = aws_sdk_ecr::model::ImageIdentifier { image_tag: "latest".to_string() }
한동안 고민이 많았지만 마음을 바꿔 봤더니S3의 example 어떻게 해야 할지 알 수 있었다.builder쓰면 돼요.나는 Rust에 Builder의 디자인 모델이 있다는 것을 처음 알았다.
ImageIdentifier의 Builder 제작 후 이미지tag 를 지정합니다.이번 ECR은 이름world 라벨이 달린 이미지image_ids를 저장했기 때문에 다음과 같이 쓸 수 있다.
let rsp = client
    .batch_get_image()
    .repository_name("hello")
    .image_ids(
        aws_sdk_ecr::model::ImageIdentifier::builder()
            .set_image_tag(Some("world".to_string()))
            .build(),
    )
    .send()
    .await?;

선언을 표시하기 전에


그리고 반응에서 이미지 선언만 하면 돼.결국 이런 느낌의 코드를 만들었다.
#[tokio::main]
pub async fn get_image_manifest() -> Result<String, aws_sdk_ecr::Error> {
    let shared_config = aws_config::load_from_env().await;
    let client = aws_sdk_ecr::Client::new(&shared_config);
    let rsp = client
        .batch_get_image()
        .repository_name("hello")
        .image_ids(
            aws_sdk_ecr::model::ImageIdentifier::builder()
                .set_image_tag(Some("world".to_string()))
                .build(),
        )
        .send()
        .await?;
    let image = &rsp.images.unwrap_or_default()[0];
    let manifest = image.image_manifest.clone().unwrap();
    Ok(manifest)
}

fn main() {
    let manifest = get_image_manifest();
    match manifest {
        Ok(m) => println!("{}", m),
        Err(e) => println!("{:?}", e),
    }
}
이렇게 하면 줄 바뀐 후의 선언을 나타낼 수 있다.
{
   "schemaVersion": 2,
   "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
   "config": {
      "mediaType": "application/vnd.docker.container.image.v1+json",
      "size": 6144,
      "digest": "sha256:23ec2b3c5d992269b1d5257f8c9dc1c479a6272661f7af9e6ffe6d92f0c0c7a7"
   },
   "layers": [
      {
         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
         "size": 26712436,
         "digest": "sha256:ad3e435fd20eac564bc5199d427f4ee1703faa28f75c285b27adacb62d34c44b"
      },
      {
         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
         "size": 832,
         "digest": "sha256:32ab836c5190871415440d5c00f3c8841f126f70e1559632401d65f325ebf7bf"
      },
   ]
}

끝말


Rust의 SDK는 뭐라고 하기보다는 Rust의 문법과 개념을 잘 모를 때 쉽게 알아차렸기 때문에 이제 Rust의 책을 다시 읽었다.

좋은 웹페이지 즐겨찾기