Add a using statement for Microsoft.AspNetCore.Components.Authorization in your top level _Imports.razor file.
Update all Blazor component parameters to be public.
Update implementations of IJSRuntime to return ValueTask<T>.
Replace calls to MapBlazorHub<TComponent> with a single call to MapBlazorHub.
Update calls to RenderComponentAsync and RenderStaticComponentAsync to use the new overloads to RenderComponentAsync that take a RenderMode parameter (see Render multiple Blazor components from MVC views or pages below for details).
(Optional) Remove page specific _Imports.razor file with the @layout directive to use the default layout specified through the router instead.
Remove any use of the PageDisplay component and replace with LayoutView, RouteView, or AuthorizeRouteView as appropriate (see Blazor routing improvements below for details).
Replace uses of IUriHelper with NavigationManager.
Remove any use of @ref:suppressField.
Replace the previous RevalidatingAuthenticationStateProvider code with the new RevalidatingIdentityAuthenticationStateProvider code from the project template.
Replace Microsoft.AspNetCore.Components.UIEventArgs with System.EventArgs and remove the “UI” prefix from all EventArgs derived types (UIChangeEventArgs -> ChangeEventArgs, etc.).
Replace DotNetObjectRef with DotNetObjectReference.
Replace OnAfterRender() and OnAfterRenderAsync() implementations with OnAfterRender(bool firstRender) or OnAfterRenderAsync(bool firstRender).
In gRPC projects:
Update calls to GrpcClient.Create with a call GrpcChannel.ForAddress to create a new gRPC channel and new up your typed gRPC clients using this channel.
Rebuild any project or project dependency that uses gRPC code generation for an ABI change in which all clients inherit from ClientBase instead of LiteClientBase. There are no code changes required for this change.
You should now be all set to use .NET Core 3.0 Preview 9!
Blazor event handlers and data binding attributes moved to Microsoft.AspNetCore.Components.Web
In this release we moved the set of bindings and event handlers available for HTML elements into the Microsoft.AspNetCore.Components.Web.dll assembly and into the Microsoft.AspNetCore.Components.Web namespace. This change was made to isolate the web specific aspects of the Blazor programming from the core programming model. This section provides additional details on how to upgrade your existing projects to react to this change.
Blazor apps
Open the application’s root _Imports.razor and add @using Microsoft.AspNetCore.Components.Web. Blazor apps get a reference to the Microsoft.AspNetCore.Components.Web package implicitly without any additional package references, so adding a reference to this package isn’t necessary.
Blazor libraries
Add a package reference to the Microsoft.AspNetCore.Components.Web package package if you don’t already have one. Then open the root _Imports.razor file for the project (create the file if you don’t already have it) and add @using Microsoft.AspNetCore.Components.Web.
Troubleshooting guidance
With the correct references and using statement for Microsoft.AspNetCore.Components.Web, event handlers like @onclick and @bind should be bold font and colorized as shown below when using Visual Studio.
If @bind or @onclick are colorized as a normal HTML attribute, then the @using statement is missing.
If you’re missing a using statement for the Microsoft.AspNetCore.Components.Web namespace, you may see build failures. For example, the following build error for the code shown above indicates that the @bind attribute wasn’t recognized:
CS0169 The field 'Index.text' is never used
CS0428 Cannot convert method group 'Submit' to non-delegate type 'object'. Did you intend to invoke the method?
In other cases you may get a runtime exception and the app fails to render. For example, the following runtime exception seen in the browser console indicates that the @onclick attribute wasn’t recognized:
Error: There was an error applying batch 2.
DOMException: Failed to execute 'setAttribute' on 'Element': '@onclick' is not a valid attribute name.
Add a using statement for the Microsoft.AspNetCore.Components.Web namespace to address these issues. If adding the using statement fixed the problem, consider moving to the using statement app’s root _Imports.razor so it will apply to all files.
If you add the Microsoft.AspNetCore.Components.Web namespace but get the following build error, then you’re missing a package reference to the Microsoft.AspNetCore.Components.Web package:
CS0234 The type or namespace name 'Web' does not exist in the namespace 'Microsoft.AspNetCore.Components' (are you missing an assembly reference?)
Add a package reference to the Microsoft.AspNetCore.Components.Web package to address the issue.
Blazor routing improvements
In this release we’ve revised the Blazor Router component to make it more flexible and to enable new scenarios. The Router component in Blazor handles rendering the correct component that matches the current address. Routable components are marked with the @page directive, which adds the RouteAttribute to the generated component classes. If the current address matches a route, then the Router renders the contents of its Found parameter. If no route matches, then the Router component renders the contents of its NotFound parameter.
To render the component with the matched route, use the new RouteView component passing in the supplied RouteData from the Router along with any desired parameters. The RouteView component will render the matched component with its layout if it has one. You can also optionally specify a default layout to use if the matched component doesn’t have one.
<Router AppAssembly="typeof(Program).Assembly"> <Found Context="routeData"> <RouteView RouteData="routeData" DefaultLayout="typeof(MainLayout)" /> </Found> <NotFound> <h1>Page not found</h1> <p>Sorry, but there's nothing here!</p> </NotFound>
</Router>
Render content using a specific layout
To render a component using a particular layout, use the new LayoutView component. This is useful when specifying content for not found pages that you still want to use the app’s layout.
Authorization is no longer handled directly by the Router. Instead, you use the AuthorizeRouteView component. The AuthorizeRouteView component is a RouteView that will only render the matched component if the user is authorized. Authorization rules for specific components are specified using the AuthorizeAttribute. The AuthorizeRouteView component also sets up the AuthenticationState as a cascading value if there isn’t one already. Otherwise, you can still manually setup the AuthenticationState as a cascading value using the CascadingAuthenticationState component.
You can optionally set the NotAuthorized and Authorizing parameters of the AuthorizedRouteView component to specify content to display if the user is not authorized or authorization is still in progress.
You can now specify additional assemblies for the Router component to consider when searching for routable components. These assemblies will be considered in addition to the specified AppAssembly. You specify these assemblies using the AdditionalAssemblies parameter. For example, if Component1 is a routable component defined in a referenced class library, then you can support routing to this component like this:
Render multiple Blazor components from MVC views or pages
We’ve reenabled support for rendering multiple components from a view or page in a Blazor Server app. To render a component from a .cshtml file, use the Html.RenderComponentAsync<TComponent>(RenderMode renderMode, object parameters) HTML helper method with the desired RenderMode.
RenderMode
Description
Supports parameters?
Static
Statically render the component with the specified parameters.
Yes
Server
Render a marker where the component should be rendered interactively by the Blazor Server app.
No
ServerPrerendered
Statically prerender the component along with a marker to indicate the component should later be rendered interactively by the Blazor Server app.
No
Support for stateful prerendering has been removed in this release due to security concerns. You can no longer prerender components and then connect back to the same component state when the app loads. We may reenable this feature in a future release post .NET Core 3.0.
Blazor Server apps also no longer require that the entry point components be registered in the app’s Configure method. Only a single call to MapBlazorHub() is required.
Smarter reconnection for Blazor Server apps
Blazor Server apps are stateful and require an active connection to the server in order to function. If the network connection is lost, the app will try to reconnect to the server. If the connection can be reestablished but the server state is lost, then reconnection will fail. Blazor Server apps will now detect this condition and recommend the user to refresh the browser instead of retrying to connect.
Utility base component classes for managing a dependency injection scope
In ASP.NET Core apps, scoped services are typically scoped to the current request. After the request completes, any scoped or transient services are disposed by the dependency injection (DI) system. In Blazor Server apps, the request scope lasts for the duration of the client connection, which can result in transient and scoped services living much longer than expected.
To scope services to the lifetime of a component you can use the new OwningComponentBase and OwningComponentBase<TService> base classes. These base classes expose a ScopedServices property of type IServiceProvider that can be used to resolve services that are scoped to the lifetime of the component. To author a component that inherits from a base class in Razor use the @inherits directive.
@page "/users"
@attribute [Authorize]
@inherits OwningComponentBase<Data.ApplicationDbContext> <h1>Users (@Service.Users.Count())</h1>
<ul> @foreach (var user in Service.Users) { <li>@user.UserName</li> }
</ul>
Note: Services injected into the component using @inject or the InjectAttribute are not created in the component’s scope and will still be tied to the request scope.
Razor component unit test framework prototype
We’ve started experimenting with building a unit test framework for Razor components. You can read about the prototype in Steve Sanderson’s Unit testing Blazor components – a prototype blog post. While this work won’t ship with .NET Core 3.0, we’d still love to get your feedback early in the design process. Take a look at the code on GitHub and let us know what you think!
Helper methods for returning Problem Details from controllers
Problem Details is a standardized format for returning error information from an HTTP endpoint. We’ve added new Problem and ValidationProblem method overloads to controllers that use optional parameters to simplify returning Problem Detail responses.
[Route("/error")]
public ActionResult<ProblemDetails> HandleError()
{ return Problem(title: "An error occurred while processing your request", statusCode: 500);
}
New client API for gRPC
To improve compatibility with the existing Grpc.Core implementation, we’ve changed our client API to use gRPC channels. The channel is where gRPC configuration is set and it is used to create strongly typed clients. The new API provides a more consistent client experience with Grpc.Core, making it easier to switch between using the two libraries.
// Old
using var httpClient = new HttpClient() { BaseAddress = new Uri("https://localhost:5001") };
var client = GrpcClient.Create<GreeterClient>(httpClient); // New
var channel = GrpcChannel.ForAddress("https://localhost:5001");
var client = new GreeterClient(channel); var reply = await client.GreetAsync(new HelloRequest { Name = "Santa" });
Support for async streams in streaming gRPC responses
gRPC streaming responses return a custom IAsyncStreamReader type that can be iterated on to receive all response messages in a streaming response. With the addition of async streams in C# 8, we’ve added a new extension method that makes for a more ergonomic API while consuming streaming responses.
// Old
while (await requestStream.MoveNext(CancellationToken.None))
{ var message = requestStream.Current; // …
} // New and improved
await foreach (var message in requestStream.ReadAllAsync())
{ // …
}
Give feedback
We hope you enjoy the new features in this preview release of ASP.NET Core and Blazor! Please let us know what you think by filing issues on GitHub.
Posted by: xSicKxBot - 09-11-2019, 04:27 AM - Forum: Windows
- No Replies
‘Gears 5’ now available worldwide
Today, we welcome Gears 5 fans to Sera as Gears 5 officially releases around the world. Gears 5’s Early Access period began on Thursday at 9pm local time and has been has been a hit with critics, who have describe the game as “a spectacular return to form” and “the best Gears of War game yet.” In addition to buying the standard edition, you can also play it now with Xbox Game Pass. If you haven’t already joined Xbox Game Pass, you get your first two months of Xbox Game Pass Ultimate for $2 (and if you are already an Xbox Game Pass for Console or Xbox Live Gold member, you can also upgrade your existing pre-paid months and still get two months of Xbox Game Pass Ultimate for $2).
“Gears 5 is the culmination of an incredible journey after three years of passion and dedicated work by our studio team,” said Rod Fergusson, Studio Head at The Coalition. “We set out to challenge expectations for when fans play a new Gears of War game, and are proud to share Gears 5 with the world.”
Let’s talk about last night. Wow. A big heartfelt thank you to everyone who attended #GearsInk and to everyone behind the scenes for making this event possible. Was an honour to be tattooed along side legends like @TheJohnDiMaggio and @LauraBaileyVO. Enjoy the game! pic.twitter.com/Ao1sMiS0V5
That’s just the beginning – after today’s launch, we’ll continue to use Operations to evolve your Gears 5 Multiplayer Experience with free new modes, maps, characters, customization items and more. With all of this free content, plus a regular cadence of exclusive cosmetic items in the Gears 5 Store, we think this will be the most dynamic and exciting post-launch Gears has ever had. Speaking of bonus multiplayer items, remember to download and play by September 16 to unlock the Terminator Dark Fate Character Pack.
For more information on the Gears of War franchise, stay tuned to Xbox Wire or follow Gears on Twitter @gearsofwar.
In the previous article we touched upon some of the new features introduced to Cockpit over the years. This article will look into some of the tools within the UI to perform everyday storage management tasks. To access these functionalities, install the cockpit-storaged package:
sudo dnf install cockpit-storaged
From the main screen, click the Storage menu option in the left column. Everything needed to observe and manage disks is available on the main Storage screen. Also, the top of the page displays two graphs for the disk’s reading and writing performance with the local filesystem’s information below. In addition, the options to add or modify RAID devices, volume groups, iSCSI devices, and drives are available as well. In addition, scrolling down will reveal a summary of recent logs. This allows admins to catch any errors that require immediate attention.
Filesystems
This section lists the system’s mounted partitions. Clicking on a partition will display information and options for that mounted drive. Growing and shrinking partitions are available in the Volume sub-section. There’s also a filesystem subsection that allows you to change the label and configure the mount.
If it’s part of a volume group, other logical volumes in that group will also be available. Each standard partition has the option to delete and format. Also, logical volumes have an added option to deactivate the partition.
RAID devices
Cockpit makes it super-easy to manage RAID drives. With a few simple clicks the RAID drive is created, formatted, encrypted, and mounted. For details, or a how-to on creating a RAID device from the CLI check out the article Managing RAID arrays with mdadm.
To create a RAID device, start by clicking the add (+) button. Enter a name, select the type of RAID level and the available drives, then click Create. The RAID section will show the newly created device. Select it to create the partition table and format the drive(s). You can always remove the device by clicking the Stop and Delete buttons in the top-right corner.
Logical volumes
By default, the Fedora installation uses LVM when creating the partition scheme. This allows users to create groups, and add volumes from different disks to those groups. The article, Use LVM to Upgrade Fedora, has some great tips and explanations on how it works in the command-line.
Start by clicking the add (+) button next to “Volume Groups”. Give the group a name, select the disk(s) for the volume group, and click Create. The new group is available in the Volume Groups section. The example below demonstrates a new group named “vgraiddemo”.
Now, click the newly made group then select the option to Create a New Logical Volume. Give the LV a name and select the purpose: Block device for filesystems, or pool for thinly provisioning volumes. Adjust the amount of storage, if necessary, and click the Format button to finalize the creation.
Cockpit can also configure current volume groups. To add a drive to an existing group, click the name of the volume group, then click the add (+) button next to “Physical Volumes”. Select the disk from the list and click the Add button. In one shot, not only has a new PV, been created, but it’s also added to the group. From here, we can add the available storage to a partition, or create a new LV. The example below demonstrates how the additional space is used to grow the root filesystem.
iSCSI targets
Connecting to an iSCSI server is a quick process and requires two things, the initiator’s name, which is assigned to the client, and the name or IP of the server, or target. Therefore we will need to change the initiator’s name on the system to match the configurations on the target server.
To change the initiator’s name, click the button with the pencil icon, enter the name, and click Change.
To add the iSCSI target, click the add (+) button, enter the server’s address, the username and password, if required, and click Next. Select the target — verify the name, address, and port, — and click Add to finalize the process.
To remove a target, click the “checkmark” button. A red trashcan will appear beside the target(s). Click it to remove the target from the setup list.
NFS mount
Cockpit even allows sysadmins to configure NFS shares within the UI. To add NFS shares, click the add (+) button in the NFS mounts section. Enter the server’s address, the path of the share on the server, and a location on the local machine to mount the share. Adjust the mount options if needed and click Add to view information about the share. We also have the options to unmount, edit, and remove the share. The example below demonstrates how the NFS share on SERVER02 is mounted to the /mnt directory.
Conclusion
As we’ve seen in this article, a lot of the storage-related tasks that require lengthy, and multiple, lines of commands can be easily done within the web UI with just a few clicks. Cockpit is continuously evolving and every new feature makes the project better and better. In the next article we’ll explore the features and components on the networking side of things.
Nintendo Of Europe Unveils New Super Smash Bros. Ultimate Tournament Portal
Nintendo of Europe has today introduced a brand new website portal for Super Smash Bros. Ultimate players looking to take their gaming to the next level.
Players of all skill levels are encouraged to visit the site to join and participate in tournaments happening all over Europe. Nintendo says that “attending local tournaments is about much more than simply winning or losing: it’s a great way for players to meet other competitors, improve their skills, and enjoy fun competitive multiplayer”.
Event organisers can also submit their own tournaments, which players will then be able to discover and join. Nintendo actually has its very own tournament set to take place called the Super Smash Bros. Ultimate European Circuit. This event will see solo players vying for the title of Europe’s best Smash player across seven events, the first of which is taking place in the Netherlands near the end of October.
Think you’ve got what it takes to be the best in Europe? Assuming you’re like us, and the answer to that is a huge ‘no’, will you be checking out some smaller, local tournaments to have some fun instead? Let us know in the comments below.
Posted by: xSicKxBot - 09-11-2019, 04:26 AM - Forum: Lounge
- No Replies
James Bond Stars Line Up For New No Time To Die Images
The title of the next James Bond movie was finally revealed last month, and now some official images have been released. The film is titled No Time To Die, and will be Daniel Craig's fifth outing as the iconic British super-spy. It hits theaters in April 2020.
Before you get too excited, the new images aren't actually shots from the film. They are publicity pictures of Craig, co-star Léa Seydoux, and director Cary Joji Fukunaga, on location in Matera, Italy. Frankly, Craig looks like he'd rather be anywhere but posing for these pictures, but it's certainly a suitably glamorous-looking location for the next Bond movie. Check them out below:
Seydoux will reprise the role of Madeleine Swan from 2015's Spectre, and will be joined by Ralph Fiennes, Ben Whishaw, and Naomie Harris as M, Q, and Miss Moneypenny respectively. The new cast members include Rami Malek in a villainous role, plus Billy Magnussen and Ana de Armas. No Time To Die releases on April 3, 2020--check out some on-set footage here.
The official synopsis was released last month. It reads: "In No Time To Die, Bond has left active service and is enjoying a tranquil life in Jamaica. His peace is short-lived when his old friend Felix Leiter from the CIA turns up asking for help. The mission to rescue a kidnapped scientist turns out to be far more treacherous than expected, leading Bond onto the trail of a mysterious villain armed with dangerous new technology."
In related news, former Bond actor Pierce Brosnan recently revealed he thought it was time for a woman to take over the role of 007. "I think we've watched the guys do it for the last 40 years," he said. "Get out of the way, guys, and put a woman up there. I think it would be exhilarating; it would be exciting."
The Cloud Native Computing Foundation (CNCF), which sustains and integrates open source technologies like Kubernetes and Prometheus, today announced that its End User Community has grown to 100 members. The CNCF End User Community consists of enterprises and startups that are committed to accelerating the adoption of cloud native technologies and improving the deployment experience. (Yahoo!)
Epic have just released Unreal Engine 4.23. The star feature, the new Chaos physics and destruction engine announced back at GDC made it’s beta release in this version, although you currently have to build UE4 from source. The new physics system enables you to destroy world geometry with fine tune control as well as tightly integrate with the Niagara particle system.
Details of this release from the Unreal Engine blog:
Thanks to our next-gen virtual production tools and enhanced real-time ray tracing, film and TV production is transformed. Now you can achieve final shots live on set, with LED walls powered by nDisplay that not only place real-world actors and props within UE4 environments, but also light and cast reflections onto them (Beta). We’ve also added VR scouting tools (Beta), enhanced Live Link real-time data streaming, and the ability to remotely control UE4 from an iPad or other device (Beta). Ray tracing has received numerous enhancements to improve stability and performance, and to support additional material and geometry types—including landscape geometry, instanced static meshes, procedural meshes, and Niagara sprite particles.
Unreal Engine lets you build realistic worlds without bounds. Fracture, shatter, and demolish massive-scale scenes at cinematic quality with unprecedented levels of artistic control using the new Chaos physics and destruction system. Paint stunning vistas for users to experience using runtime Virtual Texturing, non-destructive Landscape editing, and interactive Actor placement using the Foliage tool.
We have optimized systems, provided new tools, and added features to help you do more for less. Virtual Texturing reduces texture memory overhead for light maps and detailed artist-created textures, and improves rendering performance for procedural or layered materials respectively. Animation streaming enables more animations to be used by limiting the runtime memory impact to only those currently in use. Use Unreal Insights to collect, analyze, and visualize data on UE4 behavior for profiling, helping you understand engine performance from either live or pre-recorded sessions.
This release includes 192 improvements submitted by the incredible community of Unreal Engine developers on GitHub!
Be sure to check the full release announcement for more details on the release or watch the video below.
Redesigning Configuration Refresh for Azure App Configuration
August 27th, 2019
Overview
Since its inception, the .NET Core configuration provider for Azure App Configuration has provided the capability to monitor changes and sync them to the configuration within a running application. We recently redesigned this functionality to allow for on-demand refresh of the configuration. The new design paves the way for smarter applications that only refresh the configuration when necessary. As a result, inactive applications no longer have to monitor for configuration changes unnecessarily.
Initial design : Timer-based watch
In the initial design, configuration was kept in sync with Azure App Configuration using a watch mechanism which ran on a timer. At the time of initialization of the Azure App Configuration provider, users could specify the configuration settings to be updated and an optional polling interval. In case the polling interval was not specified, a default value of 30 seconds was used.
public static IWebHost BuildWebHost(string[] args)
{ WebHost.CreateDefaultBuilder(args) .ConfigureAppConfiguration((hostingContext, config) => { // Load settings from Azure App Configuration // Set up the provider to listen for changes triggered by a sentinel value var settings = config.Build(); string appConfigurationEndpoint = settings["AzureAppConfigurationEndpoint"]; config.AddAzureAppConfiguration(options => { options.ConnectWithManagedIdentity(appConfigurationEndpoint) .Use(keyFilter: "WebDemo:*") .WatchAndReloadAll(key: "WebDemo:Sentinel", label: LabelFilter.Null); }); settings = config.Build(); }) .UseStartup<Startup>() .Build();
}
For example, in the above code snippet, Azure App Configuration would be pinged every 30 seconds for changes. These calls would be made irrespective of whether the application was active or not. As a result, there would be unnecessary usage of network and CPU resources within inactive applications. Applications needed a way to trigger a refresh of the configuration on demand in order to be able to limit the refreshes to active applications. Then unnecessary checks for changes could be avoided.
This timer-based watch mechanism had the following fundamental design flaws.
It could not be invoked on-demand.
It continued to run in the background even in applications that could be considered inactive.
It promoted constant polling of configuration rather than a more intelligent approach of updating configuration when applications are active or need to ensure freshness.
New design : Activity-based refresh
The new refresh mechanism allows users to keep their configuration updated using a middleware to determine activity. As long as the ASP.NET Core web application continues to receive requests, the configuration settings continue to get updated with the configuration store.
The application can be configured to trigger refresh for each request by adding the Azure App Configuration middleware from package Microsoft.Azure.AppConfiguration.AspNetCore in your application’s startup code.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{ app.UseAzureAppConfiguration(); app.UseMvc();
}
At the time of initialization of the configuration provider, the user can use the ConfigureRefresh method to register the configuration settings to be updated with an optional cache expiration time. In case the cache expiration time is not specified, a default value of 30 seconds is used.
public static IWebHost BuildWebHost(string[] args)
{ WebHost.CreateDefaultBuilder(args) .ConfigureAppConfiguration((hostingContext, config) => { // Load settings from Azure App Configuration // Set up the provider to listen for changes triggered by a sentinel value var settings = config.Build(); string appConfigurationEndpoint = settings["AzureAppConfigurationEndpoint"]; config.AddAzureAppConfiguration(options => { options.ConnectWithManagedIdentity(appConfigurationEndpoint) .Use(keyFilter: "WebDemo:*") .ConfigureRefresh((refreshOptions) => { // Indicates that all settings should be refreshed when the given key has changed refreshOptions.Register(key: "WebDemo:Sentinel", label: LabelFilter.Null, refreshAll: true); }); }); settings = config.Build(); }) .UseStartup<Startup>() .Build();
}
In order to keep the settings updated and avoid unnecessary calls to the configuration store, an internal cache is used for each setting. Until the cached value of a setting has expired, the refresh operation does not update the value. This happens even when the value has changed in the configuration store.
Try it now!
For more information about Azure App Configuration, check out the following resources. You can find step-by-step tutorials that would help you get started with dynamic configuration using the new refresh mechanism within minutes. Please let us know what you think by filing issues on GitHub.
By Amber Neely Saturday, September 07, 2019, 06:07 am PT (09:07 am ET)
Twitch, a live game streaming service, has released an Apple TV app public beta through TestFlight, giving users a chance to try out the service before it goes live.
While Twitch has had an iOS and desktop PC and Mac app for some time, this is marks the public debut of the app for Apple TV.
The app will boast the same features that the iOS and desktops apps do. Features include the ability to watch both live and prerecorded videos as well as the ability to participate in the on-screen chat.
Those who wish to take part in the Twitch public beta need to install and sign into Apple’s TestFlight app on either an iPhone or iPad. Following that, install TestFlight on the Apple TV.
After the apps have been installed on the iOS device and the Apple TV, tap the public TestFlight Twitch link on the iOS device. It will then populate the Apple TV TestfFlight and can be run from there.
Twitch encourages users to use the tvOS app the same way they would use the other apps. The company states on their beta page that “we don’t want to be too prescriptive so explore the app, watch streams, and try out different features. If you find a bug, the app crashes on you, or you encounter other issues send us your feedback.”
The Amazon-owned streaming service has been around since early 2011, giving players the chance to livestream video games. Content on Twitch ranges from simple video game playthroughs to competitive speed runs, eSports broadcasts, game development streams, and more.
Since then, Twitch has expanded greatly. In addition to video game themed content, Twitch now regularly features tabletop and card game streams, art and culture streams, music streams, and “hangouts,” in which viewers are encouraged to socialize with the broadcaster.
The jump to tvOS makes sense, as Twitch is now one of the largest video services on the internet. As of 2018, Twitch boasted over 2.2 million broadcasters, with 15 million daily active users, roughly half the amount of video-giant YouTube’s daily active users in 2017.
Twitch also has well over 27,000 partner channels, giving popular streamers the ability to earn a share of the advertising revenue Twitch generates on their streams.
With the rise of containers and container technology, all major Linux distributions nowadays provide a container base image. This article presents how the Fedora project builds its base image. It also shows you how to use it to create a layered image.
Base and layered images
Before we look at how the Fedora container base image is built, let’s define a base image and a layered image. A simple way to define a base image is an image that has no parent layer. But what does that concretely mean? It means a base image usually contains only the root file system (rootfs) of an operating system. The base image generally provides the tools needed to install software in order to create layered images.
A layered image adds a collections of layers on top of the base image in order to install, configure, and run an application. Layered images reference base images in a Dockerfile using the FROM instruction:
FROM fedora:latest
How to build a base image
Fedora has a full suite of tools available to build container images. This includes podman, which does not require running as the root user.
Building a rootfs
A base image comprises mainly a tarball. This tarball contains a rootfs. There are different ways to build this rootfs. The Fedora project uses the kickstart installation method coupled with imagefactory software to create these tarballs.
The kickstart file used during the creation of the Fedora base image is available in Fedora’s build system Koji. The Fedora-Container-Base package regroups all the base image builds. If you select a build, it gives you access to all the related artifacts, including the kickstart files. Looking at an example, the %packages section at the end of the file defines all the packages to install. This is how you make software available in the base image.
Using a rootfs to build a base image
Building a base image is easy, once a rootfs is available. It requires only a Dockerfile with the following instructions:
FROM scratch
ADD layer.tar /
CMD ["/bin/bash"]
The important part here is the FROM scratch instruction, which is creating an empty image. The following instructions then add the rootfs to the image, and set the default command to be executed when the image is run.
Let’s build a base image using a Fedora rootfs built in Koji:
The layer.tar file which contains the rootfs needs to be extracted from the downloaded archive. This is only needed because Fedora generates images that are ready to be consumed by a container run-time.
So using Fedora’s generated image, it’s even easier to get a base image. Let’s see how that works:
To build a layered image that uses the Fedora base image, you only need to specify fedora in the FROM line instruction:
FROM fedora:latest
The latest tag references the latest active Fedora release (Fedora 30 at the time of writing). But it is possible to get other versions using the image tag. For example, FROM fedora:31 will use the Fedora 31 base image.
Fedora supports building and releasing software as containers. This means you can maintain a Dockerfile to make your software available to others. For more information about becoming a container image maintainer in Fedora, check out the Fedora Containers Guidelines.