-
Notifications
You must be signed in to change notification settings - Fork 444
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docker agent for api-agent #121 * support for node creation, start, stop, restart, deletion Signed-off-by: Dixing (Dex) Xu <dixingxu@gmail.com>
- Loading branch information
Showing
2 changed files
with
179 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
Flask | ||
flask-restful | ||
requests |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
import docker | ||
import base64 | ||
# import zipfile | ||
from flask import Flask | ||
from flask_restful import Resource, Api, reqparse | ||
# import json | ||
import sys | ||
import logger | ||
|
||
app = Flask(__name__) | ||
app.config['BUNDLE_ERRORS'] = True | ||
api = Api(app) | ||
res = {} | ||
|
||
parser = reqparse.RequestParser(bundle_errors=True) | ||
parser.add_argument('msp', default=None) | ||
parser.add_argument('tls', default=None) | ||
parser.add_argument('bootstrap_block', default=None) | ||
parser.add_argument('config_file', default=None) | ||
parser.add_argument('img', default='yeasy/hyperledger-fabric:2.2.0') | ||
parser.add_argument('config_file', default=None) | ||
parser.add_argument('cmd', default='/tmp/init.sh') | ||
parser.add_argument('name', default='cello-hlf-peer', help='tag name (role) to use, such as cello-hlf-peer or cello-hlf-orderer') | ||
|
||
|
||
class QueryNetwork(Resource): | ||
def get(self, network_id): | ||
client = docker.from_env() | ||
try: | ||
node = client.containers.get(network_id) | ||
res['code'] = 'OK' | ||
res['data'] = node.status | ||
except: | ||
res['code'] = 'Fail' | ||
res['msg'] = sys.exec_inf()[0] | ||
logger.debug(res) | ||
raise | ||
return res | ||
|
||
def get_port(container_id): | ||
c = docker.APIClient() | ||
res = c.inspect_container(container_id) | ||
# return res['Config']['ExposedPorts'] | ||
return res['NetworkSettings']['Ports'] | ||
|
||
|
||
class NodeCreation(Resource): | ||
def put(self): | ||
""" | ||
:param msp: all credentials under msp. | ||
:param tls: all credentials under tls. | ||
:param bootstrap-block: genesis block or latest config block of the system channel | ||
:param config-file: configuration file. | ||
:param img: container img to use, default: yeasy/hypereldger-fabric:2.2.0 | ||
:param cmd(optinal): command to run when starting the container. | ||
:param name_tag: 'cello-hlf-peer' or 'cello-hlf-orderer' depending on the role | ||
""" | ||
args = parser.parse_args() | ||
|
||
msp = args['msp'] | ||
tls = args['tls'] | ||
bootstrap_block = args['bootstrap_block'] | ||
config_file = args['config_file'] | ||
img = args['img'] | ||
cmd = args['cmd'] | ||
name_tag = args['name'] | ||
|
||
try: | ||
# same as `docker run -dit yeasy/hyperledge-fabric:2.2.0 -e VARIABLES`` | ||
container = client.containers.run(img, cmd, detach=True, tty=True, stdin_open=True, name=name_tag, environment={'msp': msp, 'tls': tls, 'bootstrap-block': bootstrap_block, 'config-file': config_file}) | ||
except: | ||
res['status'] = 'create node failed, please try again' | ||
res['msg'] = sys.exec_inf()[0] | ||
logger.debug(res) | ||
raise | ||
res['status'] = 'created' | ||
return res | ||
|
||
|
||
class NodeStart(Resource): | ||
def put(self): | ||
client = docker.from_env() | ||
container = client.containers.get(network_id) | ||
try: | ||
container.start() | ||
except: | ||
res['status'] = 'start node failed, please try again' | ||
res['msg'] = sys.exc_info()[0] | ||
logger.debug(res) | ||
raise | ||
res['status'] = 'started' | ||
return res | ||
|
||
class NodeRestart(Resource): | ||
def put(self): | ||
client = docker.from_env() | ||
container = client.containers.get(network_id) | ||
try: | ||
container.restart() | ||
except: | ||
res['status'] = 'restart node failed, please try again' | ||
res['msg'] = sys.exc_info()[0] | ||
logger.debug(res) | ||
raise | ||
res['status'] = 'restarted' | ||
return res | ||
|
||
class NodeStop(Resource): | ||
def put(self): | ||
client = docker.from_env() | ||
container = client.containers.get(network_id) | ||
try: | ||
container.stop() | ||
except: | ||
res['status'] = 'stop node failed, please try again' | ||
res['msg'] = sys.exc_info()[0] | ||
logger.debug(res) | ||
raise | ||
res['status'] = 'stopped' | ||
return res | ||
|
||
class NodeDeletion(Resource): | ||
|
||
def put(self): | ||
client = docker.from_env() | ||
container = client.containers.get(network_id) | ||
try: | ||
container.remove() | ||
except: | ||
res['status'] = 'delete node failed, please try again' | ||
res['msg'] = sys.exc_info()[0] | ||
logger.debug(res) | ||
raise | ||
res['status'] = 'deleted' | ||
return res | ||
|
||
api.add_resource(QueryNetwork, '/api/v1/query_network') | ||
api.add_resource(NodeCreation, '/api/v1/create_node') | ||
api.add_resource(NodeStart, '/api/v1/start_node') | ||
api.add_resource(NodeRestart, '/api/v1/restart_node') | ||
api.add_resource(NodeStop, '/api/v1/stop_node') | ||
api.add_resource(NodeDeletion, '/api/v1/delete_node') | ||
|
||
|
||
|
||
# @app.route('/start') | ||
# def start(): | ||
# client = docker.from_env() | ||
# con = client.containers.run('yeasy/hyperledger-fabric:2.2.0', detach=True, restart_policy={"Name": "always"}, tty=True, stdin_open=True) # same as `docker run -dit yeasy/hyperledge-fabric:2.2.0` | ||
# l = client.containers.list() | ||
# print(con.start()) | ||
# print(l) | ||
# return str(l) | ||
# | ||
# @app.route('/status/<id>') | ||
# def status(id): | ||
# client = docker.from_env() | ||
# con = client.containers.get(str(id)) | ||
# return con.status | ||
|
||
|
||
def test(): | ||
# client.images.pull('yeasy/hyperledger-fabric:2.2.0') | ||
with open('msp.zip', 'rb') as node_msp, open('tls.zip', 'rb') as tls, open('block.zip', 'rb') as block, open('peer_config.zip', 'rb') as peer_config, open('orderer_config.zip', 'rb') as orderer_config: | ||
|
||
env = { | ||
'HLF_NODE_MSP':base64.b64encode(node_msp.read()), | ||
'HLF_NODE_TLS':base64.b64encode(tls.read()), | ||
'HLF_NODE_BOOTSTRAP_BLOCK':base64.b64encode(block.read()), | ||
'HLF_NODE_PEER_CONFIG':base64.b64encode(peer_config.read()), | ||
'HLF_NODE_ORDERER_CONFIG':base64.b64encode(orderer_config.read()) | ||
} | ||
|
||
|
||
if __name__ == '__main__': | ||
app.run(port=5000, debug=True) |