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
124
125
126
127
128
129
130
131
132
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_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(repositories_url_ip:String,username:String,password:String,image_name:String,image_digest:String, layer_digest:String,layer_diff_id:String)  {
    let url = format!("{}/v2/{}/blobs/{}", repositories_url_ip, 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 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_gz_storage_path.clone(),layer_name[1].clone());
    let path1 = format!("{}/{}.tar",image_gz_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 remove_gz = fs::remove_file(path.clone());
    match remove_gz {
        Ok(_) => {},
        Err(_) => {}
    }

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

    match client.get(url).basic_auth(username,Some(password)).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 {
                                    // println!("Download image layer successfully!");

                                    let output1 = Command::new("gzip").arg("-d").arg(path.clone()).output();
                                    match output1 {
                                        Ok(res) => {
                                            match String::from_utf8(res.stdout){
                                                Ok(_) => {
                                                     // println!("Execute gzip successful!");
                                                    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() {
                                                        // println!("Image integrity");
                                                        let remove_dir_path = format!("{}/{}",path2.clone(),layer_diff_id.clone());
                                                        let remove_layer_dir = fs::remove_dir_all(remove_dir_path);
                                                        match remove_layer_dir {
                                                            Ok(_) => {},
                                                            Err(_) => {}
                                                        }
                                                        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)
        }
    }
}