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

Single-File: Process bundles in the framework #34274

Merged
merged 18 commits into from
Apr 8, 2020
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
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
19 changes: 2 additions & 17 deletions src/installer/corehost/cli/apphost/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,11 @@ endif()
set(SKIP_VERSIONING 1)

set(SOURCES
./bundle/file_entry.cpp
./bundle/manifest.cpp
./bundle/header.cpp
./bundle/marker.cpp
./bundle/reader.cpp
./bundle/extractor.cpp
./bundle/runner.cpp
./bundle/dir_utils.cpp
./bundle_marker.cpp
)

set(HEADERS
./bundle/file_type.h
./bundle/file_entry.h
./bundle/manifest.h
./bundle/header.h
./bundle/marker.h
./bundle/reader.h
./bundle/extractor.h
./bundle/runner.h
./bundle/dir_utils.h
./bundle_marker.h
)

if(CLR_CMAKE_TARGET_WIN32)
Expand Down
65 changes: 0 additions & 65 deletions src/installer/corehost/cli/apphost/bundle/runner.cpp

This file was deleted.

40 changes: 0 additions & 40 deletions src/installer/corehost/cli/apphost/bundle/runner.h

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

#include "marker.h"
#include "bundle_marker.h"
#include "pal.h"
#include "trace.h"
#include "utils.h"

using namespace bundle;

int64_t marker_t::header_offset()
int64_t bundle_marker_t::header_offset()
{
// Contains the bundle_placeholder default value at compile time.
// If this is a single-file bundle, the last 8 bytes are replaced
Expand All @@ -27,7 +25,7 @@ int64_t marker_t::header_offset()
0xee, 0x3b, 0x2d, 0xce, 0x24, 0xb3, 0x6a, 0xae
};

volatile marker_t* marker = reinterpret_cast<volatile marker_t *>(placeholder);
volatile bundle_marker_t* marker = reinterpret_cast<volatile bundle_marker_t *>(placeholder);

return marker->locator.bundle_header_offset;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,13 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

#ifndef __MARKER_H__
#define __MARKER_H__
#ifndef __BUNDLE_MARKER_H__
#define __BUNDLE_MARKER_H__

#include <cstdint>

namespace bundle
{
#pragma pack(push, 1)
union marker_t
union bundle_marker_t
{
public:
uint8_t placeholder[40];
Expand All @@ -28,5 +26,5 @@ namespace bundle
};
#pragma pack(pop)

}
#endif // __MARKER_H__

#endif // __BUNDLE_MARKER_H__
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,10 @@ void extractor_t::extract_new(reader_t& reader)
begin();
for (const file_entry_t& entry : m_manifest.files)
{
extract(entry, reader);
if (entry.needs_extraction())
{
extract(entry, reader);
}
}
commit_dir();
}
Expand All @@ -211,6 +214,11 @@ void extractor_t::verify_recover_extraction(reader_t& reader)

for (const file_entry_t& entry : m_manifest.files)
{
if (!entry.needs_extraction())
{
continue;
}

pal::string_t file_path = ext_dir;
append_path(&file_path, entry.relative_path().c_str());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,18 @@ file_entry_t file_entry_t::read(reader_t &reader)

return entry;
}

