-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathdocker_build_install_codegen.py
executable file
·164 lines (140 loc) · 6.17 KB
/
docker_build_install_codegen.py
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#!/usr/bin/env python3
import os
import docker
import uuid
from build_install_codegen import args_setup, load_from_configs
DOCKER_IMAGE = 'yuokamoto1988/ue_ros2_base'
def create_dir_mount(dir=os.getcwd(), target='', exception=[]):
volumes = []
files = os.listdir(dir)
for f in files:
if f in exception:
continue
else:
volumes.append(os.path.join(dir, f) + ':' + os.path.join(target, f))
return volumes
def exec_run_with_log(container, command, user):
_, stream = container.exec_run(command, user=user, stream=True)
for data in stream:
print(data.decode())
if __name__ == '__main__':
parser = args_setup()
parser.add_argument(
'--pull_inside_docker',
help='pull additonal repos inside docker or outside docker and mount',
action='store_true'
)
parser.add_argument(
'--docker_image',
help='docker image name. if this is not provided, yuokamoto1988/ue_ros2_base:$ROSDISTRO is used',
default=""
)
parser.add_argument(
'--create_intermediate_image',
help='if user id is not 1000, this script overwrite id of files inside docker. Since it takes time to chown many files, you can save image by this option',
action='store_true'
)
args = parser.parse_args()
config_files = ['default_config.yaml.'+args.rosdistro]
if args.config is not None:
config_files.extend(args.config)
UEPath, projectPath, pluginName, \
pluginFolderName, targetThirdpartyFolderName, \
target, black_list, dependency, name_mapping, repos, ignore_deprecated_msg = load_from_configs(config_files, args.ros_ws, False, False)
# common params
user = 'admin'
cur_dir = os.getcwd()
home = os.environ['HOME']
docker_hoeme_dir = '/home/' + user
# initialization of command and volumes for docker
volumes = [projectPath + ':' + docker_hoeme_dir + projectPath.replace(home, '')]
command = 'python3 build_install_codegen.py '
# pass arg to command inside docker.
arg_dict = vars(args)
for arg in arg_dict:
if arg in ['ros_ws', 'config', 'docker_image', 'create_intermediate_image']: #skip some args
continue
arg_value = arg_dict[arg]
if type(arg_value) == type(True):
if arg_value:
command += ' --' + arg
elif arg_value is not None :
command += ' --' + arg + ' ' + str(arg_value)
# mount UE_tools except for ros2_ws
volumes.extend(create_dir_mount(dir=cur_dir, target=docker_hoeme_dir + '/UE_tools', exception=['ros2_ws', 'tmp']))
# handle additional repos
command += ' --skip_pull '
if args.build:
if not args.pull_inside_docker:
if not os.path.exists('tmp'):
os.makedirs('tmp')
if not os.path.exists('tmp/pkgs'):
os.makedirs('tmp/pkgs')
if not os.path.exists('tmp/ros2'):
os.makedirs('tmp/ros2')
print('Pull repos')
os.system('vcs import --repos --debug ' + 'tmp/pkgs' + ' < ' + os.path.join(home, repos))
if args.type == 'base':
os.system('wget https://raw.githubusercontent.com/ros2/ros2/' + args.rosdistro + '/ros2.repos')
os.system('vcs import --repos --debug tmp/ros2 < ros2.repos')
os.system('touch tmp/ros2/ros2/example_interfaces/COLCON_IGNORE')
volumes.extend(create_dir_mount(os.path.join(cur_dir, 'tmp'), docker_hoeme_dir + '/UE_tools/ros2_ws/src'))
elif repos:
volumes.append(os.path.join(os.environ['HOME'], repos) + ':' + docker_hoeme_dir + repos.replace(home, ''))
# mount config
for config_file in config_files:
id = str(uuid.uuid4())
target_path = docker_hoeme_dir + '/config_' + id + '.yaml'
volumes.append(os.path.abspath(config_file) + ':' + target_path)
command += ' --config ' + target_path
# update volume mode
for i, v in enumerate(volumes):
volumes[i] += ':rw'
# volumes.append('/etc/group:/etc/group:ro')
# volumes.append('/etc/passwd:/etc/passwd:ro')
# create containers
client = docker.from_env()
container_name = 'ue_ros2_base'
try: #if docker exists, remove
c = client.containers.get(container_name)
c.stop()
c.remove()
except:
pass
docker_image = args.docker_image
if not args.docker_image:
docker_image = DOCKER_IMAGE + ':' + args.rosdistro
print('Run docker conatiner named:' + container_name)
print(' image name:', docker_image)
# print(' mount volumes:', volumes)
container = client.containers.run(
docker_image,
'sleep infinity',
user=0, #os.getuid(),
environment={
"USER_ID":str(os.getuid()),
"GROUP_ID":str(os.getgid())
},
name=container_name,
volumes=volumes,
detach=True)
if os.getuid() != 1000:
print('Change dir owner to same id as current user')
exec_run_with_log(container, 'chown -R admin:admin /home/admin', user='root')
exec_run_with_log(container, 'chown -R admin:admin tmp', user='root')
if args.create_intermediate_image:
os.system('docker commit ' + container_name + ' ' + docker_image + '_chown')
print('Commit image after chown as ' + docker_image + '_chown')
if args.build and repos and args.pull_inside_docker:
pull_cmd = '/bin/bash -c "vcs import --repos --debug ' + \
docker_hoeme_dir + '/UE_tools/ros2_ws/src/pkgs' + ' < ' + \
docker_hoeme_dir + repos.replace(home, '') + '"'
print('Pull repo inside container with ' + pull_cmd)
exec_run_with_log(container, pull_cmd, user='admin')
# execute command
# command = "/bin/bash -c 'source .python3_venv/bin/activate && " + command + "'"
print('Execute command in conatainer: ' + command)
if args.rosdistro == 'jazzy': # todo: this works for humble and foxy as well?
os.system('docker exec -u admin -it ' + container_name + ' ' + command)
else:
exec_run_with_log(container, command, user='admin') # this does not work with jazzy somehow