Skip to content

Commit

Permalink
[WIP] Deploy to Azure (Liminiens#29)
Browse files Browse the repository at this point in the history
* Moved to netcoreapp3.1, removed arm
* Create azure-deploy.yml
* Dockerfile is linux-x64 now
* Added ping for debug
* Added response on port 80
* Commented proxy optional section

Co-authored-by: Ayrat Hudaygulov <ayrat.hudaygulov@jet.com>
  • Loading branch information
Szer and Ayrat Hudaygulov authored Jun 9, 2020
1 parent dcf5551 commit 883d0dc
Show file tree
Hide file tree
Showing 10 changed files with 111 additions and 51 deletions.
30 changes: 30 additions & 0 deletions .github/workflows/azure-deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Deploy docker image

on:
push:
branches: [ master ]

jobs:
build:

runs-on: ubuntu-latest

steps:
- name: Docker Login
uses: Azure/docker-login@v1
with:
username: ${{ secrets.AZURE_DOCKER_REGISTRY_USER }}
password: ${{ secrets.AZURE_DOCKER_REGISTRY_PASSWORD }}
login-server: https://dotnetru.azurecr.io/v1

- uses: actions/checkout@v2

- name: Build Docker image
run: docker build . -t grinder

- name: Tag Docker image
run: docker tag grinder dotnetru.azurecr.io/vahter/grinder

- name: Push Docker image
run: docker push dotnetru.azurecr.io/vahter/grinder

16 changes: 5 additions & 11 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
FROM resin/rpi-raspbian AS QEMU
# We need this container to copy QEMU files and use at ARM container
# This will fix pipeline crashes while doing smth

FROM mcr.microsoft.com/dotnet/core/sdk:2.2.203-stretch AS build-dotnet
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build-dotnet
WORKDIR /app
# Copy csproj and restore as distinct layers
COPY *.sln ./
Expand All @@ -17,12 +13,12 @@ COPY src/Grinder/. ./src/Grinder
COPY src/Grinder.Common/. ./src/Grinder.Common
COPY src/Grinder.DataAccess/. ./src/Grinder.DataAccess
WORKDIR /app/src/Grinder
RUN dotnet publish -r linux-arm -c Release -o out
RUN dotnet publish -r linux-x64 -c Release -o out

# Build runtime image
FROM mcr.microsoft.com/dotnet/core/runtime:2.2.4-stretch-slim-arm32v7
# After COPY we can RUN anything without crashes!
COPY --from=qemu /usr/bin/qemu-arm-static /usr/bin/qemu-arm-static
FROM mcr.microsoft.com/dotnet/core/runtime:3.1

EXPOSE 80

WORKDIR /app
COPY --from=build-dotnet /app/src/Grinder/out .
Expand All @@ -31,7 +27,5 @@ RUN mkdir -p /etc/grinder && mkdir -p /app/data

VOLUME /etc/grinder/
VOLUME /app/data/
# In final container we don't need this, removing
RUN rm -f /usr/bin/qemu-arm-static

ENTRYPOINT ["dotnet", "Grinder.dll"]
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"sdk": {
"version": "2.2.100"
"version": "3.1.300"
}
}
2 changes: 1 addition & 1 deletion src/Grinder.DataAccess/Grinder.DataAccess.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<MSBuildTreatWarningsAsErrors>true</MSBuildTreatWarningsAsErrors>
</PropertyGroup>

Expand Down
2 changes: 1 addition & 1 deletion src/Grinder.ExportTool/Grinder.ExportTool.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.2</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<DisableImplicitFSharpCoreReference>true</DisableImplicitFSharpCoreReference>
<MSBuildTreatWarningsAsErrors>true</MSBuildTreatWarningsAsErrors>
</PropertyGroup>
Expand Down
26 changes: 19 additions & 7 deletions src/Grinder/Commands.fs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@ module Parser =
| Ban of BanDuration
| Unban

type Command = Command of Usernames * CommandAction
type Command =
| UserCommand of Usernames * CommandAction
| Ping

