def process_shutitfile(shutit, shutitfile_contents): # Wipe the command as we expect one in the file. shutitfile_representation = {'shutitfile': {}} shutitfile_representation['shutitfile']['cmd'] = '' shutitfile_representation['shutitfile']['maintainer'] = '' shutitfile_representation['shutitfile']['description'] = '' shutitfile_representation['shutitfile']['module_id'] = '' shutitfile_representation['shutitfile']['script'] = [] shutitfile_representation['shutitfile']['config'] = [] shutitfile_representation['shutitfile']['onbuild'] = [] shutitfile_representation['shutitfile']['volume'] = [] shutitfile_representation['shutitfile']['expose'] = [] shutitfile_representation['shutitfile']['entrypoint'] = [] shutitfile_representation['shutitfile']['env'] = [] shutitfile_representation['shutitfile']['depends'] = [] shutitfile_representation['shutitfile']['delivery'] = [] shutitfile_representation['shutitfile']['base_image'] = [] # Whether to build this module by default (defaults to 'yes/true' shutitfile_representation['shutitfile']['default_include'] = 'true' shutitfile_list, ok = shutitfile.parse_shutitfile(shutitfile_contents) if not ok: # pragma: no cover return [], False # Set defaults from given shutitfile last_shutitfile_command = '' shutitfile_state = 'NONE' inline_script = '' for item in shutitfile_list: # These items are not order-dependent and don't affect the build, so we collect them here: shutitfile_command = item[0].upper() # List of handled shutitfile_commands if shutitfile_state != 'SCRIPT_DURING': assert shutitfile_command in ('SCRIPT_END','SCRIPT_BEGIN','SCRIPT_END','FROM','ONBUILD','VOLUME','DESCRIPTION','MAINTAINER','EXPOSE','ENTRYPOINT','CMD','USER','LOGIN','LOGOUT','GET_PASSWORD','ENV','RUN','SEND','ASSERT_OUTPUT','PAUSE_POINT','EXPECT','EXPECT_MULTI','EXPECT_REACT','UNTIL','ADD','COPY','WORKDIR','COMMENT','NOTE','INSTALL','REMOVE','DEPENDS','DELIVERY','MODULE_ID','REPLACE_LINE','START_BEGIN','START_END','STOP_BEGIN','STOP_END','TEST_BEGIN','TEST_END','BUILD_BEGIN','BUILD_END','ISINSTALLED_BEGIN','ISINSTALLED_END','IF','IF_NOT','ELIF_NOT','ELIF','ELSE','ENDIF','COMMIT','PUSH','DEFAULT_INCLUDE','LOG','CONFIG','CONFIG_SECRET','QUIT','STORE_RUN','VAGRANT_LOGIN','VAGRANT_LOGOUT'), '%r is not a handled ShutItFile command' % shutitfile_command if shutitfile_command != 'SCRIPT_END' and shutitfile_state == 'SCRIPT_DURING': inline_script += '\n' + ' '.join(item) elif shutitfile_command == 'SCRIPT_BEGIN': shutitfile_state = 'SCRIPT_DURING' elif shutitfile_command == 'SCRIPT_END': shutitfile_representation['shutitfile']['script'].append(['RUN_SCRIPT', inline_script]) shutitfile_state = 'NONE' inline_script = '' elif shutitfile_command == 'FROM': if shutitfile_representation['shutitfile']['base_image'] == []: shutitfile_representation['shutitfile']['base_image'] = item[1] shutit.shutitfile['base_image'] = item[1] else: print('Ignoring FROM line as this it has already been set.') # pragma: no cover elif shutitfile_command == 'ONBUILD': # TESTED? NO # Maps to finalize :) - can we have more than one of these? assume yes # This contains within it one of the above commands, so we need to abstract this out. shutitfile_representation['shutitfile']['onbuild'].append(item[1]) elif shutitfile_command == 'MAINTAINER': shutitfile_representation['shutitfile']['maintainer'] = item[1] elif shutitfile_command == 'DESCRIPTION': shutitfile_representation['shutitfile']['description'] = item[1] elif shutitfile_command == 'VOLUME': # TESTED? NO # Put in the run.sh. try: shutitfile_representation['shutitfile']['volume'].append(' '.join(json.loads(item[1]))) except Exception: shutitfile_representation['shutitfile']['volume'].append(item[1]) elif shutitfile_command == 'EXPOSE': # TESTED? NO # Put in the run.sh. shutitfile_representation['shutitfile']['expose'].append(item[1]) elif shutitfile_command == 'ENTRYPOINT': # TESTED? NO # Put in the run.sh? Yes, if it exists it goes at the front of cmd try: shutitfile_representation['shutitfile']['entrypoint'] = ' '.join(json.loads(item[1])) except Exception: shutitfile_representation['shutitfile']['entrypoint'] = item[1] elif shutitfile_command == 'CMD': # TESTED? NO # Put in the run.sh try: shutitfile_representation['shutitfile']['cmd'] = ' '.join(json.loads(item[1])) except Exception: shutitfile_representation['shutitfile']['cmd'] = item[1] # Other items to be run through sequentially (as they are part of the script) elif shutitfile_command == 'GET_PASSWORD': # If we are directed to get the password, change the previous directive internally. if last_shutitfile_command not in ('LOGIN','USER'): shutit.fail('GET_PASSWORD line not after a USER or LOGIN line: ' + shutitfile_command + ' ' + item[1]) # pragma: no cover if last_shutitfile_command in ('LOGIN','USER'): if last_shutitfile_command == 'LOGIN': shutitfile_representation['shutitfile']['script'][-1][0] = 'LOGIN_WITH_PASSWORD' elif last_shutitfile_command == 'USER': shutitfile_representation['shutitfile']['script'][-1][0] = 'USER_WITH_PASSWORD' shutitfile_representation['shutitfile']['script'][-1].append(item[1]) elif shutitfile_command == 'ENV': # Put in the run.sh. shutitfile_representation['shutitfile']['script'].append([shutitfile_command, item[1]]) # Set in the build shutitfile_representation['shutitfile']['env'].append(item[1]) elif shutitfile_command in ('RUN','SEND'): # Only handle simple commands for now and ignore the fact that shutitfiles run with /bin/sh -c rather than bash. try: shutitfile_representation['shutitfile']['script'].append([shutitfile_command, ' '.join(json.loads(item[1]))]) except Exception: shutitfile_representation['shutitfile']['script'].append([shutitfile_command, item[1]]) elif shutitfile_command == 'ASSERT_OUTPUT': if last_shutitfile_command not in ('RUN','SEND'): shutit.fail('ASSERT_OUTPUT line not after a RUN/SEND line: ' + shutitfile_command + ' ' + item[1]) # pragma: no cover shutitfile_representation['shutitfile']['script'][-1][0] = 'ASSERT_OUTPUT_SEND' shutitfile_representation['shutitfile']['script'].append([shutitfile_command, item[1]]) elif shutitfile_command == 'EXPECT': if last_shutitfile_command not in ('RUN','SEND','GET_PASSWORD'): shutit.fail('EXPECT line not after a RUN, SEND or GET_PASSWORD line: ' + shutitfile_command + ' ' + item[1]) # pragma: no cover shutitfile_representation['shutitfile']['script'][-1][0] = 'SEND_EXPECT' shutitfile_representation['shutitfile']['script'].append([shutitfile_command, item[1]]) elif shutitfile_command == 'EXPECT_MULTI': if last_shutitfile_command not in ('RUN','SEND','GET_PASSWORD'): shutit.fail('EXPECT_MULTI line not after a RUN, SEND or GET_PASSWORD line: ' + shutitfile_command + ' ' + item[1]) # pragma: no cover shutitfile_representation['shutitfile']['script'][-1][0] = 'SEND_EXPECT_MULTI' shutitfile_representation['shutitfile']['script'].append([shutitfile_command, item[1]]) elif shutitfile_command == 'EXPECT_REACT': if last_shutitfile_command not in ('RUN','SEND','GET_PASSWORD'): shutit.fail('EXPECT_REACT line not after a RUN, SEND or GET_PASSWORD line: ' + shutitfile_command + ' ' + item[1]) # pragma: no cover shutitfile_representation['shutitfile']['script'][-1][0] = 'SEND_EXPECT_REACT' shutitfile_representation['shutitfile']['script'].append([shutitfile_command, item[1]]) elif shutitfile_command == 'UNTIL': if last_shutitfile_command not in ('RUN','SEND'): shutit.fail('UNTIL line not after a RUN, SEND: ' + shutitfile_command + ' ' + item[1]) # pragma: no cover shutitfile_representation['shutitfile']['script'][-1][0] = 'SEND_UNTIL' shutitfile_representation['shutitfile']['script'].append([shutitfile_command, item[1]]) elif shutitfile_command == 'DEPENDS': shutitfile_representation['shutitfile']['depends'].append([shutitfile_command, item[1]]) elif shutitfile_command == 'DELIVERY': shutitfile_representation['shutitfile']['delivery'].append([shutitfile_command, item[1]]) elif shutitfile_command == 'MODULE_ID': # Only one item allowed. shutitfile_representation['shutitfile']['module_id'] = item[1] elif shutitfile_command == 'DEFAULT_INCLUDE': shutitfile_representation['shutitfile']['default_include'] = item[1] elif shutitfile_command == 'CONFIG': shutitfile_representation['shutitfile']['config'].append([shutitfile_command, item[1]]) elif shutitfile_command == 'CONFIG_SECRET': shutitfile_representation['shutitfile']['config'].append([shutitfile_command, item[1]]) elif shutitfile_command in ('ADD','COPY','WORKDIR','COMMENT','INSTALL','REMOVE','REPLACE_LINE','LOG','COMMIT','PUSH','QUIT','PAUSE_POINT','USER','LOGIN','LOGOUT','VAGRANT_LOGIN','VAGRANT_LOGOUT'): shutitfile_representation['shutitfile']['script'].append([shutitfile_command, item[1]]) elif shutitfile_command in ('IF','IF_NOT','ELIF_NOT','ELIF','STORE_RUN'): # Parser retrieved two items here shutitfile_representation['shutitfile']['script'].append([shutitfile_command, item[1], item[2]]) elif shutitfile_command in ('ELSE','ENDIF','START_BEGIN','START_END','STOP_BEGIN','STOP_END','TEST_BEGIN','TEST_END','BUILD_BEGIN','BUILD_END','ISINSTALLED_BEGIN','ISINSTALLED_END'): shutitfile_representation['shutitfile']['script'].append([shutitfile_command]) else: shutit.fail('shutitfile command: ' + shutitfile_command + ' not processed') # pragma: no cover last_shutitfile_command = shutitfile_command return shutitfile_representation, True
def process_shutitfile(shutit, shutitfile_contents): # Wipe the command as we expect one in the file. shutitfile_representation = {'shutitfile': {}} shutitfile_representation['shutitfile']['cmd'] = '' shutitfile_representation['shutitfile']['maintainer'] = '' shutitfile_representation['shutitfile']['description'] = '' shutitfile_representation['shutitfile']['module_id'] = '' shutitfile_representation['shutitfile']['script'] = [] shutitfile_representation['shutitfile']['config'] = [] shutitfile_representation['shutitfile']['onbuild'] = [] shutitfile_representation['shutitfile']['volume'] = [] shutitfile_representation['shutitfile']['expose'] = [] shutitfile_representation['shutitfile']['entrypoint'] = [] shutitfile_representation['shutitfile']['env'] = [] shutitfile_representation['shutitfile']['depends'] = [] shutitfile_representation['shutitfile']['delivery'] = [] shutitfile_representation['shutitfile']['base_image'] = [] # Whether to build this module by default (defaults to 'yes/true' shutitfile_representation['shutitfile']['default_include'] = 'true' shutitfile_list, ok = shutitfile.parse_shutitfile(shutitfile_contents) if not ok: # pragma: no cover return [], False # Set defaults from given shutitfile last_shutitfile_command = '' shutitfile_state = 'NONE' inline_script = '' for item in shutitfile_list: # These items are not order-dependent and don't affect the build, so we collect them here: shutitfile_command = item[0].upper() # List of handled shutitfile_commands if shutitfile_state != 'SCRIPT_DURING': assert shutitfile_command in ('SCRIPT_END','SCRIPT_BEGIN','SCRIPT_END','FROM','ONBUILD','VOLUME','DESCRIPTION','MAINTAINER','EXPOSE','ENTRYPOINT','CMD','USER','LOGIN','LOGOUT','GET_PASSWORD','ENV','RUN','SEND','ASSERT_OUTPUT','PAUSE_POINT','EXPECT','EXPECT_MULTI','EXPECT_REACT','UNTIL','ADD','COPY','WORKDIR','COMMENT','NOTE','INSTALL','REMOVE','DEPENDS','DELIVERY','MODULE_ID','REPLACE_LINE','ENSURE_LINE','START_BEGIN','START_END','STOP_BEGIN','STOP_END','TEST_BEGIN','TEST_END','BUILD_BEGIN','BUILD_END','ISINSTALLED_BEGIN','ISINSTALLED_END','IF','IF_NOT','ELIF_NOT','ELIF','ELSE','ENDIF','COMMIT','PUSH','DEFAULT_INCLUDE','LOG','CONFIG','CONFIG_SECRET','QUIT','STORE_RUN','VAGRANT_LOGIN','VAGRANT_LOGOUT'), shutit_util.print_debug(msg='%r is not a handled ShutItFile command' % shutitfile_command) if shutitfile_command != 'SCRIPT_END' and shutitfile_state == 'SCRIPT_DURING': inline_script += '\n' + ' '.join(item) elif shutitfile_command == 'SCRIPT_BEGIN': shutitfile_state = 'SCRIPT_DURING' elif shutitfile_command == 'SCRIPT_END': shutitfile_representation['shutitfile']['script'].append(['RUN_SCRIPT', inline_script]) shutitfile_state = 'NONE' inline_script = '' elif shutitfile_command == 'FROM': if shutitfile_representation['shutitfile']['base_image'] == []: shutitfile_representation['shutitfile']['base_image'] = item[1] shutit.shutitfile['base_image'] = item[1] else: shutit_global.shutit_global_object.shutit_print('Ignoring FROM line as this it has already been set.') # pragma: no cover elif shutitfile_command == 'ONBUILD': # TESTED? NO # Maps to finalize :) - can we have more than one of these? assume yes # This contains within it one of the above commands, so we need to abstract this out. shutitfile_representation['shutitfile']['onbuild'].append(item[1]) elif shutitfile_command == 'MAINTAINER': shutitfile_representation['shutitfile']['maintainer'] = item[1] elif shutitfile_command == 'DESCRIPTION': shutitfile_representation['shutitfile']['description'] = item[1] elif shutitfile_command == 'VOLUME': # TESTED? NO # Put in the run.sh. try: shutitfile_representation['shutitfile']['volume'].append(' '.join(json.loads(item[1]))) except Exception: shutitfile_representation['shutitfile']['volume'].append(item[1]) elif shutitfile_command == 'EXPOSE': # TESTED? NO # Put in the run.sh. shutitfile_representation['shutitfile']['expose'].append(item[1]) elif shutitfile_command == 'ENTRYPOINT': # TESTED? NO # Put in the run.sh? Yes, if it exists it goes at the front of cmd try: shutitfile_representation['shutitfile']['entrypoint'] = ' '.join(json.loads(item[1])) except Exception: shutitfile_representation['shutitfile']['entrypoint'] = item[1] elif shutitfile_command == 'CMD': # TESTED? NO # Put in the run.sh try: shutitfile_representation['shutitfile']['cmd'] = ' '.join(json.loads(item[1])) except Exception: shutitfile_representation['shutitfile']['cmd'] = item[1] # Other items to be run through sequentially (as they are part of the script) elif shutitfile_command == 'GET_PASSWORD': # If we are directed to get the password, change the previous directive internally. if last_shutitfile_command not in ('LOGIN','USER'): shutit.fail('GET_PASSWORD line not after a USER or LOGIN line: ' + shutitfile_command + ' ' + item[1]) # pragma: no cover if last_shutitfile_command in ('LOGIN','USER'): if last_shutitfile_command == 'LOGIN': shutitfile_representation['shutitfile']['script'][-1][0] = 'LOGIN_WITH_PASSWORD' elif last_shutitfile_command == 'USER': shutitfile_representation['shutitfile']['script'][-1][0] = 'USER_WITH_PASSWORD' shutitfile_representation['shutitfile']['script'][-1].append(item[1]) elif shutitfile_command == 'ENV': # Put in the run.sh. shutitfile_representation['shutitfile']['script'].append([shutitfile_command, item[1]]) # Set in the build shutitfile_representation['shutitfile']['env'].append(item[1]) elif shutitfile_command in ('RUN','SEND'): # Only handle simple commands for now and ignore the fact that shutitfiles run with /bin/sh -c rather than bash. try: shutitfile_representation['shutitfile']['script'].append([shutitfile_command, ' '.join(json.loads(item[1]))]) except Exception: shutitfile_representation['shutitfile']['script'].append([shutitfile_command, item[1]]) elif shutitfile_command == 'ASSERT_OUTPUT': if last_shutitfile_command not in ('RUN','SEND'): shutit.fail('ASSERT_OUTPUT line not after a RUN/SEND line: ' + shutitfile_command + ' ' + item[1]) # pragma: no cover shutitfile_representation['shutitfile']['script'][-1][0] = 'ASSERT_OUTPUT_SEND' shutitfile_representation['shutitfile']['script'].append([shutitfile_command, item[1]]) elif shutitfile_command == 'EXPECT': if last_shutitfile_command not in ('RUN','SEND','GET_PASSWORD'): shutit.fail('EXPECT line not after a RUN, SEND or GET_PASSWORD line: ' + shutitfile_command + ' ' + item[1]) # pragma: no cover shutitfile_representation['shutitfile']['script'][-1][0] = 'SEND_EXPECT' shutitfile_representation['shutitfile']['script'].append([shutitfile_command, item[1]]) elif shutitfile_command == 'EXPECT_MULTI': if last_shutitfile_command not in ('RUN','SEND','GET_PASSWORD'): shutit.fail('EXPECT_MULTI line not after a RUN, SEND or GET_PASSWORD line: ' + shutitfile_command + ' ' + item[1]) # pragma: no cover shutitfile_representation['shutitfile']['script'][-1][0] = 'SEND_EXPECT_MULTI' shutitfile_representation['shutitfile']['script'].append([shutitfile_command, item[1]]) elif shutitfile_command == 'EXPECT_REACT': if last_shutitfile_command not in ('RUN','SEND','GET_PASSWORD'): shutit.fail('EXPECT_REACT line not after a RUN, SEND or GET_PASSWORD line: ' + shutitfile_command + ' ' + item[1]) # pragma: no cover shutitfile_representation['shutitfile']['script'][-1][0] = 'SEND_EXPECT_REACT' shutitfile_representation['shutitfile']['script'].append([shutitfile_command, item[1]]) elif shutitfile_command == 'UNTIL': if last_shutitfile_command not in ('RUN','SEND'): shutit.fail('UNTIL line not after a RUN, SEND: ' + shutitfile_command + ' ' + item[1]) # pragma: no cover shutitfile_representation['shutitfile']['script'][-1][0] = 'SEND_UNTIL' shutitfile_representation['shutitfile']['script'].append([shutitfile_command, item[1]]) elif shutitfile_command == 'DEPENDS': shutitfile_representation['shutitfile']['depends'].append([shutitfile_command, item[1]]) elif shutitfile_command == 'DELIVERY': shutitfile_representation['shutitfile']['delivery'].append([shutitfile_command, item[1]]) elif shutitfile_command == 'MODULE_ID': # Only one item allowed. shutitfile_representation['shutitfile']['module_id'] = item[1] elif shutitfile_command == 'DEFAULT_INCLUDE': shutitfile_representation['shutitfile']['default_include'] = item[1] elif shutitfile_command == 'CONFIG': shutitfile_representation['shutitfile']['config'].append([shutitfile_command, item[1]]) elif shutitfile_command == 'CONFIG_SECRET': shutitfile_representation['shutitfile']['config'].append([shutitfile_command, item[1]]) elif shutitfile_command in ('ADD','COPY','WORKDIR','COMMENT','INSTALL','REMOVE','REPLACE_LINE','ENSURE_LINE','LOG','COMMIT','PUSH','QUIT','PAUSE_POINT','USER','LOGIN','LOGOUT','VAGRANT_LOGIN','VAGRANT_LOGOUT'): shutitfile_representation['shutitfile']['script'].append([shutitfile_command, item[1]]) elif shutitfile_command in ('IF','IF_NOT','ELIF_NOT','ELIF','STORE_RUN'): # Parser retrieved two items here shutitfile_representation['shutitfile']['script'].append([shutitfile_command, item[1], item[2]]) elif shutitfile_command in ('ELSE','ENDIF','START_BEGIN','START_END','STOP_BEGIN','STOP_END','TEST_BEGIN','TEST_END','BUILD_BEGIN','BUILD_END','ISINSTALLED_BEGIN','ISINSTALLED_END'): shutitfile_representation['shutitfile']['script'].append([shutitfile_command]) else: shutit.fail('shutitfile command: ' + shutitfile_command + ' not processed') # pragma: no cover last_shutitfile_command = shutitfile_command return shutitfile_representation, True