blob: 47fbfc5e17e5f9fe3bf5bc68b0a7a965162ab8f2 [file] [log] [blame]
Ben Nemec9a973262019-08-12 20:10:49 +00001#!/usr/bin/env python3
2# Copyright 2016 Red Hat, Inc.
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may
5# not use this file except in compliance with the License. You may obtain
6# a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations
14# under the License.
15
16import socket
17import sys
18import os
19import os.path
20import json
21
22server_address = "/tmp/openstack.sock"
23
24sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
25
26try:
27 sock.connect(server_address)
28except socket.error as msg:
29 print(msg, file=sys.stderr)
30 sys.exit(1)
31
32
33def send(sock, doc):
34 jdoc = json.dumps(doc)
35 sock.send(b'%d\n' % len(jdoc))
36 sock.sendall(jdoc.encode('utf-8'))
37
38def recv(sock):
39 length_str = b''
40
41 char = sock.recv(1)
42 if len(char) == 0:
43 print("Unexpected end of file", file=sys.stderr)
44 sys.exit(1)
45
46 while char != b'\n':
47 length_str += char
48 char = sock.recv(1)
49 if len(char) == 0:
50 print("Unexpected end of file", file=sys.stderr)
51 sys.exit(1)
52
53 total = int(length_str)
54
55 # use a memoryview to receive the data chunk by chunk efficiently
56 jdoc = memoryview(bytearray(total))
57 next_offset = 0
58 while total - next_offset > 0:
59 recv_size = sock.recv_into(jdoc[next_offset:], total - next_offset)
60 next_offset += recv_size
61 try:
62 doc = json.loads(jdoc.tobytes())
63 except (TypeError, ValueError) as e:
64 raise Exception('Data received was not in JSON format')
65 return doc
66
67try:
68 env = {}
69 passenv = ["CINDER_VERSION",
70 "OS_AUTH_URL",
Ben Nemec9a973262019-08-12 20:10:49 +000071 "OS_NO_CACHE",
72 "OS_PASSWORD",
73 "OS_PROJECT_NAME",
74 "OS_REGION_NAME",
75 "OS_TENANT_NAME",
76 "OS_USERNAME",
77 "OS_VOLUME_API_VERSION",
78 "OS_CLOUD"]
79 for name in passenv:
80 if name in os.environ:
81 env[name] = os.environ[name]
82
83 cmd = {
84 "app": os.path.basename(sys.argv[0]),
85 "env": env,
86 "argv": sys.argv[1:]
87 }
88 try:
89 image_idx = sys.argv.index('image')
90 create_idx = sys.argv.index('create')
91 missing_file = image_idx < create_idx and \
92 not any(x.startswith('--file') for x in sys.argv)
93 except ValueError:
94 missing_file = False
95
96 if missing_file:
97 # This means we were called with an image create command, but were
98 # not provided a --file option. That likely means we're being passed
99 # the image data to stdin, which won't work because we do not proxy
100 # stdin to the server. So, we just reject the operation and ask the
101 # caller to provide the file with --file instead.
102 # We've already connected to the server, we need to send it some dummy
103 # data so it doesn't wait forever.
104 send(sock, {})
105 print('Image create without --file is not allowed in server mode',
106 file=sys.stderr)
107 sys.exit(1)
108 else:
109 send(sock, cmd)
110
111 doc = recv(sock)
112 if doc["stdout"] != b'':
113 print(doc["stdout"], end='')
114 if doc["stderr"] != b'':
115 print(doc["stderr"], file=sys.stderr)
116 sys.exit(doc["status"])
117finally:
118 sock.close()