oci_image.c 12.3 KB
Newer Older
D
dogsheng 已提交
1 2
/******************************************************************************
* Copyright (c) Huawei Technologies Co., Ltd. 2019. All rights reserved.
3 4 5 6
 * iSulad licensed under the Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *     http://license.coscl.org.cn/MulanPSL2
D
dogsheng 已提交
7 8 9
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
 * PURPOSE.
10
 * See the Mulan PSL v2 for more details.
D
dogsheng 已提交
11 12
* Author: liuhao
* Create: 2019-07-15
13
* Description: provide oci image operator definition
D
dogsheng 已提交
14
*******************************************************************************/
15
#include "oci_image.h"
D
dogsheng 已提交
16 17 18 19

#include <pthread.h>
#include <semaphore.h>

H
haozi007 已提交
20
#include "isula_libutils/log.h"
L
lifeng68 已提交
21
#include "isula_libutils/log.h"
W
WangFengTu 已提交
22 23 24
#include "oci_pull.h"
#include "oci_login.h"
#include "oci_logout.h"
25
#include "registry.h"
D
dogsheng 已提交
26
#include "utils.h"
L
lifeng68 已提交
27
#include "utils_images.h"
28
#include "storage.h"
G
gaohuatao 已提交
29
#include "oci_load.h"
L
lifeng68 已提交
30
#include "oci_import.h"
W
WangFengTu 已提交
31
#include "oci_export.h"
D
dogsheng 已提交
32 33 34

#define IMAGE_NOT_KNOWN_ERR "image not known"

L
lifeng68 已提交
35 36 37 38 39 40 41 42 43 44 45 46 47 48
// only use overlay as the driver name if specify overlay2 or overlay
static char *format_driver_name(const char *driver)
{
    if (driver == NULL) {
        return NULL;
    }

    if (strcmp(driver, "overlay") == 0 || strcmp(driver, "overlay2") == 0) {
        return util_strdup_s("overlay");
    } else {
        return util_strdup_s(driver);
    }
}

49
static int storage_module_init_helper(const isulad_daemon_configs *args)
50 51 52 53 54 55 56 57 58 59 60
{
    int ret = 0;
    struct storage_module_init_options *storage_opts = NULL;

    storage_opts = util_common_calloc_s(sizeof(struct storage_module_init_options));
    if (storage_opts == NULL) {
        ERROR("Memory out");
        ret = -1;
        goto out;
    }

61
    storage_opts->driver_name = format_driver_name(args->storage_driver);
L
lifeng68 已提交
62 63 64 65 66 67
    if (storage_opts->driver_name == NULL) {
        ERROR("Failed to get storage driver name");
        ret = -1;
        goto out;
    }

68
    storage_opts->storage_root = util_path_join(args->graph, GRAPH_ROOTPATH_NAME);
69 70 71 72 73 74
    if (storage_opts->storage_root == NULL) {
        ERROR("Failed to get storage root dir");
        ret = -1;
        goto out;
    }

75
    storage_opts->storage_run_root = util_path_join(args->state, GRAPH_ROOTPATH_NAME);
76 77 78 79 80 81
    if (storage_opts->storage_run_root == NULL) {
        ERROR("Failed to get storage run root dir");
        ret = -1;
        goto out;
    }

82 83
    if (dup_array_of_strings((const char **)args->storage_opts, args->storage_opts_len, &storage_opts->driver_opts,
                             &storage_opts->driver_opts_len) != 0) {
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
        ERROR("Failed to get storage storage opts");
        ret = -1;
        goto out;
    }

    if (storage_module_init(storage_opts) != 0) {
        ERROR("Failed to init storage module");
        ret = -1;
        goto out;
    }

out:
    free_storage_module_init_options(storage_opts);
    return ret;
}

100 101 102 103 104 105 106 107 108 109 110 111 112
static void cleanup_image_tmpdir()
{
    if (util_recursive_rmdir(IMAGE_TMP_PATH, 0)) {
        ERROR("failed to remove directory %s", IMAGE_TMP_PATH);
    }

    if (util_mkdir_p(IMAGE_TMP_PATH, 0600)) {
        ERROR("failed to create directory %s", IMAGE_TMP_PATH);
    }

    return;
}

