public async Task <IActionResult> Customize([FromBody] RelayBuildRequest request, [FromServices] ICustomizer customizer) { RelayBuild newBuild = null; System.Action cleanupBuild = () => { if (newBuild != null) { try { context.RelayBuilds.Remove(newBuild); context.SaveChanges(); } catch (Exception) { } } }; try { newBuild = Convert(request); byte[] output; { context.RelayBuilds.Add(newBuild); context.SaveChanges(); } output = await customizer.CustomizeNodeRelay(newBuild); var buildName = String.IsNullOrEmpty(newBuild.Name) ? "" : $"_{newBuild.Name}"; return(File(output, "application/octet-stream", $"Relay_{newBuild.Arch.ToString().ToLower()}_{newBuild.BuildId:x}{buildName}.{newBuild.Type.ToString().ToLower()}")); } catch (TimeoutException e) { cleanupBuild(); return(StatusCode(StatusCodes.Status408RequestTimeout, e.Message)); } catch (CommandQueues.InvalidGateway e) { cleanupBuild(); return(StatusCode(StatusCodes.Status410Gone, $"Failed to add build, because {e.Message}. Try restarting gateway.")); } catch (Exception e) when(e is CustomizerError || e is GatewayResponseError) { cleanupBuild(); return(BadRequest(e.Message)); } catch (Exception e) { cleanupBuild(); return(StatusCode(StatusCodes.Status500InternalServerError, $"Unknown error. {e.Message}")); } }
/// <summary> /// Run customizer /// </summary> /// <param name="targetType">Target type (dll, exe, reflective)</param> /// <param name="architecture">Architecture (x64/x86)</param> /// <param name="commands">C3 Node relay API commands to run at startup</param> /// <returns>Customized C3 node relay binary</returns> public async Task <byte[]> CustomizeNodeRelay(RelayBuild build) { if (build is null) { throw new ArgumentNullException(nameof(build)); } var c3FileName = Path.Combine(PayloadTemplateDir, GetRelayFileName(build.Type, build.Arch)); var bin = File.ReadAllBytes(c3FileName); // FIXME support more then one startupCommand var newBuildResponse = Utils.Cast <GatewayResponses.NewBuild>(await commandQueue.GetResponse(build.ParentGatwayAgentId, new GatewayRequests.NewBuild(build), timeoutMilliseconds: 5000)); return(ApplyPatch(bin, CreatePatch(build.PublicKey, build.BroadcastKey, (uint)(build.BuildId), newBuildResponse.BinaryCommand))); }
public NewBuild(RelayBuild relayBuild) { BuildId = relayBuild.BuildId; Command = relayBuild.StartupCommands[0].ToObject <Command>().Data; Arch = relayBuild.Arch; }