1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
use reqwest::header::HeaderMap;
use std::fs::File;
use std::fs;
use std::io::prelude::*;
use sha256::digest_bytes;
use std::process::Command;
use crate::get_token_dockerhub::get_token_dockerhub;

// use crate::get_manifest::get_manifest_info;

// pub async fn get_layers_all(repositories_url_ip:String,image_name:String,image_version:String){
//         match get_manifest_info(repositories_url_ip.clone(),image_name.clone(),image_version.clone()).await {
//         Ok(res) => {
//             for i in 0..res.layers.len() {
//                 get_layers(repositories_url_ip.clone(),image_name.clone(),res.config.digest.clone(),res.layers[i].digest.clone()).await;
//             }
//         },
//         _ => {}
//     }
// }


pub async fn get_layers_dockerhub(image_name:String,image_digest:String, layer_digest:String,layer_diff_id:String)  {
    let url = format!("https://registry.hub.docker.com/v2/{}/blobs/{}", image_name, layer_digest);
    // println!("get_layers_url:{}",url);
    let client = reqwest::Client::new();

    let mut headers = HeaderMap::new();

    headers.insert("Content-Type", "application/vnd.docker.image.rootfs.diff.tar.gzip".parse().unwrap());
    headers.insert("Accept-Language", "zh-CN,zh;q=0.9,zh-TW;q=0.8,en-US;q=0.7,en;q=0.6".parse().unwrap());
    let token_1 = get_token_dockerhub(image_name.clone()).await.unwrap();
    let token = format!("{}",token_1.access_token);

    let image_storage_path_1 = image_digest.split(':');
    let image_storage_path_2: Vec<&str> = image_storage_path_1.collect();
    let image_storage_path_3 = image_storage_path_2[1];
    let image_storage_path_4 = format!("{}",image_storage_path_3.clone());

    let image_storage_path = format!("/var/lib/AntKing/images/{}",image_storage_path_4);
    let image_gz_storage_path = format!("/var/lib/AntKing/gz/{}",image_storage_path_4);
    fs::create_dir_all(image_storage_path.clone()).unwrap();
    fs::create_dir_all(image_gz_storage_path.clone()).unwrap();

    let layer_name_tmp = layer_digest.split(':');
    let layer_name: Vec<&str> = layer_name_tmp.collect();

    let path = format!("{}/{}.tar.gz",image_storage_path.clone(),layer_name[1].clone());
    let path1 = format!("{}/{}.tar",image_storage_path.clone(),layer_name[1].clone());


    let layer_storage_path_1 = layer_diff_id.split(':');
    let layer_storage_path_2: Vec<&str> = layer_storage_path_1.collect();
    let layer_storage_path_3 = layer_storage_path_2[1];
    let layer_storage_path_4 = format!("{}",layer_storage_path_3.clone());
    let path2 = format!("{}/{}",image_storage_path.clone(),layer_storage_path_4.clone());

    fs::create_dir_all(path2.clone()).unwrap();

    let mut file = File::create(path.clone()).unwrap();

    match client.get(url).bearer_auth(token.clone()).headers(headers).send().await {
        Ok(r) => {
            match r.bytes().await {
                Ok(r1) => {
                    let write_result = file.write(&*r1);
                    match write_result {
                        Ok(r2) => {
                            if r2 > 0 {
                                let image_layer_sha256 = format!("sha256:{}",digest_bytes(&*fs::read(path.clone()).unwrap()));
                                if image_layer_sha256 == layer_digest {
                                    let cmd = format!("cp {} {}",path.clone(),image_gz_storage_path.clone());
                                    Command::new("sh").arg("-c").arg(cmd).output().unwrap().stdout;

                                    let output1 = Command::new("gzip").arg("-d").arg(path.clone()).output();
                                    match output1 {
                                        Ok(res) => {
                                            match String::from_utf8(res.stdout){
                                                Ok(_) => {
                                                    let image_layer_tar_sha256 = format!("sha256:{}",digest_bytes(&*fs::read(path1.clone()).unwrap()));
                                                    // TODO 获取diffID与image_layer_tar_sha256比较
                                                    if image_layer_tar_sha256 == layer_diff_id.clone() {
                                                        let cmd = format!("tar -xvf {} -C {}",path1,path2);
                                                        let output2 = Command::new("sh").arg("-c").arg(cmd.clone()).output();
                                                        match output2 {
                                                            Ok(_) => {
                                                                // println!("Execute tar successful!");
                                                            },
                                                            Err(e) => {
                                                                println!("Execute tar exception! Reason:{}",e);
                                                            }
                                                        }
                                                    }
                                                },
                                                Err(e) => {
                                                     println!("Execute gzip exception! Reason:{}",e);
                                                }
                                            }
                                        },
                                        Err(e) => {
                                            println!("Execute gzip exception! Reason:{}",e);
                                        }
                                    }
                                }else {
                                    println!("Failed to download image layer! The reason is: sha256 is not consistency!")
                                }
                            }else {
                                println!("The image layer is empty!")
                            }
                        }
                        Err(e) => {
                            println!("Failed to download image layer! reason:{}",e)
                        }
                    }
                }
                _ => {}
            }
        },
        Err(e) => {
            println!("Failed to download image layer! Reason:{}",e)
        }
    }
}