113
int oci_init(const isulad_daemon_configs *args)
D
dogsheng 已提交
114
{
W
WangFengTu 已提交
115
    int ret = 0;
D
dogsheng 已提交
116

117
    if (args == NULL) {
D
dogsheng 已提交
118 119 120 121
        ERROR("Invalid image config");
        return ret;
    }

122 123
    cleanup_image_tmpdir();

W
WangFengTu 已提交
124
    ret = registry_init();
125
    if (ret != 0) {
W
WangFengTu 已提交
126
        ret = -1;
127 128 129
        goto out;
    }

130 131
    if (storage_module_init_helper(args) != 0) {
        ret = -1;
D
dogsheng 已提交
132 133 134 135
        goto out;
    }

out:
W
WangFengTu 已提交
136

D
dogsheng 已提交
137 138 139
    return ret;
}

140 141 142 143 144
void oci_exit()
{
    storage_module_exit();
}

145
int oci_pull_rf(const im_pull_request *request, im_pull_response *response)
D
dogsheng 已提交
146
{
W
WangFengTu 已提交
147
    return oci_do_pull_image(request, response);
D
dogsheng 已提交
148 149
}

150
int oci_prepare_rf(const im_prepare_request *request, char **real_rootfs)
D
dogsheng 已提交
151
{
152 153
    int ret = 0;

D
dogsheng 已提交
154 155 156 157 158
    if (request == NULL) {
        ERROR("Bim is NULL");
        return -1;
    }

159 160 161 162 163 164 165 166 167
    if (storage_rootfs_create(request->container_id, request->image_name, request->storage_opt, real_rootfs) != 0) {
        ERROR("Failed to create container rootfs:%s", request->container_id);
        isulad_set_error_message("Failed to create container rootfs:%s", request->container_id);
        ret = -1;
        goto out;
    }

out:
    return ret;
D
dogsheng 已提交
168 169
}

170
int oci_merge_conf_rf(const char *img_name, container_config *container_spec)
D
dogsheng 已提交
171
{
172
    int ret = 0;
D
dogsheng 已提交
173

174 175
    if (img_name == NULL || container_spec == NULL) {
        ERROR("Invalid input arguments for oci_merge_conf_rf");
D
dogsheng 已提交
176 177 178
        return -1;
    }

179
    ret = oci_image_conf_merge_into_spec(img_name, container_spec);
D
dogsheng 已提交
180
    if (ret != 0) {
181 182
        ERROR("Failed to merge oci config for image: %s", img_name);
        ret = -1;
D
dogsheng 已提交
183 184 185 186 187 188 189
        goto out;
    }

out:
    return ret;
}

190
int oci_delete_rf(const im_delete_rootfs_request *request)
D
dogsheng 已提交
191 192 193 194 195
{
    if (request == NULL) {
        ERROR("Request is NULL");
        return -1;
    }
196

197
    return storage_rootfs_delete(request->name_id);
D
dogsheng 已提交
198 199
}

200
int oci_mount_rf(const im_mount_request *request)
D
dogsheng 已提交
201
{
202 203
    char *mount_point = NULL;

D
dogsheng 已提交
204 205 206 207
    if (request == NULL) {
        ERROR("Invalid arguments");
        return -1;
    }
L
lifeng68 已提交
208

209 210 211 212 213 214 215 216
    mount_point = storage_rootfs_mount(request->name_id);
    if (mount_point == NULL) {
        ERROR("Failed to mount rootfs %s", request->name_id);
        return -1;
    }

    free(mount_point);
    return 0;
D
dogsheng 已提交
217 218
}

219
int oci_umount_rf(const im_umount_request *request)
D
dogsheng 已提交
220 221 222 223 224
{
    if (request == NULL) {
        ERROR("Invalid arguments");
        return -1;
    }
L
lifeng68 已提交
225 226

    return storage_rootfs_umount(request->name_id);
D
dogsheng 已提交
227 228
}

