Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
iSulad
提交
642cd5e5
I
iSulad
项目概览
openeuler
/
iSulad
通知
15
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
I
iSulad
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
642cd5e5
编写于
6月 05, 2020
作者:
W
WangFengTu
提交者:
lifeng68
7月 25, 2020
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
support import rootfs tarbal to be image
Signed-off-by:
N
WangFengTu
<
wangfengtu@huawei.com
>
上级
8e735c3d
变更
18
隐藏空白更改
内联
并排
Showing
18 changed file
with
1039 addition
and
153 deletion
+1039
-153
CI/test_cases/image_cases/image_import.bash
CI/test_cases/image_cases/image_import.bash
+65
-0
CI/test_cases/image_cases/rootfs.tar
CI/test_cases/image_cases/rootfs.tar
+0
-0
CI/test_cases/image_cases/rootfs.tar.xz
CI/test_cases/image_cases/rootfs.tar.xz
+0
-0
src/cutils/utils.c
src/cutils/utils.c
+112
-0
src/cutils/utils.h
src/cutils/utils.h
+6
-0
src/image/oci/oci_image.c
src/image/oci/oci_image.c
+15
-0
src/image/oci/oci_import.c
src/image/oci/oci_import.c
+539
-3
src/image/oci/oci_import.h
src/image/oci/oci_import.h
+2
-1
src/image/oci/registry/registry.c
src/image/oci/registry/registry.c
+1
-23
src/image/oci/registry/registry_apiv2.c
src/image/oci/registry/registry_apiv2.c
+0
-111
src/image/oci/registry/registry_common.c
src/image/oci/registry/registry_common.c
+0
-10
src/image/oci/registry/registry_common.h
src/image/oci/registry/registry_common.h
+0
-1
src/image/oci/registry/registry_type.h
src/image/oci/registry/registry_type.h
+2
-4
src/image/oci/utils_images.h
src/image/oci/utils_images.h
+2
-0
src/sha256/sha256.c
src/sha256/sha256.c
+28
-0
src/sha256/sha256.h
src/sha256/sha256.h
+4
-0
src/tar/util_archive.c
src/tar/util_archive.c
+261
-0
src/tar/util_archive.h
src/tar/util_archive.h
+2
-0
未找到文件。
CI/test_cases/image_cases/image_import.bash
0 → 100755
浏览文件 @
642cd5e5
#!/bin/bash
#
# attributes: isulad basic image
# concurrent: NA
# spend time: 2
#######################################################################
##- @Copyright (C) Huawei Technologies., Ltd. 2020. All rights reserved.
# - 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
# - 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.
# - See the Mulan PSL v2 for more details.
##- @Description:CI
##- @Author: wangfengtu
##- @Create: 2020-06-19
#######################################################################
declare
-r
curr_path
=
$(
dirname
$(
readlink
-f
"
$0
"
))
source
../helpers.bash
rootfs_tar
=
"
${
curr_path
}
/rootfs.tar"
rootfs_tar_xz
=
"
${
curr_path
}
/rootfs.tar.xz"
import_tar
=
"import_tar"
import_tar_xz
=
"import_tar_xz"
function
test_image_import
()
{
local
ret
=
0
local test
=
"isula import image test => (
${
FUNCNAME
[@]
}
)"
msg_info
"
${
test
}
starting..."
isula import
$rootfs_tar
${
import_tar
}
[[
$?
-ne
0
]]
&&
msg_err
"
${
FUNCNAME
[0]
}
:
${
LINENO
}
- import image failed:
${
rootfs_tar
}
"
&&
((
ret++
))
isula import
$rootfs_tar_xz
${
import_tar_xz
}
[[
$?
-ne
0
]]
&&
msg_err
"
${
FUNCNAME
[0]
}
:
${
LINENO
}
- import image failed:
${
rootfs_tar_xz
}
"
&&
((
ret++
))
isula run
--rm
-ti
${
import_tar
}
echo
hello
[[
$?
-ne
0
]]
&&
msg_err
"
${
FUNCNAME
[0]
}
:
${
LINENO
}
- fail to run
${
import_tar
}
"
&&
((
ret++
))
isula run
--rm
-ti
${
import_tar_xz
}
echo
hello
[[
$?
-ne
0
]]
&&
msg_err
"
${
FUNCNAME
[0]
}
:
${
LINENO
}
- fail to run
${
import_tar_xz
}
"
&&
((
ret++
))
isula
rm
-f
`
isula ps
-a
-q
`
isula rmi
${
import_tar
}
[[
$?
-ne
0
]]
&&
msg_err
"
${
FUNCNAME
[0]
}
:
${
LINENO
}
- fail to remove
${
import_tar
}
"
&&
((
ret++
))
isula rmi
${
import_tar_xz
}
[[
$?
-ne
0
]]
&&
msg_err
"
${
FUNCNAME
[0]
}
:
${
LINENO
}
- fail to remove
${
import_tar_xz
}
"
&&
((
ret++
))
msg_info
"
${
test
}
finished with return
${
ret
}
..."
return
${
ret
}
}
declare
-i
ans
=
0
test_image_import
||
((
ans++
))
show_result
${
ans
}
"
${
curr_path
}
/
${
0
}
"
CI/test_cases/image_cases/rootfs.tar
0 → 100644
浏览文件 @
642cd5e5
文件已添加
CI/test_cases/image_cases/rootfs.tar.xz
0 → 100644
浏览文件 @
642cd5e5
文件已添加
src/cutils/utils.c
浏览文件 @
642cd5e5
...
...
@@ -39,6 +39,7 @@
#include <sys/types.h>
#include <sys/wait.h>
#include <termios.h>
#include <sys/utsname.h>
#include "utils.h"
#include "isula_libutils/log.h"
...
...
@@ -1647,3 +1648,114 @@ char *util_int_to_string(long long int data)
return
util_strdup_s
(
numstr
);
}
static
char
*
get_cpu_variant
()
{
char
*
variant
=
NULL
;
char
*
cpuinfo
=
NULL
;
char
*
start_pos
=
NULL
;
char
*
end_pos
=
NULL
;
cpuinfo
=
util_read_text_file
(
"/proc/cpuinfo"
);
if
(
cpuinfo
==
NULL
)
{
ERROR
(
"read /proc/cpuinfo failed"
);
return
NULL
;
}
start_pos
=
strstr
(
cpuinfo
,
"CPU architecture"
);
if
(
start_pos
==
NULL
)
{
ERROR
(
"can not found the key
\"
CPU architecture
\"
when try to get cpu variant"
);
goto
out
;
}
end_pos
=
strchr
(
start_pos
,
'\n'
);
if
(
end_pos
!=
NULL
)
{
*
end_pos
=
0
;
}
start_pos
=
strchr
(
start_pos
,
':'
);
if
(
start_pos
==
NULL
)
{
ERROR
(
"can not found delimiter
\"
:
\"
when try to get cpu variant"
);
goto
out
;
}
util_trim_newline
(
start_pos
);
start_pos
=
util_trim_space
(
start_pos
);
variant
=
strings_to_lower
(
start_pos
);
out:
free
(
cpuinfo
);
cpuinfo
=
NULL
;
return
variant
;
}
int
normalized_host_os_arch
(
char
**
host_os
,
char
**
host_arch
,
char
**
host_variant
)
{
int
ret
=
0
;
struct
utsname
uts
;
char
*
tmp_variant
=
NULL
;
if
(
host_os
==
NULL
||
host_arch
==
NULL
||
host_variant
==
NULL
)
{
ERROR
(
"Invalid NULL pointer"
);
return
-
1
;
}
if
(
uname
(
&
uts
)
<
0
)
{
ERROR
(
"Failed to read host arch and os: %s"
,
strerror
(
errno
));
ret
=
-
1
;
goto
out
;
}
*
host_os
=
strings_to_lower
(
uts
.
sysname
);
if
(
strcasecmp
(
"i386"
,
uts
.
machine
)
==
0
)
{
*
host_arch
=
util_strdup_s
(
"386"
);
}
else
if
((
strcasecmp
(
"x86_64"
,
uts
.
machine
)
==
0
)
||
(
strcasecmp
(
"x86-64"
,
uts
.
machine
)
==
0
))
{
*
host_arch
=
util_strdup_s
(
"amd64"
);
}
else
if
(
strcasecmp
(
"aarch64"
,
uts
.
machine
)
==
0
)
{
*
host_arch
=
util_strdup_s
(
"arm64"
);
}
else
if
((
strcasecmp
(
"armhf"
,
uts
.
machine
)
==
0
)
||
(
strcasecmp
(
"armel"
,
uts
.
machine
)
==
0
))
{
*
host_arch
=
util_strdup_s
(
"arm"
);
}
else
{
*
host_arch
=
util_strdup_s
(
uts
.
machine
);
}
if
(
!
strcmp
(
*
host_arch
,
"arm"
)
||
!
strcmp
(
*
host_arch
,
"arm64"
))
{
*
host_variant
=
get_cpu_variant
();
if
(
!
strcmp
(
*
host_arch
,
"arm64"
)
&&
*
host_variant
!=
NULL
&&
(
!
strcmp
(
*
host_variant
,
"8"
)
||
!
strcmp
(
*
host_variant
,
"v8"
)))
{
free
(
*
host_variant
);
*
host_variant
=
NULL
;
}
if
(
!
strcmp
(
*
host_arch
,
"arm"
)
&&
*
host_variant
==
NULL
)
{
*
host_variant
=
util_strdup_s
(
"v7"
);
}
else
if
(
!
strcmp
(
*
host_arch
,
"arm"
)
&&
*
host_variant
!=
NULL
)
{
tmp_variant
=
*
host_variant
;
*
host_variant
=
NULL
;
if
(
!
strcmp
(
tmp_variant
,
"5"
))
{
*
host_variant
=
util_strdup_s
(
"v5"
);
}
else
if
(
!
strcmp
(
tmp_variant
,
"6"
))
{
*
host_variant
=
util_strdup_s
(
"v6"
);
}
else
if
(
!
strcmp
(
tmp_variant
,
"7"
))
{
*
host_variant
=
util_strdup_s
(
"v7"
);
}
else
if
(
!
strcmp
(
tmp_variant
,
"8"
))
{
*
host_variant
=
util_strdup_s
(
"v8"
);
}
else
{
*
host_variant
=
util_strdup_s
(
tmp_variant
);
}
free
(
tmp_variant
);
tmp_variant
=
NULL
;
}
}
out:
if
(
ret
!=
0
)
{
free
(
*
host_os
);
*
host_os
=
NULL
;
free
(
*
host_arch
);
*
host_arch
=
NULL
;
free
(
*
host_variant
);
*
host_variant
=
NULL
;
}
return
ret
;
}
src/cutils/utils.h
浏览文件 @
642cd5e5
...
...
@@ -397,6 +397,12 @@ char *util_uint_to_string(long long unsigned int data);
char
*
util_int_to_string
(
long
long
int
data
);
char
*
without_sha256_prefix
(
char
*
digest
);
int
normalized_host_os_arch
(
char
**
host_os
,
char
**
host_arch
,
char
**
host_variant
);
char
*
util_full_digest_str
(
char
*
str
);
#ifdef __cplusplus
}
#endif
...
...
src/image/oci/oci_image.c
浏览文件 @
642cd5e5
...
...
@@ -97,6 +97,19 @@ out:
return
ret
;
}
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
;
}
int
oci_init
(
const
struct
service_arguments
*
args
)
{
int
ret
=
0
;
...
...
@@ -106,6 +119,8 @@ int oci_init(const struct service_arguments *args)
return
ret
;
}
cleanup_image_tmpdir
();
ret
=
registry_init
();
if
(
ret
!=
0
)
{
ret
=
-
1
;
...
...
src/image/oci/oci_import.c
浏览文件 @
642cd5e5
...
...
@@ -12,11 +12,547 @@
* Create: 2020-05-26
* Description: isula image import operator implement
*******************************************************************************/
#include "mediatype.h"
#include "oci_import.h"
#include "isula_libutils/log.h"
#include "storage.h"
#include "libisulad.h"
#include "utils.h"
#include "isula_libutils/registry_manifest_schema2.h"
#include "isula_libutils/docker_image_config_v2.h"
#include "util_archive.h"
#include "utils_images.h"
#include "sha256.h"
int
oci_do_import
(
const
char
*
file
,
const
char
*
tag
,
char
**
id
)
#define IMPORT_COMMENT "Imported from tarball"
#define ROOTFS_TYPE "layers"
#define MANIFEST_BIG_DATA_KEY "manifest"
#define TIME_BUF_MAX_LEN 128
#define TEMP_FILE_TEMPLATE IMAGE_TMP_PATH"import-XXXXXX"
typedef
struct
{
char
*
manifest
;
char
*
manifest_digest
;
char
*
config
;
char
*
config_digest
;
char
*
uncompressed_digest
;
char
*
compressed_digest
;
int64_t
compressed_size
;
types_timestamp_t
now_time
;
char
*
tag
;
char
*
uncompressed_file
;
}
import_desc
;
static
void
free_import_desc
(
import_desc
*
desc
)
{
if
(
desc
==
NULL
)
{
return
;
}
free
(
desc
->
manifest
);
desc
->
manifest
=
NULL
;
free
(
desc
->
manifest_digest
);
desc
->
manifest_digest
=
NULL
;
free
(
desc
->
config
);
desc
->
config
=
NULL
;
free
(
desc
->
config_digest
);
desc
->
config_digest
=
NULL
;
free
(
desc
->
uncompressed_digest
);
desc
->
uncompressed_digest
=
NULL
;
free
(
desc
->
compressed_digest
);
desc
->
compressed_digest
=
NULL
;
free
(
desc
->
tag
);
desc
->
tag
=
NULL
;
free
(
desc
->
uncompressed_digest
);
desc
->
uncompressed_digest
=
NULL
;
free
(
desc
->
uncompressed_file
);
desc
->
uncompressed_file
=
NULL
;
free
(
desc
);
return
;
}
static
int
register_layer
(
import_desc
*
desc
)
{
char
*
id
=
NULL
;
struct
layer
*
l
=
NULL
;
if
(
desc
==
NULL
||
desc
->
uncompressed_digest
==
NULL
||
desc
->
compressed_digest
==
NULL
)
{
ERROR
(
"Invalid NULL param"
);
return
-
1
;
}
id
=
without_sha256_prefix
(
desc
->
uncompressed_digest
);
if
(
id
==
NULL
)
{
ERROR
(
"Invalid NULL param"
);
return
-
1
;
}
l
=
storage_layer_get
(
id
);
if
(
l
!=
NULL
)
{
free_layer
(
l
);
l
=
NULL
;
return
0
;
}
else
{
storage_layer_create_opts_t
copts
=
{
.
parent
=
NULL
,
.
uncompress_digest
=
desc
->
uncompressed_digest
,
.
compressed_digest
=
desc
->
compressed_digest
,
.
writable
=
false
,
.
layer_data_path
=
desc
->
uncompressed_file
,
};
return
storage_layer_create
(
id
,
&
copts
);
}
}
static
int
create_config
(
import_desc
*
desc
)
{
int
ret
=
0
;
docker_image_config_v2
*
config
=
NULL
;
char
*
host_os
=
NULL
;
char
*
host_arch
=
NULL
;
char
*
host_variant
=
NULL
;
parser_error
err
=
NULL
;
char
time_str
[
TIME_BUF_MAX_LEN
]
=
{
0
};
if
(
desc
==
NULL
||
desc
->
uncompressed_digest
==
NULL
)
{
ERROR
(
"Invalid NULL param"
);
return
-
1
;
}
config
=
util_common_calloc_s
(
sizeof
(
docker_image_config_v2
));
if
(
config
==
NULL
)
{
ERROR
(
"out of memory"
);
return
-
1
;
}
ret
=
normalized_host_os_arch
(
&
host_os
,
&
host_arch
,
&
host_variant
);
if
(
ret
!=
0
)
{
ERROR
(
"get host os and arch for import failed"
);
isulad_try_set_error_message
(
"get host os and arch for import failed"
);
goto
out
;
}
config
->
rootfs
=
util_common_calloc_s
(
sizeof
(
docker_image_rootfs
));
config
->
config
=
util_common_calloc_s
(
sizeof
(
container_config
));
config
->
container_config
=
util_common_calloc_s
(
sizeof
(
container_config
));
config
->
history
=
util_common_calloc_s
(
sizeof
(
docker_image_history
*
));
if
(
config
->
history
==
NULL
||
config
->
config
==
NULL
||
config
->
container_config
==
NULL
||
config
->
rootfs
==
NULL
)
{
ERROR
(
"out of memory"
);
isulad_try_set_error_message
(
"out of memory"
);
ret
=
-
1
;
goto
out
;
}
config
->
history_len
=
1
;
config
->
rootfs
->
type
=
util_strdup_s
(
ROOTFS_TYPE
);
config
->
rootfs
->
diff_ids
=
util_common_calloc_s
(
sizeof
(
char
*
));
if
(
config
->
rootfs
->
diff_ids
==
NULL
)
{
ERROR
(
"out of memory"
);
isulad_try_set_error_message
(
"out of memory"
);
ret
=
-
1
;
goto
out
;
}
config
->
rootfs
->
diff_ids_len
=
1
;
config
->
history
[
0
]
=
util_common_calloc_s
(
sizeof
(
docker_image_history
));
if
(
config
->
history
[
0
]
==
NULL
)
{
ERROR
(
"out of memory"
);
isulad_try_set_error_message
(
"out of memory"
);
ret
=
-
1
;
goto
out
;
}
if
(
!
get_time_buffer
(
&
desc
->
now_time
,
time_str
,
TIME_BUF_MAX_LEN
))
{
ERROR
(
"get time string from timestamp failed"
);
isulad_try_set_error_message
(
"get time string from timestamp failed"
);
ret
=
-
1
;
goto
out
;
}
config
->
history
[
0
]
->
comment
=
util_strdup_s
(
IMPORT_COMMENT
);
config
->
history
[
0
]
->
created
=
util_strdup_s
(
time_str
);
config
->
rootfs
->
diff_ids
[
0
]
=
util_strdup_s
(
desc
->
uncompressed_digest
);
config
->
comment
=
util_strdup_s
(
IMPORT_COMMENT
);
config
->
created
=
util_strdup_s
(
time_str
);
config
->
os
=
host_os
;
host_os
=
NULL
;
config
->
architecture
=
host_arch
;
host_arch
=
NULL
;
desc
->
config
=
docker_image_config_v2_generate_json
(
config
,
NULL
,
&
err
);
if
(
desc
->
config
==
NULL
)
{
ERROR
(
"generate default config for import failed: %s"
,
err
);
isulad_try_set_error_message
(
"generate default config for import failed: %s"
,
err
);
ret
=
-
1
;
goto
out
;
}
desc
->
config_digest
=
sha256_full_digest_str
(
desc
->
config
);
if
(
desc
->
config_digest
==
NULL
)
{
ERROR
(
"calc digest of config for import failed"
);
isulad_try_set_error_message
(
"calc digest of config for import failed"
);
ret
=
-
1
;
goto
out
;
}
out:
free
(
err
);
err
=
NULL
;
free
(
host_os
);
host_os
=
NULL
;
free
(
host_arch
);
host_arch
=
NULL
;
free
(
host_variant
);
host_variant
=
NULL
;
free_docker_image_config_v2
(
config
);
config
=
NULL
;
return
ret
;
}
static
int
create_manifest
(
import_desc
*
desc
)
{
int
ret
=
0
;
registry_manifest_schema2
*
manifest
=
NULL
;
parser_error
err
=
NULL
;
if
(
desc
==
NULL
||
desc
->
compressed_digest
==
NULL
||
desc
->
config
==
NULL
||
desc
->
config_digest
==
NULL
)
{
ERROR
(
"Invalid NULL param"
);
return
-
1
;
}
manifest
=
util_common_calloc_s
(
sizeof
(
registry_manifest_schema2
));
if
(
manifest
==
NULL
)
{
ERROR
(
"out of memory"
);
isulad_try_set_error_message
(
"out of memory"
);
ret
=
-
1
;
goto
out
;
}
manifest
->
config
=
util_common_calloc_s
(
sizeof
(
registry_manifest_schema2_config
));
manifest
->
layers
=
util_common_calloc_s
(
sizeof
(
registry_manifest_schema2_layers_element
*
));
if
(
manifest
->
config
==
NULL
||
manifest
->
layers
==
NULL
)
{
ERROR
(
"out of memory"
);
isulad_try_set_error_message
(
"out of memory"
);
ret
=
-
1
;
goto
out
;
}
manifest
->
layers_len
=
1
;
manifest
->
layers
[
0
]
=
util_common_calloc_s
(
sizeof
(
registry_manifest_schema2_layers_element
*
));
if
(
manifest
->
layers
[
0
]
==
NULL
)
{
ERROR
(
"out of memory"
);
isulad_try_set_error_message
(
"out of memory"
);
ret
=
-
1
;
goto
out
;
}
manifest
->
config
->
size
=
strlen
(
desc
->
config
);
manifest
->
config
->
media_type
=
util_strdup_s
(
DOCKER_IMAGE_V1
);
manifest
->
config
->
digest
=
util_strdup_s
(
desc
->
config_digest
);
manifest
->
layers
[
0
]
->
media_type
=
util_strdup_s
(
DOCKER_IMAGE_LAYER_TAR_GZIP
);
manifest
->
layers
[
0
]
->
size
=
desc
->
compressed_size
;
manifest
->
layers
[
0
]
->
digest
=
util_strdup_s
(
desc
->
compressed_digest
);
manifest
->
schema_version
=
2
;
manifest
->
media_type
=
util_strdup_s
(
DOCKER_MANIFEST_SCHEMA2_JSON
);
desc
->
manifest
=
registry_manifest_schema2_generate_json
(
manifest
,
NULL
,
&
err
);
if
(
desc
->
manifest
==
NULL
)
{
ERROR
(
"generate default manifest for import failed: %s"
,
err
);
isulad_try_set_error_message
(
"generate default manifest for import failed: %s"
,
err
);
ret
=
-
1
;
goto
out
;
}
desc
->
manifest_digest
=
sha256_full_digest_str
(
desc
->
manifest
);
if
(
desc
->
manifest_digest
==
NULL
)
{
ERROR
(
"calc digest of manifest for import failed"
);
isulad_try_set_error_message
(
"calc digest of manifest for import failed"
);
ret
=
-
1
;
goto
out
;
}
out:
free
(
err
);
err
=
NULL
;
free_registry_manifest_schema2
(
manifest
);
manifest
=
NULL
;
return
ret
;
}
static
int
register_image
(
import_desc
*
desc
)
{
int
ret
=
0
;
char
*
image_id
=
NULL
;
char
*
pre_top_layer
=
NULL
;
char
*
top_layer_id
=
NULL
;
bool
image_created
=
false
;
struct
storage_img_create_options
opts
=
{
0
};
if
(
desc
==
NULL
||
desc
->
manifest
==
NULL
||
desc
->
manifest_digest
==
NULL
||
desc
->
config
==
NULL
||
desc
->
config_digest
==
NULL
||
desc
->
uncompressed_digest
==
NULL
)
{
ERROR
(
"Invalid NULL param"
);
return
-
1
;
}
opts
.
create_time
=
&
desc
->
now_time
;
opts
.
digest
=
desc
->
manifest_digest
;
image_id
=
without_sha256_prefix
(
desc
->
config_digest
);
top_layer_id
=
without_sha256_prefix
(
desc
->
uncompressed_digest
);
ret
=
storage_img_create
(
image_id
,
top_layer_id
,
NULL
,
&
opts
);
if
(
ret
!=
0
)
{
pre_top_layer
=
storage_get_img_top_layer
(
image_id
);
if
(
pre_top_layer
==
NULL
)
{
ERROR
(
"create image %s for %s failed"
,
image_id
,
desc
->
tag
);
ret
=
-
1
;
goto
out
;
}
if
(
strcmp
(
pre_top_layer
,
top_layer_id
)
!=
0
)
{
ERROR
(
"error committing image, image id %s exist, but top layer doesn't match. local %s, import %s"
,
image_id
,
pre_top_layer
,
top_layer_id
);
ret
=
-
1
;
goto
out
;
}
ret
=
0
;
}
image_created
=
true
;
ret
=
storage_img_add_name
(
image_id
,
desc
->
tag
);
if
(
ret
!=
0
)
{
ERROR
(
"add image name %s failed"
,
desc
->
tag
);
goto
out
;
}
ret
=
storage_img_set_big_data
(
image_id
,
desc
->
config_digest
,
desc
->
config
);
if
(
ret
!=
0
)
{
ERROR
(
"set config for import %s failed"
,
desc
->
tag
);
goto
out
;
}
ret
=
storage_img_set_big_data
(
image_id
,
MANIFEST_BIG_DATA_KEY
,
desc
->
manifest
);
if
(
ret
!=
0
)
{
ERROR
(
"set manifest for import %s failed"
,
desc
->
tag
);
goto
out
;
}
ret
=
storage_img_set_loaded_time
(
image_id
,
&
desc
->
now_time
);
if
(
ret
!=
0
)
{
ERROR
(
"set loaded time failed"
);
goto
out
;
}
ret
=
storage_img_set_image_size
(
image_id
);
if
(
ret
!=
0
)
{
ERROR
(
"set image size failed for %s failed"
,
desc
->
tag
);
isulad_try_set_error_message
(
"set image size failed"
);
goto
out
;
}
out:
if
(
ret
!=
0
&&
image_created
)
{
if
(
storage_img_delete
(
image_id
,
true
))
{
ERROR
(
"delete image %s failed"
,
image_id
);
}
}
return
ret
;
}
static
char
*
create_temp_file
()
{
int
fd
=
-
1
;
char
temp_file
[]
=
TEMP_FILE_TEMPLATE
;
fd
=
mkstemp
(
temp_file
);
if
(
fd
<
0
)
{
ERROR
(
"make temporary file failed: %s"
,
strerror
(
errno
));
isulad_try_set_error_message
(
"make temporary file failed: %s"
,
strerror
(
errno
));
return
NULL
;
}
close
(
fd
);
return
util_strdup_s
(
temp_file
);
}
static
import_desc
*
prepre_import
(
char
*
file
,
char
*
tag
)
{
int
ret
=
0
;
import_desc
*
desc
=
NULL
;
char
*
errmsg
=
NULL
;
desc
=
util_common_calloc_s
(
sizeof
(
import_desc
));
if
(
desc
==
NULL
)
{
ERROR
(
"out of memory"
);
isulad_try_set_error_message
(
"out of memory"
);
return
NULL
;
}
desc
->
compressed_size
=
util_file_size
(
file
);
if
(
desc
->
compressed_size
<
0
)
{
ERROR
(
"Calc size of file %s for import failed"
,
file
);
isulad_try_set_error_message
(
"Calc size of file %s for import failed"
,
file
);
ret
=
-
1
;
goto
out
;
}
desc
->
compressed_digest
=
sha256_full_file_digest
(
file
);
if
(
desc
->
compressed_digest
==
NULL
)
{
ERROR
(
"Calc compressed digest of file %s failed"
,
file
);
isulad_try_set_error_message
(
"Calc compressed digest of file %s failed"
,
file
);
ret
=
-
1
;
goto
out
;
}
desc
->
uncompressed_file
=
create_temp_file
();
if
(
desc
->
uncompressed_file
==
NULL
)
{
ERROR
(
"create temporary file for import failed"
);
isulad_try_set_error_message
(
"create temporary file for import failed"
);
ret
=
-
1
;
goto
out
;
}
ret
=
archive_uncompress
(
file
,
desc
->
uncompressed_file
,
&
errmsg
);
if
(
ret
!=
0
)
{
ERROR
(
"uncompress %s for import failed: %s"
,
file
,
errmsg
);
isulad_try_set_error_message
(
"uncompress %s for import failed: %s"
,
file
,
errmsg
);
ret
=
-
1
;
goto
out
;
}
desc
->
uncompressed_digest
=
sha256_full_file_digest
(
desc
->
uncompressed_file
);
if
(
desc
->
uncompressed_digest
==
NULL
)
{
ERROR
(
"Calc uncompressed digest of file %s failed"
,
file
);
isulad_try_set_error_message
(
"Calc uncompressed digest of file %s failed"
,
file
);
ret
=
-
1
;
goto
out
;
}
if
(
!
get_now_time_stamp
(
&
desc
->
now_time
))
{
ERROR
(
"get time stamp for import failed"
);
isulad_try_set_error_message
(
"get time stamp for import failed"
);
ret
=
-
1
;
goto
out
;
}
desc
->
tag
=
util_strdup_s
(
tag
);
out:
if
(
ret
!=
0
)
{
free_import_desc
(
desc
);
desc
=
NULL
;
}
free
(
errmsg
);
errmsg
=
NULL
;
return
desc
;
}
static
int
do_import
(
char
*
file
,
char
*
tag
)
{
int
ret
=
0
;
import_desc
*
desc
=
NULL
;
if
(
file
==
NULL
||
tag
==
NULL
)
{
ERROR
(
"Invalid NULL param"
);
return
-
1
;
}
desc
=
prepre_import
(
file
,
tag
);
if
(
desc
==
NULL
)
{
ERROR
(
"Prepare import %s to be %s failed"
,
file
,
tag
);
isulad_try_set_error_message
(
"Prepare import failed"
);
return
-
1
;
}
ret
=
register_layer
(
desc
);
if
(
ret
!=
0
)
{
ERROR
(
"Register layer from file %s for import failed"
,
file
);
isulad_try_set_error_message
(
"Register layer from file %s for import failed"
,
file
);
goto
out
;
}
ret
=
create_config
(
desc
);
if
(
ret
!=
0
)
{
ERROR
(
"Create config for import failed"
);
isulad_try_set_error_message
(
"Create config for import failed"
);
ret
=
-
1
;
goto
out
;
}
ret
=
create_manifest
(
desc
);
if
(
ret
!=
0
)
{
ERROR
(
"Create manifest for import failed"
);
isulad_try_set_error_message
(
"Create manifest for import failed"
);
ret
=
-
1
;
goto
out
;
}
ret
=
register_image
(
desc
);
if
(
ret
!=
0
)
{
ERROR
(
"Register image for import failed"
);
isulad_try_set_error_message
(
"Register image for import failed"
);
goto
out
;
}
out:
if
(
desc
->
uncompressed_file
!=
NULL
)
{
if
(
util_path_remove
(
desc
->
uncompressed_file
))
{
WARN
(
"failed to remove file %s: %s"
,
desc
->
uncompressed_file
,
strerror
(
errno
));
}
}
free_import_desc
(
desc
);
desc
=
NULL
;
return
ret
;
}
int
oci_do_import
(
char
*
file
,
char
*
tag
,
char
**
id
)
{
int
ret
=
0
;
imagetool_image
*
image
=
NULL
;
if
(
file
==
NULL
||
tag
==
NULL
||
id
==
NULL
)
{
ERROR
(
"Invalid NULL param"
);
return
-
1
;
}
ret
=
do_import
(
file
,
tag
);
if
(
ret
!=
0
)
{
ERROR
(
"import %s failed"
,
tag
);
goto
out
;
}
image
=
storage_img_get
(
tag
);
if
(
image
==
NULL
)
{
ERROR
(
"get image %s failed after import"
,
tag
);
isulad_try_set_error_message
(
"get image %s failed after import"
,
tag
);
ret
=
-
1
;
goto
out
;
}
*
id
=
util_strdup_s
(
image
->
id
);
out:
free_imagetool_image
(
image
);
return
ret
;
}
void
oci_import_cleanup
()
{
//TODO implement import function by storage API
return
0
;
return
;
}
src/image/oci/oci_import.h
浏览文件 @
642cd5e5
...
...
@@ -19,7 +19,8 @@
extern
"C"
{
#endif
int
oci_do_import
(
const
char
*
file
,
const
char
*
tag
,
char
**
id
);
int
oci_do_import
(
char
*
file
,
char
*
tag
,
char
**
id
);
void
oci_import_cleanup
();
#ifdef __cplusplus
}
...
...
src/image/oci/registry/registry.c
浏览文件 @
642cd5e5
...
...
@@ -1476,7 +1476,7 @@ static int prepare_pull_desc(pull_descriptor *desc, registry_pull_options *optio
{
int
ret
=
0
;
int
sret
=
0
;
char
blobpath
[
REGISTRY_TMP_DIR_LEN
]
=
REGISTRY_TMP_DIR
;
char
blobpath
[]
=
REGISTRY_TMP_DIR
;
char
scope
[
PATH_MAX
]
=
{
0
};
if
(
desc
==
NULL
||
options
==
NULL
)
{
...
...
@@ -1630,32 +1630,10 @@ static void cached_layers_kvfree(void *key, void *value)
return
;
}
static
void
remove_temporary_dirs
()
{
int
ret
=
0
;
int
sret
=
0
;
char
cmd
[
PATH_MAX
]
=
{
0
};
sret
=
snprintf
(
cmd
,
sizeof
(
cmd
),
"/usr/bin/rm -rf %s"
,
REGISTRY_TMP_DIR_ALL
);
if
(
sret
<
0
||
(
size_t
)
sret
>=
sizeof
(
cmd
))
{
ERROR
(
"Failed to sprintf cmd to remove temporary directory"
);
return
;
}
ret
=
system
(
cmd
);
if
(
ret
!=
0
)
{
ERROR
(
"execute
\"
%s
\"
got result %d"
,
cmd
,
ret
);
}
return
;
}
int
registry_init
()
{
int
ret
=
0
;
remove_temporary_dirs
();
g_shared
=
util_common_calloc_s
(
sizeof
(
registry_global
));
if
(
g_shared
==
NULL
)
{
ERROR
(
"out of memory"
);
...
...
src/image/oci/registry/registry_apiv2.c
浏览文件 @
642cd5e5
...
...
@@ -680,117 +680,6 @@ out:
return
ret
;
}
static
char
*
get_cpu_variant
()
{
char
*
variant
=
NULL
;
char
*
cpuinfo
=
NULL
;
char
*
start_pos
=
NULL
;
char
*
end_pos
=
NULL
;
cpuinfo
=
util_read_text_file
(
"/proc/cpuinfo"
);
if
(
cpuinfo
==
NULL
)
{
ERROR
(
"read /proc/cpuinfo failed"
);
return
NULL
;
}
start_pos
=
strstr
(
cpuinfo
,
"CPU architecture"
);
if
(
start_pos
==
NULL
)
{
ERROR
(
"can not found the key
\"
CPU architecture
\"
when try to get cpu variant"
);
goto
out
;
}
end_pos
=
strchr
(
start_pos
,
'\n'
);
if
(
end_pos
!=
NULL
)
{
*
end_pos
=
0
;
}
start_pos
=
strchr
(
start_pos
,
':'
);
if
(
start_pos
==
NULL
)
{
ERROR
(
"can not found delimiter
\"
:
\"
when try to get cpu variant"
);
goto
out
;
}
util_trim_newline
(
start_pos
);
start_pos
=
util_trim_space
(
start_pos
);
variant
=
util_strdup_s
(
start_pos
);
out:
free
(
cpuinfo
);
cpuinfo
=
NULL
;
return
variant
;
}
static
int
normalized_host_os_arch
(
char
**
host_os
,
char
**
host_arch
,
char
**
host_variant
)
{
int
ret
=
0
;
struct
utsname
uts
;
char
*
tmp_variant
=
NULL
;
if
(
host_os
==
NULL
||
host_arch
==
NULL
||
host_variant
==
NULL
)
{
ERROR
(
"Invalid NULL pointer"
);
return
-
1
;
}
if
(
uname
(
&
uts
)
<
0
)
{
ERROR
(
"Failed to read host arch and os: %s"
,
strerror
(
errno
));
ret
=
-
1
;
goto
out
;
}
*
host_os
=
util_strdup_s
(
uts
.
sysname
);
if
(
strcasecmp
(
"i386"
,
uts
.
machine
)
==
0
)
{
*
host_arch
=
util_strdup_s
(
"386"
);
}
else
if
((
strcasecmp
(
"x86_64"
,
uts
.
machine
)
==
0
)
||
(
strcasecmp
(
"x86-64"
,
uts
.
machine
)
==
0
))
{
*
host_arch
=
util_strdup_s
(
"amd64"
);
}
else
if
(
strcasecmp
(
"aarch64"
,
uts
.
machine
)
==
0
)
{
*
host_arch
=
strdup
(
"arm64"
);
}
else
if
((
strcasecmp
(
"armhf"
,
uts
.
machine
)
==
0
)
||
(
strcasecmp
(
"armel"
,
uts
.
machine
)
==
0
))
{
*
host_arch
=
strdup
(
"arm"
);
}
else
{
*
host_arch
=
strdup
(
uts
.
machine
);
}
if
(
!
strcmp
(
*
host_arch
,
"arm"
)
||
!
strcmp
(
*
host_arch
,
"arm64"
))
{
*
host_variant
=
get_cpu_variant
();
if
(
!
strcmp
(
*
host_arch
,
"arm64"
)
&&
*
host_variant
!=
NULL
&&
(
!
strcmp
(
*
host_variant
,
"8"
)
||
!
strcmp
(
*
host_variant
,
"v8"
)))
{
free
(
*
host_variant
);
*
host_variant
=
NULL
;
}
if
(
!
strcmp
(
*
host_arch
,
"arm"
)
&&
*
host_variant
==
NULL
)
{
*
host_variant
=
util_strdup_s
(
"v7"
);
}
else
if
(
!
strcmp
(
*
host_arch
,
"arm"
)
&&
*
host_variant
!=
NULL
)
{
tmp_variant
=
*
host_variant
;
*
host_variant
=
NULL
;
if
(
!
strcmp
(
tmp_variant
,
"5"
))
{
*
host_variant
=
util_strdup_s
(
"v5"
);
}
else
if
(
!
strcmp
(
tmp_variant
,
"6"
))
{
*
host_variant
=
util_strdup_s
(
"v6"
);
}
else
if
(
!
strcmp
(
tmp_variant
,
"7"
))
{
*
host_variant
=
util_strdup_s
(
"v7"
);
}
else
if
(
!
strcmp
(
tmp_variant
,
"8"
))
{
*
host_variant
=
util_strdup_s
(
"v8"
);
}
else
{
*
host_variant
=
util_strdup_s
(
tmp_variant
);
}
free
(
tmp_variant
);
tmp_variant
=
NULL
;
}
}
out:
if
(
ret
!=
0
)
{
free
(
*
host_os
);
*
host_os
=
NULL
;
free
(
*
host_arch
);
*
host_arch
=
NULL
;
free
(
*
host_variant
);
*
host_variant
=
NULL
;
}
return
ret
;
}
static
bool
is_variant_same
(
char
*
variant1
,
char
*
variant2
)
{
if
(
variant1
==
NULL
&&
variant2
==
NULL
)
{
...
...
src/image/oci/registry/registry_common.c
浏览文件 @
642cd5e5
...
...
@@ -159,16 +159,6 @@ out:
return
ret
;
}
char
*
without_sha256_prefix
(
char
*
digest
)
{
if
(
digest
==
NULL
)
{
ERROR
(
"Invalid digest NULL when strip sha256 prefix"
);
return
NULL
;
}
return
digest
+
strlen
(
SHA256_PREFIX
);
}
types_timestamp_t
created_to_timestamp
(
char
*
created
)
{
int64_t
nanos
=
0
;
...
...
src/image/oci/registry/registry_common.h
浏览文件 @
642cd5e5
...
...
@@ -32,7 +32,6 @@ extern "C" {
void
free_items_not_inherit
(
docker_image_config_v2
*
config
);
int
add_rootfs_and_history
(
const
layer_blob
*
layers
,
size_t
layers_len
,
const
registry_manifest_schema1
*
manifest
,
docker_image_config_v2
*
config
);
char
*
without_sha256_prefix
(
char
*
digest
);
types_timestamp_t
created_to_timestamp
(
char
*
created
);
#ifdef __cplusplus
...
...
src/image/oci/registry/registry_type.h
浏览文件 @
642cd5e5
...
...
@@ -20,14 +20,12 @@
#include <time.h>
#include "types_def.h"
#include "utils_images.h"
// 8 is enough for challenge, usually only one challenge is provided.
#define CHALLENGE_MAX 8
#define REGISTRY_TMP_DIR_COMMON "/var/tmp/isulad-registry-"
#define REGISTRY_TMP_DIR_LEN 32
#define REGISTRY_TMP_DIR REGISTRY_TMP_DIR_COMMON"XXXXXX"
#define REGISTRY_TMP_DIR_ALL REGISTRY_TMP_DIR_COMMON"*"
#define REGISTRY_TMP_DIR IMAGE_TMP_PATH"registry-XXXXXX"
#define MAX_LAYER_NUM 125
#define ROOTFS_TYPE "layers"
...
...
src/image/oci/utils_images.h
浏览文件 @
642cd5e5
...
...
@@ -32,6 +32,8 @@ extern "C" {
#define DEFAULT_REPO_PREFIX "library/"
#define MAX_ID_BUF_LEN 256
#define IMAGE_TMP_PATH "/var/tmp/isula-image/"
char
*
oci_get_host
(
const
char
*
name
);
char
*
oci_host_from_mirror
(
const
char
*
mirror
);
char
*
oci_default_tag
(
const
char
*
name
);
...
...
src/sha256/sha256.c
浏览文件 @
642cd5e5
...
...
@@ -496,3 +496,31 @@ bool sha256_valid_digest_file(const char *path, const char *digest)
return
true
;
}
char
*
sha256_full_digest_str
(
char
*
str
)
{
char
*
digest
=
NULL
;
char
*
full_digest
=
NULL
;
digest
=
sha256_digest_str
(
str
);
if
(
digest
==
NULL
)
{
ERROR
(
"Failed to calculate chain id"
);
return
NULL
;
}
full_digest
=
util_full_digest
(
digest
);
free
(
digest
);
return
full_digest
;
}
char
*
without_sha256_prefix
(
char
*
digest
)
{
if
(
digest
==
NULL
||
!
util_has_prefix
(
digest
,
SHA256_PREFIX
))
{
ERROR
(
"Invalid digest when strip sha256 prefix"
);
return
NULL
;
}
return
digest
+
strlen
(
SHA256_PREFIX
);
}
src/sha256/sha256.h
浏览文件 @
642cd5e5
...
...
@@ -50,6 +50,10 @@ char *sha256_full_file_digest(const char *filename);
bool
sha256_valid_digest_file
(
const
char
*
path
,
const
char
*
digest
);
char
*
sha256_full_digest_str
(
char
*
str
);
char
*
without_sha256_prefix
(
char
*
digest
);
#ifdef __cplusplus
}
#endif
...
...
src/tar/util_archive.c
浏览文件 @
642cd5e5
...
...
@@ -294,3 +294,264 @@ child_out:
cleanup:
return
ret
;
}
static
void
try_set_errbuf_and_log
(
char
*
errbuf
,
const
char
*
format
,
...)
{
int
ret
=
0
;
if
(
errbuf
==
NULL
||
strlen
(
errbuf
)
>
0
)
{
return
;
}
va_list
argp
;
va_start
(
argp
,
format
);
ret
=
vsnprintf
(
errbuf
,
BUFSIZ
,
format
,
argp
);
va_end
(
argp
);
if
(
ret
<
0
||
ret
>=
BUFSIZ
)
{
return
;
}
ERROR
(
"%s"
,
errbuf
);
return
;
}
static
int
copy_data_between_archives
(
struct
archive
*
ar
,
struct
archive
*
aw
,
char
*
errbuf
)
{
int
r
=
ARCHIVE_FAILED
;
const
void
*
buff
=
NULL
;
size_t
size
;
int64_t
offset
;
for
(;;)
{
r
=
archive_read_data_block
(
ar
,
&
buff
,
&
size
,
&
offset
);
if
(
r
==
ARCHIVE_EOF
)
{
return
ARCHIVE_OK
;
}
if
(
r
<
ARCHIVE_OK
)
{
try_set_errbuf_and_log
(
errbuf
,
"tar archive read result %d, error: %s"
,
r
,
archive_error_string
(
ar
));
return
r
;
}
r
=
archive_write_data
(
aw
,
buff
,
size
);
if
(
r
<
ARCHIVE_OK
)
{
try_set_errbuf_and_log
(
errbuf
,
"tar archive write result %d, error: %s"
,
r
,
archive_error_string
(
aw
));
return
r
;
}
}
}
static
int
archive_uncompress_handler
(
struct
archive
*
src
,
struct
archive
*
dest
,
char
*
errbuf
)
{
int
ret
=
0
;
struct
archive_entry
*
entry
=
NULL
;
for
(;;)
{
ret
=
archive_read_next_header
(
src
,
&
entry
);
if
(
ret
==
ARCHIVE_EOF
)
{
break
;
}
if
(
ret
!=
ARCHIVE_OK
)
{
try_set_errbuf_and_log
(
errbuf
,
"Warning reading tar header: %s"
,
archive_error_string
(
src
));
ret
=
-
1
;
goto
out
;
}
ret
=
archive_write_header
(
dest
,
entry
);
if
(
ret
!=
ARCHIVE_OK
)
{
try_set_errbuf_and_log
(
errbuf
,
"Fail to handle tar header: %s"
,
archive_error_string
(
dest
));
ret
=
-
1
;
goto
out
;
}
else
if
(
archive_entry_size
(
entry
)
>
0
)
{
ret
=
copy_data_between_archives
(
src
,
dest
,
errbuf
);
if
(
ret
!=
ARCHIVE_OK
)
{
try_set_errbuf_and_log
(
errbuf
,
"Failed to do copy tar data: %s"
,
archive_error_string
(
dest
));
ret
=
-
1
;
goto
out
;
}
}
ret
=
archive_write_finish_entry
(
dest
);
if
(
ret
!=
ARCHIVE_OK
)
{
try_set_errbuf_and_log
(
errbuf
,
"Failed to freeing archive entry: %s
\n
"
,
archive_error_string
(
dest
));
ret
=
-
1
;
goto
out
;
}
}
ret
=
0
;
out:
return
ret
;
}
static
struct
archive
*
create_read_archive
(
const
char
*
file
,
char
*
errbuf
)
{
int
ret
=
0
;
struct
archive
*
read_archive
=
NULL
;
read_archive
=
archive_read_new
();
if
(
read_archive
==
NULL
)
{
try_set_errbuf_and_log
(
errbuf
,
"Failed to malloc archive read object: %s"
,
strerror
(
errno
));
ret
=
-
1
;
goto
out
;
}
ret
=
archive_read_support_filter_all
(
read_archive
);
if
(
ret
!=
ARCHIVE_OK
)
{
try_set_errbuf_and_log
(
errbuf
,
"Failed to set archive read support filter all, result is %d, errmsg: %s"
,
ret
,
archive_error_string
(
read_archive
));
ret
=
-
1
;
goto
out
;
}
ret
=
archive_read_support_format_all
(
read_archive
);
if
(
ret
!=
ARCHIVE_OK
)
{
try_set_errbuf_and_log
(
errbuf
,
"Failed to set archive read support format all, result is %d, errmsg: %s"
,
ret
,
archive_error_string
(
read_archive
));
ret
=
-
1
;
goto
out
;
}
ret
=
archive_read_open_filename
(
read_archive
,
file
,
ARCHIVE_READ_BUFFER_SIZE
);
if
(
ret
!=
ARCHIVE_OK
)
{
try_set_errbuf_and_log
(
errbuf
,
"Failed to open archive %s: %s"
,
file
,
archive_error_string
(
read_archive
));
ret
=
-
1
;
goto
out
;
}
out:
if
(
ret
!=
ARCHIVE_OK
&&
read_archive
!=
NULL
)
{
if
(
archive_read_free
(
read_archive
)
!=
ARCHIVE_OK
)
{
try_set_errbuf_and_log
(
errbuf
,
"Failed to free archive %s: %s"
,
file
,
archive_error_string
(
read_archive
));
}
read_archive
=
NULL
;
}
return
read_archive
;
}
static
struct
archive
*
create_write_archive
(
const
char
*
file
,
int
format_code
,
char
*
errbuf
)
{
int
ret
=
0
;
struct
archive
*
write_archive
=
NULL
;
write_archive
=
archive_write_new
();
if
(
write_archive
==
NULL
)
{
try_set_errbuf_and_log
(
errbuf
,
"Failed to malloc archive write object: %s"
,
strerror
(
errno
));
ret
=
-
1
;
goto
out
;
}
ret
=
archive_write_set_format
(
write_archive
,
format_code
);
if
(
ret
!=
ARCHIVE_OK
)
{
try_set_errbuf_and_log
(
errbuf
,
"Failed to set format %d, result is %d, errmsg: %s"
,
format_code
,
ret
,
archive_error_string
(
write_archive
));
ret
=
-
1
;
goto
out
;
}
ret
=
archive_write_open_filename
(
write_archive
,
file
);
if
(
ret
!=
ARCHIVE_OK
)
{
try_set_errbuf_and_log
(
errbuf
,
"Failed to open archive %s: %s"
,
file
,
archive_error_string
(
write_archive
));
ret
=
-
1
;
goto
out
;
}
out:
if
(
ret
!=
ARCHIVE_OK
&&
write_archive
!=
NULL
)
{
if
(
archive_write_free
(
write_archive
)
!=
ARCHIVE_OK
)
{
try_set_errbuf_and_log
(
errbuf
,
"Failed to free archive %s: %s"
,
file
,
archive_error_string
(
write_archive
));
}
write_archive
=
NULL
;
}
return
write_archive
;
}
void
destroy_all_archive
(
struct
archive
*
read_archive
,
struct
archive
*
write_archive
,
char
*
errbuf
)
{
if
(
read_archive
!=
NULL
)
{
if
(
archive_read_free
(
read_archive
)
!=
ARCHIVE_OK
)
{
try_set_errbuf_and_log
(
errbuf
,
"Failed to free read archive: %s"
,
archive_error_string
(
read_archive
));
}
}
if
(
write_archive
!=
NULL
)
{
if
(
archive_write_free
(
write_archive
)
!=
ARCHIVE_OK
)
{
try_set_errbuf_and_log
(
errbuf
,
"Failed to free write archive: %s"
,
archive_error_string
(
write_archive
));
}
}
return
;
}
static
int
try_read_format_code
(
const
char
*
file
)
{
int
ret
=
0
;
char
errbuf
[
BUFSIZ
]
=
{
0
};
int
format_code
=
ARCHIVE_FORMAT_TAR_GNUTAR
;
struct
archive_entry
*
entry
=
NULL
;
struct
archive
*
ar
=
NULL
;
ar
=
create_read_archive
(
file
,
errbuf
);
if
(
ar
==
NULL
)
{
return
ARCHIVE_FORMAT_TAR_GNUTAR
;
}
// format code upated when archive_read_next_header is called
ret
=
archive_read_next_header
(
ar
,
&
entry
);
if
(
ret
==
ARCHIVE_OK
)
{
ret
=
archive_format
(
ar
);
if
(
ret
!=
0
)
{
// if not updated, result format code is default to be 0
format_code
=
ret
;
}
}
archive_read_free
(
ar
);
return
format_code
;
}
int
archive_uncompress
(
const
char
*
src
,
const
char
*
dest
,
char
**
errmsg
)
{
char
errbuf
[
BUFSIZ
]
=
{
0
};
struct
archive
*
src_archive
=
NULL
;
struct
archive
*
dest_archive
=
NULL
;
int
ret
=
0
;
src_archive
=
create_read_archive
(
src
,
errbuf
);
if
(
src_archive
==
NULL
)
{
try_set_errbuf_and_log
(
errbuf
,
"Failed to create archive read object"
);
ret
=
-
1
;
goto
out
;
}
dest_archive
=
create_write_archive
(
dest
,
try_read_format_code
(
src
),
errbuf
);
if
(
dest_archive
==
NULL
)
{
try_set_errbuf_and_log
(
errbuf
,
"Failed to create archive write object"
);
ret
=
-
1
;
goto
out
;
}
ret
=
archive_uncompress_handler
(
src_archive
,
dest_archive
,
errbuf
);
if
(
ret
!=
0
)
{
try_set_errbuf_and_log
(
errbuf
,
"Failed to uncompress %s to %s"
,
src
,
dest
);
goto
out
;
}
out:
destroy_all_archive
(
src_archive
,
dest_archive
,
errbuf
);
src_archive
=
NULL
;
dest_archive
=
NULL
;
if
(
errmsg
!=
NULL
&&
strlen
(
errbuf
)
!=
0
)
{
*
errmsg
=
util_strdup_s
(
errbuf
);
}
return
ret
;
}
src/tar/util_archive.h
浏览文件 @
642cd5e5
...
...
@@ -38,6 +38,8 @@ struct archive_options {
int
archive_unpack
(
const
struct
io_read_wrapper
*
content
,
const
char
*
dstdir
,
const
struct
archive_options
*
options
);
int
archive_uncompress
(
const
char
*
src
,
const
char
*
dest
,
char
**
errmsg
);
#ifdef __cplusplus
}
#endif
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录