let str s = pstring s

Expand Down Expand Up @@ -107,18 +109,22 @@ module Parser =
|> List.map attempt
|> choice

let pban: Parser<BanDuration, unit> =
let pban: Parser<CommandAction, unit> =
str "ban" .>> spaces >>. (pforeverBan <|> pdistinctTimeFractions)
|>> Ban

let punban: Parser<CommandAction, unit> =
str "unban" .>> spaces >>% Unban

let pping: Parser<Command, unit> =
str "ping" >>% Ping

let pcommandAction: Parser<CommandAction, unit> =
(pban |>> Ban) <|> punban
pban <|> punban

let parseCommand botUsername =
pbotUsername botUsername >>.
pipe2 many1Usernames pcommandAction (fun usernames command -> Command(Usernames(usernames), command))
(pping <|> pipe2 many1Usernames pcommandAction (fun usernames command -> UserCommand(Usernames(usernames), command)))

let runCommandParser botUsername str: ParserResult<Command, unit> =
run (parseCommand botUsername) str
Expand Down Expand Up @@ -275,12 +281,13 @@ module Processing =
ChatId: TelegramChatId
Usernames: UserUsername seq
}

type Command =
| BanCommand of BanCommandContext
| BanOnReplyCommand of ActionOnReplyCommandContext
| UnbanCommand of UnbanCommandContext
| UnbanOnReplyCommand of ActionOnReplyCommandContext
| PingCommand
| DoNothingCommand

type CommandError =
Expand Down Expand Up @@ -374,7 +381,7 @@ module Processing =

let parseTextMessage (context: TextMessageContext): Command =
match Parser.parse %context.BotUsername context.MessageText with
| BotCommand(Command((Usernames usernames), Ban(duration))) ->
| BotCommand(UserCommand((Usernames usernames), Ban(duration))) ->
let usernames =
usernames
|> Seq.map ^ fun username -> %username
Expand All @@ -387,7 +394,7 @@ module Processing =
Until = duration
}
BanCommand context
| BotCommand(Command((Usernames usernames), Unban)) ->
| BotCommand(UserCommand((Usernames usernames), Unban)) ->
let usernames =
usernames
|> Seq.map ^ fun username -> %username
Expand All @@ -399,6 +406,8 @@ module Processing =
Usernames = usernames
}
UnbanCommand context
| BotCommand(Ping) ->
PingCommand
| InvalidCommand _ ->
DoNothingCommand

Expand Down Expand Up @@ -538,6 +547,9 @@ module Processing =
}

return Some <| UnbanOnReplyMessage(context.From, message, errors)
| PingCommand ->
do! botApi.SendTextToChannel "pong"
return None
| DoNothingCommand ->
return None
}
Expand Down
5 changes: 3 additions & 2 deletions src/Grinder/Grinder.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.2</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<ServerGarbageCollection>false</ServerGarbageCollection>
<TieredCompilation>true</TieredCompilation>
<DisableImplicitFSharpCoreReference>true</DisableImplicitFSharpCoreReference>
Expand All @@ -15,6 +15,7 @@
<PackageReference Include="FSharp.UMX" Version="1.0.0-preview-001" />
<PackageReference Include="Funogram" Version="1.3.1" />
<PackageReference Include="HttpToSocks5Proxy" Version="1.1.3" />
<PackageReference Include="Microsoft.Azure.AppConfiguration.AspNetCore" Version="3.0.1" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="2.2.4" />
Expand All @@ -40,4 +41,4 @@
<ProjectReference Include="..\Grinder.DataAccess\Grinder.DataAccess.csproj" />
</ItemGroup>

</Project>
</Project>
64 changes: 43 additions & 21 deletions src/Grinder/Program.fs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
namespace Grinder

open System.Net
open System.Threading
open Microsoft.Extensions.Configuration
open Funogram
open Grinder
Expand All @@ -10,6 +12,7 @@ open Funogram.Api
open Funogram.Bot
open Funogram.Types
open FunogramExt
open System

