Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support bundle upload #3356

Merged
merged 48 commits into from
Aug 6, 2020
Merged
Show file tree
Hide file tree
Changes from 45 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
896df10
Rename logs => module logs
lfitchett Feb 14, 2020
0aa8462
make handler classes
lfitchett Feb 14, 2020
53b737c
include new dm
lfitchett Feb 18, 2020
8365880
chkpnt
lfitchett Feb 19, 2020
2892b5b
start able to write to in memory
lfitchett Feb 20, 2020
816125c
fix types
lfitchett Feb 20, 2020
c10e625
output to console
lfitchett Feb 20, 2020
1ee21b6
fix flags
lfitchett Feb 21, 2020
bd1fcc5
start able to write to in memory
lfitchett Feb 20, 2020
cbe49dc
fix types
lfitchett Feb 20, 2020
7399a69
output to console
lfitchett Feb 20, 2020
11207e4
fix flags
lfitchett Feb 21, 2020
f95dbfa
re-enable tests
lfitchett Feb 21, 2020
b1d9e1c
import zip module and use display
lfitchett Feb 21, 2020
e3c1492
Merge branch 'support_bundle_console' into support-bundle_upload
lfitchett Feb 21, 2020
0f1ca43
use --output - for stdout
lfitchett Feb 21, 2020
c3bb918
call support bundle
lfitchett Feb 22, 2020
130bfec
parse params
lfitchett Feb 24, 2020
62d15b6
add new api version
lfitchett Feb 24, 2020
1000cf1
reuse http client
lfitchett Feb 24, 2020
796b513
flesh out request
lfitchett Feb 24, 2020
4f84daf
make logs uploader more generic
lfitchett Feb 24, 2020
f8d254c
Merge remote-tracking branch 'upstream/master' into support-bundle_up…
lfitchett Feb 24, 2020
fe5f5e9
fix merge issue
lfitchett Feb 24, 2020
d9c2281
Merge branch 'master' of https://github.com/Azure/iotedge into suppor…
lfitchett Jul 17, 2020
8a34d7f
Merge branch 'master' of https://github.com/Azure/iotedge into suppor…
lfitchett Jul 24, 2020
7fcc125
bring in api changes
lfitchett Jul 24, 2020
24fdfaf
fix version
lfitchett Jul 24, 2020
fbac54a
add get_result
lfitchett Jul 29, 2020
7980e66
move support bundle logic to own file
lfitchett Jul 30, 2020
9b25a70
remove s
lfitchett Jul 30, 2020
73204b6
collect bundle
lfitchett Jul 30, 2020
ceb81dc
wrap read in body
lfitchett Jul 30, 2020
ef7f3f8
return support bundle size
lfitchett Jul 30, 2020
13454c7
send full sb
lfitchett Aug 3, 2020
b56104e
fix fileResponse
lfitchett Aug 3, 2020
5038341
read params
lfitchett Aug 3, 2020
686cc1d
parse_since
lfitchett Aug 3, 2020
e9f1962
pass hostname
lfitchett Aug 3, 2020
bd38674
Merge branch 'master' of https://github.com/Azure/iotedge into suppor…
lfitchett Aug 4, 2020
a31f544
Merge branch 'master' of https://github.com/Azure/iotedge into suppor…
lfitchett Aug 4, 2020
71f9b91
clippy
lfitchett Aug 5, 2020
e0a6f7a
re-enable first test
lfitchett Aug 5, 2020
84bd7d0
add logs test back
lfitchett Aug 5, 2020
c1df8a8
rename ILogsUPloader file to IRequestsUploader
lfitchett Aug 5, 2020
fd7cdd9
remove unused IDisposable
lfitchett Aug 5, 2020
13260b9
get iothub hostname from edgeAgent
lfitchett Aug 5, 2020
4097263
Merge branch 'master' into support-bundle_upload
kodiakhq[bot] Aug 6, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright (c) Microsoft. All rights reserved.
namespace Microsoft.Azure.Devices.Edge.Agent.Core.Logs
{
using System;
using System.IO;
using System.Threading.Tasks;

public interface IRequestsUploader
{
Task UploadLogs(string uri, string module, byte[] payload, LogsContentEncoding logsContentEncoding, LogsContentType logsContentType);

Task<Func<ArraySegment<byte>, Task>> GetLogsUploaderCallback(string uri, string module, LogsContentEncoding logsContentEncoding, LogsContentType logsContentType);

Task UploadSupportBundle(string uri, Stream source);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ namespace Microsoft.Azure.Devices.Edge.Agent.Core.Requests
using Microsoft.Azure.Devices.Edge.Util.Json;
using Newtonsoft.Json;

public class LogsRequest
public class ModuleLogsRequest
{
public LogsRequest(
public ModuleLogsRequest(
string schemaVersion,
List<LogRequestItem> items,
LogsContentEncoding encoding,
Expand All @@ -23,7 +23,7 @@ public LogsRequest(
}

[JsonConstructor]
LogsRequest(
ModuleLogsRequest(
string schemaVersion,
List<LogRequestItem> items,
LogsContentEncoding? encoding,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace Microsoft.Azure.Devices.Edge.Agent.Core.Requests
using Microsoft.Azure.Devices.Edge.Util;
using Microsoft.Extensions.Logging;

public class LogsRequestHandler : RequestHandlerBase<LogsRequest, IEnumerable<LogsResponse>>
public class ModuleLogsRequestHandler : RequestHandlerBase<ModuleLogsRequest, IEnumerable<ModuleLogsResponse>>
{
const int MaxTailValue = 500;

Expand All @@ -20,17 +20,17 @@ public class LogsRequestHandler : RequestHandlerBase<LogsRequest, IEnumerable<Lo
readonly ILogsProvider logsProvider;
readonly IRuntimeInfoProvider runtimeInfoProvider;

public LogsRequestHandler(ILogsProvider logsProvider, IRuntimeInfoProvider runtimeInfoProvider)
public ModuleLogsRequestHandler(ILogsProvider logsProvider, IRuntimeInfoProvider runtimeInfoProvider)
{
this.logsProvider = Preconditions.CheckNotNull(logsProvider, nameof(logsProvider));
this.runtimeInfoProvider = Preconditions.CheckNotNull(runtimeInfoProvider, nameof(runtimeInfoProvider));
}

public override string RequestName => "GetLogs";

protected override async Task<Option<IEnumerable<LogsResponse>>> HandleRequestInternal(Option<LogsRequest> payloadOption, CancellationToken cancellationToken)
protected override async Task<Option<IEnumerable<ModuleLogsResponse>>> HandleRequestInternal(Option<ModuleLogsRequest> payloadOption, CancellationToken cancellationToken)
{
LogsRequest payload = payloadOption.Expect(() => new ArgumentException("Request payload not found"));
ModuleLogsRequest payload = payloadOption.Expect(() => new ArgumentException("Request payload not found"));
if (ExpectedSchemaVersion.CompareMajorVersion(payload.SchemaVersion, "logs upload request schema") != 0)
{
Events.MismatchedMinorVersions(payload.SchemaVersion, ExpectedSchemaVersion);
Expand All @@ -47,7 +47,7 @@ protected override async Task<Option<IEnumerable<LogsResponse>>> HandleRequestIn
false);

IList<(string id, ModuleLogOptions logOptions)> logOptionsList = await requestToOptionsMapper.MapToLogOptions(payload.Items, cancellationToken);
IEnumerable<Task<LogsResponse>> uploadLogsTasks = logOptionsList.Select(
IEnumerable<Task<ModuleLogsResponse>> uploadLogsTasks = logOptionsList.Select(
async l =>
{
Events.ReceivedLogOptions(l);
Expand All @@ -65,17 +65,17 @@ protected override async Task<Option<IEnumerable<LogsResponse>>> HandleRequestIn

Events.ReceivedModuleLogs(moduleLogs, l.id);
return logOptions.ContentEncoding == LogsContentEncoding.Gzip
? new LogsResponse(l.id, moduleLogs)
: new LogsResponse(l.id, moduleLogs.FromBytes());
? new ModuleLogsResponse(l.id, moduleLogs)
: new ModuleLogsResponse(l.id, moduleLogs.FromBytes());
});
IEnumerable<LogsResponse> response = await Task.WhenAll(uploadLogsTasks);
IEnumerable<ModuleLogsResponse> response = await Task.WhenAll(uploadLogsTasks);
return Option.Some(response);
}

static class Events
{
const int IdStart = AgentEventIds.LogsRequestHandler;
static readonly ILogger Log = Logger.Factory.CreateLogger<LogsRequestHandler>();
static readonly ILogger Log = Logger.Factory.CreateLogger<ModuleLogsRequestHandler>();

enum EventIds
{
Expand Down Expand Up @@ -107,7 +107,7 @@ public static void ReceivedLogOptions((string id, ModuleLogOptions logOptions) r
}
}

public static void ProcessingRequest(LogsRequest payload)
public static void ProcessingRequest(ModuleLogsRequest payload)
{
Log.LogInformation((int)EventIds.ProcessingRequest, $"Processing request to get logs for {payload.ToJson()}");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,20 @@ namespace Microsoft.Azure.Devices.Edge.Agent.Core.Requests
using Microsoft.Azure.Devices.Edge.Util.Json;
using Newtonsoft.Json;

public class LogsResponse
public class ModuleLogsResponse
{
public LogsResponse(string id, byte[] payloadBytes)
public ModuleLogsResponse(string id, byte[] payloadBytes)
: this(id, null, payloadBytes)
{
}

public LogsResponse(string id, string payload)
public ModuleLogsResponse(string id, string payload)
: this(id, payload, null)
{
}

[JsonConstructor]
LogsResponse(string id, string payload, byte[] payloadBytes)
ModuleLogsResponse(string id, string payload, byte[] payloadBytes)
{
this.Id = Preconditions.CheckNonWhiteSpace(id, nameof(id));
this.PayloadBytes = Option.Maybe(payloadBytes);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ namespace Microsoft.Azure.Devices.Edge.Agent.Core.Requests
using Microsoft.Azure.Devices.Edge.Util.Json;
using Newtonsoft.Json;

public class LogsUploadRequest
public class ModuleLogsUploadRequest
{
public LogsUploadRequest(
public ModuleLogsUploadRequest(
string schemaVersion,
List<LogRequestItem> items,
LogsContentEncoding encoding,
Expand All @@ -25,7 +25,7 @@ public LogsUploadRequest(
}

[JsonConstructor]
LogsUploadRequest(
ModuleLogsUploadRequest(
string schemaVersion,
List<LogRequestItem> items,
LogsContentEncoding? encoding,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,26 @@ namespace Microsoft.Azure.Devices.Edge.Agent.Core.Requests
using Microsoft.Azure.Devices.Edge.Util;
using Microsoft.Extensions.Logging;

public class LogsUploadRequestHandler : RequestHandlerBase<LogsUploadRequest, TaskStatusResponse>
public class ModuleLogsUploadRequestHandler : RequestHandlerBase<ModuleLogsUploadRequest, TaskStatusResponse>
{
static readonly Version ExpectedSchemaVersion = new Version("1.0");

readonly ILogsUploader logsUploader;
readonly IRequestsUploader requestsUploader;
readonly ILogsProvider logsProvider;
readonly IRuntimeInfoProvider runtimeInfoProvider;

public LogsUploadRequestHandler(ILogsUploader logsUploader, ILogsProvider logsProvider, IRuntimeInfoProvider runtimeInfoProvider)
public ModuleLogsUploadRequestHandler(IRequestsUploader requestsUploader, ILogsProvider logsProvider, IRuntimeInfoProvider runtimeInfoProvider)
{
this.logsProvider = Preconditions.CheckNotNull(logsProvider, nameof(logsProvider));
this.logsUploader = Preconditions.CheckNotNull(logsUploader, nameof(logsUploader));
this.requestsUploader = Preconditions.CheckNotNull(requestsUploader, nameof(requestsUploader));
this.runtimeInfoProvider = Preconditions.CheckNotNull(runtimeInfoProvider, nameof(runtimeInfoProvider));
}

public override string RequestName => "UploadLogs";
public override string RequestName => "UploadModuleLogs";

protected override async Task<Option<TaskStatusResponse>> HandleRequestInternal(Option<LogsUploadRequest> payloadOption, CancellationToken cancellationToken)
protected override async Task<Option<TaskStatusResponse>> HandleRequestInternal(Option<ModuleLogsUploadRequest> payloadOption, CancellationToken cancellationToken)
{
LogsUploadRequest payload = payloadOption.Expect(() => new ArgumentException("Request payload not found"));
ModuleLogsUploadRequest payload = payloadOption.Expect(() => new ArgumentException("Request payload not found"));
if (ExpectedSchemaVersion.CompareMajorVersion(payload.SchemaVersion, "logs upload request schema") != 0)
{
Events.MismatchedMinorVersions(payload.SchemaVersion, ExpectedSchemaVersion);
Expand Down Expand Up @@ -69,11 +69,11 @@ async Task UploadLogs(string sasUrl, string id, ModuleLogOptions moduleLogOption
if (moduleLogOptions.ContentType == LogsContentType.Json)
{
byte[] logBytes = await this.logsProvider.GetLogs(id, moduleLogOptions, token);
await this.logsUploader.Upload(sasUrl, id, logBytes, moduleLogOptions.ContentEncoding, moduleLogOptions.ContentType);
await this.requestsUploader.UploadLogs(sasUrl, id, logBytes, moduleLogOptions.ContentEncoding, moduleLogOptions.ContentType);
}
else if (moduleLogOptions.ContentType == LogsContentType.Text)
{
Func<ArraySegment<byte>, Task> uploaderCallback = await this.logsUploader.GetUploaderCallback(sasUrl, id, moduleLogOptions.ContentEncoding, moduleLogOptions.ContentType);
Func<ArraySegment<byte>, Task> uploaderCallback = await this.requestsUploader.GetLogsUploaderCallback(sasUrl, id, moduleLogOptions.ContentEncoding, moduleLogOptions.ContentType);
await this.logsProvider.GetLogsStream(id, moduleLogOptions, uploaderCallback, token);
}

Expand All @@ -83,7 +83,7 @@ async Task UploadLogs(string sasUrl, string id, ModuleLogOptions moduleLogOption
static class Events
{
const int IdStart = AgentEventIds.LogsUploadRequestHandler;
static readonly ILogger Log = Logger.Factory.CreateLogger<LogsUploadRequestHandler>();
static readonly ILogger Log = Logger.Factory.CreateLogger<ModuleLogsUploadRequestHandler>();

enum EventIds
{
Expand All @@ -98,7 +98,7 @@ public static void MismatchedMinorVersions(string payloadSchemaVersion, Version
Log.LogWarning((int)EventIds.MismatchedMinorVersions, $"Logs upload request schema version {payloadSchemaVersion} does not match expected schema version {expectedSchemaVersion}. Some settings may not be supported.");
}

public static void ProcessingRequest(LogsUploadRequest payload)
public static void ProcessingRequest(ModuleLogsUploadRequest payload)
{
Log.LogInformation((int)EventIds.ProcessingRequest, $"Processing request to upload logs for {payload.ToJson()}");
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright (c) Microsoft. All rights reserved.

namespace Microsoft.Azure.Devices.Edge.Agent.Core.Requests
{
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Azure.Devices.Edge.Util;
using Newtonsoft.Json;

public class SupportBundleRequest
{
public SupportBundleRequest(string schemaVersion, string sasUrl, string since, string iothubHostname, bool? edgeRuntimeOnly)
{
this.SchemaVersion = Preconditions.CheckNonWhiteSpace(schemaVersion, nameof(schemaVersion));
this.SasUrl = Preconditions.CheckNotNull(sasUrl, nameof(sasUrl));
this.Since = Option.Maybe(since);
this.IothubHostname = Option.Maybe(iothubHostname);
this.EdgeRuntimeOnly = Option.Maybe(edgeRuntimeOnly);
}

[JsonProperty("schemaVersion")]
public string SchemaVersion { get; }

[JsonIgnore]
public string SasUrl { get; }

[JsonProperty("since")]
public Option<string> Since { get; }

[JsonProperty("iothubHostname")]
public Option<string> IothubHostname { get; }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is this used?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iotedge check has it as an option, so the support bundle does too

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if a user specifies a different IoTHub?
I think this parameter definitely seems odd - I would say remove it and use the IOTHub that EdgeAgent is using.
@veyalla ?

Copy link
Contributor

@veyalla veyalla Aug 5, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using IoT Hub that edge agent is using would actually be an improvement over running support-bundle locally because currently we cannot run any connectivity tests when using DPS because we can't get the iot hub name from config yaml. The recommendation for DPS-provisioned devices is to use the command line parameter to explicitly specify iot hub name which is behavior the direct method is implementing.

However, it would cause inconsistent behavior for the same command when run locally vs remotely which is weird. There was some thoughts from @arsing around getting the iot hub name from a cached provisioning result when run locally on a DPS provisioned device. If that can be implemented we could have a consistent experience.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

provisioning_backup.json has the hub name, so iotedge check / support-bundle could read it from there.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(If you do make that change, you'll probably want to keep the --iothub-hostname parameter to check / support-bundle so that passing it is not an error, such as when running old EA with new host package.)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO, we should make the change Arnav is suggesting, it will improve troubleshooting experience for customers running check / support-bundle locally and also provide consistency when running it locally or remotely. Thoughts @CindyXing ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, wherever we can infer the IoThub, we should I can't think of a scenario where support bundle or iotedge check would need to talk to a different IoTHub.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So for this pr, I'll remove the iothubHostname param, and just fill it in from ea's known hostname


[JsonProperty("edgeRuntimeOnly")]
public Option<bool> EdgeRuntimeOnly { get; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright (c) Microsoft. All rights reserved.

namespace Microsoft.Azure.Devices.Edge.Agent.Core.Requests
{
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Azure.Devices.Edge.Agent.Core.Logs;
using Microsoft.Azure.Devices.Edge.Util;

public class SupportBundleRequestHandler : RequestHandlerBase<SupportBundleRequest, TaskStatusResponse>
{
public delegate Task<Stream> GetSupportBundle(Option<string> since, Option<string> iothubHostname, Option<bool> edgeRuntimeOnly, CancellationToken token);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of a delegate seems like an Interface might be cleaner?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure which interface I would use, but a delegate seemed like an clean way to pass a single function in. I've used this pattern before in the code base.


readonly GetSupportBundle getSupportBundle;
readonly IRequestsUploader requestsUploader;

public SupportBundleRequestHandler(GetSupportBundle getSupportBundle, IRequestsUploader requestsUploader)
{
this.getSupportBundle = getSupportBundle;
this.requestsUploader = requestsUploader;
}

public override string RequestName => "UploadSupportBundle";

protected override Task<Option<TaskStatusResponse>> HandleRequestInternal(Option<SupportBundleRequest> payloadOption, CancellationToken cancellationToken)
{
SupportBundleRequest payload = payloadOption.Expect(() => new ArgumentException("Request payload not found"));

(string correlationId, BackgroundTaskStatus status) = BackgroundTask.Run(
async () =>
{
Stream source = await this.getSupportBundle(payload.Since, payload.IothubHostname, payload.EdgeRuntimeOnly, cancellationToken);
await this.requestsUploader.UploadSupportBundle(payload.SasUrl, source);
},
"upload support bundle",
cancellationToken);

return Task.FromResult(Option.Some(TaskStatusResponse.Create(correlationId, status)));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,7 @@ public interface IModuleManager
Task PrepareUpdateAsync(ModuleSpec moduleSpec);

Task<Stream> GetModuleLogs(string name, bool follow, Option<int> tail, Option<string> since, CancellationToken cancellationToken);

Task<Stream> GetSupportBundle(Option<string> since, Option<string> iothubHostname, Option<bool> edgeRuntimeOnly, CancellationToken token);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace Microsoft.Azure.Devices.Edge.Agent.Edgelet
using Microsoft.Azure.Devices.Edge.Util;
using Microsoft.Azure.Devices.Edge.Util.Edged;

public class ModuleManagementHttpClient : IModuleManager, IIdentityManager, IDeviceManager
public class ModuleManagementHttpClient : IModuleManager, IIdentityManager, IDeviceManager, IDisposable
lfitchett marked this conversation as resolved.
Show resolved Hide resolved
{
readonly ModuleManagementHttpClientVersioned inner;

Expand Down Expand Up @@ -60,9 +60,13 @@ public ModuleManagementHttpClient(Uri managementUri, string serverSupportedApiVe
public Task<Stream> GetModuleLogs(string name, bool follow, Option<int> tail, Option<string> since, CancellationToken cancellationToken) =>
this.inner.GetModuleLogs(name, follow, tail, since, cancellationToken);

public Task<Stream> GetSupportBundle(Option<string> since, Option<string> iothubHostname, Option<bool> edgeRuntimeOnly, CancellationToken token) =>
this.inner.GetSupportBundle(since, iothubHostname, edgeRuntimeOnly, token);

internal static ModuleManagementHttpClientVersioned GetVersionedModuleManagement(Uri managementUri, string serverSupportedApiVersion, string clientSupportedApiVersion)
{
ApiVersion supportedVersion = GetSupportedVersion(serverSupportedApiVersion, clientSupportedApiVersion);

if (supportedVersion == ApiVersion.Version20180628)
{
return new Version_2018_06_28.ModuleManagementHttpClient(managementUri);
Expand Down Expand Up @@ -108,5 +112,10 @@ static ApiVersion GetSupportedVersion(string serverSupportedApiVersion, string c

return serverVersion.Value < clientVersion.Value ? serverVersion : clientVersion;
}

public void Dispose()
{
this.inner.Dispose();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,8 @@ public Task<Stream> GetModuleLogs(string module, bool follow, Option<int> tail,
this.moduleManager.GetModuleLogs(module, follow, tail, since, cancellationToken);

public Task<SystemInfo> GetSystemInfo(CancellationToken token) => this.moduleManager.GetSystemInfoAsync(token);

public Task<Stream> GetSupportBundle(Option<string> since, Option<string> iothubHostname, Option<bool> edgeRuntimeOnly, CancellationToken token) =>
this.moduleManager.GetSupportBundle(since, iothubHostname, edgeRuntimeOnly, token);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,11 @@ public override Task<SystemResources> GetSystemResourcesAsync()
return Task.FromResult<SystemResources>(null);
}

public override Task<System.IO.Stream> GetSupportBundle(Option<string> since, Option<string> iothubHostname, Option<bool> edgeRuntimeOnly, CancellationToken token)
{
return Task.FromResult(System.IO.Stream.Null);
}

protected override void HandleException(Exception exception, string operation)
{
switch (exception)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,11 @@ public override Task<SystemResources> GetSystemResourcesAsync()
return Task.FromResult<SystemResources>(null);
}

public override Task<System.IO.Stream> GetSupportBundle(Option<string> since, Option<string> iothubHostname, Option<bool> edgeRuntimeOnly, CancellationToken token)
{
return Task.FromResult(System.IO.Stream.Null);
}

protected override void HandleException(Exception exception, string operation)
{
switch (exception)
Expand Down
Loading