229
int oci_rmi(const im_rmi_request *request)
D
dogsheng 已提交
230
{
J
jikui 已提交
231 232
    int ret = 0;
    char *image_ID = NULL;
D
dogsheng 已提交
233
    char *real_image_name = NULL;
J
jikui 已提交
234 235 236 237 238
    char **image_names = NULL;
    size_t image_names_len;
    char **reduced_image_names = NULL;
    size_t reduced_image_names_len = 0;
    size_t i;
D
dogsheng 已提交
239 240 241 242 243 244 245 246 247

    if (request == NULL || request->image.image == NULL) {
        ERROR("Invalid input arguments");
        return -1;
    }

    real_image_name = oci_resolve_image_name(request->image.image);
    if (real_image_name == NULL) {
        ERROR("Failed to resolve image name");
J
jikui 已提交
248 249 250
        ret = -1;
        goto out;
    }
L
lifeng68 已提交
251 252

    if (storage_img_get_names(real_image_name, &image_names, &image_names_len) != 0) {
J
jikui 已提交
253 254 255 256 257
        ERROR("Get image %s names failed", real_image_name);
        ret = -1;
        goto out;
    }

L
lifeng68 已提交
258
    image_ID = storage_img_get_image_id(real_image_name);
J
jikui 已提交
259 260 261
    if (image_ID == NULL) {
        ERROR("Get id of image %s failed", real_image_name);
        ret = -1;
D
dogsheng 已提交
262 263 264
        goto out;
    }

J
jikui 已提交
265 266 267 268 269 270 271 272 273 274 275 276 277 278 279
    if (image_names_len == 1 || util_has_prefix(image_ID, real_image_name)) {
        ret = storage_img_delete(real_image_name, true);
        if (ret != 0) {
            ERROR("Failed to remove image '%s'", real_image_name);
        }
        goto out;
    }

    reduced_image_names = (char **)util_smart_calloc_s(sizeof(char *), image_names_len - 1);
    if (reduced_image_names == NULL) {
        ERROR("Out of memory");
        ret = -1;
        goto out;
    }

280
    for (i = 0; i < image_names_len; i++) {
J
jikui 已提交
281 282 283 284 285 286 287 288 289 290 291 292
        if (strcmp(image_names[i], real_image_name) != 0) {
            reduced_image_names[reduced_image_names_len] = util_strdup_s(image_names[i]);
            if (reduced_image_names[reduced_image_names_len] == NULL) {
                ERROR("Out of memory");
                ret = -1;
                goto out;
            }
            reduced_image_names_len++;
        }
    }

    ret = storage_img_set_names(real_image_name, (const char **)reduced_image_names, reduced_image_names_len);
D
dogsheng 已提交
293
    if (ret != 0) {
L
lifeng68 已提交
294
        ERROR("Failed to set names of image '%s'", real_image_name);
L
LiFeng 已提交
295
        goto out;
D
dogsheng 已提交
296
    }
L
LiFeng 已提交
297

D
dogsheng 已提交
298 299
out:
    free(real_image_name);
J
jikui 已提交
300 301 302
    free(image_ID);
    util_free_array_by_len(image_names, image_names_len);
    util_free_array_by_len(reduced_image_names, image_names_len - 1);
D
dogsheng 已提交
303 304 305
    return ret;
}

L
lifeng68 已提交
306
int oci_import(const im_import_request *request, char **id)
W
WangFengTu 已提交
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323
{
    int ret = -1;
    char *dest_name = NULL;
    char *errmsg = NULL;

    if (request == NULL || request->file == NULL || request->tag == NULL || id == NULL) {
        ERROR("Invalid input arguments");
        return -1;
    }

    dest_name = oci_normalize_image_name(request->tag);
    if (dest_name == NULL) {
        ret = -1;
        ERROR("Failed to resolve image name");
        goto err_out;
    }

L
lifeng68 已提交
324
    ret = oci_do_import(request->file, dest_name, id);
W
WangFengTu 已提交
325 326 327 328 329 330 331 332 333 334 335 336 337 338 339
    if (ret != 0) {
        goto err_out;
    }

    goto out;

err_out:
    free(*id);
    *id = NULL;
out:
    free(dest_name);
    free(errmsg);
    return ret;
}

L
LiFeng 已提交
340
int oci_tag(const im_tag_request *request)
W
WangFengTu 已提交
341 342 343 344
{
    int ret = -1;
    char *src_name = NULL;
    char *dest_name = NULL;
J
jikui 已提交
345
    const char *errmsg = NULL;
W
WangFengTu 已提交
346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364

    if (request == NULL || request->src_name.image == NULL || request->dest_name.image == NULL) {
        ERROR("Invalid input arguments");
        return -1;
    }

    src_name = oci_resolve_image_name(request->src_name.image);
    if (src_name == NULL) {
        ret = -1;
        ERROR("Failed to resolve source image name");
        goto out;
    }
    dest_name = oci_normalize_image_name(request->dest_name.image);
    if (src_name == NULL) {
        ret = -1;
        ERROR("Failed to resolve source image name");
        goto out;
    }

J
jikui 已提交
365
    ret = storage_img_add_name(src_name, dest_name);
W
WangFengTu 已提交
366
    if (ret != 0) {
J
jikui 已提交
367
        errmsg = "add name failed when run isula tag";
W
WangFengTu 已提交
368 369 370 371 372 373 374 375 376 377 378
        isulad_set_error_message("Failed to tag image with error: %s", errmsg);
        ERROR("Failed to tag image '%s' to '%s' with error: %s", src_name, dest_name, errmsg);
        goto out;
    }

out:
    free(src_name);
    free(dest_name);
    return ret;
}