module Program =
open System.Net.Http
Expand Down Expand Up @@ -40,10 +43,11 @@ module Program =
Bot: BotConfig
}

let createHttpClient config =
let createHttpClient (config: Socks5Configuration) =
let messageHandler = new HttpClientHandler()
messageHandler.Proxy <- HttpToSocks5Proxy(config.Hostname, config.Port, config.Username, config.Password)
messageHandler.UseProxy <- true
if not (isNull (box config)) then
messageHandler.Proxy <- HttpToSocks5Proxy(config.Hostname, config.Port, config.Username, config.Password)
messageHandler.UseProxy <- true
new HttpClient(messageHandler)

let createBotApi config (settings: BotSettings) = {
Expand Down Expand Up @@ -124,11 +128,20 @@ module Program =

[<EntryPoint>]
let main _ =
let config =
let mutable configBuilder =
ConfigurationBuilder()
.AddJsonFile("appsettings.json", false, true)
.AddJsonFile("/etc/grinder/appsettings.json", true, true)
.AddEnvironmentVariables("Grinder_")

match Environment.GetEnvironmentVariable("DOTNETRU_APP_CONFIG") with
| null -> ()
| connString ->
configBuilder <- configBuilder
.AddAzureAppConfiguration connString

let config =
configBuilder
.Build()
.Get<Config>()
.Bot;
Expand All @@ -142,23 +155,32 @@ module Program =

GrinderContext.MigrateUp()

async {
printfn "Starting bot"

let settings = {
Token = config.Token
ChatsToMonitor = ChatsToMonitor.Create config.ChatsToMonitor
AllowedUsers = AllowedUsers.Create config.AllowedUsers
ChannelId = %config.ChannelId
AdminUserId = %config.AdminUserId
}
do! startBot botConfiguration (onUpdate settings (createBotApi botConfiguration settings) dataApi) None
|> Async.StartChild
|> Async.Ignore

printfn "Bot started"
do! Async.Sleep(-1)
} |> Async.RunSynchronously
printfn "Starting bot"

let settings = {
Token = config.Token
ChatsToMonitor = ChatsToMonitor.Create config.ChatsToMonitor
AllowedUsers = AllowedUsers.Create config.AllowedUsers
ChannelId = %config.ChannelId
AdminUserId = %config.AdminUserId
}
startBot botConfiguration (onUpdate settings (createBotApi botConfiguration settings) dataApi) None
|> Async.Start

printfn "Bot started"

// Needed for azure web app deploy check. We have to response with anything on port 80
use listener = new HttpListener()
listener.Prefixes.Add("http://*:80/")
listener.Start()

let buffer = System.Text.Encoding.UTF8.GetBytes "OK"

while true do
let ctx = listener.GetContext()
let output = ctx.Response.OutputStream
output.Write(buffer, 0, buffer.Length)
output.Close();

printfn "Bot exited"
0 // return an integer exit code
13 changes: 7 additions & 6 deletions src/Grinder/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
"Token": "REPLACEME",
"ChannelId": 0,
"AdminUserId": 0,
"Socks5Proxy": {
"Hostname": "REPLACEME",
"Port": 0,
"Username": "REPLACEME",
"Password": "REPLACEME"
},
// uncomment if you need proxy
// "Socks5Proxy": {
// "Hostname": "REPLACEME",
// "Port": 0,
// "Username": "REPLACEME",
// "Password": "REPLACEME"
// },
"ChatsToMonitor": [
"REPLACEME"
],
Expand Down
2 changes: 1 addition & 1 deletion tests/Grinder.Tests/Grinder.Tests.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.2</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
<GenerateProgramFile>false</GenerateProgramFile>
<IsPackable>false</IsPackable>
<DisableImplicitFSharpCoreReference>true</DisableImplicitFSharpCoreReference>
Expand Down

0 comments on commit 883d0dc

Please sign in to comment.