diff --git a/config/constants.go b/config/constants.go index 2a2ce33b2..6008aeed1 100644 --- a/config/constants.go +++ b/config/constants.go @@ -9,10 +9,6 @@ const ( WebRoot = "webroot" // PrivateHLSStoragePath is the HLS write directory. PrivateHLSStoragePath = "hls" - // ExtraInfoFile is the markdown file for page content. Remove this after the migrator is removed. - ExtraInfoFile = "data/content.md" - // StatsFile is the json file we used to save stats in. Remove this after the migrator is removed. - StatsFile = "data/stats.json" // FfmpegSuggestedVersion is the version of ffmpeg we suggest. FfmpegSuggestedVersion = "v4.1.5" // Requires the v // BackupDirectory is the directory we write backup files to. diff --git a/core/core.go b/core/core.go index 458dc2375..e0e8a2f98 100644 --- a/core/core.go +++ b/core/core.go @@ -33,8 +33,6 @@ func Start() error { resetDirectories() data.PopulateDefaults() - // Once a couple versions pass we can remove the old data migrators. - data.RunMigrations() if err := data.VerifySettings(); err != nil { log.Error(err) diff --git a/core/data/migrator.go b/core/data/migrator.go deleted file mode 100644 index 47009c72a..000000000 --- a/core/data/migrator.go +++ /dev/null @@ -1,266 +0,0 @@ -package data - -import ( - "encoding/json" - "io/ioutil" - "os" - "path/filepath" - - "github.com/owncast/owncast/config" - "github.com/owncast/owncast/models" - "github.com/owncast/owncast/utils" - log "github.com/sirupsen/logrus" - "gopkg.in/yaml.v2" -) - -// RunMigrations will start the migration process from the config file. -func RunMigrations() { - if !utils.DoesFileExists(config.BackupDirectory) { - if err := os.Mkdir(config.BackupDirectory, 0700); err != nil { - log.Errorln("Unable to create backup directory", err) - return - } - } - - migrateConfigFile() - migrateStatsFile() - migrateYPKey() -} - -func migrateStatsFile() { - oldStats := models.Stats{} - - if !utils.DoesFileExists(config.StatsFile) { - return - } - - log.Infoln("Migrating", config.StatsFile, "to new datastore") - - jsonFile, err := ioutil.ReadFile(config.StatsFile) - if err != nil { - log.Errorln(err) - return - } - - if err := json.Unmarshal(jsonFile, &oldStats); err != nil { - log.Errorln(err) - return - } - - _ = SetPeakSessionViewerCount(oldStats.SessionMaxViewerCount) - _ = SetPeakOverallViewerCount(oldStats.OverallMaxViewerCount) - - if err := utils.Move(config.StatsFile, "backup/stats.old"); err != nil { - log.Warnln(err) - } -} - -func migrateYPKey() { - filePath := ".yp.key" - - if !utils.DoesFileExists(filePath) { - return - } - - log.Infoln("Migrating", filePath, "to new datastore") - - keyFile, err := ioutil.ReadFile(filePath) - if err != nil { - log.Errorln("Unable to migrate", keyFile, "there may be issues registering with the directory") - } - - if err := SetDirectoryRegistrationKey(string(keyFile)); err != nil { - log.Errorln("Unable to migrate", keyFile, "there may be issues registering with the directory") - return - } - - if err := utils.Move(filePath, "backup/yp.key.old"); err != nil { - log.Warnln(err) - } -} - -func migrateConfigFile() { - filePath := config.ConfigFilePath - - if !utils.DoesFileExists(filePath) { - return - } - - log.Infoln("Migrating", filePath, "to new datastore") - - var oldConfig configFile - - yamlFile, err := ioutil.ReadFile(filePath) - if err != nil { - log.Errorln("config file err", err) - return - } - - if err := yaml.Unmarshal(yamlFile, &oldConfig); err != nil { - log.Errorln("Error reading the config file.", err) - return - } - - _ = SetServerName(oldConfig.InstanceDetails.Name) - _ = SetServerSummary(oldConfig.InstanceDetails.Summary) - _ = SetServerMetadataTags(oldConfig.InstanceDetails.Tags) - _ = SetStreamKey(oldConfig.VideoSettings.StreamingKey) - _ = SetNSFW(oldConfig.InstanceDetails.NSFW) - _ = SetServerURL(oldConfig.YP.InstanceURL) - _ = SetDirectoryEnabled(oldConfig.YP.Enabled) - _ = SetSocialHandles(oldConfig.InstanceDetails.SocialHandles) - _ = SetFfmpegPath(oldConfig.FFMpegPath) - _ = SetHTTPPortNumber(float64(oldConfig.WebServerPort)) - _ = SetRTMPPortNumber(float64(oldConfig.RTMPServerPort)) - - // Migrate logo - if logo := oldConfig.InstanceDetails.Logo; logo != "" { - filename := filepath.Base(logo) - oldPath := filepath.Join("webroot", logo) - newPath := filepath.Join("data", filename) - - log.Infoln("Copying logo from", oldPath, "to", newPath) - err := utils.Copy(oldPath, newPath) - if err != nil { - log.Errorln("Error moving logo", logo, err) - } else { - _ = SetLogoPath(filename) - } - } - - // Migrate video variants - variants := []models.StreamOutputVariant{} - for _, variant := range oldConfig.VideoSettings.StreamQualities { - migratedVariant := models.StreamOutputVariant{} - migratedVariant.IsAudioPassthrough = true - migratedVariant.IsVideoPassthrough = variant.IsVideoPassthrough || variant.VideoBitrate == 0 - migratedVariant.Framerate = variant.Framerate - migratedVariant.VideoBitrate = variant.VideoBitrate - migratedVariant.ScaledHeight = variant.ScaledHeight - migratedVariant.ScaledWidth = variant.ScaledWidth - - presetMapping := map[string]int{ - "ultrafast": 1, - "superfast": 2, - "veryfast": 3, - "faster": 4, - "fast": 5, - } - migratedVariant.CPUUsageLevel = presetMapping[variant.EncoderPreset] - variants = append(variants, migratedVariant) - } - _ = SetStreamOutputVariants(variants) - - // Migrate latency level - level := 2 - oldSegmentLength := oldConfig.VideoSettings.ChunkLengthInSeconds - oldNumberOfSegments := oldConfig.Files.MaxNumberInPlaylist - latencyLevels := models.GetLatencyConfigs() - - if oldSegmentLength == latencyLevels[0].SecondsPerSegment && oldNumberOfSegments == latencyLevels[0].SegmentCount { - level = 0 - } else if oldSegmentLength == latencyLevels[1].SecondsPerSegment && oldNumberOfSegments == latencyLevels[2].SegmentCount { - level = 1 - } else if oldSegmentLength == latencyLevels[2].SecondsPerSegment && oldNumberOfSegments == latencyLevels[2].SegmentCount { - level = 2 - } else if oldSegmentLength == latencyLevels[3].SecondsPerSegment && oldNumberOfSegments == latencyLevels[3].SegmentCount { - level = 3 - } else if oldSegmentLength >= latencyLevels[4].SecondsPerSegment && oldNumberOfSegments >= latencyLevels[4].SegmentCount { - level = 4 - } - - _ = SetStreamLatencyLevel(float64(level)) - - // Migrate storage config - _ = SetS3Config(models.S3(oldConfig.Storage)) - - // Migrate the old content.md file - content, err := ioutil.ReadFile(config.ExtraInfoFile) - if err == nil && len(content) > 0 { - _ = SetExtraPageBodyContent(string(content)) - } - - if err := utils.Move(filePath, "backup/config.old"); err != nil { - log.Warnln(err) - } - - log.Infoln("Your old config file can be found in the backup directory for reference. For all future configuration use the web admin.") -} - -type configFile struct { - DatabaseFilePath string `yaml:"databaseFile"` - EnableDebugFeatures bool `yaml:"-"` - FFMpegPath string - Files files `yaml:"files"` - InstanceDetails instanceDetails `yaml:"instanceDetails"` - VersionInfo string `yaml:"-"` // For storing the version/build number - VersionNumber string `yaml:"-"` - VideoSettings videoSettings `yaml:"videoSettings"` - WebServerPort int - RTMPServerPort int - YP yp `yaml:"yp"` - Storage s3 `yaml:"s3"` -} - -// instanceDetails defines the user-visible information about this particular instance. -type instanceDetails struct { - Name string `yaml:"name"` - Title string `yaml:"title"` - Summary string `yaml:"summary"` - Logo string `yaml:"logo"` - Tags []string `yaml:"tags"` - Version string `yaml:"version"` - NSFW bool `yaml:"nsfw"` - ExtraPageContent string `yaml:"extraPageContent"` - StreamTitle string `yaml:"streamTitle"` - SocialHandles []models.SocialHandle `yaml:"socialHandles"` -} - -type videoSettings struct { - ChunkLengthInSeconds int `yaml:"chunkLengthInSeconds"` - StreamingKey string `yaml:"streamingKey"` - StreamQualities []streamQuality `yaml:"streamQualities"` - HighestQualityStreamIndex int `yaml:"-"` -} - -// yp allows registration to the central Owncast yp (Yellow pages) service operating as a directory. -type yp struct { - Enabled bool `yaml:"enabled"` - InstanceURL string `yaml:"instanceURL"` // The public URL the directory should link to -} - -// streamQuality defines the specifics of a single HLS stream variant. -type streamQuality struct { - // Enable passthrough to copy the video and/or audio directly from the - // incoming stream and disable any transcoding. It will ignore any of - // the below settings. - IsVideoPassthrough bool `yaml:"videoPassthrough" json:"videoPassthrough"` - IsAudioPassthrough bool `yaml:"audioPassthrough" json:"audioPassthrough"` - - VideoBitrate int `yaml:"videoBitrate" json:"videoBitrate"` - AudioBitrate int `yaml:"audioBitrate" json:"audioBitrate"` - - // Set only one of these in order to keep your current aspect ratio. - // Or set neither to not scale the video. - ScaledWidth int `yaml:"scaledWidth" json:"scaledWidth,omitempty"` - ScaledHeight int `yaml:"scaledHeight" json:"scaledHeight,omitempty"` - - Framerate int `yaml:"framerate" json:"framerate"` - EncoderPreset string `yaml:"encoderPreset" json:"encoderPreset"` -} - -type files struct { - MaxNumberInPlaylist int `yaml:"maxNumberInPlaylist"` -} - -// s3 is for configuring the s3 integration. -type s3 struct { - Enabled bool `yaml:"enabled" json:"enabled"` - Endpoint string `yaml:"endpoint" json:"endpoint,omitempty"` - ServingEndpoint string `yaml:"servingEndpoint" json:"servingEndpoint,omitempty"` - AccessKey string `yaml:"accessKey" json:"accessKey,omitempty"` - Secret string `yaml:"secret" json:"secret,omitempty"` - Bucket string `yaml:"bucket" json:"bucket,omitempty"` - Region string `yaml:"region" json:"region,omitempty"` - ACL string `yaml:"acl" json:"acl,omitempty"` -}