bool file_entry_t::needs_extraction() const
{
switch (m_type)
{
// Once the runtime can load assemblies from bundle,
// file_type_t::assembly should be in this category
case file_type_t::deps_json:
case file_type_t::runtime_config_json:
return false;

default:
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ namespace bundle
int64_t offset() const { return m_offset; }
int64_t size() const { return m_size; }
file_type_t type() const { return m_type; }
bool needs_extraction() const;

static file_entry_t read(reader_t &reader);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,23 @@

using namespace bundle;

// The AppHost expects the bundle_header to be an exact_match for which it was built.
// The framework accepts backwards compatible header versions.
bool header_fixed_t::is_valid(bool exact_match) const
bool header_fixed_t::is_valid() const
{
if (num_embedded_files <= 0)
{
return false;
}

if (exact_match)
{
return (major_version == header_t::major_version) && (minor_version == header_t::minor_version);
}

return ((major_version < header_t::major_version) ||
(major_version == header_t::major_version && minor_version <= header_t::minor_version));
// .net 5 host expects the version information to be 2.0
// .net core 3 single-file bundles are handled within the netcoreapp3.x apphost, and are not processed here in the framework.
return (major_version == header_t::major_version) && (minor_version == header_t::minor_version);
}

header_t header_t::read(reader_t& reader, bool need_exact_version)
header_t header_t::read(reader_t& reader)
{
const header_fixed_t* fixed_header = reinterpret_cast<const header_fixed_t*>(reader.read_direct(sizeof(header_fixed_t)));

if (!fixed_header->is_valid(need_exact_version))
if (!fixed_header->is_valid())
{
trace::error(_X("Failure processing application bundle."));
trace::error(_X("Bundle header version compatibility check failed."));
Expand All @@ -42,12 +36,12 @@ header_t header_t::read(reader_t& reader, bool need_exact_version)
header_t header(fixed_header->num_embedded_files);

// bundle_id is a component of the extraction path
reader.read_path_string(header.m_bundle_id);
size_t bundle_id_size = reader.read_path_string(header.m_bundle_id);

if (fixed_header->major_version > 1)
{
header.m_v2_header = reinterpret_cast<const header_fixed_v2_t*>(reader.read_direct(sizeof(header_fixed_v2_t)));
}
const header_fixed_v2_t *v2_header = reinterpret_cast<const header_fixed_v2_t*>(reader.read_direct(sizeof(header_fixed_v2_t)));
header.m_v2_header = *v2_header;

header.m_header_size = sizeof(header_fixed_t) + bundle_id_size + sizeof(header_fixed_v2_t);

return header;
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,8 @@ namespace bundle
uint32_t minor_version;
int32_t num_embedded_files;

bool is_valid(bool exact_match = false) const;
bool is_valid() const;
};
#pragma pack(pop)

// netcoreapp3_compat_mode flag is set on a .net5 app, which chooses to build single-file apps in .netcore3.x compat mode,
// This indicates that:
Expand All @@ -46,12 +45,13 @@ namespace bundle
netcoreapp3_compat_mode = 1
};

#pragma pack(push, 1)
struct location_t
{
public:
int64_t offset;
int64_t size;

bool is_valid() const { return offset != 0; }
};

// header_fixed_v2_t is available in single-file apps targetting .net5+ frameworks.
Expand All @@ -65,6 +65,8 @@ namespace bundle
location_t deps_json_location;
location_t runtimeconfig_json_location;
header_flags_t flags;

bool is_netcoreapp3_compat_mode() const { return (flags & header_flags_t::netcoreapp3_compat_mode) != 0; }
};
#pragma pack(pop)

Expand All @@ -74,23 +76,29 @@ namespace bundle
header_t(int32_t num_embedded_files = 0)
: m_num_embedded_files(num_embedded_files)
, m_bundle_id()
, m_v2_header(NULL)

, m_v2_header()
, m_header_size(0)
{
}

static header_t read(reader_t& reader, bool need_exact_version);
const pal::string_t& bundle_id() { return m_bundle_id; }
int32_t num_embedded_files() { return m_num_embedded_files; }
static header_t read(reader_t& reader);
const pal::string_t& bundle_id() const { return m_bundle_id; }
int32_t num_embedded_files() const { return m_num_embedded_files; }

const location_t& deps_json_location() const { return m_v2_header.deps_json_location; }
const location_t& runtimeconfig_json_location() const { return m_v2_header.runtimeconfig_json_location; }
bool is_netcoreapp3_compat_mode() const { return m_v2_header.is_netcoreapp3_compat_mode(); }

size_t size() const { return m_header_size; }

static const uint32_t major_version = 2;
static const uint32_t minor_version = 0;

private:
int32_t m_num_embedded_files;
pal::string_t m_bundle_id;
const header_fixed_v2_t* m_v2_header;

header_fixed_v2_t m_v2_header;
size_t m_header_size;
};
}
#endif // __HEADER_H__
Loading