379
int oci_container_filesystem_usage(const im_container_fs_usage_request *request, imagetool_fs_info **fs_usage)
D
dogsheng 已提交
380 381
{
    int ret = 0;
382
    imagetool_fs_info *layer_fs_tmp = NULL;
D
dogsheng 已提交
383 384 385 386 387 388

    if (request == NULL || fs_usage == NULL) {
        ERROR("Invalid input arguments");
        return -1;
    }

389 390 391 392
    layer_fs_tmp = util_common_calloc_s(sizeof(imagetool_fs_info));
    if (layer_fs_tmp == NULL) {
        ERROR("Memory out");
        ret = -1;
D
dogsheng 已提交
393 394 395
        goto out;
    }

396 397 398
    ret = storage_rootfs_fs_usgae(request->name_id, layer_fs_tmp);
    if (ret != 0) {
        ERROR("Failed to inspect container filesystem info");
D
dogsheng 已提交
399
        ret = -1;
400
        goto out;
D
dogsheng 已提交
401 402
    }

403 404 405
    *fs_usage = layer_fs_tmp;
    layer_fs_tmp = NULL;

D
dogsheng 已提交
406
out:
407
    free_imagetool_fs_info(layer_fs_tmp);
D
dogsheng 已提交
408 409 410
    return ret;
}

411
int oci_get_filesystem_info(im_fs_info_response **response)
D
dogsheng 已提交
412 413 414 415 416 417 418 419 420 421 422 423 424
{
    int ret = -1;

    if (response == NULL) {
        ERROR("Invalid input arguments");
        return -1;
    }

    *response = (im_fs_info_response *)util_common_calloc_s(sizeof(im_fs_info_response));
    if (*response == NULL) {
        ERROR("Out of memory");
        return -1;
    }
L
LiFeng 已提交
425 426 427 428 429 430 431 432

    (*response)->fs_info = util_common_calloc_s(sizeof(imagetool_fs_info));
    if ((*response)->fs_info == NULL) {
        ERROR("Out of memory");
        goto err_out;
    }

    ret = storage_get_images_fs_usage((*response)->fs_info);
D
dogsheng 已提交
433 434 435 436 437 438
    if (ret != 0) {
        ERROR("Failed to inspect image filesystem info");
        goto err_out;
    }

    return 0;
L
LiFeng 已提交
439

D
dogsheng 已提交
440 441 442 443 444 445
err_out:
    free_im_fs_info_response(*response);
    *response = NULL;
    return -1;
}

446
int oci_load_image(const im_load_request *request)
D
dogsheng 已提交
447 448 449 450 451 452 453 454
{
    int ret = 0;

    if (request == NULL) {
        ERROR("Invalid input arguments");
        return -1;
    }

G
gaohuatao 已提交
455
    ret = oci_do_load(request);
D
dogsheng 已提交
456 457 458 459 460 461 462 463 464
    if (ret != 0) {
        ERROR("Failed to load image");
        goto out;
    }

out:
    return ret;
}

465
int oci_export_rf(const im_export_request *request)
D
dogsheng 已提交
466 467 468 469 470 471 472 473
{
    int ret = 0;

    if (request == NULL) {
        ERROR("Invalid input arguments");
        return -1;
    }

W
WangFengTu 已提交
474
    ret = oci_do_export(request->name_id, request->file);
D
dogsheng 已提交
475 476 477 478 479 480 481
    if (ret != 0) {
        ERROR("Failed to export container: %s", request->name_id);
    }

    return ret;
}

482
int oci_login(const im_login_request *request)
D
dogsheng 已提交
483 484 485 486 487 488 489 490
{
    int ret = 0;

    if (request == NULL) {
        ERROR("Invalid input arguments");
        return -1;
    }

W
WangFengTu 已提交
491
    ret = oci_do_login(request->server, request->username, request->password);
D
dogsheng 已提交
492 493 494 495 496 497 498
    if (ret != 0) {
        ERROR("Login failed");
    }

    return ret;
}

499
int oci_logout(const im_logout_request *request)
D
dogsheng 已提交
500 501 502 503 504 505 506 507
{
    int ret = 0;

    if (request == NULL) {
        ERROR("Invalid input arguments");
        return -1;
    }

W
WangFengTu 已提交
508
    ret = oci_do_logout(request->server);
D
dogsheng 已提交
509 510 511 512 513 514
    if (ret != 0) {
        ERROR("Logout failed");
    }

    return ret;
}