Imported Upstream version 1.25.0
[platform/core/ml/nnfw.git] / compiler / onecc-docker / onecc-docker
1 #!/usr/bin/env python3
2
3 # Copyright (c) 2022 Samsung Electronics Co., Ltd. All Rights Reserved
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 #     http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 import sys
18 import subprocess
19 import requests
20 import os
21 import argparse
22 import re
23
24
25 class RequestHandler:
26     def __init__(self, token=None, timeout=None):
27         if token:
28             self.headers = {"Authorization": "Bearer {}".format(token)}
29         else:
30             self.headers = {}
31         self.timeout = timeout or 5
32
33     def make_request(self, url):
34         try:
35             response = requests.get(url, headers=self.headers, timeout=self.timeout)
36             response.raise_for_status()
37             return response
38         except requests.RequestException as e:
39             raise SystemExit('[onecc-docker] error: {}'.format(e))
40
41
42 # 5 sec timeout is set based on github.com/Samsung/ONE/issues/11134
43 def _request_recent_version(token=None):
44     response = RequestHandler(
45         token,
46         timeout=5).make_request(url="https://api.github.com/repos/Samsung/ONE/releases")
47     versions = [release_item["tag_name"] for release_item in response.json()]
48
49     for version in versions:
50         # Return the latest version with the given format
51         # to filter out such as 'onert-micro-0.1.0' release
52         # which doesn't contain onecc package.
53         if bool(re.match(r'^\d+\.\d+\.\d+$', version)):
54             return version
55
56     raise SystemExit('[onecc-docker] Failed to get latest onecc version')
57
58
59 # 10 sec timeout is set based on github.com/Samsung/ONE/issues/11134
60 def _run(cmd, is_shell=False, timeout=10):
61     result = subprocess.Popen(
62         cmd, shell=is_shell, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
63
64     stdout, stderr = result.communicate(timeout=timeout)
65     stdout = stdout.decode('utf-8')
66     stderr = stderr.decode('utf-8')
67
68     if result.returncode:
69         print(stderr, end='')
70         exit(result.returncode)
71     else:
72         return stdout
73
74
75 def _image_exists(name):
76     cmd = ['docker', 'images', '-q', name]
77     lines = _run(cmd).splitlines()
78     return lines
79
80
81 def main():
82     script_path = os.path.dirname(os.path.realpath(__file__))
83     dockerfile_path = os.path.join(script_path, 'docker')
84
85     onecc_docker_usage = 'onecc-docker [-h] [-t TOKEN] [COMMAND <args>]'
86     onecc_docker_desc = 'Run onecc via docker'
87     parser = argparse.ArgumentParser(
88         usage=onecc_docker_usage, description=onecc_docker_desc)
89     parser.add_argument(
90         "-t",
91         "--token",
92         help=
93         "Token for authentication to GitHub. This is a workaround for Rate limit exceeded error"
94     )
95
96     args, onecc_arguments = parser.parse_known_args()
97     authorization_token = args.token
98
99     recent_version = _request_recent_version(authorization_token)
100     image_name = f"onecc:{recent_version}"
101     build_arg = f"VERSION={recent_version}"
102
103     if not _image_exists(image_name):
104         build_cmd = [
105             "docker", "build", "-t", image_name, "--build-arg", build_arg, dockerfile_path
106         ]
107         print('[onecc-docker] Build docker image ...')
108         _run(build_cmd, timeout=30)
109         print('[onecc-docker] Docker image is built successfully.')
110
111     contianer_name = f"onecc_{recent_version.replace('.','_')}"
112     user_cmd = ' '.join(onecc_arguments)
113
114     run_cmd = [
115         "docker", "run", "--rm", "-u", "$(id -u):$(id -g)", "--name", contianer_name,
116         "-v", "${HOME}:${HOME}", "-e", "HOME=${HOME}", "-w", "${PWD}", image_name,
117         user_cmd
118     ]
119
120     cmd = ' '.join(run_cmd)
121     output = _run(cmd, is_shell=True)
122     print(output, end='')
123
124
125 if __name__ == "__main__":
126     try:
127         main()
128     except Exception as e:
129         prog_name = os.path.basename(__file__)
130         print(f"{prog_name}: {type(e).__name__}: " + str(e), file=sys.stderr)
131         sys.exit(255)