Skip to content

Commit 14eb854

Browse files
authored
Merge pull request #2030 from JoeStech/dotnet_migration
Two LPs: .NET for Cobalt and creating a Cobalt VM
2 parents fe0caeb + 42a1694 commit 14eb854

File tree

13 files changed

+545
-0
lines changed

13 files changed

+545
-0
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
---
2+
title: Create the Cobalt 100 virtual machine
3+
weight: 2
4+
5+
### FIXED, DO NOT MODIFY
6+
layout: learningpathall
7+
---
8+
9+
## Use the Azure Portal to deploy a Cobalt 100 VM
10+
11+
Azure Cobalt 100 VMs are a part of the ['D' family of Azure VMs](https://learn.microsoft.com/en-us/azure/virtual-machines/sizes/general-purpose/d-family). To deploy one, follow these steps:
12+
13+
1. Sign in to the [Azure Portal](https://portal.azure.com/).
14+
2. Select **Create a resource → Compute → Virtual machine**.
15+
3. Complete the *Basics* tab:
16+
![Azure Portal – Basics tab for the VM wizard#center](images/create-cobalt-vm.png)
17+
The Dpsv6-series are powered by Cobalt 100. Selecting Standard_D4ps_v6 will give you a Cobalt VM with 4 physical cores. you can change the 4 to another value if you want a different number of cores.
18+
4. Upload your public SSH key or generate a new one in the wizard.
19+
5. Disallow public inbound ports for now.
20+
5. Accept the defaults on the *Disks* tab.
21+
6. On the *Networking* tab ensure that a **Public IP** is selected. You will need it to connect later. Leave the NSG settings as *Basic* for now.
22+
23+
Click **Review + create** followed by **Create**. Azure now deploys the VM and the automatically-generated Network Security Group (NSG). Provisioning takes ~2 minutes.
24+
25+
Navigate to the **Deployment in progress** pane or open the **Notifications** panel to track progress. When the deployment succeeds proceed to the next step to expose an inbound port.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
---
2+
title: Open an inbound port in the Network Security Group
3+
weight: 3
4+
5+
### FIXED, DO NOT MODIFY
6+
layout: learningpathall
7+
---
8+
9+
## Allow external traffic to TCP ports 22 (SSH) and 8080
10+
11+
Every new virtual machine created through the Azure wizard is associated with a **Network Security Group (NSG)**. An NSG acts like a stateful firewall – if no rule explicitly allows traffic, Azure blocks it.
12+
13+
In this step you will open port 22 for SSH, as well as port 8080 so that a web application running on the VM is reachable from your IP for testing. Substitute a different port if required by your workload, or a different IP range if you'd like broader accessibility.
14+
15+
1. In the Azure Portal open the newly created VM resource and click **Networking → Network settings** in the left nav.
16+
2. Select the **Network security group**.
17+
3. In the left nav click **Settings → Inbound security rules**
18+
4. Click **Add** at the top of the screen.
19+
5. Fill in the form, specifying **My IP address** as the source and 22 as the destination port:
20+
![Add inbound security rule with source of my IP and destination port 22#center](images/create-nsg-rule.png)
21+
22+
To open port 8080, follow steps 4 and 5 again, but instead choose port 8080 for the destination port.
23+
24+
You have now opened ports 22 and 8080 to your IP. In the next step you will verify connectivity.
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
---
2+
title: Verify connectivity to the Cobalt 100 VM
3+
weight: 4
4+
5+
### FIXED, DO NOT MODIFY
6+
layout: learningpathall
7+
---
8+
9+
## Connect over SSH and test the open port
10+
11+
1. On the **Overview** page for the VM copy the **Public IP address**.
12+
2. Open a terminal on your local machine and SSH to the VM (replace *azureuser* if you chose a different admin username):
13+
14+
```bash
15+
ssh -i [path to your pem file] azureuser@[public IP]
16+
```
17+
18+
Where `[public IP]` is your public IP and `[path to your pem file]` is the path to your SSH key file.
19+
20+
Accept the prompt to add the host to *known_hosts* the first time you connect.
21+
22+
### Start a simple HTTP server
23+
24+
If you do not already have an application listening on TCP 8080 you can start one temporarily:
25+
26+
```bash
27+
sudo apt update -y && sudo apt install -y python3
28+
python3 -m http.server 8080
29+
```
30+
31+
Leave this terminal open – the server runs in the foreground.
32+
33+
### Test from your local machine
34+
35+
In a second local terminal run `curl` to confirm you can reach the server through the NSG rule you created:
36+
37+
```bash
38+
curl http://[public IP]:8080
39+
```
40+
41+
Where `[public IP]` is your public IP.
42+
43+
You should see an HTML directory listing (or your application response). Receiving a response verifies that TCP 8080 is open and the VM is reachable from the public internet.
44+
45+
Terminate the Python server when you are finished testing (press `Ctrl + C`).
46+
47+
You now have an Arm-based Cobalt 100 VM with an exposed port 8080 that you can use to run any test server. To learn about optimizing .NET workloads on Cobalt, check out [Migrating a .NET application to Azure Cobalt](../../dotnet-migration/).
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
---
2+
title: Create an Azure Cobalt 100 VM
3+
4+
minutes_to_complete: 10
5+
6+
who_is_this_for: Developers and DevOps engineers who need an Arm-based virtual machine on Azure and want to expose an application port to the internet.
7+
8+
learning_objectives:
9+
- Deploy an Arm-based Cobalt 100 virtual machine (VM) on Microsoft Azure.
10+
- Connect to the Cobalt 100 VM using SSH.
11+
- Open an inbound TCP port in the associated Network Security Group (NSG).
12+
- Verify external connectivity to the newly opened port.
13+
14+
prerequisites:
15+
- A Microsoft Azure subscription with permission to create resources
16+
- Basic familiarity with SSH
17+
18+
author: Joe Stech
19+
20+
### Tags
21+
# Tagging metadata, see the Learning Path guide for the allowed values
22+
skilllevels: Introductory
23+
subjects: Containers and Virtualization
24+
arm_ips:
25+
- Neoverse
26+
tools_software_languages:
27+
- Azure Portal
28+
- Azure CLI
29+
operatingsystems:
30+
- Linux
31+
32+
33+
further_reading:
34+
- resource:
35+
title: Azure Cobalt 100 VM documentation
36+
link: https://learn.microsoft.com/azure/virtual-machines/cobalt-100
37+
type: Documentation
38+
- resource:
39+
title: Azure Virtual Machines overview
40+
link: https://learn.microsoft.com/azure/virtual-machines/
41+
type: Documentation
42+
- resource:
43+
title: Configure Azure network security group rules
44+
link: https://learn.microsoft.com/azure/virtual-network/security-overview
45+
type: Documentation
46+
47+
48+
49+
### FIXED, DO NOT MODIFY
50+
# ================================================================================
51+
weight: 1 # _index.md always has weight of 1 to order correctly
52+
layout: "learningpathall" # All files under learning paths have this same wrapper
53+
learning_path_main_page: "yes" # This should be surfaced when looking for related content. Only set for _index.md of learning path content.
54+
---
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
# ================================================================================
3+
# FIXED, DO NOT MODIFY THIS FILE
4+
# ================================================================================
5+
weight: 21 # Set to always be larger than the content in this path to be at the end of the navigation.
6+
title: "Next Steps" # Always the same, html page title.
7+
layout: "learningpathall" # All files under learning paths have this same wrapper for Hugo processing.
8+
---
123 KB
Loading
39 KB
Loading
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
---
2+
title: Create a basic OrchardCore application
3+
weight: 2
4+
5+
### FIXED, DO NOT MODIFY
6+
layout: learningpathall
7+
---
8+
9+
# Create a basic OrchardCore application
10+
11+
In this section, you will learn how to create and compile a basic [OrchardCore](https://github.com/OrchardCMS/OrchardCore) CMS application, as an example of a popular Linux-based .NET workload. OrchardCore is a modular and multi-tenant application framework built with ASP.NET Core, which can be used to create content-driven websites.
12+
13+
## Step 1: Set up your development environment
14+
15+
1. Launch an Azure Cobalt instance running Ubuntu 24.04, and open port 8080 to the internet. For instructions on how to do this, see the [Create an Azure Cobalt 100 VM](../../cobalt) Learning Path.
16+
17+
2. **Install .NET SDK**:
18+
19+
```bash
20+
wget https://packages.microsoft.com/config/ubuntu/24.04/packages-microsoft-prod.deb
21+
sudo dpkg -i packages-microsoft-prod.deb
22+
sudo apt-get update
23+
sudo apt-get install -y dotnet-sdk-8.0
24+
```
25+
26+
3. **Verify installations**:
27+
28+
```bash
29+
dotnet --version
30+
```
31+
32+
## Step 2: Install the OrchardCore Templates
33+
34+
To start building an OrchardCore application, you need to install the OrchardCore templates. Open your terminal and run the following command:
35+
36+
```bash
37+
dotnet new -i OrchardCore.ProjectTemplates::1.0.0-rc2-13450
38+
```
39+
40+
This command installs the OrchardCore project templates, which you will use to create a new application.
41+
42+
## Step 3: Create a new OrchardCore application
43+
44+
1. **Create a new project**: Use the `dotnet` CLI to create a new OrchardCore application.
45+
46+
```bash
47+
dotnet new occms -n MyOrchardCoreApp
48+
```
49+
50+
This command creates a new OrchardCore CMS application in a directory named `MyOrchardCoreApp`.
51+
52+
2. **Navigate to the project directory**:
53+
54+
```bash
55+
cd MyOrchardCoreApp
56+
```
57+
58+
## Step 4: Run the OrchardCore application
59+
60+
1. **Build the application**: Compile the application using the following command:
61+
62+
```bash
63+
dotnet build
64+
```
65+
66+
2. **Run the application**: Start the application with:
67+
68+
```bash
69+
dotnet run --urls http://0.0.0.0:8080
70+
```
71+
72+
3. **Access the application**: Open a web browser and navigate to `http://[instance IP]:8080` to see your OrchardCore application in action, where `[instance IP]` is the public IP of your Azure Cobalt instance.
73+
74+
4. **Configure the application as a blog** In the resulting configuration page,
75+
76+
You have successfully created and run a basic OrchardCore CMS application. In the next sections, you will learn how to integrate a C shared library into your .NET application and explore performance optimizations for Arm architecture.
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
---
2+
title: Add a simple C shared library to your .NET OrchardCore application
3+
weight: 3
4+
5+
### FIXED, DO NOT MODIFY
6+
layout: learningpathall
7+
---
8+
9+
## Introduction
10+
11+
In this section, you will learn how to integrate a simple C shared library into your .NET OrchardCore application. This process involves creating a C library, compiling it, and then using it within your .NET application. This integration can help you leverage existing C code and libraries, enhancing the functionality and performance of your application.
12+
13+
14+
## Step 1: Create a C shared library
15+
16+
First, you need to create a simple C shared library. This library will contain a function that you will call from your .NET application.
17+
18+
1. Create a new file named `mylib.c` with the following content:
19+
20+
```c
21+
#include <stdio.h>
22+
23+
void greet() {
24+
printf("Hello from the C library!\n");
25+
}
26+
```
27+
28+
2. Compile the C file into a shared library:
29+
30+
```bash
31+
gcc -shared -o libmylib.so -fPIC mylib.c
32+
```
33+
34+
This will generate a shared library file (`libmylib.so`).
35+
36+
## Step 2: Use the C library in your .NET application
37+
38+
Now that you have a shared library, you can use it in your .NET application.
39+
40+
1. In your OrchardCore application, create a new class file named `NativeMethods.cs`:
41+
42+
```csharp
43+
using System;
44+
using System.Runtime.InteropServices;
45+
46+
public static class NativeMethods
47+
{
48+
[DllImport("mylib", EntryPoint = "greet")]
49+
public static extern void Greet();
50+
}
51+
```
52+
53+
2. Call the `Greet` method from your application. For example, you can add the following code to your main program or a controller:
54+
55+
```csharp
56+
using OrchardCore.Logging;
57+
58+
var builder = WebApplication.CreateBuilder(args);
59+
60+
builder.Host.UseNLogHost();
61+
62+
builder.Services
63+
.AddOrchardCms()
64+
// // Orchard Specific Pipeline
65+
// .ConfigureServices( services => {
66+
// })
67+
// .Configure( (app, routes, services) => {
68+
// })
69+
;
70+
71+
var app = builder.Build();
72+
73+
Console.WriteLine("Calling native greet..."); // NEW INTEROP LINE
74+
NativeMethods.Greet(); // NEW INTEROP LINE
75+
76+
if (!app.Environment.IsDevelopment())
77+
{
78+
app.UseExceptionHandler("/Error");
79+
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
80+
app.UseHsts();
81+
}
82+
83+
app.UseHttpsRedirection();
84+
app.UseStaticFiles();
85+
86+
app.UseOrchardCore();
87+
88+
app.Run();
89+
```
90+
91+
3. Ensure that dotnet can find your shared library:
92+
93+
```bash
94+
export LD_LIBRARY_PATH=$(pwd):$LD_LIBRARY_PATH
95+
```
96+
97+
## Step 3: Run your application
98+
99+
Now when you run `dotnet run`, you will see
100+
101+
```bash
102+
Calling native greet...
103+
Hello from the C library!
104+
```
105+
106+
in the logging output.
107+
108+
## Compiling for Arm
109+
110+
If you are compiling for Arm directly on Azure Cobalt, the compiler understands what default processor optimizations it should use, and you can compile as done in Step 1 above. However, if you are cross-compiling in your build pipeline, you should specify `-mcpu=neoverse-n2 -O3` when running the cross-compiler:
111+
112+
```bash
113+
aarch64-linux-gnu-gcc -mcpu=neoverse-n2 -O3 -shared -o libmylib.so -fPIC mylib.c
114+
```
115+
116+
The `-mcpu=neoverse-n2` flag specifies the Cobalt architecture, and `-O3` ensures that maximum optimizations are completed (including SIMD opimizations).
117+
118+
In the next section, you will explore how to make your build architecture agnostic with the anyCPU feature.

0 commit comments

Comments
 (0)